Skip to content

Commit 8348741

Browse files
committed
closes #8261
Signed-off-by: osamahammad21 <osama21@aucegypt.edu>
1 parent f091c6e commit 8348741

14 files changed

Lines changed: 300 additions & 2 deletions

File tree

src/odb/include/odb/3dblox.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class Connection;
2222
class DesignDef;
2323
class dbChipRegionInst;
2424
class dbChipInst;
25+
class BumpMapEntry;
26+
class dbChipRegion;
2527

2628
class ThreeDBlox
2729
{
@@ -37,6 +39,7 @@ class ThreeDBlox
3739
dbChip* createDesignTopChiplet(const DesignDef& design);
3840
void createChipInst(const ChipletInst& chip_inst);
3941
void createConnection(const Connection& connection);
42+
void createBump(const BumpMapEntry& entry, dbChipRegion* chip_region);
4043
dbChipRegionInst* resolvePath(const std::string& path,
4144
std::vector<dbChipInst*>& path_insts);
4245
void readHeaderIncludes(const std::vector<std::string>& includes);

src/odb/src/3dblox/3dblox.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <string>
1111
#include <vector>
1212

13+
#include "bmapParser.h"
1314
#include "dbvParser.h"
1415
#include "dbxParser.h"
1516
#include "objects.h"
@@ -206,6 +207,13 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet)
206207

