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 5c10e56a4f6..a4dd18cfd5b 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,16 +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); + readDefForChip(db_, logger_, chip, chiplet.external.def_file); } const int dbu_per_micron = db_->getDbuPerMicron(); if (chiplet.design_width != -1.0) { @@ -677,6 +682,22 @@ void ThreeDBlox::createChipInst(const ChipletInst& chip_inst) chip_inst.reference, chip_inst.name); } + + if (!chip_inst.external.def_file.empty()) { + if (insts_with_def_.contains(chip)) { + 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()); + } + readDefForChip(db_, logger_, chip, chip_inst.external.def_file); + } + dbChipInst* inst = dbChipInst::create(db_->getChip(), chip, chip_inst.name); auto orient_str = chip_inst.orient; if (dup_orient_map.contains(orient_str)) { diff --git a/src/odb/src/3dblox/dbxWriter.cpp b/src/odb/src/3dblox/dbxWriter.cpp index 39684afd5f8..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,8 +66,15 @@ 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; + + if (written_def_chips_.find(chip) == written_def_chips_.end()) { + YAML::Node external_node = instance_node["external"]; + external_node["def_file"] = std::string(master_name) + ".def"; + written_def_chips_.insert(chip); + } } void DbxWriter::writeStack(YAML::Node& stack_node, odb::dbChip* chiplet) 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