Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/odb/include/odb/3dblox.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,6 @@ class ThreeDBlox
sta::Sta* sta_ = nullptr;
std::unordered_set<odb::dbTech*> written_techs_;
std::unordered_set<odb::dbLib*> written_libs_;
std::unordered_set<std::string> read_files_;
};
} // namespace odb
2 changes: 2 additions & 0 deletions src/odb/include/odb/dbTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ class dbTransform

dbOrientType getOrient() const { return orient_; }
Point getOffset() const { return Point(offset_.x(), offset_.y()); }
Point3D getOffset3D() const { return offset_; }
bool isMirrorZ() const { return mirror_z_; }

friend dbOStream& operator<<(dbOStream& stream, const dbTransform& t);
friend dbIStream& operator>>(dbIStream& stream, dbTransform& t);
Expand Down
18 changes: 18 additions & 0 deletions src/odb/include/odb/geom.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,18 @@ class Cuboid
// A cuboid intersects any part of this cuboid.
bool intersects(const Cuboid& b) const;

// A cuboid intersects any part of this cuboid in XY plane
bool xyIntersects(const Cuboid& b) const;

// A point intersects the interior of this cuboid
bool overlaps(const Point3D& p) const;

// A cuboid intersects the interior of this cuboid
bool overlaps(const Cuboid& b) const;

// A cuboid intersects the interior of this cuboid in XY plane
bool xyOverlaps(const Cuboid& b) const;

// A cuboid is contained in the interior of this cuboid
bool contains(const Cuboid& b) const;

Expand Down Expand Up @@ -1252,6 +1258,12 @@ inline bool Cuboid::intersects(const Cuboid& b) const
&& (b.ylo_ <= yhi_) && (b.zhi_ >= zlo_) && (b.zlo_ <= zhi_);
}

inline bool Cuboid::xyIntersects(const Cuboid& b) const
{
return (b.xhi_ >= xlo_) && (b.xlo_ <= xhi_) && (b.yhi_ >= ylo_)
&& (b.ylo_ <= yhi_);
}

inline bool Cuboid::overlaps(const Point3D& p) const
{
return (p.x() > xlo_) && (p.x() < xhi_) && (p.y() > ylo_) && (p.y() < yhi_)
Expand All @@ -1264,6 +1276,12 @@ inline bool Cuboid::overlaps(const Cuboid& b) const
&& (b.ylo_ < yhi_) && (b.zhi_ > zlo_) && (b.zlo_ < zhi_);
}

inline bool Cuboid::xyOverlaps(const Cuboid& b) const
{
return (b.xhi_ > xlo_) && (b.xlo_ < xhi_) && (b.yhi_ > ylo_)
&& (b.ylo_ < yhi_);
}