207208
chip->setOffset(Point(chiplet.offset.x * db_->getDbuPerMicron(),
208209
chiplet.offset.y * db_->getDbuPerMicron()));
210+
if (chip->getChipType() != dbChip::ChipType::HIER
211+
&& chip->getBlock() == nullptr) {
212+
// blackbox stage, create block
213+
auto block = odb::dbBlock::create(chip, chiplet.name.c_str());
214+
block->setDieArea(Rect(0, 0, chip->getWidth(), chip->getHeight()));
215+
block->setCoreArea(Rect(0, 0, chip->getWidth(), chip->getHeight()));
216+
}
209217
for (const auto& [_, region] : chiplet.regions) {
210218
createRegion(region, chip);
211219
}
@@ -244,7 +252,72 @@ void ThreeDBlox::createRegion(const ChipletRegion& region, dbChip* chip)
244252
box);
245253
}
246254
chip_region->setBox(box);
255+
// Read bump map file
256+
if (!region.bmap.empty()) {
257+
BmapParser parser(logger_);
258+
BumpMapData data = parser.parseFile(region.bmap);
259+
for (const auto& entry : data.entries) {
260+
createBump(entry, chip_region);
261+
}
262+
}
263+
}
264+
265+
void ThreeDBlox::createBump(const BumpMapEntry& entry,
266+
dbChipRegion* chip_region)
267+
{
268+
auto chip = chip_region->getChip();
269+
auto block = chip->getBlock();
270+
auto inst = block->findInst(entry.bump_inst_name.c_str());
271+
if (inst == nullptr) {
272+
// create inst
273+
auto master = db_->findMaster(entry.bump_cell_type.c_str());
274+
if (master == nullptr) {
275+
logger_->error(utl::ODB,
276+
531,
277+
"3DBV Parser Error: Bump cell type {} not found",
278+
entry.bump_cell_type);
279+
}
280+
if (master->getLib()->getTech() != chip->getTech()) {
281+
logger_->error(utl::ODB,
282+
532,
283+
"3DBV Parser Error: Bump cell type {} is not in the same "
284+
"tech as the chip region {}/{}",
285+
entry.bump_cell_type,
286+
chip->getName(),
287+
chip_region->getName());
288+
}
289+
inst = dbInst::create(block, master, entry.bump_inst_name.c_str());
290+
}
291+
auto bump = dbChipBump::create(chip_region, inst);
292+
inst->setOrigin(entry.x * db_->getDbuPerMicron(),
293+
entry.y * db_->getDbuPerMicron());
294+
inst->setPlacementStatus(dbPlacementStatus::FIRM);
295+
if (entry.net_name != "-") {
296+
auto net = block->findNet(entry.net_name.c_str());
297+
if (net == nullptr) {
298+
logger_->error(utl::ODB,
299+
534,
300+
"3DBV Parser Error: Bump net {} not found",
301+
entry.net_name);
302+
}
303+
bump->setNet(net);
304+
inst->getITerms().begin()->connect(net);
305+
}
306+
if (entry.port_name != "-") {
307+
auto bterm = block->findBTerm(entry.port_name.c_str());
308+
if (bterm == nullptr) {
309+
logger_->error(utl::ODB,
310+
533,
311+
"3DBV Parser Error: Bump port {} not found",
312+
entry.port_name);
313+
}
314+
bump->setBTerm(bterm);
315+
if (bump->getNet()) {
316+
bterm->connect(bump->getNet());
317+
}
318+
}
247319
}
320+
248321
dbChip* ThreeDBlox::createDesignTopChiplet(const DesignDef& design)
249322
{
250323
dbChip* chip

src/odb/src/3dblox/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ find_package(yaml-cpp REQUIRED)
55

66
add_library(3dblox
77
baseParser.cpp
8+
bmapParser.cpp
89
dbvParser.cpp
910
dbxParser.cpp
1011
3dblox.cpp

src/odb/src/3dblox/bmapParser.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright (c) 2019-2025, The OpenROAD Authors
3+
4+
#include "bmapParser.h"
5+
6+
#include <fstream>
7+
#include <sstream>
8+
#include <string>
9+
#include <vector>
10+
11+
#include "objects.h"
12+
#include "utl/Logger.h"
13+
namespace odb {
14+
15+
BmapParser::BmapParser(utl::Logger* logger) : logger_(logger)
16+
{
17+
}
18+
19+
BumpMapData BmapParser::parseFile(const std::string& filename)
20+
{
21+
current_file_path_ = filename;
22+
std::ifstream file(filename);
23+
if (!file.is_open()) {
24+
logger_->error(
25+
utl::ODB, 535, "Bump Map Parser Error: Cannot open file: {}", filename);
26+
}
27+
28+
std::stringstream buffer;
29+
buffer << file.rdbuf();
30+
std::string content = buffer.str();
31+
file.close();
32+
33+
BumpMapData data;
34+
parseBumpMapContent(data, content);
35+
36+
return data;
37+
}
38+
39+
void BmapParser::parseBumpMapContent(BumpMapData& data,
40+
const std::string& content)
41+
{
42+
std::istringstream stream(content);
43+
std::string line;
44+
int line_number = 0;
45+
46+
while (std::getline(stream, line)) {
47+
line_number++;
48+
49+
// Skip empty lines and comments (lines starting with #)
50+
if (line.empty() || line[0] == '#') {
51+
continue;
52+
}
53+
54+
parseBumpMapLine(data, line, line_number);
55+
}
56+
}
57+
58+
void BmapParser::parseBumpMapLine(BumpMapData& data,
59+
const std::string& line,
60+
int line_number)
61+
{
62+
std::vector<std::string> tokens = splitLine(line);
63+
64+
// Check if we have exactly 6 columns
65+
if (tokens.size() != 6) {
66+
logger_->error(
67+
utl::ODB,
68+
536,
69+
"Bump Map Parser Error: file {} Line {} has {} columns, expected 6. "
70+
"Format: bumpInstName bumpCellType x y portName netName",
71+
current_file_path_,
72+
line_number,
73+
tokens.size());
74+
}
75+
76+
try {
77+
// Parse coordinates as doubles
78+
const double x = std::stod(tokens[2]);
79+
const double y = std::stod(tokens[3]);
80+
81+
// Create bump map entry
82+
BumpMapEntry entry(tokens[0], tokens[1], x, y, tokens[4], tokens[5]);
83+
data.entries.push_back(entry);
84+
85+
} catch (const std::exception& e) {
86+
logger_->error(utl::ODB,
87+
537,
88+
"Bump Map Parser Error: file {} Line {} - Invalid "
89+
"coordinate format: {}",
90+
current_file_path_,
91+
line_number,
92+
std::string(e.what()));
93+
}
94+
}
95+
96+
std::vector<std::string> BmapParser::splitLine(const std::string& line)
97+
{
98+
std::vector<std::string> tokens;
99+
std::istringstream stream(line);
100+
std::string token;
101+
102+
while (stream >> token) {
103+
tokens.push_back(token);
104+
}
105+
106+
return tokens;
107+
}
108+
109+
} // namespace odb

src/odb/src/3dblox/bmapParser.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
// Copyright (c) 2019-2025, The OpenROAD Authors
3+
4+
#pragma once
5+
6+
#include <string>
7+
#include <vector>
8+
9+
namespace utl {
10+
class Logger;
11+
}
12+
namespace odb {
13+
class BumpMapData;
14+
class BumpMapEntry;
15+
16+
class BmapParser
17+
{
18+
public:
19+
BmapParser(utl::Logger* logger);
20+
21+
BumpMapData parseFile(const std::string& filename);
22+
23+
private:
24+
void parseBumpMapContent(BumpMapData& data, const std::string& content);
25+
void parseBumpMapLine(BumpMapData& data,
26+
const std::string& line,
27+
int line_number);
28+
std::vector<std::string> splitLine(const std::string& line);
29+
30+
utl::Logger* logger_;
31+
std::string current_file_path_;
32+
};
33+
34+
} // namespace odb

src/odb/src/3dblox/dbvParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,12 @@ void DbvParser::parseRegion(ChipletRegion& region,
207207
{
208208
if (region_node["bmap"]) {
209209
extractValue(region_node, "bmap", region.bmap);
210+
region.bmap = resolvePath(region.bmap);
210211
}
211212

212213
if (region_node["pmap"]) {
213214
extractValue(region_node, "pmap", region.pmap);
215+
region.pmap = resolvePath(region.pmap);
214216
}
215217

216218
if (region_node["side"]) {

src/odb/src/3dblox/objects.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,35 @@ struct DbxData
122122
std::map<std::string, Connection> connections;
123123
};
124124

125+
struct BumpMapEntry
126+
{
127+
std::string bump_inst_name;
128+
std::string bump_cell_type;
129+
double x{0.0};
130+
double y{0.0};
131+
std::string port_name;
132+
std::string net_name;
133+
134+
BumpMapEntry() = default;
135+
BumpMapEntry(const std::string& inst_name,
136+
const std::string& cell_type,
137+
double x_coord,
138+
double y_coord,
139+
const std::string& port,
140+
const std::string& net)
141+
: bump_inst_name(inst_name),
142+
bump_cell_type(cell_type),
143+
x(x_coord),
144+
y(y_coord),
145+
port_name(port),
146+
net_name(net)
147+
{
148+
}
149+
};
150+
151+
struct BumpMapData
152+
{
153+
std::vector<BumpMapEntry> entries;
154+
};
155+
125156
} // namespace odb

src/odb/src/db/dbChipInst.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ dbChipInst* dbChipInst::create(dbChip* parent_chip,
254254
bumpinst->region_next_ = regioninst->chip_bump_insts_;
255255
regioninst->chip_bump_insts_ = bumpinst->getOID();
256256
}
257+
// reverse the chip_bump_insts_ list
258+
((dbChipRegionInst*) regioninst)->getChipBumpInsts().reverse();
257259
}
260+
// reverse the chip_region_insts_ list
261+
((dbChipInst*) chipinst)->getRegions().reverse();
258262
return (dbChipInst*) chipinst;
259263
}
260264

src/odb/test/cpp/Test3DBloxParser.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,24 @@ TEST_F(DbvFixture, test_3dbx)
111111
EXPECT_EQ(connection->getThickness(), 0.0);
112112
}
113113

