@@ -312,23 +312,81 @@ class DbInstanceNetIterator : public InstanceNetIterator
312312 dbSet<dbNet>::iterator end_;
313313 dbSet<dbModNet>::iterator mod_net_iter_;
314314 dbSet<dbModNet>::iterator mod_net_end_;
315+ std::vector<dbNet*> flat_nets_vec_;
316+ size_t flat_net_idx_ = 0 ;
315317};
316318
317319DbInstanceNetIterator::DbInstanceNetIterator (const Instance* instance,
318320 const dbNetwork* network)
319321 : network_(network)
320322{
321323 if (network_->hasHierarchy ()) {
322- dbInst* db_inst;
323- dbModInst* mod_inst;
324- network_->staToDb (instance, db_inst, mod_inst);
325- if (mod_inst) {
326- dbModule* master = mod_inst->getMaster ();
327- dbSet<dbModNet> nets = master->getModNets ();
328- mod_net_iter_ = nets.begin ();
329- mod_net_end_ = nets.end ();
324+ //
325+ // In hierarchical flow, the net iterator collects both hierarchical
326+ // nets (dbModNets) and unique flat nets (dbNets) within the
327+ // instance's module scope.
328+ // Flat nets can be retrieved by traversing instance ITerms and BTerms.
329+ // Avoids the duplication b/w flat and hierarchical nets.
330+ //
331+
332+ // Get the module of the instance
333+ dbModule* module = nullptr ;
334+ if (instance == network->topInstance ()) {
335+ module = network->block ()->getTopModule ();
336+ } else {
337+ dbInst* db_inst;
338+ dbModInst* mod_inst;
339+ network_->staToDb (instance, db_inst, mod_inst);
340+ if (mod_inst) {
341+ module = mod_inst->getMaster ();
342+ }
343+ }
344+
345+ if (module ) {
346+ // Get dbModNets
347+ dbSet<dbModNet> mod_nets = module ->getModNets ();
348+ mod_net_iter_ = mod_nets.begin ();
349+ mod_net_end_ = mod_nets.end ();
350+
351+ // Keep track of flat nets that are already represented by a mod_net
352+ // to avoid returning both.
353+ std::set<dbNet*> handled_flat_nets;
354+ for (dbModNet* mod_net : mod_nets) {
355+ dbNet* flat_net = network_->findRelatedDbNet (mod_net);
356+ if (flat_net) {
357+ handled_flat_nets.insert (flat_net);
358+ }
359+ }
360+
361+ // Collect dbNets from children dbInsts' pins that are not already
362+ // handled.
363+ std::set<dbNet*> flat_nets_set;
364+ for (dbInst* child_inst : module ->getInsts ()) {
365+ for (dbITerm* iterm : child_inst->getITerms ()) {
366+ dbNet* flat_net = iterm->getNet ();
367+ if (flat_net
368+ && handled_flat_nets.find (flat_net) == handled_flat_nets.end ()) {
369+ flat_nets_set.insert (flat_net);
370+ }
371+ }
372+ }
373+
374+ // For top instance, also check top-level ports (BTerms)
375+ if (instance == network->topInstance ()) {
376+ for (dbBTerm* bterm : network->block ()->getBTerms ()) {
377+ dbNet* flat_net = bterm->getNet ();
378+ if (flat_net
379+ && handled_flat_nets.find (flat_net) == handled_flat_nets.end ()) {
380+ flat_nets_set.insert (flat_net);
381+ }
382+ }
383+ }
384+ flat_nets_vec_.assign (flat_nets_set.begin (), flat_nets_set.end ());
330385 }
331386 } else {
387+ //
388+ // In flat flow, the net iterator collects all nets from top block
389+ //
332390 if (instance == network->topInstance ()) {
333391 dbSet<dbNet> nets = network->block ()->getNets ();
334392 iter_ = nets.begin ();
@@ -340,17 +398,27 @@ DbInstanceNetIterator::DbInstanceNetIterator(const Instance* instance,
340398bool DbInstanceNetIterator::hasNext ()
341399{
342400 if (network_->hasHierarchy ()) {
343- return mod_net_iter_ != mod_net_end_;
401+ if (mod_net_iter_ != mod_net_end_) {
402+ return true ;
403+ }
404+ return flat_net_idx_ < flat_nets_vec_.size ();
344405 }
345406 return iter_ != end_;
346407}
347408
348409Net* DbInstanceNetIterator::next ()
349410{
350411 if (network_->hasHierarchy ()) {
351- dbModNet* net = *mod_net_iter_;
352- mod_net_iter_++;
353- return network_->dbToSta (net);
412+ if (mod_net_iter_ != mod_net_end_) {
413+ dbModNet* net = *mod_net_iter_;
414+ mod_net_iter_++;
415+ return network_->dbToSta (net);
416+ }
417+ if (flat_net_idx_ < flat_nets_vec_.size ()) {
418+ dbNet* net = flat_nets_vec_[flat_net_idx_++];
419+ return network_->dbToSta (net);
420+ }
421+ return nullptr ;
354422 }
355423 dbNet* net = *iter_;
356424 iter_++;
0 commit comments