Skip to content

Commit 20c0d00

Browse files
Merge pull request #9043 from gadfort/3dblx-port
odb: fix bmap reader to use bterm instead of net since net can have multiple bterms, but bterm can only have one net
2 parents 974d64f + cdb3597 commit 20c0d00

File tree

6 files changed

+213
-29
lines changed

6 files changed

+213
-29
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <string>
77
#include <unordered_set>
8+
#include <utility>
89
#include <vector>
910

1011
namespace utl {
@@ -26,6 +27,7 @@ class dbChipInst;
2627
class BumpMapEntry;
2728
class dbChipRegion;
2829
class dbBlock;
30+
class dbBTerm;
2931
class dbInst;
3032
class dbTech;
3133
class dbLib;
@@ -49,7 +51,8 @@ class ThreeDBlox
4951
void createChipInst(const ChipletInst& chip_inst);
5052
void createConnection(const Connection& connection);
5153
void createBump(const BumpMapEntry& entry, dbChipRegion* chip_region);
52-
dbInst* createBump(const BumpMapEntry& entry, dbBlock* block);
54+
std::pair<dbInst*, dbBTerm*> createBump(const BumpMapEntry& entry,
55+
dbBlock* block);
5356
dbChipRegionInst* resolvePath(const std::string& path,
5457
std::vector<dbChipInst*>& path_insts);
5558
void readHeaderIncludes(const std::vector<std::string>& includes);

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

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <sstream>
1111
#include <string>
1212
#include <unordered_set>
13+
#include <utility>
1314
#include <vector>
1415

1516
#include "bmapParser.h"
@@ -581,7 +582,7 @@ void ThreeDBlox::readBMap(const std::string& bmap_file)
581582

582583
BmapParser parser(logger_);
583584
BumpMapData data = parser.parseFile(bmap_file);
584-
std::vector<odb::dbInst*> bumps;
585+
std::vector<std::pair<odb::dbInst*, odb::dbBTerm*>> bumps;
585586
bumps.reserve(data.entries.size());
586587
for (const auto& entry : data.entries) {
587588
bumps.push_back(createBump(entry, block));
@@ -595,7 +596,7 @@ void ThreeDBlox::readBMap(const std::string& bmap_file)
595596

596597
// Populate where the bpins should be made
597598
std::map<odb::dbMaster*, BPinInfo> bpininfo;
598-
for (dbInst* inst : bumps) {
599+
for (const auto& [inst, bterm] : bumps) {
599600
dbMaster* master = inst->getMaster();
600601
if (bpininfo.find(master) != bpininfo.end()) {
601602
continue;
@@ -645,7 +646,11 @@ void ThreeDBlox::readBMap(const std::string& bmap_file)
645646
}
646647

647648
// create bpins
648-
for (dbInst* inst : bumps) {
649+
for (const auto& [inst, bterm] : bumps) {
650+
if (bterm == nullptr) {
651+
continue;
652+
}
653+
649654
auto masterbpin = bpininfo.find(inst->getMaster());
650655
if (masterbpin == bpininfo.end()) {
651656
continue;
@@ -654,28 +659,22 @@ void ThreeDBlox::readBMap(const std::string& bmap_file)
654659
const BPinInfo& pin_info = masterbpin->second;
655660

656661
const dbTransform xform = inst->getTransform();
657-
for (dbITerm* iterm : inst->getITerms()) {
658-
dbNet* net = iterm->getNet();
659-
if (net == nullptr) {
660-
continue;
661-
}
662-
dbBTerm* bterm = net->get1stBTerm();
663-
dbBPin* pin = dbBPin::create(bterm);
664-
Rect shape = pin_info.rect;
665-
xform.apply(shape);
666-
dbBox::create(pin,
667-
pin_info.layer,
668-
shape.xMin(),
669-
shape.yMin(),
670-
shape.xMax(),
671-
shape.yMax());
672-
pin->setPlacementStatus(odb::dbPlacementStatus::FIRM);
673-
break;
674-
}
662+
dbBPin* pin = dbBPin::create(bterm);
663+
Rect shape = pin_info.rect;
664+
xform.apply(shape);
665+
dbBox::create(pin,
666+
pin_info.layer,
667+
shape.xMin(),
668+
shape.yMin(),
669+
shape.xMax(),
670+
shape.yMax());
671+
pin->setPlacementStatus(odb::dbPlacementStatus::FIRM);
675672
}
676673
}
677674

678-
dbInst* ThreeDBlox::createBump(const BumpMapEntry& entry, dbBlock* block)
675+
std::pair<dbInst*, odb::dbBTerm*> ThreeDBlox::createBump(
676+
const BumpMapEntry& entry,
677+
dbBlock* block)
679678
{
680679
const int dbus = db_->getDbuPerMicron();
681680
dbInst* inst = block->findInst(entry.bump_inst_name.c_str());
@@ -693,22 +692,52 @@ dbInst* ThreeDBlox::createBump(const BumpMapEntry& entry, dbBlock* block)
693692
inst->setOrigin(entry.x * dbus, entry.y * dbus);
694693
inst->setPlacementStatus(dbPlacementStatus::FIRM);
695694

696-
// Net entry doesn't make sense
697-
if (entry.net_name != "-") {
698-
dbNet* net = block->findNet(entry.net_name.c_str());
699-
if (net == nullptr) {
695+
dbNet* net = nullptr;
696+
dbBTerm* term = nullptr;
697+
698+
// Find bterm
699+
if (entry.port_name != "-") {
700+
term = block->findBTerm(entry.port_name.c_str());
701+
if (term == nullptr) {
700702
logger_->error(utl::ODB,
701703
539,
704+
"3DBV Parser Error: Bump port {} not found",
705+
entry.port_name);
706+
}
707+
net = term->getNet();
708+
}
709+
710+
// Find term via net
711+
if (term == nullptr && entry.net_name != "-") {
712+
net = block->findNet(entry.net_name.c_str());
713+
if (net == nullptr) {
714+
logger_->error(utl::ODB,
715+
543,
702716
"3DBV Parser Error: Bump net {} not found",
703717
entry.net_name);
704718
}
719+
if (net->getBTerms().empty()) {
720+
logger_->error(utl::ODB,
721+
544,
722+
"3DBV Parser Error: Bump net {} has no bterms",
723+
entry.net_name);
724+
}
725+
if (net->getBTerms().size() > 1) {
726+
logger_->error(utl::ODB,
727+
542,
728+
"3DBV Parser Error: Bump net {} has multiple bterms",
729+
entry.net_name);
730+
}
731+
term = net->get1stBTerm();
732+
}
733+
734+
if (net != nullptr) {
705735
for (odb::dbITerm* iterm : inst->getITerms()) {
706736
iterm->connect(net);
707737
}
708738
}
709-
// Port already on the net, so skip
710739

711-
return inst;
740+
return {inst, term};
712741
}
713742

714743
} // namespace odb

src/odb/test/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ filegroup(
283283
"data/example.3dbx",
284284
"data/example.bmap",
285285
"data/example1.bmap",
286+
"data/example2.bmap",
287+
"data/example3.bmap",
286288
"data/floorplan_initialize.def",
287289
"data/floorplan_initialize.v",
288290
"data/floorplan_initialize2.def",

src/odb/test/cpp/Test3DBloxParser.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <iostream>
2+
#include <stdexcept>
23
#include <string>
34

45
#include "gtest/gtest.h"
@@ -201,5 +202,148 @@ TEST_F(SimpleDbFixture, test_bump_map_reader)
201202
EXPECT_EQ(sig2_box->getBox().yMax(), 202000);
202203
}
203204

205+
TEST_F(SimpleDbFixture, test_bump_map_reader_netsonly)
206+
{
207+
createSimpleDB();
208+
209+
db_->setDbuPerMicron(1000);
210+
211+
// Create BUMP master
212+
dbLib* lib = db_->findLib("lib1");
213+
dbTechLayer* bot_layer
214+
= dbTechLayer::create(lib->getTech(), "BOT", dbTechLayerType::ROUTING);
215+
dbTechLayer* layer
216+
= dbTechLayer::create(lib->getTech(), "TOP", dbTechLayerType::ROUTING);
217+
dbMaster* master = dbMaster::create(lib, "BUMP");
218+
master->setWidth(10000);
219+
master->setHeight(10000);
220+
master->setOrigin(5000, 5000);
221+
master->setType(dbMasterType::COVER_BUMP);
222+
dbMTerm* term
223+
= dbMTerm::create(master, "PAD", dbIoType::INOUT, dbSigType::SIGNAL);
224+
dbMPin* bot_pin = dbMPin::create(term);
225+
dbBox::create(bot_pin, bot_layer, -1000, -1000, 1000, 1000);
226+
dbMPin* pin = dbMPin::create(term);
227+
dbBox::create(pin, layer, -2000, -2000, 2000, 2000);
228+
master->setFrozen();
229+
230+
// Create BTerms
231+
dbBlock* block = db_->getChip()->getBlock();
232+
dbBTerm* SIG1 = dbBTerm::create(dbNet::create(block, "SIG1"), "SIG1");
233+
dbBTerm* SIG2 = dbBTerm::create(dbNet::create(block, "SIG2"), "SIG2");
234+
block->setDieArea(Rect(0, 0, 500, 500));
235+
236+
EXPECT_EQ(block->getInsts().size(), 0);
237+
238+
ThreeDBlox parser(&logger_, db_.get());
239+
std::string path = getFilePath(prefix + "data/example2.bmap");
240+
parser.readBMap(path);
241+
242+
// Check bumps were created
243+
EXPECT_EQ(block->getInsts().size(), 2);
244+
dbInst* inst1 = block->findInst("bump1");
245+
EXPECT_EQ(inst1->getBBox()->getBox().xCenter(), 100 * 1000);
246+
EXPECT_EQ(inst1->getBBox()->getBox().yCenter(), 200 * 1000);
247+
dbInst* inst2 = block->findInst("bump2");
248+
EXPECT_EQ(inst2->getBBox()->getBox().xCenter(), 150 * 1000);
249+
EXPECT_EQ(inst2->getBBox()->getBox().yCenter(), 200 * 1000);
250+
251+
// Check that BPins where added
252+
EXPECT_EQ(SIG1->getBPins().size(), 1);
253+
EXPECT_EQ(SIG2->getBPins().size(), 1);
254+
EXPECT_EQ(SIG1->getBPins().begin()->getBoxes().size(), 1);
255+
EXPECT_EQ(SIG2->getBPins().begin()->getBoxes().size(), 1);
256+
257+
// Check bPin shape and layer
258+
dbBox* sig1_box = *SIG1->getBPins().begin()->getBoxes().begin();
259+
dbBox* sig2_box = *SIG2->getBPins().begin()->getBoxes().begin();
260+
EXPECT_EQ(sig1_box->getTechLayer(), layer);
261+
EXPECT_EQ(sig1_box->getBox().xMin(), 98000);
262+
EXPECT_EQ(sig1_box->getBox().yMin(), 198000);
263+
EXPECT_EQ(sig1_box->getBox().xMax(), 102000);
264+
EXPECT_EQ(sig1_box->getBox().yMax(), 202000);
265+
EXPECT_EQ(sig2_box->getTechLayer(), layer);
266+
EXPECT_EQ(sig2_box->getBox().xMin(), 148000);
267+
EXPECT_EQ(sig2_box->getBox().yMin(), 198000);
268+
EXPECT_EQ(sig2_box->getBox().xMax(), 152000);
269+
EXPECT_EQ(sig2_box->getBox().yMax(), 202000);
270+
}
271+
272+
TEST_F(SimpleDbFixture, test_bump_map_reader_multiple_bterms)
273+
{
274+
createSimpleDB();
275+
276+
db_->setDbuPerMicron(1000);
277+
278+
// Create BUMP master
279+
dbLib* lib = db_->findLib("lib1");
280+
dbTechLayer* bot_layer
281+
= dbTechLayer::create(lib->getTech(), "BOT", dbTechLayerType::ROUTING);
282+
dbTechLayer* layer
283+
= dbTechLayer::create(lib->getTech(), "TOP", dbTechLayerType::ROUTING);
284+
dbMaster* master = dbMaster::create(lib, "BUMP");
285+
master->setWidth(10000);
286+
master->setHeight(10000);
287+
master->setOrigin(5000, 5000);
288+
master->setType(dbMasterType::COVER_BUMP);
289+
dbMTerm* term
290+
= dbMTerm::create(master, "PAD", dbIoType::INOUT, dbSigType::SIGNAL);
291+
dbMPin* bot_pin = dbMPin::create(term);
292+
dbBox::create(bot_pin, bot_layer, -1000, -1000, 1000, 1000);
293+
dbMPin* pin = dbMPin::create(term);
294+
dbBox::create(pin, layer, -2000, -2000, 2000, 2000);
295+
master->setFrozen();
296+
297+
// Create BTerms
298+
dbBlock* block = db_->getChip()->getBlock();
299+
dbNet* net = dbNet::create(block, "SIG1");
300+
dbBTerm::create(net, "TERM1");
301+
dbBTerm::create(net, "TERM2");
302+
block->setDieArea(Rect(0, 0, 500, 500));
303+
304+
EXPECT_EQ(block->getInsts().size(), 0);
305+
306+
ThreeDBlox parser(&logger_, db_.get());
307+
std::string path = getFilePath(prefix + "data/example3.bmap");
308+
EXPECT_THROW(parser.readBMap(path), std::runtime_error);
309+
}
310+
311+
TEST_F(SimpleDbFixture, test_bump_map_reader_no_bterms)
312+
{
313+
createSimpleDB();
314+
315+
db_->setDbuPerMicron(1000);
316+
317+
// Create BUMP master
318+
dbLib* lib = db_->findLib("lib1");
319+
dbTechLayer* bot_layer
320+
= dbTechLayer::create(lib->getTech(), "BOT", dbTechLayerType::ROUTING);
321+
dbTechLayer* layer
322+
= dbTechLayer::create(lib->getTech(), "TOP", dbTechLayerType::ROUTING);
323+
dbMaster* master = dbMaster::create(lib, "BUMP");
324+
master->setWidth(10000);
325+
master->setHeight(10000);
326+
master->setOrigin(5000, 5000);
327+
master->setType(dbMasterType::COVER_BUMP);
328+
dbMTerm* term
329+
= dbMTerm::create(master, "PAD", dbIoType::INOUT, dbSigType::SIGNAL);
330+
dbMPin* bot_pin = dbMPin::create(term);
331+
dbBox::create(bot_pin, bot_layer, -1000, -1000, 1000, 1000);
332+
dbMPin* pin = dbMPin::create(term);
333+
dbBox::create(pin, layer, -2000, -2000, 2000, 2000);
334+
master->setFrozen();
335+
336+
// Create BTerms
337+
dbBlock* block = db_->getChip()->getBlock();
338+
dbNet::create(block, "SIG1");
339+
block->setDieArea(Rect(0, 0, 500, 500));
340+
341+
EXPECT_EQ(block->getInsts().size(), 0);
342+
343+
ThreeDBlox parser(&logger_, db_.get());
344+
std::string path = getFilePath(prefix + "data/example3.bmap");
345+
EXPECT_THROW(parser.readBMap(path), std::runtime_error);
346+
}
347+
204348
} // namespace
205349
} // namespace odb

src/odb/test/data/example2.bmap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# bumpInstName bumpCellType x y portName netName
2+
bump1 BUMP 100.0 200.0 - SIG1
3+
bump2 BUMP 150.0 200.0 - SIG2

src/odb/test/data/example3.bmap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# bumpInstName bumpCellType x y portName netName
2+
bump1 BUMP 100.0 200.0 - SIG1
3+
bump2 BUMP 150.0 200.0 - SIG1

0 commit comments

Comments
 (0)