inline bool Cuboid::contains(const Cuboid& b) const
{
return (xlo_ <= b.xlo_) && (ylo_ <= b.ylo_) && (zlo_ <= b.zlo_)
Expand Down
144 changes: 111 additions & 33 deletions src/odb/src/3dblox/3dblox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ ThreeDBlox::ThreeDBlox(utl::Logger* logger, odb::dbDatabase* db, sta::Sta* sta)

void ThreeDBlox::readDbv(const std::string& dbv_file)
{
std::string full_path = std::filesystem::absolute(dbv_file).string();
read_files_.insert(full_path);
DbvParser parser(logger_);
DbvData data = parser.parseFile(dbv_file);
if (db_->getDbuPerMicron() == 0) {
Expand Down Expand Up @@ -79,6 +81,8 @@ void ThreeDBlox::readDbv(const std::string& dbv_file)

void ThreeDBlox::readDbx(const std::string& dbx_file)
{
std::string full_path = std::filesystem::absolute(dbx_file).string();
read_files_.insert(full_path);
DbxParser parser(logger_);
DbxData data = parser.parseFile(dbx_file);
readHeaderIncludes(data.header.includes);
Expand Down Expand Up @@ -160,7 +164,7 @@ void ThreeDBlox::writeDbv(const std::string& dbv_file, odb::dbChip* chip)
}
// write used techs
for (auto tech : getUsedTechs(chip)) {
if (written_techs_.find(tech) != written_techs_.end()) {
if (written_techs_.contains(tech)) {
continue;
}
written_techs_.insert(tech);
Expand All @@ -171,7 +175,7 @@ void ThreeDBlox::writeDbv(const std::string& dbv_file, odb::dbChip* chip)
}
// write used libs
for (auto lib : getUsedLibs(chip)) {
if (written_libs_.find(lib) != written_libs_.end()) {
if (written_libs_.contains(lib)) {
continue;
}
written_libs_.insert(lib);
Expand Down Expand Up @@ -229,6 +233,19 @@ void ThreeDBlox::calculateSize(dbChip* chip)
void ThreeDBlox::readHeaderIncludes(const std::vector<std::string>& includes)
{
for (const auto& include : includes) {
// Resolve full path to check against read_files_
// Note: This logic assumes 'include' is relative to CWD or is absolute.
// If recursively parsed files have includes relative to themselves,
// the parser (DbxParser) handles finding them, but we might check the wrong
// string here if we don't know the base path.
// However, since we don't have base path info readily available without API
// change, we use absolute() as a best-effort de-duplication key.
std::string full_path = std::filesystem::absolute(include).string();
if (read_files_.contains(full_path)) {
continue;
}
read_files_.insert(full_path);

if (include.find(".3dbv") != std::string::npos) {
readDbv(include);
} else if (include.find(".3dbx") != std::string::npos) {
Expand All @@ -237,7 +254,8 @@ void ThreeDBlox::readHeaderIncludes(const std::vector<std::string>& includes)
}
}

dbChip::ChipType getChipType(const std::string& type, utl::Logger* logger)
static dbChip::ChipType getChipType(const std::string& type,
utl::Logger* logger)
{
if (type == "die") {
return dbChip::ChipType::DIE;
Expand All @@ -258,7 +276,7 @@ dbChip::ChipType getChipType(const std::string& type, utl::Logger* logger)
utl::ODB, 527, "3DBV Parser Error: Invalid chip type: {}", type);
}

std::string getFileName(const std::string& tech_file_path)
static std::string getFileName(const std::string& tech_file_path)
{
std::filesystem::path tech_file_path_fs(tech_file_path);
return tech_file_path_fs.stem().string();
Expand Down Expand Up @@ -317,6 +335,9 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet)
chip = dbChip::create(
db_, tech, chiplet.name, getChipType(chiplet.type, logger_));
}
if (tech != nullptr) {
odb::dbStringProperty::create(chip, "3dblox_tech", tech->getName().c_str());
}
// Read DEF file
if (!chiplet.external.def_file.empty()) {
odb::defin def_reader(db_, logger_, odb::defin::DEFAULT);
Expand Down Expand Up @@ -376,8 +397,8 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet)
}
}

dbChipRegion::Side getChipRegionSide(const std::string& side,
utl::Logger* logger)
static dbChipRegion::Side getChipRegionSide(const std::string& side,
utl::Logger* logger)
{
if (side == "front") {
return dbChipRegion::Side::FRONT;
Expand All @@ -398,10 +419,21 @@ void ThreeDBlox::createRegion(const ChipletRegion& region, dbChip* chip)
{
dbTechLayer* layer = nullptr;
if (!region.layer.empty()) {
// TODO: add layer
dbTech* tech = chip->getTech();
if (tech) {
layer = tech->findLayer(region.layer.c_str());
}
}
dbTechLayer* layer_to_pass = (chip->getBlock() != nullptr) ? layer : nullptr;
dbChipRegion* chip_region
= dbChipRegion::create(chip,
region.name,
getChipRegionSide(region.side, logger_),
layer_to_pass);
if (layer != nullptr && layer_to_pass == nullptr) {
odb::dbStringProperty::create(
chip_region, "3dblox_layer", layer->getName().c_str());
}
dbChipRegion* chip_region = dbChipRegion::create(
chip, region.name, getChipRegionSide(region.side, logger_), layer);
Rect box;
box.mergeInit();
for (const auto& coord : region.coords) {
Expand Down Expand Up @@ -435,7 +467,8 @@ void ThreeDBlox::createBump(const BumpMapEntry& entry,
"3DBV Parser Error: Bump cell type {} not found",
entry.bump_cell_type);
}
if (master->getLib()->getTech() != chip->getTech()) {
dbTech* master_tech = master->getLib()->getTech();
if (master_tech != chip->getTech()) {
logger_->error(utl::ODB,
532,
"3DBV Parser Error: Bump cell type {} is not in the same "
Expand All @@ -447,44 +480,77 @@ void ThreeDBlox::createBump(const BumpMapEntry& entry,
inst = dbInst::create(block, master, entry.bump_inst_name.c_str());
}
auto bump = dbChipBump::create(chip_region, inst);

Rect bbox;
inst->getMaster()->getPlacementBoundary(bbox);
int x = (entry.x * db_->getDbuPerMicron()) - bbox.xCenter()
+ chip->getOffset().x();
int y = (entry.y * db_->getDbuPerMicron()) - bbox.yCenter()
+ chip->getOffset().y();

inst->setOrigin(x, y);
inst->setPlacementStatus(dbPlacementStatus::FIRM);

dbNet* net = nullptr;
if (entry.net_name != "-") {
auto net = block->findNet(entry.net_name.c_str());
net = block->findNet(entry.net_name.c_str());
if (net == nullptr) {
logger_->error(utl::ODB,
534,
"3DBV Parser Error: Bump net {} not found",
entry.net_name);
net = dbNet::create(block, entry.net_name.c_str());
debugPrint(logger_,
utl::ODB,
"3dblox",
1,
"Creating missing net {} for bump {}",
entry.net_name,
entry.bump_inst_name);
}
bump->setNet(net);
inst->getITerms().begin()->connect(net);
if (!inst->getITerms().empty()) {
inst->getITerms().begin()->connect(net);
}
}
if (entry.port_name != "-") {
auto bterm = block->findBTerm(entry.port_name.c_str());
if (bterm == nullptr) {
logger_->error(utl::ODB,
533,
"3DBV Parser Error: Bump port {} not found",
entry.port_name);
if (net != nullptr) {
bterm = dbBTerm::create(net, entry.port_name.c_str());
debugPrint(logger_,
utl::ODB,
"3dblox",
1,
"Creating missing port {} for bump {}",
entry.port_name,
entry.bump_inst_name);
} else {
logger_->warn(utl::ODB,
545,
"Cannot create missing port {} for bump {} because no "
"net is specified.",
entry.port_name,
entry.bump_inst_name);
}
}
bump->setBTerm(bterm);
if (bump->getNet()) {
bterm->connect(bump->getNet());
if (bterm != nullptr) {
bump->setBTerm(bterm);
if (bump->getNet()) {
bterm->connect(bump->getNet());
}
}
}
}

dbChip* ThreeDBlox::createDesignTopChiplet(const DesignDef& design)
{
dbChip* chip
= dbChip::create(db_, nullptr, design.name, dbChip::ChipType::HIER);
dbChip* chip = db_->findChip(design.name.c_str());
if (chip == nullptr) {
chip = dbChip::create(db_, nullptr, design.name, dbChip::ChipType::HIER);
}
if (!design.external.verilog_file.empty()) {
if (odb::dbProperty::find(chip, "verilog_file") == nullptr) {
odb::dbStringProperty::create(
chip, "verilog_file", design.external.verilog_file.c_str());
}
}
db_->setTopChip(chip);
return chip;
}
Expand All @@ -502,7 +568,7 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst)
}
dbChipInst* inst = dbChipInst::create(db_->getChip(), chip, chip_inst.name);
auto orient_str = chip_inst.orient;
if (dup_orient_map.find(orient_str) != dup_orient_map.end()) {
if (dup_orient_map.contains(orient_str)) {
orient_str = dup_orient_map[orient_str];
}
auto orient = dbOrientType3D::fromString(orient_str);
Expand All @@ -514,11 +580,21 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst)
chip_inst.name);
}
inst->setOrient(orient.value());
inst->setLoc(Point3D(chip_inst.loc.x * db_->getDbuPerMicron(),
chip_inst.loc.y * db_->getDbuPerMicron(),
chip_inst.z * db_->getDbuPerMicron()));
inst->setLoc(Point3D{
static_cast<int>(chip_inst.loc.x * db_->getDbuPerMicron()),
static_cast<int>(chip_inst.loc.y * db_->getDbuPerMicron()),
static_cast<int>(chip_inst.z * db_->getDbuPerMicron()),
});

if (!chip_inst.external.verilog_file.empty()) {
if (odb::dbProperty::find(chip, "verilog_file") == nullptr) {
std::string verilog_file = chip_inst.external.verilog_file;
verilog_file = std::filesystem::absolute(verilog_file).string();
odb::dbStringProperty::create(chip, "verilog_file", verilog_file.c_str());
}
}
}
std::vector<std::string> splitPath(const std::string& path)
static std::vector<std::string> splitPath(const std::string& path)
{
std::vector<std::string> parts;
std::istringstream stream(path);
Expand Down Expand Up @@ -560,10 +636,11 @@ dbChipRegionInst* ThreeDBlox::resolvePath(const std::string& path,
// Replace the last part with just the chip instance name
path_parts.back() = last_chip_inst;

// TODO: Traverse hierarchy and find region
// Traverse hierarchy and find region
path_insts.reserve(path_parts.size());
dbChip* curr_chip = db_->getChip();
dbChipInst* curr_chip_inst = nullptr;

for (const auto& inst_name : path_parts) {
curr_chip_inst = curr_chip->findChipInst(inst_name);
if (curr_chip_inst == nullptr) {
Expand Down Expand Up @@ -625,7 +702,7 @@ void ThreeDBlox::readBMap(const std::string& bmap_file)
std::map<odb::dbMaster*, BPinInfo> bpininfo;
for (const auto& [inst, bterm] : bumps) {
dbMaster* master = inst->getMaster();
if (bpininfo.find(master) != bpininfo.end()) {
if (bpininfo.contains(master)) {
continue;
}

Expand Down Expand Up @@ -668,7 +745,8 @@ void ThreeDBlox::readBMap(const std::string& bmap_file)
top_shape_ptr = &(*top_shapes.begin());
}

bpininfo.emplace(master, BPinInfo{max_layer, *top_shape_ptr});
bpininfo.emplace(master,
BPinInfo{.layer = max_layer, .rect = *top_shape_ptr});
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/odb/src/3dblox/checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ void Checker::checkOverlappingChips(const UnfoldedModel& model,
marker->addSource(inst1->chip_inst_path.back());
marker->addSource(inst2->chip_inst_path.back());

std::string comment = "Chips " + inst1->getName() + " and "
+ inst2->getName() + " overlap";
std::string comment
= "Chips " + inst1->name + " and " + inst2->name + " overlap";
marker->setComment(comment);
}
}
Expand Down
Loading