From 62eb5308339f76e44e1acb22d653eef35980fdfb Mon Sep 17 00:00:00 2001 From: Jorge Ferreira Date: Thu, 9 Apr 2026 19:37:45 +0000 Subject: [PATCH 1/4] Fix ODB: DEF_file in 3dbx (Issue #10077) Signed-off-by: Jorge Ferreira --- src/odb/src/3dblox/3dblox.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/odb/src/3dblox/3dblox.cpp b/src/odb/src/3dblox/3dblox.cpp index 5c10e56a4f6..45a5b90f9c8 100644 --- a/src/odb/src/3dblox/3dblox.cpp +++ b/src/odb/src/3dblox/3dblox.cpp @@ -464,6 +464,7 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet) chiplet.external.def_file.c_str(), chip, /*issue_callback*/ false); + odb::dbBoolProperty::create(chip, "def_file_read", true); } const int dbu_per_micron = db_->getDbuPerMicron(); if (chiplet.design_width != -1.0) { @@ -677,6 +678,23 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst) chip_inst.reference, chip_inst.name); } + + if (!chip_inst.external.def_file.empty()) { + if (odb::dbProperty::find(chip, "def_file_read") == nullptr) { + if (chip->getBlock() != nullptr) { + odb::dbBlock::destroy(chip->getBlock()); + } + odb::defin def_reader(db_, logger_, odb::defin::DEFAULT); + std::vector search_libs; + for (odb::dbLib* lib : db_->getLibs()) { + search_libs.push_back(lib); + } + def_reader.readChip( + search_libs, chip_inst.external.def_file.c_str(), chip, false); + odb::dbBoolProperty::create(chip, "def_file_read", true); + } + } + dbChipInst* inst = dbChipInst::create(db_->getChip(), chip, chip_inst.name); auto orient_str = chip_inst.orient; if (dup_orient_map.contains(orient_str)) { From fc03a5e955b52e0c03a93a35b437b03b96cf3cfe Mon Sep 17 00:00:00 2001 From: Jorge Ferreira Date: Fri, 10 Apr 2026 01:56:53 +0000 Subject: [PATCH 2/4] Fix: read and write def_file under ChipletInst to follow 3DBlox standard (Issue #10077) Signed-off-by: Jorge Ferreira --- src/odb/src/3dblox/3dblox.cpp | 34 +++++++++++++++++++++----------- src/odb/src/3dblox/dbxWriter.cpp | 5 +++++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/odb/src/3dblox/3dblox.cpp b/src/odb/src/3dblox/3dblox.cpp index 45a5b90f9c8..d261e01c067 100644 --- a/src/odb/src/3dblox/3dblox.cpp +++ b/src/odb/src/3dblox/3dblox.cpp @@ -465,6 +465,12 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet) chip, /*issue_callback*/ false); odb::dbBoolProperty::create(chip, "def_file_read", true); + if (auto* prop = odb::dbStringProperty::find(chip, "def_file_path")) { + prop->setValue(chiplet.external.def_file.c_str()); + } else { + odb::dbStringProperty::create( + chip, "def_file_path", chiplet.external.def_file.c_str()); + } } const int dbu_per_micron = db_->getDbuPerMicron(); if (chiplet.design_width != -1.0) { @@ -680,18 +686,22 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst) } if (!chip_inst.external.def_file.empty()) { - if (odb::dbProperty::find(chip, "def_file_read") == nullptr) { - if (chip->getBlock() != nullptr) { - odb::dbBlock::destroy(chip->getBlock()); - } - odb::defin def_reader(db_, logger_, odb::defin::DEFAULT); - std::vector search_libs; - for (odb::dbLib* lib : db_->getLibs()) { - search_libs.push_back(lib); - } - def_reader.readChip( - search_libs, chip_inst.external.def_file.c_str(), chip, false); - odb::dbBoolProperty::create(chip, "def_file_read", true); + if (chip->getBlock() != nullptr) { + odb::dbBlock::destroy(chip->getBlock()); + } + odb::defin def_reader(db_, logger_, odb::defin::DEFAULT); + std::vector search_libs; + for (odb::dbLib* lib : db_->getLibs()) { + search_libs.push_back(lib); + } + def_reader.readChip( + search_libs, chip_inst.external.def_file.c_str(), chip, false); + odb::dbBoolProperty::create(chip, "def_file_read", true); + if (auto* prop = odb::dbStringProperty::find(chip, "def_file_path")) { + prop->setValue(chip_inst.external.def_file.c_str()); + } else { + odb::dbStringProperty::create( + chip, "def_file_path", chip_inst.external.def_file.c_str()); } } diff --git a/src/odb/src/3dblox/dbxWriter.cpp b/src/odb/src/3dblox/dbxWriter.cpp index 39684afd5f8..059e07e0fa6 100644 --- a/src/odb/src/3dblox/dbxWriter.cpp +++ b/src/odb/src/3dblox/dbxWriter.cpp @@ -67,6 +67,11 @@ void DbxWriter::writeChipletInst(YAML::Node& instance_node, { auto master_name = inst->getMasterChip()->getName(); instance_node["reference"] = master_name; + auto* chip = inst->getMasterChip(); + if (odb::dbProperty::find(chip, "def_file_read") != nullptr) { + YAML::Node external_node = instance_node["external"]; + external_node["def_file"] = std::string(chip->getName()) + ".def"; + } } void DbxWriter::writeStack(YAML::Node& stack_node, odb::dbChip* chiplet) From 0b26cd18da5ca596d073b558c082bee7247a8bd5 Mon Sep 17 00:00:00 2001 From: Jorge Ferreira Date: Tue, 14 Apr 2026 22:05:17 +0000 Subject: [PATCH 3/4] style: apply clang-format to 3dblox files Signed-off-by: Jorge Ferreira --- src/odb/include/odb/3dblox.h | 1 + src/odb/src/3dblox/3dblox.cpp | 55 ++++++++++++++------------------ src/odb/src/3dblox/dbxWriter.cpp | 11 ++++--- src/odb/src/3dblox/dbxWriter.h | 3 ++ 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/odb/include/odb/3dblox.h b/src/odb/include/odb/3dblox.h index b6e07ff5626..ebe0eb33c6e 100644 --- a/src/odb/include/odb/3dblox.h +++ b/src/odb/include/odb/3dblox.h @@ -69,5 +69,6 @@ class ThreeDBlox std::unordered_set written_techs_; std::unordered_set written_libs_; std::unordered_set read_files_; + std::unordered_set insts_with_def_; }; } // namespace odb diff --git a/src/odb/src/3dblox/3dblox.cpp b/src/odb/src/3dblox/3dblox.cpp index d261e01c067..11687d9bffa 100644 --- a/src/odb/src/3dblox/3dblox.cpp +++ b/src/odb/src/3dblox/3dblox.cpp @@ -398,6 +398,20 @@ static std::string getFileName(const std::string& tech_file_path) return tech_file_path_fs.stem().string(); } +static inline void readDefForChip(odb::dbDatabase* db, + utl::Logger* logger, + odb::dbChip* chip, + const std::string& def_file) +{ + odb::defin def_reader(db, logger, odb::defin::DEFAULT); + std::vector search_libs; + for (odb::dbLib* lib : db->getLibs()) { + search_libs.push_back(lib); + } + // No callbacks here as we are going to give one postRead3Dbx later + def_reader.readChip(search_libs, def_file.c_str(), chip, false); +} + void ThreeDBlox::createChiplet(const ChipletDef& chiplet) { dbTech* tech = nullptr; @@ -454,23 +468,7 @@ void ThreeDBlox::createChiplet(const ChipletDef& chiplet) // Read DEF file if (!chiplet.external.def_file.empty()) { - odb::defin def_reader(db_, logger_, odb::defin::DEFAULT); - std::vector search_libs; - for (odb::dbLib* lib : db_->getLibs()) { - search_libs.push_back(lib); - } - // No callbacks here as we are going to give one postRead3Dbx later - def_reader.readChip(search_libs, - chiplet.external.def_file.c_str(), - chip, - /*issue_callback*/ false); - odb::dbBoolProperty::create(chip, "def_file_read", true); - if (auto* prop = odb::dbStringProperty::find(chip, "def_file_path")) { - prop->setValue(chiplet.external.def_file.c_str()); - } else { - odb::dbStringProperty::create( - chip, "def_file_path", chiplet.external.def_file.c_str()); - } + readDefForChip(db_, logger_, chip, chiplet.external.def_file); } const int dbu_per_micron = db_->getDbuPerMicron(); if (chiplet.design_width != -1.0) { @@ -686,23 +684,18 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst) } if (!chip_inst.external.def_file.empty()) { + if (insts_with_def_.count(chip) > 0) { + logger_->error(utl::ODB, + 546, + "3DBX Parser Error: There can't be 2 instances of the " + "same chiplet {} with a def file each", + chip->getName()); + } + insts_with_def_.insert(chip); if (chip->getBlock() != nullptr) { odb::dbBlock::destroy(chip->getBlock()); } - odb::defin def_reader(db_, logger_, odb::defin::DEFAULT); - std::vector search_libs; - for (odb::dbLib* lib : db_->getLibs()) { - search_libs.push_back(lib); - } - def_reader.readChip( - search_libs, chip_inst.external.def_file.c_str(), chip, false); - odb::dbBoolProperty::create(chip, "def_file_read", true); - if (auto* prop = odb::dbStringProperty::find(chip, "def_file_path")) { - prop->setValue(chip_inst.external.def_file.c_str()); - } else { - odb::dbStringProperty::create( - chip, "def_file_path", chip_inst.external.def_file.c_str()); - } + readDefForChip(db_, logger_, chip, chip_inst.external.def_file); } dbChipInst* inst = dbChipInst::create(db_->getChip(), chip, chip_inst.name); diff --git a/src/odb/src/3dblox/dbxWriter.cpp b/src/odb/src/3dblox/dbxWriter.cpp index 059e07e0fa6..fbce5ad86be 100644 --- a/src/odb/src/3dblox/dbxWriter.cpp +++ b/src/odb/src/3dblox/dbxWriter.cpp @@ -21,6 +21,7 @@ DbxWriter::DbxWriter(utl::Logger* logger, odb::dbDatabase* db) void DbxWriter::writeChiplet(const std::string& filename, odb::dbChip* chiplet) { + written_def_chips_.clear(); YAML::Node root; writeYamlContent(root, chiplet); writeYamlToFile(filename, root); @@ -65,12 +66,14 @@ void DbxWriter::writeChipletInsts(YAML::Node& instances_node, void DbxWriter::writeChipletInst(YAML::Node& instance_node, odb::dbChipInst* inst) { - auto master_name = inst->getMasterChip()->getName(); + auto chip = inst->getMasterChip(); + auto master_name = chip->getName(); instance_node["reference"] = master_name; - auto* chip = inst->getMasterChip(); - if (odb::dbProperty::find(chip, "def_file_read") != nullptr) { + + if (written_def_chips_.find(chip) == written_def_chips_.end()) { YAML::Node external_node = instance_node["external"]; - external_node["def_file"] = std::string(chip->getName()) + ".def"; + external_node["def_file"] = std::string(master_name) + ".def"; + written_def_chips_.insert(chip); } } diff --git a/src/odb/src/3dblox/dbxWriter.h b/src/odb/src/3dblox/dbxWriter.h index dbe33ed0506..f8faf10f2ad 100644 --- a/src/odb/src/3dblox/dbxWriter.h +++ b/src/odb/src/3dblox/dbxWriter.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include "baseWriter.h" @@ -42,6 +43,8 @@ class DbxWriter : public BaseWriter void writeConnection(YAML::Node& connection_node, odb::dbChipConn* conn); std::string buildPath(const std::vector& path_insts, odb::dbChipRegionInst* region); + + std::unordered_set written_def_chips_; }; } // namespace odb \ No newline at end of file From 362e77fd2614cfb7a8636b236e2758587d059da6 Mon Sep 17 00:00:00 2001 From: Jorge Ferreira Date: Tue, 14 Apr 2026 22:09:42 +0000 Subject: [PATCH 4/4] fix: use contains instead of count > 0 Signed-off-by: Jorge Ferreira --- src/odb/src/3dblox/3dblox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odb/src/3dblox/3dblox.cpp b/src/odb/src/3dblox/3dblox.cpp index 11687d9bffa..a4dd18cfd5b 100644 --- a/src/odb/src/3dblox/3dblox.cpp +++ b/src/odb/src/3dblox/3dblox.cpp @@ -684,7 +684,7 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst) } if (!chip_inst.external.def_file.empty()) { - if (insts_with_def_.count(chip) > 0) { + if (insts_with_def_.contains(chip)) { logger_->error(utl::ODB, 546, "3DBX Parser Error: There can't be 2 instances of the "