@@ -957,6 +957,38 @@ bool dbNetwork::isLeaf(const Instance* instance) const
957957
958958Instance* dbNetwork::findInstance (const char * path_name) const
959959{
960+ if (hierarchy_) { // are we in hierarchical mode ?
961+ std::string path_name_str = path_name;
962+ // search for the last token in the string, which is the leaf instance name
963+ size_t last_idx = path_name_str.find_last_of (' /' );
964+ if (last_idx != std::string::npos) {
965+ std::string leaf_inst_name = path_name_str.substr (last_idx + 1 );
966+ // get the parent name, which is the hierarchical prefix in the string
967+ std::string parent_name_str = path_name_str.substr (0 , last_idx);
968+ // get the module instance from the block
969+ dbModInst* parent_mod_inst
970+ = block ()->findModInst (parent_name_str.c_str ());
971+ if (parent_mod_inst) {
972+ // get the module definition
973+ // (we are in a uniquified environment so all modules are uniquified).
974+ dbModule* module_defn = parent_mod_inst->getMaster ();
975+ if (module_defn) {
976+ // get the leaf instance definition from the module
977+ dbInst* ret = module_defn->findDbInst (leaf_inst_name.c_str ());
978+ if (ret) {
979+ return (Instance*) ret;
980+ }
981+ }
982+ }
983+ }
984+ }
985+ // fall through (even in hierarchical mode).
986+ // Note: the fall through is the work around so that if the name
987+ // is stored in flat form it will be found. TODO: stash the names
988+ // hierachically by default for all cases and not flat in the dbBlock.
989+ // (currently we,mostly, stash the names flat in the block and that is wrong
990+ // in hierachical mode).
991+ //
960992 dbInst* inst = block_->findInst (path_name);
961993 return dbToSta (inst);
962994}
@@ -1021,6 +1053,28 @@ Pin* dbNetwork::findPin(const Instance* instance, const Port* port) const
10211053 return findPin (instance, port_name);
10221054}
10231055
1056+ //
1057+ // Catch all see if a net exists anywhere in the design hierarchy
1058+ //
1059+ // TODO: remove this by removing flat net table so that all
1060+ // net names stored in their scope (so dbNet in top dbModule not
1061+ // in block).
1062+ //
1063+ Net* dbNetwork::findNetAllScopes (const char * net_name) const
1064+ {
1065+ for (auto dbm : block_->getModules ()) {
1066+ dbNet* dnet = block_->findNet (net_name);
1067+ if (dnet) {
1068+ return dbToSta (dnet);
1069+ }
1070+ dbModNet* modnet = dbm->getModNet (net_name);
1071+ if (modnet) {
1072+ return dbToSta (modnet);
1073+ }
1074+ }
1075+ return nullptr ;
1076+ }
1077+
10241078Net* dbNetwork::findNet (const Instance* instance, const char * net_name) const
10251079{
10261080 dbModule* scope = nullptr ;
@@ -1057,7 +1111,6 @@ Net* dbNetwork::findNet(const Instance* instance, const char* net_name) const
10571111 return dbToSta (modnet);
10581112 }
10591113 }
1060-
10611114 return nullptr ;
10621115}
10631116
@@ -3459,7 +3512,6 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
34593512 dbNet* dest_flat_net = flatNet ((Pin*) dest_pin);
34603513 disconnectPin ((Pin*) dest_pin);
34613514 connectPin ((Pin*) dest_pin, (Net*) dest_flat_net, (Net*) dest_mod_net);
3462- // dest_pin->connect(dest_mod_net);
34633515 return ;
34643516 }
34653517 }
@@ -3471,54 +3523,69 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
34713523 std::vector<dbModule*> dest_parent_tree;
34723524 getParentHierarchy (source_db_module, source_parent_tree);
34733525 getParentHierarchy (dest_db_module, dest_parent_tree);
3526+
34743527 dbModule* highest_common_module
34753528 = findHighestCommonModule (source_parent_tree, dest_parent_tree);
34763529 dbModNet* top_net = source_db_mod_net;
34773530 dbModITerm* top_mod_dest = nullptr ;
34783531
34793532 // make source hierarchy (bottom to top).
34803533 dbModule* cur_module = source_db_module;
3534+ int level = 0 ;
3535+
34813536 while (cur_module != highest_common_module) {
34823537 std::string connection_name_o
34833538 = std::string (connection_name) + std::string (" _o" );
34843539 dbModBTerm* mod_bterm
34853540 = dbModBTerm::create (cur_module, connection_name_o.c_str ());
3486- if (!source_db_mod_net) {
3487- source_db_mod_net
3488- = dbModNet::create (source_db_module, connection_name_o.c_str ());
3489- }
3490- source_pin->connect (source_db_mod_net);
3541+ source_db_mod_net
3542+ = dbModNet::create (source_db_module, connection_name_o.c_str ());
3543+
34913544 mod_bterm->connect (source_db_mod_net);
34923545 mod_bterm->setIoType (dbIoType::OUTPUT);
34933546 mod_bterm->setSigType (dbSigType::SIGNAL);
3547+
3548+ // at leaf level make connection
3549+ if (level == 0 ) {
3550+ dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3551+ if (source_pin_mod_net) {
3552+ disconnectPin ((Pin*) source_pin, (Net*) source_pin_mod_net);
3553+ }
3554+ connectPin ((Pin*) source_pin, (Net*) source_db_mod_net);
3555+ }
3556+
34943557 dbModInst* parent_inst = cur_module->getModInst ();
34953558 cur_module = parent_inst->getParent ();
34963559 dbModITerm* mod_iterm = dbModITerm::create (
34973560 parent_inst, connection_name_o.c_str (), mod_bterm);
34983561 source_db_mod_net = dbModNet::create (cur_module, connection_name);
34993562 mod_iterm->connect (source_db_mod_net);
35003563 top_net = source_db_mod_net;
3564+ level = level + 1 ;
35013565 }
35023566
35033567 // make dest hierarchy
3568+ level = 0 ;
35043569 cur_module = dest_db_module;
35053570 while (cur_module != highest_common_module) {
35063571 std::string connection_name_i
35073572 = std::string (connection_name) + std::string (" _i" );
35083573 dbModBTerm* mod_bterm
35093574 = dbModBTerm::create (cur_module, connection_name_i.c_str ());
3510- // We may have a destination mod net (see first part), but check to make
3511- // sure it is in this module. If not, create one and hook it to the
3512- // destination pin also hook up the modbterm to it.
3513- if ((dest_db_mod_net == nullptr )
3514- || (dest_db_mod_net->getParent () != cur_module)) {
3515- dest_db_mod_net
3516- = dbModNet::create (cur_module, connection_name_i.c_str ());
3517- }
3518- dest_pin->connect (dest_db_mod_net);
3575+ dest_db_mod_net = dbModNet::create (cur_module, connection_name_i.c_str ());
3576+
35193577 mod_bterm->connect (dest_db_mod_net);
35203578 mod_bterm->setIoType (dbIoType::INPUT);
35213579 mod_bterm->setSigType (dbSigType::SIGNAL);
3580+
3581+ if (level == 0 ) {
3582+ dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3583+ if (dest_pin_mod_net) {
3584+ disconnectPin ((Pin*) dest_pin, (Net*) dest_pin_mod_net);
3585+ }
3586+ connectPin ((Pin*) dest_pin, (Net*) dest_db_mod_net);
3587+ }
3588+
35223589 dbModInst* parent_inst = cur_module->getModInst ();
35233590 cur_module = parent_inst->getParent ();
35243591 dbModITerm* mod_iterm = dbModITerm::create (
@@ -3553,6 +3620,34 @@ void dbNetwork::hierarchicalConnect(dbITerm* source_pin,
35533620 dest_pin->connect (top_net);
35543621 }
35553622
3623+ // What we are doing here is making sure that the
3624+ // hierarchical nets at the source and the destination
3625+ // are correctly associated. In the above code
3626+ // we are wiring/unwiring modnets without regard to the
3627+ // flat net association. We clean that up here.
3628+ // Note we cannot reassociate until after we have built
3629+ // the hiearchy tree
3630+
3631+ // reassociate the dest pin
3632+
3633+ dbModNet* dest_pin_mod_net = hierNet ((Pin*) dest_pin);
3634+ if (dest_pin_mod_net) {
3635+ dbNet* dest_pin_flat_net = flatNet ((Pin*) dest_pin);
3636+ dest_pin->disconnect ();
3637+ connectPin (
3638+ (Pin*) dest_pin, (Net*) dest_pin_flat_net, (Net*) dest_pin_mod_net);
3639+ }
3640+
3641+ // reassociate the source pin
3642+ dbModNet* source_pin_mod_net = hierNet ((Pin*) source_pin);
3643+ if (source_pin_mod_net) {
3644+ dbNet* source_pin_flat_net = flatNet ((Pin*) source_pin);
3645+ source_pin->disconnect ();
3646+ connectPin ((Pin*) source_pin,
3647+ (Net*) source_pin_flat_net,
3648+ (Net*) source_pin_mod_net);
3649+ }
3650+
35563651 // During the addition of new ports and new wiring we may
35573652 // leave orphaned pins, clean them up.
35583653 std::set<dbModInst*> cleaned_up;
@@ -3793,6 +3888,13 @@ void dbNetwork::reassociateHierFlatNet(dbModNet* mod_net,
37933888 visitConnectedPins (dbToSta (new_flat_net), visitordb, visited_dbnets);
37943889}
37953890
3891+ void dbNetwork::reassociateFromDbNetView (dbNet* flat_net, dbModNet* mod_net)
3892+ {
3893+ DbModNetAssociation visitordb (this , mod_net);
3894+ NetSet visited_dbnets (this );
3895+ visitConnectedPins (dbToSta (flat_net), visitordb, visited_dbnets);
3896+ }
3897+
37963898void dbNetwork::replaceHierModule (dbModInst* mod_inst, dbModule* module )
37973899{
37983900 (void ) mod_inst->swapMaster (module );
@@ -3880,6 +3982,22 @@ void PinModDbNetConnection::operator()(const Pin* pin)
38803982 ->getOwningInstanceParent (const_cast <Pin*>(pin));
38813983 (void ) owning_instance;
38823984 if (dbnet_ != nullptr && dbnet_ != candidate_flat_net) {
3985+ /*
3986+ //How to debug in orfs:
3987+ //uncomment this code
3988+ //then use gdb -p pid on the openroad process
3989+ //to see stack trace.
3990+ printf("Axiom check fail\n");
3991+ printf("Flat nets are %s %s for modnet %s\n",
3992+ db_network_->name(db_network_->dbToSta(dbnet_)),
3993+ db_network_->name(db_network_->dbToSta(candidate_flat_net)),
3994+ db_network_->name(search_net_));
3995+ printf("Suspending, access from gdb to debug\n");
3996+ fflush(stdout);
3997+ int forever_loop=1;
3998+ while(forever_loop);
3999+ */
4000+
38834001 logger_->error (
38844002 ORD,
38854003 2030 ,
@@ -3991,4 +4109,54 @@ bool dbNetwork::hasHierarchicalElements() const
39914109 return false ;
39924110}
39934111
4112+ class AccumulateNetFlatLoadPins : public PinVisitor
4113+ {
4114+ public:
4115+ AccumulateNetFlatLoadPins (dbNetwork* nwk,
4116+ Pin* drvr_pin,
4117+ std::unordered_set<const Pin*>& accumulated_pins)
4118+ : nwk_(nwk), drvr_pin_(drvr_pin), flat_load_pinset_(accumulated_pins)
4119+ {
4120+ }
4121+ void operator ()(const Pin* pin) override ;
4122+
4123+ private:
4124+ dbNetwork* nwk_;
4125+ Pin* drvr_pin_;
4126+ std::unordered_set<const sta::Pin*>& flat_load_pinset_;
4127+ };
4128+
4129+ void AccumulateNetFlatLoadPins::operator ()(const Pin* pin)
4130+ {
4131+ if (pin != drvr_pin_) {
4132+ dbITerm* iterm = nullptr ;
4133+ dbBTerm* bterm = nullptr ;
4134+ dbModITerm* moditerm = nullptr ;
4135+ // only stash the flat loads on instances (iterms)
4136+ nwk_->staToDb (pin, iterm, bterm, moditerm);
4137+ if (iterm /* || bterm */ ) {
4138+ flat_load_pinset_.insert (pin);
4139+ }
4140+ }
4141+ }
4142+
4143+ void dbNetwork::accumulateFlatLoadPinsOnNet (
4144+ Net* net,
4145+ Pin* drvr_pin,
4146+ std::unordered_set<const Pin*>& accumulated_pins)
4147+ {
4148+ NetSet visited_nets (this );
4149+ // just the flat load pins
4150+ AccumulateNetFlatLoadPins rp (this , drvr_pin, accumulated_pins);
4151+ visitConnectedPins (net, rp, visited_nets);
4152+ }
4153+
4154+ void dbNetwork::AxiomCheck ()
4155+ {
4156+ dbSet<dbModNet> mod_nets = block ()->getModNets ();
4157+ for (auto mod_net : mod_nets) {
4158+ findRelatedDbNet (mod_net);
4159+ }
4160+ }
4161+
39944162} // namespace sta
0 commit comments