@@ -92,7 +92,7 @@ void Connect::setOnGrid(const std::vector<odb::dbTechLayer*>& layers)
9292 ongrid_.insert (layers.begin (), layers.end ());
9393}
9494
95- void Connect::setSplitCuts (const std::map<odb::dbTechLayer*, int >& splits)
95+ void Connect::setSplitCuts (const std::map<odb::dbTechLayer*, SplitCut >& splits)
9696{
9797 split_cuts_ = splits;
9898 // remove top and bottom layers of the stack
@@ -107,7 +107,17 @@ int Connect::getSplitCutPitch(odb::dbTechLayer* layer) const
107107 return 0 ;
108108 }
109109
110- return layer_itr->second ;
110+ return layer_itr->second .pitch ;
111+ }
112+
113+ bool Connect::getSplitCutStagger (odb::dbTechLayer* layer) const
114+ {
115+ auto layer_itr = split_cuts_.find (layer);
116+ if (layer_itr == split_cuts_.end ()) {
117+ return false ;
118+ }
119+
120+ return layer_itr->second .stagger ;
111121}
112122
113123bool Connect::appliesToVia (const ViaPtr& via) const
@@ -417,10 +427,11 @@ void Connect::report() const
417427 }
418428 if (!split_cuts_.empty ()) {
419429 logger->report (" Split cuts:" );
420- for (const auto & [layer, pitch ] : split_cuts_) {
421- logger->report (" Layer: {} with pitch {:.4f}" ,
430+ for (const auto & [layer, cut_def ] : split_cuts_) {
431+ logger->report (" Layer: {} with pitch {:.4f}{} " ,
422432 layer->getName (),
423- pitch / dbu_per_micron);
433+ cut_def.pitch / dbu_per_micron,
434+ cut_def.stagger ? " staggered" : " " );
424435 }
425436 }
426437}
@@ -448,10 +459,27 @@ void Connect::makeVia(odb::dbSWire* wire,
448459 return ;
449460 }
450461
462+ odb::dbNet* index_net = nullptr ;
463+ if (!split_cuts_.empty ()) {
464+ index_net = wire->getNet ();
465+ }
466+
451467 const ViaIndex via_index
452- = std::make_pair ( intersection.dx (), intersection.dy ());
468+ = std::make_tuple (index_net, intersection.dx (), intersection.dy ());
453469 auto & via = vias_[via_index];
454470
471+ debugPrint (grid_->getLogger (),
472+ utl::PDN,
473+ " Via" ,
474+ 2 ,
475+ " Cache {} at {} / {} / {}" ,
476+ via == nullptr ? " miss" : " hit" ,
477+ std::get<0 >(via_index) != nullptr
478+ ? std::get<0 >(via_index)->getName ()
479+ : " null" ,
480+ std::get<1 >(via_index),
481+ std::get<2 >(via_index));
482+
455483 bool skip_caching = false ;
456484 // make the via stack if one is not available for the given size
457485 if (via == nullptr ) {
@@ -509,7 +537,8 @@ void Connect::makeVia(odb::dbSWire* wire,
509537 }
510538 }
511539
512- auto * new_via = makeSingleLayerVia (wire->getBlock (),
540+ auto * new_via = makeSingleLayerVia (wire->getNet (),
541+ wire->getBlock (),
513542 l0,
514543 via_lower_rects,
515544 lower_constraint,
@@ -550,6 +579,7 @@ void Connect::makeVia(odb::dbSWire* wire,
550579}
551580
552581DbVia* Connect::generateDbVia (
582+ odb::dbNet* net,
553583 const std::vector<std::shared_ptr<ViaGenerator>>& generators,
554584 odb::dbBlock* block) const
555585{
@@ -571,13 +601,19 @@ DbVia* Connect::generateDbVia(
571601 via->getCutLayer ()->getName (),
572602 via->hasCutClass () ? via->getCutClass ()->getName () : " none" );
573603
574- const int lower_split = getSplitCut (via->getBottomLayer ());
575- const int upper_split = getSplitCut (via->getTopLayer ());
576- if (lower_split != 0 || upper_split != 0 ) {
577- const int pitch = std::max (lower_split, upper_split);
578- via->setSplitCutArray (lower_split != 0 , upper_split != 0 );
604+ const auto lower_split = getSplitCut (via->getBottomLayer ());
605+ const auto upper_split = getSplitCut (via->getTopLayer ());
606+ if (lower_split. pitch != 0 || upper_split. pitch != 0 ) {
607+ const int pitch = std::max (lower_split. pitch , upper_split. pitch );
608+ via->setSplitCutArray (lower_split. pitch != 0 , upper_split. pitch != 0 );
579609 via->setCutPitchX (pitch);
580610 via->setCutPitchY (pitch);
611+ if (lower_split.stagger || upper_split.stagger ) {
612+ if (net->getSigType () == odb::dbSigType::GROUND) {
613+ via->setCutOffsetX (pitch / 2 );
614+ via->setCutOffsetY (pitch / 2 );
615+ }
616+ }
581617 }
582618
583619 const bool lower_is_internal = via->getBottomLayer () != layer0_;
@@ -628,6 +664,7 @@ DbVia* Connect::generateDbVia(
628664}
629665
630666DbVia* Connect::makeSingleLayerVia (
667+ odb::dbNet* net,
631668 odb::dbBlock* block,
632669 odb::dbTechLayer* lower,
633670 const std::set<odb::Rect>& lower_rects,
@@ -678,7 +715,7 @@ DbVia* Connect::makeSingleLayerVia(
678715 generate_vias.size (),
679716 generate_via_rules_.size ());
680717
681- DbVia* generate_via = generateDbVia (generate_vias, block);
718+ DbVia* generate_via = generateDbVia (net, generate_vias, block);
682719
683720 if (generate_via != nullptr ) {
684721 return generate_via;
@@ -720,7 +757,7 @@ DbVia* Connect::makeSingleLayerVia(
720757 tech_vias.size (),
721758 tech_vias_.size ());
722759
723- return generateDbVia (tech_vias, block);
760+ return generateDbVia (net, tech_vias, block);
724761}
725762
726763void Connect::populateGenerateRules ()
@@ -831,13 +868,13 @@ bool Connect::techViaContains(odb::dbTechVia* via,
831868 return via->getBottomLayer () == lower && via->getTopLayer () == upper;
832869}
833870
834- int Connect::getSplitCut (odb::dbTechLayer* layer) const
871+ Connect::SplitCut Connect::getSplitCut (odb::dbTechLayer* layer) const
835872{
836873 auto split_itr = split_cuts_.find (layer);
837874 if (split_itr != split_cuts_.end ()) {
838875 return split_itr->second ;
839876 }
840- return 0 ;
877+ return SplitCut{} ;
841878}
842879
843880void Connect::clearShapes ()
0 commit comments