From 0ad40ec95f7e4d1b18d50e32ef25f7993163936e Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Wed, 5 Jun 2024 12:44:29 -0700 Subject: [PATCH 1/5] Reworked sta is to use uniquified ids in hierarchy mode. Signed-off-by:Andy Fox Signed-off-by: andyfox-rushc --- src/dbSta/src/dbNetwork.cc | 124 +++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 34 deletions(-) diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index bdbb260dabe..0e1bd01540a 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -65,9 +65,12 @@ using odb::dbModBTermObj; using odb::dbModInstObj; using odb::dbModITerm; using odb::dbModITermObj; +using odb::dbModNetObj; using odb::dbModule; +using odb::dbModuleObj; using odb::dbMTerm; using odb::dbNet; +using odb::dbNetObj; using odb::dbObject; using odb::dbObjectType; using odb::dbPlacementStatus; @@ -82,6 +85,71 @@ char* tmpStringCopy(const char* str) return tmp; } +// +// Handling of object ids (Hierachy Mode) +//-------------------------------------- +// +// The database assigns a number to each object. These numbers +// are scoped based on the type. Eg dbModInst 1..N or dbInst 1..N. +// The timer requires a unique id for each object for its visit +// pattern, so we uniquify the numbers by suffixing a discriminating +// address pattern to the lower bits and shifting. +// Everytime a new type of timing related object is added, we +// must update this code, so it is isolated and marked up here. +// +// The id is used by the STA traversers to accumulate visited. +// lower 4 bits used to encode type +// + +#define DBITERM_ID 0x0 +#define DBBTERM_ID 0x1 +#define DBINST_ID 0x2 +#define DBNET_ID 0x3 +#define DBMODITERM_ID 0x4 +#define DBMODBTERM_ID 0x5 +#define DBMODINST_ID 0x6 +#define DBMODNET_ID 0x7 +#define DBMODULE_ID 0x8 +// Number of lower bits used +#define DBIDTAG_WIDTH 0x4 + +ObjectId getDbNwkObjectId(dbObjectType typ, ObjectId db_id) +{ + switch (typ) { + case dbITermObj: { + return ((db_id << DBIDTAG_WIDTH) | DBITERM_ID); + } break; + case dbBTermObj: { + return ((db_id << DBIDTAG_WIDTH) | DBBTERM_ID); + } break; + case dbInstObj: { + return ((db_id << DBIDTAG_WIDTH) | DBINST_ID); + } break; + case dbNetObj: { + return ((db_id << DBIDTAG_WIDTH) | DBNET_ID); + } break; + case dbModITermObj: { + return ((db_id << DBIDTAG_WIDTH) | DBMODITERM_ID); + } break; + case dbModBTermObj: { + return ((db_id << DBIDTAG_WIDTH) | DBMODBTERM_ID); + } break; + case dbModInstObj: { + return ((db_id << DBIDTAG_WIDTH) | DBMODINST_ID); + } break; + case dbModNetObj: { + return ((db_id << DBIDTAG_WIDTH) | DBMODNET_ID); + } break; + case dbModuleObj: { + return ((db_id << DBIDTAG_WIDTH) | DBMODULE_ID); + } break; + default: + return 0; + break; + } + return 0; +} + class DbLibraryIterator1 : public Iterator { public: @@ -489,6 +557,11 @@ int dbNetwork::metersToDbu(double dist) const ObjectId dbNetwork::id(const Port* port) const { + if (hierarchy_) { + dbObject* obj = reinterpret_cast(const_cast(port)); + dbObjectType type = obj->getObjectType(); + return getDbNwkObjectId(type, obj->getId()); + } if (!port) { // should not match anything else return std::numeric_limits::max(); @@ -504,15 +577,10 @@ ObjectId dbNetwork::id(const Instance* instance) const return 0; } if (hierarchy_) { - dbInst* db_inst; - dbModInst* mod_inst; - staToDb(instance, db_inst, mod_inst); - if (db_inst) { - return db_inst->getId() << 1; - } - if (mod_inst) { - return (mod_inst->getId() << 1) + 1; - } + dbObject* obj + = reinterpret_cast(const_cast(instance)); + dbObjectType type = obj->getObjectType(); + return getDbNwkObjectId(type, obj->getId()); } return staToDb(instance)->getId(); } @@ -760,28 +828,12 @@ ObjectId dbNetwork::id(const Pin* pin) const dbModBTerm* modbterm = nullptr; static std::map id_ptr_map; - staToDb(pin, iterm, bterm, moditerm, modbterm); if (hierarchy_) { - // The id is used by the STA traversers to accumulate visited. - // lower bits used to encode type - // id,00 <- iterm - // id,01 <- bterm - // id,10 <- moditerm - // id,11 <- modbterm - if (iterm != nullptr) { - return iterm->getId() << 2; - } - if (bterm != nullptr) { - return (bterm->getId() << 2) | 0x1; - } - if (moditerm != nullptr) { - return (moditerm->getId() << 2) | 0x2; - } - if (modbterm != nullptr) { - return (modbterm->getId() << 2) | 0x3; - } + dbObject* obj = reinterpret_cast(const_cast(pin)); + dbObjectType type = obj->getObjectType(); + return getDbNwkObjectId(type, obj->getId()); } else { if (iterm != nullptr) { return iterm->getId() << 1; @@ -1067,12 +1119,9 @@ ObjectId dbNetwork::id(const Net* net) const dbNet* dnet = nullptr; staToDb(net, dnet, modnet); if (hierarchy_) { - if (dnet) { - return dnet->getId() << 1; - } - if (modnet) { - return (modnet->getId() << 1) + 1; - } + dbObject* obj = reinterpret_cast(const_cast(net)); + dbObjectType type = obj->getObjectType(); + return getDbNwkObjectId(type, obj->getId()); } else { return dnet->getId(); } @@ -1208,6 +1257,11 @@ const Net* dbNetwork::highestConnectedNet(Net* net) const ObjectId dbNetwork::id(const Term* term) const { + if (hierarchy_) { + dbObject* obj = reinterpret_cast(const_cast(term)); + dbObjectType type = obj->getObjectType(); + return getDbNwkObjectId(type, obj->getId()); + } return staToDb(term)->getId(); } @@ -1886,6 +1940,8 @@ dbMaster* dbNetwork::staToDb(const LibertyCell* cell) const dbMTerm* dbNetwork::staToDb(const Port* port) const { + // Todo fix to use modbterm + const ConcretePort* cport = reinterpret_cast(port); return reinterpret_cast(cport->extPort()); } From 917f192bb2168d1b509745dec7fecf140f794243 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Wed, 5 Jun 2024 15:45:27 -0700 Subject: [PATCH 2/5] const expr, add error message for undefined modtype. Signed-off-by: Andy Fox Signed-off-by: andyfox-rushc --- src/dbSta/include/db_sta/dbNetwork.hh | 2 ++ src/dbSta/src/dbNetwork.cc | 28 ++++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/dbSta/include/db_sta/dbNetwork.hh b/src/dbSta/include/db_sta/dbNetwork.hh index 0b6fb213347..0b685f3049a 100644 --- a/src/dbSta/include/db_sta/dbNetwork.hh +++ b/src/dbSta/include/db_sta/dbNetwork.hh @@ -65,6 +65,7 @@ using odb::dbModule; using odb::dbMTerm; using odb::dbNet; using odb::dbObject; +using odb::dbObjectType; using odb::dbSet; using odb::dbSigType; using odb::Point; @@ -103,6 +104,7 @@ class dbNetwork : public ConcreteNetwork void addObserver(dbNetworkObserver* observer); void removeObserver(dbNetworkObserver* observer); + ObjectId getDbNwkObjectId(dbObjectType typ, ObjectId db_id) const; dbBlock* block() const { return block_; } void makeLibrary(dbLib* lib); void makeCell(Library* library, dbMaster* master); diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index 0e1bd01540a..ad102659603 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -101,19 +101,19 @@ char* tmpStringCopy(const char* str) // lower 4 bits used to encode type // -#define DBITERM_ID 0x0 -#define DBBTERM_ID 0x1 -#define DBINST_ID 0x2 -#define DBNET_ID 0x3 -#define DBMODITERM_ID 0x4 -#define DBMODBTERM_ID 0x5 -#define DBMODINST_ID 0x6 -#define DBMODNET_ID 0x7 -#define DBMODULE_ID 0x8 +static constexpr unsigned DBITERM_ID = 0x0; +static constexpr unsigned DBBTERM_ID = 0x1; +static constexpr unsigned DBINST_ID = 0x2; +static constexpr unsigned DBNET_ID = 0x3; +static constexpr unsigned DBMODITERM_ID = 0x4; +static constexpr unsigned DBMODBTERM_ID = 0x5; +static constexpr unsigned DBMODINST_ID = 0x6; +static constexpr unsigned DBMODNET_ID = 0x7; +static constexpr unsigned DBMODULE_ID = 0x8; // Number of lower bits used -#define DBIDTAG_WIDTH 0x4 +static constexpr unsigned DBIDTAG_WIDTH = 0x4; -ObjectId getDbNwkObjectId(dbObjectType typ, ObjectId db_id) +ObjectId dbNetwork::getDbNwkObjectId(dbObjectType typ, ObjectId db_id) const { switch (typ) { case dbITermObj: { @@ -144,6 +144,12 @@ ObjectId getDbNwkObjectId(dbObjectType typ, ObjectId db_id) return ((db_id << DBIDTAG_WIDTH) | DBMODULE_ID); } break; default: + logger_->error( + ORD, + 2017, + "Error: unknown database type passed into unique id generation"); + // note the default "exception undefined case" in database is 0. + // so we reasonably expect upstream tools to handle this. return 0; break; } From c655c477fd98e4809e20de185495aad7cba9cf05 Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Thu, 6 Jun 2024 00:57:27 -0700 Subject: [PATCH 3/5] Added range check for db id in dbNetwork -- move this to database code, once hierarchy brought up. Signed-off-by:Andy Fox Signed-off-by: andyfox-rushc --- src/dbSta/src/dbNetwork.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index ad102659603..8ef79d320d4 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -115,6 +115,10 @@ static constexpr unsigned DBIDTAG_WIDTH = 0x4; ObjectId dbNetwork::getDbNwkObjectId(dbObjectType typ, ObjectId db_id) const { + if (db_id > (std::numeric_limits::max() >> DBIDTAG_WIDTH)) { + logger_->error(ORD, 2019, "Error: database id exceeds capacity"); + } + switch (typ) { case dbITermObj: { return ((db_id << DBIDTAG_WIDTH) | DBITERM_ID); From b29477a5632f2a681b6bb1d9bd59e76c263d62ba Mon Sep 17 00:00:00 2001 From: andyfox-rushc Date: Sun, 9 Jun 2024 09:24:24 -0700 Subject: [PATCH 4/5] Put static constexpr in class dbNetwork. Signed-off-by: andyfox-rushc --- src/dbSta/include/db_sta/dbNetwork.hh | 14 ++++++++++++++ src/dbSta/src/dbNetwork.cc | 12 ------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/dbSta/include/db_sta/dbNetwork.hh b/src/dbSta/include/db_sta/dbNetwork.hh index 0b685f3049a..07e90ce40da 100644 --- a/src/dbSta/include/db_sta/dbNetwork.hh +++ b/src/dbSta/include/db_sta/dbNetwork.hh @@ -92,6 +92,20 @@ class dbNetwork : public ConcreteNetwork public: dbNetwork(); ~dbNetwork() override; + + // unique addresses for the db objects + static constexpr unsigned DBITERM_ID = 0x0; + static constexpr unsigned DBBTERM_ID = 0x1; + static constexpr unsigned DBINST_ID = 0x2; + static constexpr unsigned DBNET_ID = 0x3; + static constexpr unsigned DBMODITERM_ID = 0x4; + static constexpr unsigned DBMODBTERM_ID = 0x5; + static constexpr unsigned DBMODINST_ID = 0x6; + static constexpr unsigned DBMODNET_ID = 0x7; + static constexpr unsigned DBMODULE_ID = 0x8; + // Number of lower bits used + static constexpr unsigned DBIDTAG_WIDTH = 0x4; + void init(dbDatabase* db, Logger* logger); void setBlock(dbBlock* block); void clear() override; diff --git a/src/dbSta/src/dbNetwork.cc b/src/dbSta/src/dbNetwork.cc index 8ef79d320d4..9078cd2e225 100644 --- a/src/dbSta/src/dbNetwork.cc +++ b/src/dbSta/src/dbNetwork.cc @@ -101,18 +101,6 @@ char* tmpStringCopy(const char* str) // lower 4 bits used to encode type // -static constexpr unsigned DBITERM_ID = 0x0; -static constexpr unsigned DBBTERM_ID = 0x1; -static constexpr unsigned DBINST_ID = 0x2; -static constexpr unsigned DBNET_ID = 0x3; -static constexpr unsigned DBMODITERM_ID = 0x4; -static constexpr unsigned DBMODBTERM_ID = 0x5; -static constexpr unsigned DBMODINST_ID = 0x6; -static constexpr unsigned DBMODNET_ID = 0x7; -static constexpr unsigned DBMODULE_ID = 0x8; -// Number of lower bits used -static constexpr unsigned DBIDTAG_WIDTH = 0x4; - ObjectId dbNetwork::getDbNwkObjectId(dbObjectType typ, ObjectId db_id) const { if (db_id > (std::numeric_limits::max() >> DBIDTAG_WIDTH)) { From 77ea5a42d0db7d16e791006621ac7f567fe05274 Mon Sep 17 00:00:00 2001 From: Matt Liberty Date: Mon, 10 Jun 2024 11:09:49 -0700 Subject: [PATCH 5/5] dbSta: make things private that can be Signed-off-by: Matt Liberty --- src/dbSta/include/db_sta/dbNetwork.hh | 29 ++++++++++++++------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/dbSta/include/db_sta/dbNetwork.hh b/src/dbSta/include/db_sta/dbNetwork.hh index 07e90ce40da..47f3b92c06d 100644 --- a/src/dbSta/include/db_sta/dbNetwork.hh +++ b/src/dbSta/include/db_sta/dbNetwork.hh @@ -93,19 +93,6 @@ class dbNetwork : public ConcreteNetwork dbNetwork(); ~dbNetwork() override; - // unique addresses for the db objects - static constexpr unsigned DBITERM_ID = 0x0; - static constexpr unsigned DBBTERM_ID = 0x1; - static constexpr unsigned DBINST_ID = 0x2; - static constexpr unsigned DBNET_ID = 0x3; - static constexpr unsigned DBMODITERM_ID = 0x4; - static constexpr unsigned DBMODBTERM_ID = 0x5; - static constexpr unsigned DBMODINST_ID = 0x6; - static constexpr unsigned DBMODNET_ID = 0x7; - static constexpr unsigned DBMODULE_ID = 0x8; - // Number of lower bits used - static constexpr unsigned DBIDTAG_WIDTH = 0x4; - void init(dbDatabase* db, Logger* logger); void setBlock(dbBlock* block); void clear() override; @@ -118,7 +105,6 @@ class dbNetwork : public ConcreteNetwork void addObserver(dbNetworkObserver* observer); void removeObserver(dbNetworkObserver* observer); - ObjectId getDbNwkObjectId(dbObjectType typ, ObjectId db_id) const; dbBlock* block() const { return block_; } void makeLibrary(dbLib* lib); void makeCell(Library* library, dbMaster* master); @@ -303,6 +289,8 @@ class dbNetwork : public ConcreteNetwork PinVisitor& visitor, NetSet& visited_nets) const override; bool portMsbFirst(const char* port_name, const char* cell_name); + ObjectId getDbNwkObjectId(dbObjectType typ, ObjectId db_id) const; + dbDatabase* db_ = nullptr; Logger* logger_ = nullptr; dbBlock* block_ = nullptr; @@ -310,6 +298,19 @@ class dbNetwork : public ConcreteNetwork Cell* top_cell_ = nullptr; std::set observers_; + // unique addresses for the db objects + static constexpr unsigned DBITERM_ID = 0x0; + static constexpr unsigned DBBTERM_ID = 0x1; + static constexpr unsigned DBINST_ID = 0x2; + static constexpr unsigned DBNET_ID = 0x3; + static constexpr unsigned DBMODITERM_ID = 0x4; + static constexpr unsigned DBMODBTERM_ID = 0x5; + static constexpr unsigned DBMODINST_ID = 0x6; + static constexpr unsigned DBMODNET_ID = 0x7; + static constexpr unsigned DBMODULE_ID = 0x8; + // Number of lower bits used + static constexpr unsigned DBIDTAG_WIDTH = 0x4; + private: bool hierarchy_ = false; };