114+
TEST_F(DbvFixture, test_bump_map_parser)
115+
{
116+
auto region = db_->findChip("SoC")->findChipRegion("r1");
117+
EXPECT_EQ(region->getChipBumps().size(), 2);
118+
auto bump = *region->getChipBumps().begin();
119+
EXPECT_EQ(bump->getInst()->getName(), "bump1");
120+
EXPECT_EQ(bump->getInst()->getMaster()->getName(), "BUMP");
121+
EXPECT_EQ(bump->getInst()->getOrigin().x(), 100.0 * db_->getDbuPerMicron());
122+
EXPECT_EQ(bump->getInst()->getOrigin().y(), 200.0 * db_->getDbuPerMicron());
123+
EXPECT_EQ(bump->getNet(), nullptr);
124+
EXPECT_EQ(bump->getBTerm(), nullptr);
125+
auto soc_inst = db_->getChip()->findChipInst("soc_inst");
126+
auto region_inst = soc_inst->findChipRegionInst("r1");
127+
EXPECT_EQ(region_inst->getChipBumpInsts().size(), 2);
128+
auto bump_inst = *region_inst->getChipBumpInsts().begin();
129+
EXPECT_EQ(bump_inst->getChipBump(), bump);
130+
EXPECT_EQ(bump_inst->getChipRegionInst(), region_inst);
131+
}
132+
114133
} // namespace
115134
} // namespace odb

src/odb/test/data/example.3dbv

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ChipletDef:
2020
regions:
2121
r1:
2222
side: front
23-
bmap: Collateral/SoC/design/SoC_r1.bmap
23+
bmap: example.bmap
2424
pmap: Collateral/SoC/design/SoC_r1.pmap
2525
layer: UBM
2626
coords:
@@ -31,5 +31,5 @@ ChipletDef:
3131
external:
3232
APR_tech_file: [NG45_PATH/*_tech.lef]
3333
liberty_file: [NG45_PATH/fake_macros.lib]
34-
LEF_file: [NG45_PATH/fake_macros.lef]
34+
LEF_file: [NG45_PATH/fake_macros.lef, NG45_PATH/fake_bumps.lef]
3535
DEF_file: ../fake_macros.def

0 commit comments

Comments
 (0)