@@ -2038,6 +2038,14 @@ void dbNetwork::readDbAfter(odb::dbDatabase* db)
20382038 for (dbLib* lib : db_->getLibs ()) {
20392039 makeLibrary (lib);
20402040 }
2041+
2042+ for (dbModule* module : block_->getModules ()) {
2043+ // top_module is not a hierarchical module in this context.
2044+ if (module != block_->getTopModule ()) {
2045+ registerHierModule (dbToSta (module ));
2046+ }
2047+ }
2048+
20412049 readDbNetlistAfter ();
20422050 }
20432051
@@ -2062,7 +2070,6 @@ void dbNetwork::makeCell(Library* library, dbMaster* master)
20622070 master->staSetCell (reinterpret_cast <void *>(cell));
20632071 // keep track of db leaf cells. These are cells for which we
20642072 // use the concrete network.
2065- registerConcreteCell (cell);
20662073 ConcreteCell* ccell = reinterpret_cast <ConcreteCell*>(cell);
20672074 ccell->setExtCell (reinterpret_cast <void *>(master));
20682075
@@ -2308,7 +2315,6 @@ Instance* dbNetwork::makeInstance(LibertyCell* cell,
23082315 // to get timing characteristics, so they have to be
23092316 // concrete
23102317 Cell* inst_cell = dbToSta (master);
2311- registerConcreteCell (inst_cell);
23122318 std::unique_ptr<sta::CellPortIterator> port_iter{portIterator (inst_cell)};
23132319 while (port_iter->hasNext ()) {
23142320 Port* cur_port = port_iter->next ();
@@ -2326,13 +2332,12 @@ Instance* dbNetwork::makeInstance(LibertyCell* cell,
23262332 dbInst* inst = dbInst::create (block_, master, name, false , parent);
23272333 Cell* inst_cell = dbToSta (master);
23282334 //
2329- // Register all liberty cells as being concrete
2335+ // Register all ports of liberty cells as being concrete
23302336 // Sometimes this method is called by the sta
23312337 // to build "test circuits" eg to find the max wire length
23322338 // And those cells need to use the external api
23332339 // to get timing characteristics, so they have to be
23342340 // concrete
2335- registerConcreteCell (inst_cell);
23362341 std::unique_ptr<sta::CellPortIterator> port_iter{portIterator (inst_cell)};
23372342 while (port_iter->hasNext ()) {
23382343 Port* cur_port = port_iter->next ();
@@ -3193,6 +3198,16 @@ LibertyPort* dbNetwork::libertyPort(const Pin* pin) const
31933198 return nullptr ;
31943199}
31953200
3201+ void dbNetwork::registerHierModule (const Cell* cell)
3202+ {
3203+ hier_modules_.insert (cell);
3204+ }
3205+
3206+ void dbNetwork::unregisterHierModule (const Cell* cell)
3207+ {
3208+ hier_modules_.erase (cell);
3209+ }
3210+
31963211/*
31973212We keep a registry of the concrete cells.
31983213For these we know to use the concrete network interface.
@@ -3201,18 +3216,17 @@ The concrete cells are created outside of the odb world
32013216So we simply note them and then when we inspect a cell
32023217we can decide whether or not to use the ConcreteNetwork api.
32033218*/
3204-
3205- void dbNetwork::registerConcreteCell (const Cell* cell)
3206- {
3207- concrete_cells_.insert (cell);
3208- }
3209-
32103219bool dbNetwork::isConcreteCell (const Cell* cell) const
32113220{
32123221 if (!hierarchy_) {
32133222 return true ;
32143223 }
3215- return (concrete_cells_.find (cell) != concrete_cells_.end ());
3224+
3225+ if (cell == top_cell_) {
3226+ return false ;
3227+ }
3228+
3229+ return (hier_modules_.find (cell) == hier_modules_.end ());
32163230}
32173231
32183232void dbNetwork::registerConcretePort (const Port* port)
0 commit comments