From dad5671fc54de150371591b9d4aabda793d1ca9f Mon Sep 17 00:00:00 2001 From: Osama Date: Sun, 28 Jan 2024 15:06:57 +0200 Subject: [PATCH 01/26] drt: unblock bterm needed edges & repair_pdn_layer layer range Signed-off-by: Osama --- src/drt/include/triton_route/TritonRoute.h | 3 +- src/drt/src/TritonRoute.cpp | 81 +++++++++++++++------- src/drt/src/TritonRoute.i | 6 +- src/drt/src/TritonRoute.tcl | 17 +++-- src/drt/src/dr/FlexDR_init.cpp | 20 +++++- src/drt/src/gc/FlexGC_cut.cpp | 8 ++- src/drt/src/gc/FlexGC_impl.h | 1 + src/drt/src/gc/FlexGC_main.cpp | 3 + src/drt/src/global.cpp | 6 +- src/drt/src/global.h | 6 +- 10 files changed, 109 insertions(+), 42 deletions(-) diff --git a/src/drt/include/triton_route/TritonRoute.h b/src/drt/include/triton_route/TritonRoute.h index d4a76e66920..375a0dccdba 100644 --- a/src/drt/include/triton_route/TritonRoute.h +++ b/src/drt/include/triton_route/TritonRoute.h @@ -94,7 +94,8 @@ struct ParamStruct bool singleStepDR = false; int minAccessPoints = -1; bool saveGuideUpdates = false; - std::string repairPDNLayerName; + std::string repairPDNLayerBeginName; + std::string repairPDNLayerEndName; }; class TritonRoute diff --git a/src/drt/src/TritonRoute.cpp b/src/drt/src/TritonRoute.cpp index de4de6cc9c7..3622d1b00d2 100644 --- a/src/drt/src/TritonRoute.cpp +++ b/src/drt/src/TritonRoute.cpp @@ -569,13 +569,22 @@ void TritonRoute::initDesign() } } - if (!REPAIR_PDN_LAYER_NAME.empty()) { - frLayer* layer = tech->getLayer(REPAIR_PDN_LAYER_NAME); + if (!REPAIR_PDN_LAYER_BEGIN_NAME.empty()) { + frLayer* layer = tech->getLayer(REPAIR_PDN_LAYER_BEGIN_NAME); if (layer) { - GC_IGNORE_PDN_LAYER = layer->getLayerNum(); + GC_IGNORE_PDN_BEGIN_LAYER = layer->getLayerNum(); + } else { + logger_->warn(utl::DRT, + 617, + "PDN layer {} not found.", + REPAIR_PDN_LAYER_BEGIN_NAME); + } + layer = tech->getLayer(REPAIR_PDN_LAYER_END_NAME); + if (layer) { + GC_IGNORE_PDN_END_LAYER = layer->getLayerNum(); } else { logger_->warn( - utl::DRT, 617, "PDN layer {} not found.", REPAIR_PDN_LAYER_NAME); + utl::DRT, 619, "PDN layer {} not found.", REPAIR_PDN_LAYER_END_NAME); } } parser.postProcess(); @@ -651,13 +660,15 @@ void TritonRoute::endFR() writer.updateTrackAssignment(db_->getChip()->getBlock()); num_drvs_ = design_->getTopBlock()->getNumMarkers(); - if (!REPAIR_PDN_LAYER_NAME.empty()) { + if (!REPAIR_PDN_LAYER_BEGIN_NAME.empty()) { auto dbBlock = db_->getChip()->getBlock(); - auto pdnLayer = design_->getTech()->getLayer(REPAIR_PDN_LAYER_NAME); - frLayerNum pdnLayerNum = pdnLayer->getLayerNum(); + auto pdnBeginLayer + = design_->getTech()->getLayer(REPAIR_PDN_LAYER_BEGIN_NAME); + auto pdnEndLayer = design_->getTech()->getLayer(REPAIR_PDN_LAYER_END_NAME); frList> markers; auto blockBox = design_->getTopBlock()->getBBox(); - GC_IGNORE_PDN_LAYER = -1; + GC_IGNORE_PDN_BEGIN_LAYER = -1; + GC_IGNORE_PDN_END_LAYER = -1; getDRCMarkers(markers, blockBox); std::vector>> allWires; for (auto* net : dbBlock->getNets()) { @@ -665,27 +676,34 @@ void TritonRoute::endFR() continue; for (auto* swire : net->getSWires()) { for (auto* wire : swire->getWires()) { - if (!wire->isVia()) { - continue; - } - // - std::vector via_boxes; - wire->getViaBoxes(via_boxes); - for (const auto& via_box : via_boxes) { - auto* layer = via_box.getTechLayer(); - if (layer->getType() != odb::dbTechLayerType::CUT) - continue; - if (layer->getName() != pdnLayer->getName()) + if (wire->isVia()) { + std::vector via_boxes; + wire->getViaBoxes(via_boxes); + for (const auto& via_box : via_boxes) { + auto* layer = getDesign()->getTech()->getLayer( + via_box.getTechLayer()->getName()); + if (layer->getLayerNum() < pdnBeginLayer->getLayerNum() + || layer->getLayerNum() > pdnEndLayer->getLayerNum()) + continue; + allWires.push_back({via_box.getBox(), wire->getId()}); + } + } else { + auto layer = getDesign()->getTech()->getLayer( + wire->getTechLayer()->getName()); + if (layer->getLayerNum() < pdnBeginLayer->getLayerNum() + || layer->getLayerNum() > pdnEndLayer->getLayerNum()) continue; - allWires.push_back({via_box.getBox(), wire->getId()}); + allWires.push_back({wire->getBox(), wire->getId()}); } } } } RTree> pdnTree(allWires); std::set> removedBoxes; + int cnt = 0; for (const auto& marker : markers) { - if (marker->getLayerNum() != pdnLayerNum) + if (marker->getLayerNum() < pdnBeginLayer->getLayerNum() + || marker->getLayerNum() > pdnEndLayer->getLayerNum()) continue; bool supply = false; for (auto src : marker->getSrcs()) { @@ -708,13 +726,22 @@ void TritonRoute::endFR() if (removedBoxes.find(bid) == removedBoxes.end()) { removedBoxes.insert(bid); auto boxPtr = odb::dbSBox::getSBox(dbBlock, bid); + std::vector>> subResults; + pdnTree.query(bgi::intersects(boxPtr->getBox()), + back_inserter(subResults)); odb::dbSBox::destroy(boxPtr); + cnt++; + for (auto& [subRect, subBid] : subResults) { + if (removedBoxes.find(subBid) == removedBoxes.end()) { + removedBoxes.insert(subBid); + auto subBoxPtr = odb::dbSBox::getSBox(dbBlock, subBid); + odb::dbSBox::destroy(subBoxPtr); + } + } } } } - logger_->report("Removed {} pdn vias on layer {}", - removedBoxes.size(), - pdnLayer->getName()); + logger_->report("Removed {} pdn vias", cnt); } } @@ -1013,7 +1040,8 @@ void TritonRoute::getDRCMarkers(frList>& markers, void TritonRoute::checkDRC(const char* filename, int x1, int y1, int x2, int y2) { - GC_IGNORE_PDN_LAYER = -1; + GC_IGNORE_PDN_BEGIN_LAYER = -1; + GC_IGNORE_PDN_END_LAYER = -1; initDesign(); auto gcellGrid = db_->getChip()->getBlock()->getGCellGrid(); if (gcellGrid != nullptr && gcellGrid->getNumGridPatternsX() == 1 @@ -1247,7 +1275,8 @@ void TritonRoute::setParams(const ParamStruct& params) MINNUMACCESSPOINT_MACROCELLPIN = params.minAccessPoints; } SAVE_GUIDE_UPDATES = params.saveGuideUpdates; - REPAIR_PDN_LAYER_NAME = params.repairPDNLayerName; + REPAIR_PDN_LAYER_BEGIN_NAME = params.repairPDNLayerBeginName; + REPAIR_PDN_LAYER_END_NAME = params.repairPDNLayerEndName; } void TritonRoute::addWorkerResults( diff --git a/src/drt/src/TritonRoute.i b/src/drt/src/TritonRoute.i index 67c94f43f80..b319d759419 100644 --- a/src/drt/src/TritonRoute.i +++ b/src/drt/src/TritonRoute.i @@ -94,7 +94,8 @@ void detailed_route_cmd(const char* outputMazeFile, bool singleStepDR, int minAccessPoints, bool saveGuideUpdates, - const char* repairPDNLayerName, + const char* repairPDNLayerBeginName, + const char* repairPDNLayerEndName, int drcReportIterStep) { auto* router = ord::OpenRoad::openRoad()->getTritonRoute(); @@ -122,7 +123,8 @@ void detailed_route_cmd(const char* outputMazeFile, singleStepDR, minAccessPoints, saveGuideUpdates, - repairPDNLayerName}); + repairPDNLayerBeginName, + repairPDNLayerEndName}); router->main(); router->setDistributed(false); } diff --git a/src/drt/src/TritonRoute.tcl b/src/drt/src/TritonRoute.tcl index fa6ca6fb31e..9b53251a350 100644 --- a/src/drt/src/TritonRoute.tcl +++ b/src/drt/src/TritonRoute.tcl @@ -58,7 +58,7 @@ sta::define_cmd_args "detailed_route" { [-no_pin_access] [-min_access_points count] [-save_guide_updates] - [-repair_pdn_vias layer] + [-repair_pdn_vias begin_layer end_layer] } proc detailed_route { args } { @@ -79,11 +79,18 @@ proc detailed_route { args } { set single_step_dr [expr [info exists flags(-single_step_dr)]] set save_guide_updates [expr [info exists flags(-save_guide_updates)]] - if { [info exists keys(-repair_pdn_vias)] } { - set repair_pdn_vias $keys(-repair_pdn_vias) + if {[info exists keys(-repair_pdn_vias)]} { + set repair_pdn_vias $keys(-repair_pdn_vias) + if {[llength $repair_pdn_vias] != 2} { + utl::error DRT 556 "-repair_pdn_vias should be a list of 2 layers; the begin via layer and end via layer" + } else { + lassign $keys(-repair_pdn_vias) repair_pdn_vias_begin repair_pdn_vias_end + } } else { - set repair_pdn_vias "" + set repair_pdn_vias_begin "" + set repair_pdn_vias_end "" } + if { [info exists keys(-output_maze)] } { set output_maze $keys(-output_maze) } else { @@ -195,7 +202,7 @@ proc detailed_route { args } { $via_in_pin_bottom_layer $via_in_pin_top_layer \ $or_seed $or_k $bottom_routing_layer $top_routing_layer $verbose \ $clean_patches $no_pin_access $single_step_dr $min_access_points \ - $save_guide_updates $repair_pdn_vias $drc_report_iter_step + $save_guide_updates $repair_pdn_vias_begin $repair_pdn_vias_end $drc_report_iter_step } proc detailed_route_num_drvs { args } { diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index d9fd4fd0be2..e2b27dd9ea1 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -3087,6 +3087,22 @@ void FlexDRWorker::initMazeCost_planarTerm(const frDesign* design) // term no bloat switch (obj->typeId()) { case frcBTerm: { + auto bterm = static_cast(obj); + bool hasHorizontalAccess = false; + bool hasVerticalAccess = false; + for (const auto& pin : bterm->getPins()) { + for (int i = 0; i < pin->getNumPinAccess(); i++) { + const auto& pa = pin->getPinAccess(i); + for (const auto& ap : pa->getAccessPoints()) { + if (ap->getLayerNum() != layerNum) + continue; + hasVerticalAccess |= ap->hasAccess(frDirEnum::N); + hasVerticalAccess |= ap->hasAccess(frDirEnum::S); + hasHorizontalAccess |= ap->hasAccess(frDirEnum::W); + hasHorizontalAccess |= ap->hasAccess(frDirEnum::E); + } + } + } FlexMazeIdx mIdx1, mIdx2; gridGraph_.getIdxBox(mIdx1, mIdx2, box); const bool isLayerHorz = layer->isHorizontal(); @@ -3095,10 +3111,10 @@ void FlexDRWorker::initMazeCost_planarTerm(const frDesign* design) FlexMazeIdx mIdx(i, j, zIdx); gridGraph_.setBlocked(i, j, zIdx, frDirEnum::U); gridGraph_.setBlocked(i, j, zIdx, frDirEnum::D); - if (isLayerHorz) { + if (isLayerHorz && hasHorizontalAccess) { gridGraph_.setBlocked(i, j, zIdx, frDirEnum::N); gridGraph_.setBlocked(i, j, zIdx, frDirEnum::S); - } else { + } else if (!isLayerHorz && hasVerticalAccess) { gridGraph_.setBlocked(i, j, zIdx, frDirEnum::W); gridGraph_.setBlocked(i, j, zIdx, frDirEnum::E); } diff --git a/src/drt/src/gc/FlexGC_cut.cpp b/src/drt/src/gc/FlexGC_cut.cpp index 4bcf9d5524c..9b250a02d3a 100644 --- a/src/drt/src/gc/FlexGC_cut.cpp +++ b/src/drt/src/gc/FlexGC_cut.cpp @@ -354,9 +354,10 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl_main( } } -inline bool isSkipVia(gcRect* rect) +bool FlexGCWorker::Impl::isSkipVia(gcRect* rect) { - return rect->getLayerNum() == GC_IGNORE_PDN_LAYER && rect->isFixed() + return rect->getLayerNum() >= GC_IGNORE_PDN_BEGIN_LAYER + && rect->getLayerNum() <= GC_IGNORE_PDN_END_LAYER && rect->isFixed() && rect->hasNet() && rect->getNet()->getFrNet() && rect->getNet()->getFrNet()->getType().isSupply(); } @@ -414,12 +415,15 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl( continue; if (isSkipVia(ptr)) continue; + queryLayerNum = layerNum1; + if (isUpperVia) checkLef58CutSpacingTbl_main(viaRect, ptr, con); else checkLef58CutSpacingTbl_main(ptr, viaRect, con); } } + void FlexGCWorker::Impl::checKeepOutZone_main(gcRect* rect, frLef58KeepOutZoneConstraint* con) { diff --git a/src/drt/src/gc/FlexGC_impl.h b/src/drt/src/gc/FlexGC_impl.h index a52e1c7c3a8..45b69d964b7 100644 --- a/src/drt/src/gc/FlexGC_impl.h +++ b/src/drt/src/gc/FlexGC_impl.h @@ -534,5 +534,6 @@ class FlexGCWorker::Impl const gtl::rectangle_data& rect); bool isOppositeDir(gcCorner* corner, gcSegment* seg); bool isWrongDir(gcSegment* edge); + bool isSkipVia(gcRect* rect); }; } // namespace fr diff --git a/src/drt/src/gc/FlexGC_main.cpp b/src/drt/src/gc/FlexGC_main.cpp index f4d8ae5b5bb..d91bb410f89 100644 --- a/src/drt/src/gc/FlexGC_main.cpp +++ b/src/drt/src/gc/FlexGC_main.cpp @@ -785,6 +785,9 @@ void FlexGCWorker::Impl::checkMetalSpacing_main(gcRect* ptr1, if (ptr1 == ptr2) { return; } + if (isSkipVia(ptr1) || isSkipVia(ptr2)) { + return; + } gtl::rectangle_data markerRect(*ptr1); auto distX = gtl::euclidean_distance(markerRect, *ptr2, gtl::HORIZONTAL); auto distY = gtl::euclidean_distance(markerRect, *ptr2, gtl::VERTICAL); diff --git a/src/drt/src/global.cpp b/src/drt/src/global.cpp index c6cbdfd7242..d40cf88fe11 100644 --- a/src/drt/src/global.cpp +++ b/src/drt/src/global.cpp @@ -112,8 +112,10 @@ int MISALIGNMENTCOST = 8; int CONGCOST = 8; int HISTCOST = 32; -std::string REPAIR_PDN_LAYER_NAME; -frLayerNum GC_IGNORE_PDN_LAYER = -1; +std::string REPAIR_PDN_LAYER_BEGIN_NAME; +std::string REPAIR_PDN_LAYER_END_NAME; +frLayerNum GC_IGNORE_PDN_BEGIN_LAYER = -1; +frLayerNum GC_IGNORE_PDN_END_LAYER = -1; namespace fr { std::ostream& operator<<(std::ostream& os, const frRect& pinFigIn) diff --git a/src/drt/src/global.h b/src/drt/src/global.h index 9540dd590a2..aa5beb5b615 100644 --- a/src/drt/src/global.h +++ b/src/drt/src/global.h @@ -111,8 +111,10 @@ extern int MISALIGNMENTCOST; extern int HISTCOST; extern int CONGCOST; -extern std::string REPAIR_PDN_LAYER_NAME; -extern fr::frLayerNum GC_IGNORE_PDN_LAYER; +extern std::string REPAIR_PDN_LAYER_BEGIN_NAME; +extern std::string REPAIR_PDN_LAYER_END_NAME; +extern fr::frLayerNum GC_IGNORE_PDN_BEGIN_LAYER; +extern fr::frLayerNum GC_IGNORE_PDN_END_LAYER; #define DIRBITSIZE 3 #define WAVEFRONTBUFFERSIZE 2 From 0f1232f3524e0be7d514e32ece84c47b931f63d4 Mon Sep 17 00:00:00 2001 From: Osama Date: Mon, 29 Jan 2024 20:13:10 +0200 Subject: [PATCH 02/26] drt: update defok Signed-off-by: Osama --- src/drt/test/ta_pin_aligned.defok | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/drt/test/ta_pin_aligned.defok b/src/drt/test/ta_pin_aligned.defok index f80d9ac14e5..d4e43f88e19 100644 --- a/src/drt/test/ta_pin_aligned.defok +++ b/src/drt/test/ta_pin_aligned.defok @@ -121,6 +121,9 @@ NETS 2 ; - Metal2_in ( PIN Metal2_out ) ( PIN Metal2_in ) + USE SIGNAL + ROUTED metal2 ( 97850 19740 0 ) ( * 180180 0 ) ; - Metal3_in ( PIN Metal3_out ) ( PIN Metal3_in ) + USE SIGNAL - + ROUTED metal3 ( 19790 97860 0 ) ( 180510 * 0 ) ; + + ROUTED metal3 ( 176400 97580 ) ( * 97860 ) + NEW metal3 ( 180510 97580 ) ( * 97860 0 ) + NEW metal3 ( 176400 97580 ) ( 180510 * ) + NEW metal3 ( 19790 97860 0 ) ( 176400 * ) ; END NETS END DESIGN From 746f1af5afd352c0dd511922564fc970c3837981 Mon Sep 17 00:00:00 2001 From: luis201420 Date: Tue, 25 Jun 2024 19:26:27 +0000 Subject: [PATCH 03/26] grt: updating only the subset of edges used by incremental GRT Signed-off-by: luis201420 --- src/grt/src/fastroute/src/utility.cpp | 50 +++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index 29460d4526b..b28c98465ab 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -1882,9 +1882,40 @@ void FastRouteCore::copyRS(void) void FastRouteCore::copyBR(void) { - int i, j, edgeID, numEdges, numNodes, min_y, min_x; + int i, j, edgeID, numEdges, numNodes, min_y, min_x, edgeCost; if (!sttrees_bk_.empty()) { + + // Reduce usage with last routes before update + for (const int& netID : net_ids_) { + numEdges = sttrees_[netID].num_edges(); + edgeCost = nets_[netID]->getEdgeCost(); + + for (edgeID = 0; edgeID < numEdges; edgeID++) { + if (sttrees_[netID].edges[edgeID].len > 0) { + const std::vector& gridsX + = sttrees_[netID].edges[edgeID].route.gridsX; + const std::vector& gridsY + = sttrees_[netID].edges[edgeID].route.gridsY; + for (i = 0; i < sttrees_[netID].edges[edgeID].route.routelen; i++) { + if (gridsX[i] == gridsX[i + 1] && gridsY[i] == gridsY[i + 1]) { + continue; + } + if (gridsX[i] == gridsX[i + 1]) // a vertical edge + { + min_y = std::min(gridsY[i], gridsY[i + 1]); + v_edges_[min_y][gridsX[i]].usage -= edgeCost; + } else /// if(gridsY[i]==gridsY[i+1])// a horizontal edge + { + min_x = std::min(gridsX[i], gridsX[i + 1]); + h_edges_[gridsY[i]][min_x].usage -= edgeCost; + } + } + } + } + } + + // Clean routes for (const int& netID : net_ids_) { numEdges = sttrees_[netID].num_edges(); for (edgeID = 0; edgeID < numEdges; edgeID++) { @@ -1895,6 +1926,7 @@ void FastRouteCore::copyBR(void) } } + // Copy saved routes for (const int& netID : net_ids_) { numNodes = sttrees_bk_[netID].num_nodes(); numEdges = sttrees_bk_[netID].num_edges(); @@ -1944,20 +1976,10 @@ void FastRouteCore::copyBR(void) } } - for (i = 0; i < y_grid_; i++) { - for (j = 0; j < x_grid_ - 1; j++) { - h_edges_[i][j].usage = 0; - } - } - for (i = 0; i < y_grid_ - 1; i++) { - for (j = 0; j < x_grid_; j++) { - v_edges_[i][j].usage = 0; - } - } - - for (int netID = 0; netID < netCount(); netID++) { + // Increase usage with new routes + for (const int& netID : net_ids_) { numEdges = sttrees_[netID].num_edges(); - int edgeCost = nets_[netID]->getEdgeCost(); + edgeCost = nets_[netID]->getEdgeCost(); for (edgeID = 0; edgeID < numEdges; edgeID++) { if (sttrees_[netID].edges[edgeID].len > 0) { From 5f09648cd201284726349aacca751e3057152936 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 8 Jul 2024 17:08:40 +0300 Subject: [PATCH 04/26] fixes The-OpenROAD-Project/OpenROAD#5307 Signed-off-by: osamahammad21 --- src/drt/src/dr/FlexDR_init.cpp | 21 +++++++++++---------- src/drt/src/dr/FlexDR_maze.cpp | 4 ++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index e3862e2a84b..f5d1d48f97e 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -3002,7 +3002,7 @@ void FlexDRWorker::route_queue_update_from_marker( allowAvoidRipup = true; dNet->setNRipupAvoids(0); } - routes.push_back({dNet, dNet->getNumReroutes(), true}); + routes.push_back({dNet, dNet->getNumReroutes(), true, nullptr}); } } } @@ -3011,14 +3011,14 @@ void FlexDRWorker::route_queue_update_from_marker( for (drNet* dNet : avoidRipupCandidates) { if (allowAvoidRipup) { dNet->incNRipupAvoids(); - checks.push_back({dNet, -1, false}); + checks.push_back({dNet, -1, false, nullptr}); } else { dNet->setNRipupAvoids(0); - routes.push_back({dNet, dNet->getNumReroutes(), true}); + routes.push_back({dNet, dNet->getNumReroutes(), true, nullptr}); } } for (auto& victimOwner : uniqueVictimOwners) { - checks.push_back({victimOwner, -1, false}); + checks.push_back({victimOwner, -1, false, nullptr}); } } @@ -3068,7 +3068,8 @@ bool FlexDRWorker::canRipup(drNet* n) void FlexDRWorker::route_queue_update_queue( const std::vector>& markers, - std::queue& rerouteQueue) + std::queue& rerouteQueue, + frBlockObject* checkingObj) { std::set uniqueVictims; std::set uniqueAggressors; @@ -3081,7 +3082,7 @@ void FlexDRWorker::route_queue_update_queue( marker, uniqueVictims, uniqueAggressors, checks, routes); } - route_queue_update_queue(checks, routes, rerouteQueue); + route_queue_update_queue(checks, routes, rerouteQueue, checkingObj); } void FlexDRWorker::initMazeCost_guide_helper(drNet* net, const bool isAdd) @@ -3490,10 +3491,10 @@ void FlexDRWorker::initMazeCost_connFig() { for (auto& net : nets_) { for (auto& connFig : net->getExtConnFigs()) { - addPathCost(connFig.get()); + addPathCost(connFig.get(), false, true); } for (auto& connFig : net->getRouteConnFigs()) { - addPathCost(connFig.get()); + addPathCost(connFig.get(), false, true); } gcWorker_->updateDRNet(net.get()); gcWorker_->updateGCWorker(); @@ -3548,9 +3549,9 @@ void FlexDRWorker::initMazeCost_via_helper(drNet* net, bool isAddPathCost) via->addToNet(net); initMazeIdx_connFig(via.get()); if (isAddPathCost) { - addPathCost(via.get(), true); + addPathCost(via.get(), true, true); } else { - subPathCost(via.get(), true); + subPathCost(via.get(), true, true); } } } diff --git a/src/drt/src/dr/FlexDR_maze.cpp b/src/drt/src/dr/FlexDR_maze.cpp index 69610fc25ab..2700ae99fe3 100644 --- a/src/drt/src/dr/FlexDR_maze.cpp +++ b/src/drt/src/dr/FlexDR_maze.cpp @@ -1466,7 +1466,7 @@ void FlexDRWorker::modPathCost(drConnFig* connFig, box = rect->getBBox(); xform.apply(box); if (modCutSpc) { - modCutSpacingCost(box, bi.z(), type); + modCutSpacingCost(box, bi.z(), type, false, bi.x(), bi.y()); } modInterLayerCutSpacingCost(box, bi.z(), type, true); modInterLayerCutSpacingCost(box, bi.z(), type, false); @@ -1782,7 +1782,7 @@ void FlexDRWorker::route_queue_main(std::queue& rerouteQueue) graphics_->startNet(net); } for (auto& uConnFig : net->getRouteConnFigs()) { - subPathCost(uConnFig.get()); + subPathCost(uConnFig.get(), false, true); workerRegionQuery.remove(uConnFig.get()); // worker region query } modEolCosts_poly(gcWorker_->getNet(net->getFrNet()), From 740309752708a303df839049e40e3108c85599df Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 8 Jul 2024 17:42:01 +0300 Subject: [PATCH 05/26] drt: code fixes Signed-off-by: osamahammad21 --- src/drt/src/dr/FlexDR_init.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index f5d1d48f97e..848b28ab4ac 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -3002,7 +3002,7 @@ void FlexDRWorker::route_queue_update_from_marker( allowAvoidRipup = true; dNet->setNRipupAvoids(0); } - routes.push_back({dNet, dNet->getNumReroutes(), true, nullptr}); + routes.push_back({dNet, dNet->getNumReroutes(), true}); } } } @@ -3011,14 +3011,14 @@ void FlexDRWorker::route_queue_update_from_marker( for (drNet* dNet : avoidRipupCandidates) { if (allowAvoidRipup) { dNet->incNRipupAvoids(); - checks.push_back({dNet, -1, false, nullptr}); + checks.push_back({dNet, -1, false}); } else { dNet->setNRipupAvoids(0); - routes.push_back({dNet, dNet->getNumReroutes(), true, nullptr}); + routes.push_back({dNet, dNet->getNumReroutes(), true}); } } for (auto& victimOwner : uniqueVictimOwners) { - checks.push_back({victimOwner, -1, false, nullptr}); + checks.push_back({victimOwner, -1, false}); } } @@ -3068,8 +3068,7 @@ bool FlexDRWorker::canRipup(drNet* n) void FlexDRWorker::route_queue_update_queue( const std::vector>& markers, - std::queue& rerouteQueue, - frBlockObject* checkingObj) + std::queue& rerouteQueue) { std::set uniqueVictims; std::set uniqueAggressors; @@ -3082,7 +3081,7 @@ void FlexDRWorker::route_queue_update_queue( marker, uniqueVictims, uniqueAggressors, checks, routes); } - route_queue_update_queue(checks, routes, rerouteQueue, checkingObj); + route_queue_update_queue(checks, routes, rerouteQueue); } void FlexDRWorker::initMazeCost_guide_helper(drNet* net, const bool isAdd) From af5a956650ff505fa07d32f0339cf54292483508 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 8 Jul 2024 18:42:39 +0300 Subject: [PATCH 06/26] drt: skip rerouting clean nets Signed-off-by: osamahammad21 --- src/drt/src/dr/FlexDR.h | 7 +++++-- src/drt/src/dr/FlexDR_init.cpp | 29 +++++++++++++++++------------ src/drt/src/dr/FlexDR_maze.cpp | 19 ++++++++++++++----- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/drt/src/dr/FlexDR.h b/src/drt/src/dr/FlexDR.h index 88ff37495b9..a5be2d219b5 100644 --- a/src/drt/src/dr/FlexDR.h +++ b/src/drt/src/dr/FlexDR.h @@ -446,6 +446,7 @@ class FlexDRWorker frBlockObject* block; int numReroute; bool doRoute; + frBlockObject* checkingObj; }; frDesign* design_ = nullptr; Logger* logger_ = nullptr; @@ -737,7 +738,8 @@ class FlexDRWorker std::set& uniqueVictims, std::set& uniqueAggressors, std::vector& checks, - std::vector& routes); + std::vector& routes, + frBlockObject* checkingObj); void getRipUpNetsFromMarker(frMarker* marker, std::set& nets, frCoord bloatDist = 0); @@ -746,7 +748,8 @@ class FlexDRWorker std::queue& rerouteQueue); void route_queue_update_queue( const std::vector>& markers, - std::queue& rerouteQueue); + std::queue& rerouteQueue, + frBlockObject* checkingObj = nullptr); bool canRipup(drNet* n); // route void addPathCost(drConnFig* connFig, diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index 848b28ab4ac..85be2f7cef7 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -2746,7 +2746,7 @@ void FlexDRWorker::route_queue_init_queue( if (getRipupMode() == RipUpMode::DRC) { for (auto& marker : markers_) { route_queue_update_from_marker( - &marker, uniqueVictims, uniqueAggressors, checks, routes); + &marker, uniqueVictims, uniqueAggressors, checks, routes, nullptr); } mazeIterInit_sortRerouteQueue(0, checks); mazeIterInit_sortRerouteQueue(0, routes); @@ -2761,7 +2761,7 @@ void FlexDRWorker::route_queue_init_queue( // sort nets mazeIterInit_sortRerouteNets(0, ripupNets); for (auto& net : ripupNets) { - routes.push_back({net, 0, true}); + routes.push_back({net, 0, true, nullptr}); // reserve via because all nets are ripped up initMazeCost_via_helper(net, true); // no need to clear the net because route objs are not pushed to the net @@ -2790,7 +2790,7 @@ void FlexDRWorker::route_queue_init_queue( // sort nets mazeIterInit_sortRerouteNets(0, ripupNets); for (auto& net : ripupNets) { - routes.push_back({net, 0, true}); + routes.push_back({net, 0, true, nullptr}); initMazeCost_via_helper(net, true); } } else if (getRipupMode() == RipUpMode::INCR) { @@ -2804,7 +2804,7 @@ void FlexDRWorker::route_queue_init_queue( // sort nets mazeIterInit_sortRerouteNets(0, ripupNets); for (auto& net : ripupNets) { - routes.push_back({net, 0, true}); + routes.push_back({net, 0, true, nullptr}); // reserve via because all nets are ripped up initMazeCost_via_helper(net, true); // no need to clear the net because route objs are not pushed to the net @@ -2840,7 +2840,8 @@ void FlexDRWorker::route_queue_update_from_marker( std::set& uniqueVictims, std::set& uniqueAggressors, std::vector& checks, - std::vector& routes) + std::vector& routes, + frBlockObject* checkingObj) { // if shapes don't overlap routeBox, ignore violation if (!getRouteBox().intersects(marker->getBBox())) { @@ -3002,7 +3003,7 @@ void FlexDRWorker::route_queue_update_from_marker( allowAvoidRipup = true; dNet->setNRipupAvoids(0); } - routes.push_back({dNet, dNet->getNumReroutes(), true}); + routes.push_back({dNet, dNet->getNumReroutes(), true, checkingObj}); } } } @@ -3011,14 +3012,14 @@ void FlexDRWorker::route_queue_update_from_marker( for (drNet* dNet : avoidRipupCandidates) { if (allowAvoidRipup) { dNet->incNRipupAvoids(); - checks.push_back({dNet, -1, false}); + checks.push_back({dNet, -1, false, checkingObj}); } else { dNet->setNRipupAvoids(0); - routes.push_back({dNet, dNet->getNumReroutes(), true}); + routes.push_back({dNet, dNet->getNumReroutes(), true, checkingObj}); } } for (auto& victimOwner : uniqueVictimOwners) { - checks.push_back({victimOwner, -1, false}); + checks.push_back({victimOwner, -1, false, checkingObj}); } } @@ -3068,17 +3069,21 @@ bool FlexDRWorker::canRipup(drNet* n) void FlexDRWorker::route_queue_update_queue( const std::vector>& markers, - std::queue& rerouteQueue) + std::queue& rerouteQueue, + frBlockObject* checkingObj) { std::set uniqueVictims; std::set uniqueAggressors; std::vector checks; std::vector routes; - + if (checkingObj != nullptr + && checkingObj->typeId() == frBlockObjectEnum::drcNet) { + checkingObj = static_cast(checkingObj)->getFrNet(); + } for (auto& uMarker : markers) { auto marker = uMarker.get(); route_queue_update_from_marker( - marker, uniqueVictims, uniqueAggressors, checks, routes); + marker, uniqueVictims, uniqueAggressors, checks, routes, checkingObj); } route_queue_update_queue(checks, routes, rerouteQueue); diff --git a/src/drt/src/dr/FlexDR_maze.cpp b/src/drt/src/dr/FlexDR_maze.cpp index 2700ae99fe3..54cb81368ca 100644 --- a/src/drt/src/dr/FlexDR_maze.cpp +++ b/src/drt/src/dr/FlexDR_maze.cpp @@ -1755,7 +1755,7 @@ void FlexDRWorker::identifyCongestionLevel() void FlexDRWorker::route_queue_main(std::queue& rerouteQueue) { int gc_version = 1; - std::map obj_gc_version; + std::map> obj_gc_version; auto& workerRegionQuery = getWorkerRegionQuery(); while (!rerouteQueue.empty()) { auto& entry = rerouteQueue.front(); @@ -1772,6 +1772,14 @@ void FlexDRWorker::route_queue_main(std::queue& rerouteQueue) if (numReroute != net->getNumReroutes()) { continue; } + if (ripupMode_ == RipUpMode::DRC && entry.checkingObj != nullptr + && obj_gc_version.find(net->getFrNet()) != obj_gc_version.end() + && obj_gc_version.find(entry.checkingObj) != obj_gc_version.end() + && obj_gc_version[net->getFrNet()] == std::make_pair(gc_version, 0) + && obj_gc_version[entry.checkingObj] + == std::make_pair(gc_version, 0)) { + continue; + } // init net->setModified(true); if (net->getFrNet()) { @@ -1890,7 +1898,8 @@ void FlexDRWorker::route_queue_main(std::queue& rerouteQueue) } } didCheck = true; - obj_gc_version[net->getFrNet()] = gc_version; + obj_gc_version[net->getFrNet()] + = {gc_version, gcWorker_->getMarkers().size()}; } else { logger_->error(DRT, 1006, "failed to setTargetNet"); @@ -1898,10 +1907,9 @@ void FlexDRWorker::route_queue_main(std::queue& rerouteQueue) } else { gcWorker_->setEnableSurgicalFix(false); if (obj_gc_version.find(obj) != obj_gc_version.end() - && obj_gc_version[obj] == gc_version) { + && obj_gc_version[obj].first == gc_version) { continue; } - obj_gc_version[obj] = gc_version; if (obj->typeId() == frcNet) { auto net = static_cast(obj); if (gcWorker_->setTargetNet(net)) { @@ -1914,10 +1922,11 @@ void FlexDRWorker::route_queue_main(std::queue& rerouteQueue) didCheck = true; } } + obj_gc_version[obj] = {gc_version, gcWorker_->getMarkers().size()}; } // end if (didCheck) { - route_queue_update_queue(gcWorker_->getMarkers(), rerouteQueue); + route_queue_update_queue(gcWorker_->getMarkers(), rerouteQueue, obj); } if (didRoute) { route_queue_markerCostDecay(); From c7f427269da5eb06e5da7a268009b32df1f71bc6 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 15 Jul 2024 23:42:54 +0000 Subject: [PATCH 07/26] drt: fix estimated forbidden penalty Signed-off-by: osamahammad21 --- src/drt/src/dr/FlexGridGraph_maze.cpp | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/drt/src/dr/FlexGridGraph_maze.cpp b/src/drt/src/dr/FlexGridGraph_maze.cpp index d108725bbe9..4650c2e1eea 100644 --- a/src/drt/src/dr/FlexGridGraph_maze.cpp +++ b/src/drt/src/dr/FlexGridGraph_maze.cpp @@ -216,31 +216,31 @@ frCost FlexGridGraph::getEstCost(const FlexMazeIdx& src, // avoid propagating to location that will cause forbidden via spacing to // boundary pin bool isForbidden = false; - if (dstMazeIdx1 == dstMazeIdx2 && gridZ == dstMazeIdx1.z()) { + if (dstMazeIdx1.z() == dstMazeIdx2.z() && gridZ == dstMazeIdx1.z()) { auto layerNum = (gridZ + 1) * 2; auto layer = getTech()->getLayer(layerNum); - if (layer->isUnidirectional()) { + if (!USENONPREFTRACKS || layer->isUnidirectional()) { bool isH = (layer->getDir() == dbTechLayerDir::HORIZONTAL); - if (isH) { + if (isH && dstMazeIdx1.y() == dstMazeIdx2.y()) { auto gap = abs(nextPoint.y() - dstPoint1.y()); if (gap - && (getTech()->isVia2ViaForbiddenLen( - gridZ, false, false, false, gap, ndr_) - || layerNum - 2 < BOTTOM_ROUTING_LAYER) - && (getTech()->isVia2ViaForbiddenLen( - gridZ, true, true, false, gap, ndr_) - || layerNum + 2 > getTech()->getTopLayerNum())) { + && (layerNum - 2 < BOTTOM_ROUTING_LAYER + || getTech()->isVia2ViaForbiddenLen( + gridZ - 1, false, false, false, gap, ndr_)) + && (layerNum + 2 > getTech()->getTopLayerNum() + || getTech()->isVia2ViaForbiddenLen( + gridZ + 1, true, true, false, gap, ndr_))) { isForbidden = true; } - } else { + } else if (!isH && dstMazeIdx1.x() == dstMazeIdx2.x()) { auto gap = abs(nextPoint.x() - dstPoint1.x()); if (gap - && (getTech()->isVia2ViaForbiddenLen( - gridZ, false, false, true, gap, ndr_) - || layerNum - 2 < BOTTOM_ROUTING_LAYER) - && (getTech()->isVia2ViaForbiddenLen( - gridZ, true, true, true, gap, ndr_) - || layerNum + 2 > getTech()->getTopLayerNum())) { + && (layerNum - 2 < BOTTOM_ROUTING_LAYER + || getTech()->isVia2ViaForbiddenLen( + gridZ - 1, false, false, true, gap, ndr_)) + && (layerNum + 2 > getTech()->getTopLayerNum() + || getTech()->isVia2ViaForbiddenLen( + gridZ + 1, true, true, true, gap, ndr_))) { isForbidden = true; } } From f9c668e33ebd314633e32f58eb47635cc3d72a91 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sat, 20 Jul 2024 11:58:22 -0400 Subject: [PATCH 08/26] psm: check bbox on iterm to avoid warnings about pins without geometries Signed-off-by: Peter Gadfort --- src/psm/src/ir_network.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/psm/src/ir_network.cpp b/src/psm/src/ir_network.cpp index f4287e38f02..570c00d1cad 100644 --- a/src/psm/src/ir_network.cpp +++ b/src/psm/src/ir_network.cpp @@ -260,6 +260,11 @@ IRNetwork::generatePolygonsFromITerms(std::vector& terminals) continue; } const auto transform = inst->getTransform(); + if (iterm->getBBox().isInverted()) { + // iterm has no physical shape, so ignore. + continue; + } + int x, y; iterm->getAvgXY(&x, &y); auto base_node From 385bef6f3c459f540da4fd8d297f8208588c6936 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sat, 20 Jul 2024 12:03:07 -0400 Subject: [PATCH 09/26] psm: cleanup of insert_decap files Signed-off-by: Peter Gadfort --- src/psm/test/insert_decap1.tcl | 2 +- src/psm/test/insert_decap2.tcl | 2 +- src/psm/test/save_defok | 1 + src/psm/test/{ => sky130hd_data}/insert_decap_gcd.def | 0 4 files changed, 3 insertions(+), 2 deletions(-) create mode 120000 src/psm/test/save_defok rename src/psm/test/{ => sky130hd_data}/insert_decap_gcd.def (100%) diff --git a/src/psm/test/insert_decap1.tcl b/src/psm/test/insert_decap1.tcl index 8886a381562..db7d98f1035 100644 --- a/src/psm/test/insert_decap1.tcl +++ b/src/psm/test/insert_decap1.tcl @@ -4,7 +4,7 @@ source "helpers.tcl" read_liberty sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib read_lef "sky130hd/sky130hd.tlef" read_lef "sky130hd/sky130hd_std_cell.lef" -read_def "insert_decap_gcd.def" +read_def "sky130hd_data/insert_decap_gcd.def" source sky130hd/sky130hd.rc diff --git a/src/psm/test/insert_decap2.tcl b/src/psm/test/insert_decap2.tcl index 481588a970b..11c1578b1d8 100644 --- a/src/psm/test/insert_decap2.tcl +++ b/src/psm/test/insert_decap2.tcl @@ -8,7 +8,7 @@ read_liberty sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib source sky130hd/sky130hd.rc -read_def "insert_decap_gcd.def" +read_def "sky130hd_data/insert_decap_gcd.def" analyze_power_grid -net {VDD} insert_decap -target_cap 10.5 -cells {"sky130_fd_sc_hd__decap_3" 2.5} diff --git a/src/psm/test/save_defok b/src/psm/test/save_defok new file mode 120000 index 00000000000..899db325246 --- /dev/null +++ b/src/psm/test/save_defok @@ -0,0 +1 @@ +../../../test/shared/save_defok \ No newline at end of file diff --git a/src/psm/test/insert_decap_gcd.def b/src/psm/test/sky130hd_data/insert_decap_gcd.def similarity index 100% rename from src/psm/test/insert_decap_gcd.def rename to src/psm/test/sky130hd_data/insert_decap_gcd.def From 47885969b7b67e8aa9225a3e7bbb668d8cdb2462 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Sun, 21 Jul 2024 16:52:24 +0300 Subject: [PATCH 10/26] drt: update defok Signed-off-by: osamahammad21 --- src/drt/test/ndr_vias1.defok | 112 ++++++++++++++++++----------------- src/drt/test/ndr_vias2.defok | 78 ++++++++++++------------ 2 files changed, 98 insertions(+), 92 deletions(-) diff --git a/src/drt/test/ndr_vias1.defok b/src/drt/test/ndr_vias1.defok index c0e9fd7e499..bd356e7f80a 100644 --- a/src/drt/test/ndr_vias1.defok +++ b/src/drt/test/ndr_vias1.defok @@ -231,9 +231,9 @@ NETS 8 ; NEW met1 ( 132710 172890 210 ) ( 152030 * 210 ) NEW met1 ( 152030 169830 210 ) ( 167900 * 210 ) NEW met1 TAPER ( 116610 118490 ) ( 118220 * ) - NEW met1 TAPER ( 152950 151130 ) ( 154330 * ) - NEW met2 ( 154330 118490 210 ) ( * 151130 210 ) - NEW met2 ( 152950 151130 210 ) ( * 169830 210 ) + NEW met1 TAPER ( 152490 150450 ) ( 154330 * ) + NEW met2 ( 154330 118490 210 ) ( * 150450 210 ) + NEW met2 ( 152950 150450 210 ) ( * 169830 210 ) NEW met1 ( 118220 118490 210 ) ( 167900 * 210 ) NEW li1 TAPER ( 169510 118490 ) L1M1_PR_R NEW li1 TAPER ( 169510 169830 ) L1M1_PR_R @@ -242,13 +242,13 @@ NETS 8 ; NEW li1 TAPER ( 130870 172890 ) L1M1_PR_R NEW met1 ( 152950 169830 ) M1M2_PR_R NEW li1 TAPER ( 116610 118490 ) L1M1_PR_R - NEW li1 TAPER ( 152950 151130 ) L1M1_PR_R - NEW met1 TAPER ( 154330 151130 ) M1M2_PR_R + NEW li1 TAPER ( 152490 150450 ) L1M1_PR_R + NEW met1 TAPER ( 154330 150450 ) M1M2_PR_R NEW met1 ( 154330 118490 ) M1M2_PR_R - NEW met1 TAPER ( 152950 151130 ) M1M2_PR_R + NEW met1 TAPER ( 152950 150450 ) M1M2_PR_R NEW met1 TAPER ( 152950 169830 ) RECT ( -490 -70 0 70 ) NEW met1 TAPER ( 154330 118490 ) RECT ( -490 -70 0 70 ) - NEW met1 TAPER ( 152950 151130 ) RECT ( -490 -70 0 70 ) ; + NEW met1 TAPER ( 152950 150450 ) RECT ( -490 -70 0 70 ) ; - clknet_2_0__leaf_clk ( _414_ CLK ) ( _418_ CLK ) ( _428_ CLK ) ( _429_ CLK ) ( _432_ CLK ) ( _434_ CLK ) ( _444_ CLK ) ( _445_ CLK ) ( clkbuf_2_0__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S + ROUTED met1 ( 87630 120870 210 ) ( 91540 * 210 ) @@ -320,9 +320,9 @@ NETS 8 ; NEW met2 ( 158010 88570 210 ) ( * 101830 210 ) NEW met1 ( 158010 88570 210 ) ( 162610 * 210 ) NEW met1 TAPER ( 162610 88570 ) ( 164450 * ) - NEW met1 TAPER ( 171350 118490 ) ( 172730 * ) - NEW met2 ( 172730 90950 210 ) ( * 118490 210 ) - NEW met2 ( 172730 118490 210 ) ( * 120530 210 ) + NEW met1 TAPER ( 170890 117810 ) ( 172730 * ) + NEW met2 ( 172730 90950 210 ) ( * 117810 210 ) + NEW met2 ( 172730 117810 210 ) ( * 120530 210 ) NEW met1 TAPER ( 168130 120530 ) ( 172730 * ) NEW met1 ( 172730 120530 210 ) ( 200330 * 210 ) NEW met1 ( 152950 129370 210 ) ( 154330 * 210 ) @@ -347,8 +347,8 @@ NETS 8 ; NEW li1 TAPER ( 158010 101830 ) L1M1_PR_R NEW met1 TAPER ( 158010 101830 ) M1M2_PR_R NEW met1 ( 158010 88570 ) M1M2_PR_R - NEW li1 TAPER ( 171350 118490 ) L1M1_PR_R - NEW met1 TAPER ( 172730 118490 ) M1M2_PR_R + NEW li1 TAPER ( 170890 117810 ) L1M1_PR_R + NEW met1 TAPER ( 172730 117810 ) M1M2_PR_R NEW met1 ( 172730 90950 ) M1M2_PR_R NEW met1 TAPER ( 172730 120530 ) M1M2_PR_R NEW li1 TAPER ( 156170 129370 ) L1M1_PR_R @@ -375,13 +375,6 @@ NETS 8 ; NEW met2 ( 96830 183770 210 ) ( * 186150 210 ) NEW met1 ( 96830 183770 210 ) ( 98210 * 210 ) NEW met2 ( 98210 151130 210 ) ( * 183770 210 ) - NEW met2 ( 137770 210460 210 ) ( * 210630 210 ) - NEW met3 ( 137770 210460 450 ) ( 143290 * 450 ) - NEW met2 ( 143290 210460 210 ) ( * 210630 210 ) - NEW met1 ( 143290 210630 210 ) ( 148810 * 210 ) - NEW met1 TAPER ( 148810 210630 ) ( 150650 * ) - NEW met1 TAPER ( 135930 210630 ) ( 137770 * ) - NEW met1 ( 126270 210630 210 ) ( 135930 * 210 ) NEW met2 ( 140990 159290 210 ) ( * 175270 210 ) NEW met1 ( 140990 159290 210 ) ( 142140 * 210 ) NEW met1 TAPER ( 142140 159290 ) ( 143750 * ) @@ -390,16 +383,24 @@ NETS 8 ; NEW met1 TAPER ( 139380 175270 ) ( 140990 * ) NEW met2 ( 125810 175270 210 ) ( * 183430 210 ) NEW met1 ( 125810 175270 210 ) ( 131790 * 210 ) - NEW met2 ( 125810 206380 210 ) ( 126270 * 210 ) - NEW met2 ( 125810 183430 210 ) ( * 206380 210 ) - NEW met2 ( 111550 197370 210 ) ( * 199750 210 ) - NEW met1 ( 111550 197370 210 ) ( 125810 * 210 ) - NEW met1 TAPER ( 125810 199750 ) ( 126270 * ) NEW met1 ( 109250 186150 210 ) ( 125810 * 210 ) - NEW met2 ( 126270 206380 210 ) ( * 210630 210 ) + NEW met1 ( 146970 210970 210 ) ( 148810 * 210 ) + NEW met1 TAPER ( 148810 210970 ) ( 150650 * ) + NEW met1 ( 146970 210970 210 ) ( * 213350 210 ) + NEW met1 ( 144900 213350 210 ) ( 146970 * 210 ) + NEW met2 ( 125810 183430 210 ) ( * 193200 210 ) + NEW met2 ( 126270 200090 210 ) ( * 214030 210 ) + NEW met1 ( 126270 214030 210 ) ( 138230 * 210 ) + NEW met1 ( 138230 213690 210 ) ( * 214030 210 ) + NEW met1 ( 138230 213690 210 ) ( 144900 * 210 ) + NEW met1 ( 144900 213350 210 ) ( * 213690 210 ) + NEW met2 ( 137770 210970 210 ) ( * 214030 210 ) + NEW met2 ( 125810 193200 210 ) ( 126270 * 210 ) + NEW met2 ( 126270 193200 210 ) ( * 200090 210 ) + NEW met2 ( 111550 200090 210 ) ( * 200260 210 ) + NEW met3 ( 111550 200260 450 ) ( 126270 * 450 ) NEW met1 ( 98210 151130 ) M1M2_PR_R NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R - NEW met1 ( 126270 210630 ) M1M2_PR_R NEW li1 TAPER ( 109250 183770 ) L1M1_PR_R NEW met1 TAPER ( 109250 183770 ) M1M2_PR_R NEW met1 ( 109250 186150 ) M1M2_PR_R @@ -407,12 +408,6 @@ NETS 8 ; NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R NEW met1 ( 96830 183770 ) M1M2_PR_R - NEW li1 TAPER ( 137770 210630 ) L1M1_PR_R - NEW met1 TAPER ( 137770 210630 ) M1M2_PR_R - NEW met2 ( 137770 210460 ) M2M3_PR - NEW met2 ( 143290 210460 ) M2M3_PR - NEW met1 ( 143290 210630 ) M1M2_PR_R - NEW li1 TAPER ( 150650 210630 ) L1M1_PR_R NEW li1 TAPER ( 140990 175270 ) L1M1_PR_R NEW met1 TAPER ( 140990 175270 ) M1M2_PR_R NEW met1 ( 140990 159290 ) M1M2_PR_R @@ -423,23 +418,28 @@ NETS 8 ; NEW li1 TAPER ( 125810 183430 ) L1M1_PR_R NEW met1 TAPER ( 125810 183430 ) M1M2_PR_R NEW met1 ( 125810 175270 ) M1M2_PR_R - NEW li1 TAPER ( 111550 199750 ) L1M1_PR_R - NEW met1 TAPER ( 111550 199750 ) M1M2_PR_R - NEW met1 ( 111550 197370 ) M1M2_PR_R - NEW met1 ( 125810 197370 ) M1M2_PR_R - NEW li1 TAPER ( 126270 199750 ) L1M1_PR_R - NEW met1 TAPER ( 125810 199750 ) M1M2_PR_R NEW met1 ( 125810 186150 ) M1M2_PR_R + NEW li1 TAPER ( 150650 210970 ) L1M1_PR_R + NEW li1 TAPER ( 126270 200090 ) L1M1_PR_R + NEW met1 TAPER ( 126270 200090 ) M1M2_PR_R + NEW met1 ( 126270 214030 ) M1M2_PR_R + NEW li1 TAPER ( 137770 210970 ) L1M1_PR_R + NEW met1 TAPER ( 137770 210970 ) M1M2_PR_R + NEW met1 ( 137770 214030 ) M1M2_PR_R + NEW li1 TAPER ( 111550 200090 ) L1M1_PR_R + NEW met1 TAPER ( 111550 200090 ) M1M2_PR_R + NEW met2 ( 111550 200260 ) M2M3_PR + NEW met2 ( 126270 200260 ) M2M3_PR NEW met1 TAPER ( 109250 183770 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 96830 186150 ) RECT ( -355 -70 0 70 ) - NEW met1 TAPER ( 137770 210630 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 140990 175270 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 131790 172210 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 125810 183430 ) RECT ( -355 -70 0 70 ) - NEW met1 TAPER ( 111550 199750 ) RECT ( -355 -70 0 70 ) - NEW met2 TAPER ( 125810 197370 ) RECT ( -70 -305 70 0 ) - NEW met2 TAPER ( 125810 199750 ) RECT ( -70 -305 70 0 ) - NEW met2 TAPER ( 125810 186150 ) RECT ( -70 -305 70 0 ) ; + NEW met2 TAPER ( 125810 186150 ) RECT ( -70 -305 70 0 ) + NEW met1 TAPER ( 126270 200090 ) RECT ( -355 -70 0 70 ) + NEW met1 TAPER ( 137770 210970 ) RECT ( -355 -70 0 70 ) + NEW met1 TAPER ( 137770 214030 ) RECT ( -490 -70 0 70 ) + NEW met1 TAPER ( 111550 200090 ) RECT ( -355 -70 0 70 ) ; - clknet_2_3__leaf_clk ( _412_ CLK ) ( _419_ CLK ) ( _420_ CLK ) ( _422_ CLK ) ( _435_ CLK ) ( _436_ CLK ) ( _438_ CLK ) ( _439_ CLK ) ( clkbuf_2_3__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S + ROUTED met1 TAPER ( 204010 194310 ) ( 205850 * ) @@ -506,28 +506,30 @@ NETS 8 ; NEW li1 ( 170890 209950 ) L1M1_PR_MR NEW met1 ( 170890 209950 ) M1M2_PR ; - ctrl.state.out\[2\] ( _413_ Q ) ( _297_ A ) ( _293_ A ) ( _290_ A1 ) ( _284_ A ) ( _279_ A ) + USE SIGNAL - + ROUTED met2 ( 158470 207570 ) ( * 209950 ) - NEW met1 ( 158010 213350 ) ( 158470 * ) - NEW met2 ( 158470 209950 ) ( * 213350 ) - NEW met1 ( 158470 207570 ) ( 166290 * ) - NEW met1 ( 158010 200090 ) ( * 200430 ) + + ROUTED met1 ( 158010 200090 ) ( * 200430 ) NEW met1 ( 158010 200430 ) ( 158470 * ) NEW met2 ( 158470 194650 ) ( * 200430 ) NEW met1 ( 158010 191590 ) ( 158470 * ) NEW met2 ( 158470 191590 ) ( * 194650 ) - NEW met2 ( 158470 200430 ) ( * 207570 ) NEW met1 ( 158470 194650 ) ( 167210 * ) + NEW met2 ( 158470 200430 ) ( * 207000 ) + NEW met1 ( 158010 211650 ) ( 158470 * ) + NEW met2 ( 158010 211650 ) ( * 213350 ) + NEW met2 ( 158010 207570 ) ( * 211650 ) + NEW met2 ( 158010 207000 ) ( 158470 * ) + NEW met2 ( 158010 207000 ) ( * 207570 ) + NEW met1 ( 158010 207570 ) ( 166290 * ) NEW li1 ( 167210 194650 ) L1M1_PR_MR - NEW met1 ( 158470 207570 ) M1M2_PR - NEW li1 ( 158470 209950 ) L1M1_PR_MR - NEW met1 ( 158470 209950 ) M1M2_PR - NEW li1 ( 158010 213350 ) L1M1_PR_MR - NEW met1 ( 158470 213350 ) M1M2_PR NEW li1 ( 166290 207570 ) L1M1_PR_MR NEW li1 ( 158010 200090 ) L1M1_PR_MR NEW met1 ( 158470 200430 ) M1M2_PR NEW met1 ( 158470 194650 ) M1M2_PR NEW li1 ( 158010 191590 ) L1M1_PR_MR - NEW met1 ( 158470 191590 ) M1M2_PR ; + NEW met1 ( 158470 191590 ) M1M2_PR + NEW li1 ( 158470 211650 ) L1M1_PR_MR + NEW met1 ( 158010 211650 ) M1M2_PR + NEW li1 ( 158010 213350 ) L1M1_PR_MR + NEW met1 ( 158010 213350 ) M1M2_PR + NEW met1 ( 158010 207570 ) M1M2_PR ; END NETS END DESIGN diff --git a/src/drt/test/ndr_vias2.defok b/src/drt/test/ndr_vias2.defok index d0c7e13125e..43eb640182e 100644 --- a/src/drt/test/ndr_vias2.defok +++ b/src/drt/test/ndr_vias2.defok @@ -297,13 +297,13 @@ NETS 8 ; NEW met1 TAPER ( 117990 118150 ) ( 120060 * ) NEW met1 ( 120060 118150 210 ) ( 125350 * 210 ) NEW met2 ( 111090 120870 210 ) ( * 134470 210 ) - NEW met2 ( 131790 117300 210 ) ( * 118150 210 ) - NEW met3 ( 131790 117300 450 ) ( 144900 * 450 ) + NEW met2 ( 131330 117300 210 ) ( * 118150 210 ) + NEW met3 ( 131330 117300 450 ) ( 144900 * 450 ) NEW met4 ( 144900 89420 450 ) ( * 117300 450 ) NEW met3 ( 144900 89420 450 ) ( 146510 * 450 ) NEW met2 ( 146510 88570 210 ) ( * 89420 210 ) - NEW met2 ( 143750 115430 210 ) ( * 117300 210 ) - NEW met1 ( 125350 118150 210 ) ( 131790 * 210 ) + NEW met2 ( 143750 115770 210 ) ( * 117300 210 ) + NEW met1 ( 125350 118150 210 ) ( 131330 * 210 ) NEW met4 ( 137540 117300 450 ) ( * 131100 450 ) NEW met4 ( 136620 131100 450 ) ( 137540 * 450 ) NEW met4 ( 136620 131100 450 ) ( * 145180 450 ) @@ -325,15 +325,15 @@ NETS 8 ; NEW met1 ( 125350 118150 ) M1M2_PR_R NEW li1 TAPER ( 111090 134470 ) L1M1_PR_R NEW met1 TAPER ( 111090 134470 ) M1M2_PR_R - NEW met1 ( 131790 118150 ) M1M2_PR_R - NEW met2 ( 131790 117300 ) M2M3_PR_R + NEW met1 ( 131330 118150 ) M1M2_PR_R + NEW met2 ( 131330 117300 ) M2M3_PR_R NEW met3 ( 144900 117300 ) M3M4_PR_R NEW met3 ( 144900 89420 ) M3M4_PR_R NEW met2 ( 146510 89420 ) M2M3_PR_R NEW li1 TAPER ( 146510 88570 ) L1M1_PR_R NEW met1 TAPER ( 146510 88570 ) M1M2_PR_R - NEW li1 TAPER ( 143750 115430 ) L1M1_PR_R - NEW met1 TAPER ( 143750 115430 ) M1M2_PR_R + NEW li1 TAPER ( 143750 115770 ) L1M1_PR_R + NEW met1 TAPER ( 143750 115770 ) M1M2_PR_R NEW met2 ( 143750 117300 ) M2M3_PR_R NEW met3 ( 137540 117300 ) M3M4_PR_R NEW met3 ( 136620 145180 ) M3M4_PR_R @@ -346,7 +346,7 @@ NETS 8 ; NEW met1 TAPER ( 125350 120870 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 111090 134470 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 146510 88570 ) RECT ( -355 -70 0 70 ) - NEW met1 TAPER ( 143750 115430 ) RECT ( -355 -70 0 70 ) + NEW met1 TAPER ( 143750 115770 ) RECT ( -355 -70 0 70 ) NEW met3 TAPER ( 143750 117300 ) RECT ( -705 -150 0 150 ) NEW met3 TAPER ( 137540 117300 ) RECT ( -630 -150 0 150 ) NEW met3 TAPER ( 136620 145180 ) RECT ( -435 -150 0 150 ) @@ -356,15 +356,15 @@ NETS 8 ; + ROUTED met2 ( 156170 124270 210 ) ( * 129030 210 ) NEW met3 ( 155940 129540 450 ) ( 156170 * 450 ) NEW met2 ( 156170 129030 210 ) ( * 129540 210 ) - NEW met2 ( 158010 101660 210 ) ( * 101830 210 ) - NEW met3 ( 155940 101660 450 ) ( 158010 * 450 ) - NEW met4 ( 155940 101660 450 ) ( * 129540 450 ) + NEW met2 ( 158010 102170 210 ) ( * 102340 210 ) + NEW met3 ( 155940 102340 450 ) ( 158010 * 450 ) + NEW met4 ( 155940 102340 450 ) ( * 129540 450 ) NEW met1 ( 158010 88570 210 ) ( 162610 * 210 ) NEW met1 TAPER ( 162610 88570 ) ( 164450 * ) - NEW met2 ( 158010 88570 210 ) ( * 101660 210 ) - NEW met1 ( 164450 91290 210 ) ( 177100 * 210 ) - NEW met1 TAPER ( 177100 91290 ) ( 178710 * ) - NEW met2 ( 164450 88570 210 ) ( * 91290 210 ) + NEW met2 ( 158010 88570 210 ) ( * 102170 210 ) + NEW met1 ( 164450 90950 210 ) ( 177100 * 210 ) + NEW met1 TAPER ( 177100 90950 ) ( 178710 * ) + NEW met2 ( 164450 88570 210 ) ( * 90950 210 ) NEW met3 ( 152950 147900 450 ) ( 155940 * 450 ) NEW met2 ( 152950 147900 210 ) ( * 148070 210 ) NEW met4 ( 155940 129540 450 ) ( * 147900 450 ) @@ -392,14 +392,14 @@ NETS 8 ; NEW met1 ( 156170 124270 ) M1M2_PR_R NEW met3 ( 155940 129540 ) M3M4_PR_R NEW met2 ( 156170 129540 ) M2M3_PR_R - NEW li1 TAPER ( 158010 101830 ) L1M1_PR_R - NEW met1 TAPER ( 158010 101830 ) M1M2_PR_R - NEW met2 ( 158010 101660 ) M2M3_PR_R - NEW met3 ( 155940 101660 ) M3M4_PR_R + NEW li1 TAPER ( 158010 102170 ) L1M1_PR_R + NEW met1 TAPER ( 158010 102170 ) M1M2_PR_R + NEW met2 ( 158010 102340 ) M2M3_PR_R + NEW met3 ( 155940 102340 ) M3M4_PR_R NEW li1 TAPER ( 164450 88570 ) L1M1_PR_R NEW met1 ( 158010 88570 ) M1M2_PR_R - NEW li1 TAPER ( 178710 91290 ) L1M1_PR_R - NEW met1 ( 164450 91290 ) M1M2_PR_R + NEW li1 TAPER ( 178710 90950 ) L1M1_PR_R + NEW met1 ( 164450 90950 ) M1M2_PR_R NEW met1 TAPER ( 164450 88570 ) M1M2_PR_R NEW met3 ( 155940 147900 ) M3M4_PR_R NEW met2 ( 152950 147900 ) M2M3_PR_R @@ -419,7 +419,7 @@ NETS 8 ; NEW met1 TAPER ( 205850 96390 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 156170 129030 ) RECT ( -355 -70 0 70 ) NEW met3 TAPER ( 155940 129540 ) RECT ( -435 -150 0 150 ) - NEW met1 TAPER ( 158010 101830 ) RECT ( -355 -70 0 70 ) + NEW met1 TAPER ( 158010 102170 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 164450 88570 ) RECT ( -490 -70 0 70 ) NEW met1 TAPER ( 152950 148070 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 205850 113050 ) RECT ( -490 -70 0 70 ) @@ -437,13 +437,17 @@ NETS 8 ; NEW met4 ( 130180 179860 450 ) ( * 199580 450 ) NEW met2 ( 125810 179690 210 ) ( * 183430 210 ) NEW met1 ( 125810 179690 210 ) ( 130410 * 210 ) - NEW met2 ( 96830 185980 210 ) ( * 186150 210 ) - NEW met3 ( 96830 185980 450 ) ( 111550 * 450 ) - NEW met2 ( 111550 185980 210 ) ( * 199580 210 ) - NEW met2 ( 109250 183770 210 ) ( * 185980 210 ) + NEW met2 ( 109250 183770 210 ) ( * 186150 210 ) + NEW met1 ( 109250 186150 210 ) ( 111550 * 210 ) + NEW met2 ( 111550 186150 210 ) ( * 199580 210 ) + NEW met2 ( 96830 183770 210 ) ( * 186150 210 ) + NEW met1 ( 96830 183770 210 ) ( 107410 * 210 ) + NEW met1 TAPER ( 107410 183770 ) ( 109250 * ) + NEW met3 ( 96830 183260 450 ) ( 97060 * 450 ) + NEW met2 ( 96830 183260 210 ) ( * 183770 210 ) NEW met3 ( 97060 151300 450 ) ( 100050 * 450 ) NEW met2 ( 100050 151130 210 ) ( * 151300 210 ) - NEW met4 ( 97060 151300 450 ) ( * 185980 450 ) + NEW met4 ( 97060 151300 450 ) ( * 183260 450 ) NEW met1 ( 130410 179690 210 ) ( 131100 * 210 ) NEW met2 ( 137770 210970 210 ) ( * 212500 210 ) NEW met2 ( 150650 210970 210 ) ( * 212500 210 ) @@ -471,14 +475,15 @@ NETS 8 ; NEW li1 TAPER ( 125810 183430 ) L1M1_PR_R NEW met1 TAPER ( 125810 183430 ) M1M2_PR_R NEW met1 ( 125810 179690 ) M1M2_PR_R - NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R - NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R - NEW met2 ( 96830 185980 ) M2M3_PR_R - NEW met2 ( 111550 185980 ) M2M3_PR_R NEW li1 TAPER ( 109250 183770 ) L1M1_PR_R NEW met1 TAPER ( 109250 183770 ) M1M2_PR_R - NEW met2 ( 109250 185980 ) M2M3_PR_R - NEW met3 ( 97060 185980 ) M3M4_PR_R + NEW met1 ( 109250 186150 ) M1M2_PR_R + NEW met1 ( 111550 186150 ) M1M2_PR_R + NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R + NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R + NEW met1 ( 96830 183770 ) M1M2_PR_R + NEW met3 ( 97060 183260 ) M3M4_PR_R + NEW met2 ( 96830 183260 ) M2M3_PR_R NEW met3 ( 97060 151300 ) M3M4_PR_R NEW met2 ( 100050 151300 ) M2M3_PR_R NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R @@ -501,10 +506,9 @@ NETS 8 ; NEW met1 TAPER ( 111550 199750 ) RECT ( -355 -70 0 70 ) NEW met3 TAPER ( 130410 179860 ) RECT ( 0 -150 445 150 ) NEW met1 TAPER ( 125810 183430 ) RECT ( -355 -70 0 70 ) - NEW met1 TAPER ( 96830 186150 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 109250 183770 ) RECT ( -355 -70 0 70 ) - NEW met3 TAPER ( 109250 185980 ) RECT ( -705 -150 0 150 ) - NEW met3 TAPER ( 97060 185980 ) RECT ( -630 -150 0 150 ) + NEW met1 TAPER ( 96830 186150 ) RECT ( -355 -70 0 70 ) + NEW met3 TAPER ( 97060 183260 ) RECT ( 0 -150 435 150 ) NEW met1 TAPER ( 100050 151130 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 137770 210970 ) RECT ( -355 -70 0 70 ) NEW met1 TAPER ( 150650 210970 ) RECT ( -355 -70 0 70 ) From 988abbb0ff79b4f21df69ea73a393e1f344a5c70 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sun, 21 Jul 2024 11:10:15 -0400 Subject: [PATCH 11/26] gui: collect all layers in instance shapes Signed-off-by: Peter Gadfort --- src/gui/src/layoutViewer.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/gui/src/layoutViewer.cpp b/src/gui/src/layoutViewer.cpp index efae85b83cd..2c7e44eacc1 100644 --- a/src/gui/src/layoutViewer.cpp +++ b/src/gui/src/layoutViewer.cpp @@ -1328,10 +1328,6 @@ void LayoutViewer::boxesByLayer(dbMaster* master, LayerBoxes& boxes) for (dbBox* box : master->getObstructions()) { dbTechLayer* layer = box->getTechLayer(); dbTechLayerType type = layer->getType(); - if (type != dbTechLayerType::ROUTING && type != dbTechLayerType::CUT - && type != dbTechLayerType::IMPLANT) { - continue; - } boxes[layer].obs.emplace_back(box_to_qrect(box)); } @@ -1350,10 +1346,6 @@ void LayoutViewer::boxesByLayer(dbMaster* master, LayerBoxes& boxes) odb::Rect box_rect = via_box->getBox(); dbTechLayer* layer = via_box->getTechLayer(); dbTechLayerType type = layer->getType(); - if (type != dbTechLayerType::ROUTING - && type != dbTechLayerType::CUT) { - continue; - } via_transform.apply(box_rect); boxes[layer].mterms.emplace_back( QRect{box_rect.xMin(), @@ -1364,10 +1356,6 @@ void LayoutViewer::boxesByLayer(dbMaster* master, LayerBoxes& boxes) } else { dbTechLayer* layer = box->getTechLayer(); dbTechLayerType type = layer->getType(); - if (type != dbTechLayerType::ROUTING - && type != dbTechLayerType::CUT) { - continue; - } boxes[layer].mterms.emplace_back(box_to_qrect(box)); } } From 7616d521af7a287bba8db8ed160a50506c911f99 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sun, 21 Jul 2024 11:11:21 -0400 Subject: [PATCH 12/26] gui: add layer categories for implant and masterslice + insert all layers Signed-off-by: Peter Gadfort --- src/gui/src/displayControls.cpp | 97 +++++++++++++++++++++++++-------- src/gui/src/displayControls.h | 9 +++ 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/gui/src/displayControls.cpp b/src/gui/src/displayControls.cpp index c084f7d9efa..3e5a24ee382 100644 --- a/src/gui/src/displayControls.cpp +++ b/src/gui/src/displayControls.cpp @@ -264,6 +264,7 @@ DisplayControls::DisplayControls(QWidget* parent) : QDockWidget("Display Control", parent), view_(new QTreeView(this)), model_(new DisplayControlModel(user_data_item_idx_, this)), + routing_layers_menu_(new QMenu(this)), layers_menu_(new QMenu(this)), layers_menu_layer_(nullptr), ignore_callback_(false), @@ -295,6 +296,16 @@ DisplayControls::DisplayControls(QWidget* parent) auto layers = makeParentItem(layers_group_, "Layers", root, Qt::Checked, true); view_->expand(layers->index()); + auto implant_layer + = makeParentItem(layers_.implant, "Implant", layers, Qt::Checked, true); + auto master_layer = makeParentItem( + layers_.master, "Masterslice", layers, Qt::Unchecked, true); + auto other_layer + = makeParentItem(layers_.other, "Other", layers, Qt::Unchecked, true); + // hide initially + view_->setRowHidden(implant_layer->row(), layers->index(), true); + view_->setRowHidden(master_layer->row(), layers->index(), true); + view_->setRowHidden(other_layer->row(), layers->index(), true); // Nets group auto nets_parent @@ -556,6 +567,10 @@ void DisplayControls::createLayerMenu() &QAction::triggered, [this]() { layerShowOnlySelectedNeighbors(0, 0); }); + connect(routing_layers_menu_->addAction("Show only selected"), + &QAction::triggered, + [this]() { layerShowOnlySelectedNeighbors(0, 0); }); + const QString show_range = "Show layer range "; const QString updown_arrow = "\u2195"; const QString down_arrow = "\u2193"; @@ -576,7 +591,7 @@ void DisplayControls::createLayerMenu() arrows += down_arrow; } - connect(layers_menu_->addAction(show_range + arrows), + connect(routing_layers_menu_->addAction(show_range + arrows), &QAction::triggered, [this, up, down]() { layerShowOnlySelectedNeighbors(down, up); }); }; @@ -1205,18 +1220,54 @@ void DisplayControls::addTech(odb::dbTech* tech) libInit(tech->getDb()); for (dbTechLayer* layer : tech->getLayers()) { - dbTechLayerType type = layer->getType(); - if (type == dbTechLayerType::ROUTING || type == dbTechLayerType::CUT - || type == dbTechLayerType::IMPLANT) { - auto& row = layer_controls_[layer]; - makeLeafItem(row, - QString::fromStdString(layer->getName()), - layers_group_.name, - Qt::Checked, - true, - color(layer), - QVariant::fromValue(layer)); + auto& row = layer_controls_[layer]; + QStandardItem* parent; + Qt::CheckState checked; + switch (layer->getType()) { + case dbTechLayerType::ROUTING: + case dbTechLayerType::CUT: + parent = layers_group_.name; + checked = Qt::Checked; + break; + case dbTechLayerType::MASTERSLICE: + parent = layers_.master.name; + checked = Qt::Unchecked; + break; + case dbTechLayerType::IMPLANT: + parent = layers_.implant.name; + checked = Qt::Checked; + break; + default: + parent = layers_.other.name; + checked = Qt::Unchecked; + break; } + makeLeafItem(row, + QString::fromStdString(layer->getName()), + parent, + checked, + true, + color(layer), + QVariant::fromValue(layer)); + } + + if (layers_.implant.name->hasChildren()) { + view_->setRowHidden(layers_.implant.name->row(), + layers_group_.name->index(), + !layers_.implant.name->hasChildren()); + toggleParent(layers_.implant); + } + if (layers_.master.name->hasChildren()) { + view_->setRowHidden(layers_.master.name->row(), + layers_group_.name->index(), + !layers_.master.name->hasChildren()); + toggleParent(layers_.master); + } + if (layers_.other.name->hasChildren()) { + view_->setRowHidden(layers_.other.name->row(), + layers_group_.name->index(), + !layers_.other.name->hasChildren()); + toggleParent(layers_.other); } toggleParent(layers_group_); @@ -1919,14 +1970,12 @@ void DisplayControls::techInit(odb::dbTech* tech) 50 + gen_color() % 200, 50 + gen_color() % 200); } - } else if (type == dbTechLayerType::IMPLANT) { + } else { // Do not draw from the existing palette so the metal layers can claim // those colors. color = QColor(50 + gen_color() % 200, 50 + gen_color() % 200, 50 + gen_color() % 200); - } else { - continue; } color.setAlpha(180); layer_color_[layer] = std::move(color); @@ -2009,18 +2058,22 @@ void DisplayControls::itemContextMenu(const QPoint& point) return; } - auto* parent_item = model_->itemFromIndex(parent); - if (parent_item != layers_group_.name) { - // not a member of the layers - return; - } - const QModelIndex name_index = model_->index(index.row(), Name, parent); auto* name_item = model_->itemFromIndex(name_index); layers_menu_layer_ = name_item->data(user_data_item_idx_).value(); - layers_menu_->popup(view_->viewport()->mapToGlobal(point)); + if (layers_menu_layer_ != nullptr) { + switch (layers_menu_layer_->getType()) { + case dbTechLayerType::CUT: + case dbTechLayerType::ROUTING: + routing_layers_menu_->popup(view_->viewport()->mapToGlobal(point)); + break; + default: + layers_menu_->popup(view_->viewport()->mapToGlobal(point)); + break; + } + } } void DisplayControls::layerShowOnlySelectedNeighbors(int lower, int upper) diff --git a/src/gui/src/displayControls.h b/src/gui/src/displayControls.h index 42652430f37..0a3ddbbcf41 100644 --- a/src/gui/src/displayControls.h +++ b/src/gui/src/displayControls.h @@ -312,6 +312,13 @@ class DisplayControls : public QDockWidget, ModelRow clock; }; + struct LayerModels + { + ModelRow implant; + ModelRow master; + ModelRow other; + }; + struct InstanceModels { ModelRow stdcells; @@ -495,6 +502,7 @@ class DisplayControls : public QDockWidget, QTreeView* view_; DisplayControlModel* model_; + QMenu* routing_layers_menu_; QMenu* layers_menu_; odb::dbTechLayer* layers_menu_layer_; @@ -514,6 +522,7 @@ class DisplayControls : public QDockWidget, ModelRow shape_type_group_; // instances + LayerModels layers_; InstanceModels instances_; StdCellModels stdcell_instances_; BufferInverterModels bufinv_instances_; From 804696cd0251af27dd9bc197f9b147eaf746f7bc Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sun, 21 Jul 2024 13:48:40 -0400 Subject: [PATCH 13/26] gui: add layers to ITerm descriptor Signed-off-by: Peter Gadfort --- src/gui/src/dbDescriptors.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gui/src/dbDescriptors.cpp b/src/gui/src/dbDescriptors.cpp index 70a818a4ac3..2a34ee6bb4a 100644 --- a/src/gui/src/dbDescriptors.cpp +++ b/src/gui/src/dbDescriptors.cpp @@ -1687,11 +1687,21 @@ Descriptor::Properties DbITermDescriptor::getProperties(std::any object) const aps.insert(gui->makeSelected(iap)); } } + SelectionSet layers; + for (auto* mpin : iterm->getMTerm()->getMPins()) { + for (auto* geom : mpin->getGeometry()) { + auto* layer = geom->getTechLayer(); + if (layer != nullptr) { + layers.insert(gui->makeSelected(layer)); + } + } + } Properties props{{"Instance", gui->makeSelected(iterm->getInst())}, {"IO type", iterm->getIoType().getString()}, {"Net", std::move(net_value)}, {"Special", iterm->isSpecial()}, {"MTerm", iterm->getMTerm()->getConstName()}, + {"Layers", layers}, {"Access Points", aps}}; populateODBProperties(props, iterm); From 9c87d076c5185ae3ec55ed38f2a9e8fc7a4a80e5 Mon Sep 17 00:00:00 2001 From: Matt Liberty Date: Sat, 20 Jul 2024 21:36:17 -0700 Subject: [PATCH 14/26] mpl2: when replacing / using -- not * Fixes #5404 Signed-off-by: Matt Liberty --- src/mpl2/src/hier_rtlmp.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 6d0bbc74739..30406602eb7 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -1544,11 +1544,8 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // Write the connections between macros std::ofstream file; std::string file_name = parent->getName(); - for (auto& c : file_name) { - if (c == '/') { - c = '*'; - } - } + file_name = std::regex_replace(file_name, std::regex("/"), "--"); + file_name = report_directory_ + "/" + file_name; file.open(file_name + "net.txt"); for (auto& net : nets) { @@ -2378,11 +2375,8 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) // Write the connections between macros std::ofstream file; std::string file_name = parent->getName(); - for (auto& c : file_name) { - if (c == '/') { - c = '*'; - } - } + file_name = std::regex_replace(file_name, std::regex("/"), "--"); + file_name = report_directory_ + "/" + file_name; file.open(file_name + ".net.txt"); for (auto& net : nets) { @@ -2880,11 +2874,8 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) // Write the connections between macros std::ofstream file; std::string file_name = parent->getName(); - for (auto& c : file_name) { - if (c == '/') { - c = '*'; - } - } + file_name = std::regex_replace(file_name, std::regex("/"), "--"); + file_name = report_directory_ + "/" + file_name; file.open(file_name + ".net.txt"); for (auto& net : nets) { From 4b665890080d1ee085ed76d1a3de0355a248e4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Sun, 21 Jul 2024 22:04:20 +0200 Subject: [PATCH 15/26] rcx: less verbose, remove superfluous logging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- src/rcx/src/ext.cpp | 10 ---------- src/rcx/src/extFlow.cpp | 2 -- src/rcx/test/45_gcd.ok | 5 ----- src/rcx/test/ext_pattern.ok | 5 ----- src/rcx/test/gcd.ok | 5 ----- src/rcx/test/names.ok | 5 ----- 6 files changed, 32 deletions(-) diff --git a/src/rcx/src/ext.cpp b/src/rcx/src/ext.cpp index a60b5d6e5e6..eb4f1f389c2 100644 --- a/src/rcx/src/ext.cpp +++ b/src/rcx/src/ext.cpp @@ -234,8 +234,6 @@ void Ext::extract(ExtractOptions options) { _ext->setBlockFromChip(); odb::dbBlock* block = _ext->getBlock(); - logger_->info( - RCX, 8, "extracting parasitics of {} ...", block->getConstName()); odb::orderWires(logger_, block); @@ -250,9 +248,6 @@ void Ext::extract(ExtractOptions options) options.coupling_threshold, options.context_depth, options.ext_model_file); - - logger_->info( - RCX, 15, "Finished extracting {}.", _ext->getBlock()->getName().c_str()); } void Ext::adjust_rc(float res_factor, float cc_factor, float gndc_factor) @@ -288,9 +283,6 @@ void Ext::write_spef(const SpefOptions& options) spef_version_); return; } - if (!options.init) { - logger_->info(RCX, 16, "Writing SPEF ..."); - } _ext->writeSPEF((char*) options.file, (char*) options.nets, options.no_name_map, @@ -313,8 +305,6 @@ void Ext::write_spef(const SpefOptions& options) name, spef_version_, options.parallel); - - logger_->info(RCX, 17, "Finished writing SPEF ..."); } void Ext::read_spef(ReadSpefOpts& opt) diff --git a/src/rcx/src/extFlow.cpp b/src/rcx/src/extFlow.cpp index bccc624606e..f06f2cee3da 100644 --- a/src/rcx/src/extFlow.cpp +++ b/src/rcx/src/extFlow.cpp @@ -1229,8 +1229,6 @@ uint extMain::couplingFlow(Rect& extRect, uint totWireCnt = signalWireCounter(maxWidth); totWireCnt += totPowerWireCnt; - logger_->info(RCX, 43, "{} wires to be extracted", totWireCnt); - uint minRes[2]; minRes[1] = pitchTable[1]; minRes[0] = widthTable[1]; diff --git a/src/rcx/test/45_gcd.ok b/src/rcx/test/45_gcd.ok index 23c6e49a3b6..3c5318cf9ca 100644 --- a/src/rcx/test/45_gcd.ok +++ b/src/rcx/test/45_gcd.ok @@ -6,18 +6,13 @@ [INFO ODB-0133] Created 350 nets and 978 connections. [INFO RCX-0431] Defined process_corner X with ext_model_index 0 [INFO RCX-0029] Defined extraction corner X -[INFO RCX-0008] extracting parasitics of gcd ... [INFO RCX-0435] Reading extraction model file 45_patterns.rules ... [INFO RCX-0436] RC segment generation gcd (max_merge_res 0.0) ... [INFO RCX-0040] Final 2656 rc segments [INFO RCX-0439] Coupling Cap extraction gcd ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0043] 1954 wires to be extracted [INFO RCX-0442] 48% completion -- 954 wires have been extracted [INFO RCX-0442] 100% completion -- 1954 wires have been extracted [INFO RCX-0045] Extract 350 nets, 2972 rsegs, 2972 caps, 2876 ccs -[INFO RCX-0015] Finished extracting gcd. -[INFO RCX-0016] Writing SPEF ... [INFO RCX-0443] 350 nets finished -[INFO RCX-0017] Finished writing SPEF ... No differences found. diff --git a/src/rcx/test/ext_pattern.ok b/src/rcx/test/ext_pattern.ok index 22f4050145f..7eb3c8dda01 100644 --- a/src/rcx/test/ext_pattern.ok +++ b/src/rcx/test/ext_pattern.ok @@ -4,13 +4,11 @@ [INFO ODB-0133] Created 70552 nets and 0 connections. [INFO RCX-0431] Defined process_corner X with ext_model_index 0 [INFO RCX-0029] Defined extraction corner X -[INFO RCX-0008] extracting parasitics of blk ... [INFO RCX-0435] Reading extraction model file ext_pattern.rules ... [INFO RCX-0436] RC segment generation blk (max_merge_res 0.0) ... [INFO RCX-0040] Final 70552 rc segments [INFO RCX-0439] Coupling Cap extraction blk ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0043] 70552 wires to be extracted [INFO RCX-0442] 28% completion -- 20072 wires have been extracted [INFO RCX-0442] 36% completion -- 25945 wires have been extracted [INFO RCX-0442] 75% completion -- 53088 wires have been extracted @@ -18,8 +16,5 @@ [INFO RCX-0442] 85% completion -- 60420 wires have been extracted [INFO RCX-0442] 95% completion -- 67547 wires have been extracted [INFO RCX-0045] Extract 70550 nets, 141104 rsegs, 141104 caps, 68533 ccs -[INFO RCX-0015] Finished extracting blk. -[INFO RCX-0016] Writing SPEF ... [INFO RCX-0443] 9 nets finished -[INFO RCX-0017] Finished writing SPEF ... No differences found. diff --git a/src/rcx/test/gcd.ok b/src/rcx/test/gcd.ok index 49fd2c85da4..27c61973234 100644 --- a/src/rcx/test/gcd.ok +++ b/src/rcx/test/gcd.ok @@ -7,18 +7,13 @@ [INFO ODB-0133] Created 411 nets and 1210 connections. [INFO RCX-0431] Defined process_corner X with ext_model_index 0 [INFO RCX-0029] Defined extraction corner X -[INFO RCX-0008] extracting parasitics of gcd ... [INFO RCX-0435] Reading extraction model file ext_pattern.rules ... [INFO RCX-0436] RC segment generation gcd (max_merge_res 0.0) ... [INFO RCX-0040] Final 3221 rc segments [INFO RCX-0439] Coupling Cap extraction gcd ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0043] 2368 wires to be extracted [INFO RCX-0442] 50% completion -- 1197 wires have been extracted [INFO RCX-0442] 100% completion -- 2368 wires have been extracted [INFO RCX-0045] Extract 411 nets, 3632 rsegs, 3632 caps, 2237 ccs -[INFO RCX-0015] Finished extracting gcd. -[INFO RCX-0016] Writing SPEF ... [INFO RCX-0443] 411 nets finished -[INFO RCX-0017] Finished writing SPEF ... No differences found. diff --git a/src/rcx/test/names.ok b/src/rcx/test/names.ok index d7035ae4ccb..d78a7dca780 100644 --- a/src/rcx/test/names.ok +++ b/src/rcx/test/names.ok @@ -67,16 +67,11 @@ [INFO DRT-0179] Init gr pin query. [INFO RCX-0431] Defined process_corner X with ext_model_index 0 [INFO RCX-0029] Defined extraction corner X -[INFO RCX-0008] extracting parasitics of top ... [INFO RCX-0435] Reading extraction model file Nangate45/Nangate45.rcx_rules ... [INFO RCX-0436] RC segment generation top (max_merge_res 50.0) ... [INFO RCX-0040] Final 1 rc segments [INFO RCX-0439] Coupling Cap extraction top ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0043] 3 wires to be extracted [INFO RCX-0442] 100% completion -- 3 wires have been extracted [INFO RCX-0045] Extract -1 nets, 2 rsegs, 2 caps, 0 ccs -[INFO RCX-0015] Finished extracting top. -[INFO RCX-0016] Writing SPEF ... [INFO RCX-0443] 1 nets finished -[INFO RCX-0017] Finished writing SPEF ... From 1bcdf3284afa7729b683e242560564bb220f510c Mon Sep 17 00:00:00 2001 From: Matt Liberty Date: Sun, 21 Jul 2024 13:31:11 -0700 Subject: [PATCH 16/26] mpl2: replace more problematic characters in file names Signed-off-by: Matt Liberty --- src/mpl2/src/hier_rtlmp.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mpl2/src/hier_rtlmp.cpp b/src/mpl2/src/hier_rtlmp.cpp index 30406602eb7..ea734934c02 100644 --- a/src/mpl2/src/hier_rtlmp.cpp +++ b/src/mpl2/src/hier_rtlmp.cpp @@ -55,6 +55,11 @@ namespace mpl2 { using std::string; +static string make_filename(const string& file_name) +{ + return std::regex_replace(file_name, std::regex("[\":<>\\|\\*\\?/]"), "--"); +} + /////////////////////////////////////////////////////////// // Class HierRTLMP using utl::MPL; @@ -1544,7 +1549,7 @@ void HierRTLMP::runHierarchicalMacroPlacement(Cluster* parent) // Write the connections between macros std::ofstream file; std::string file_name = parent->getName(); - file_name = std::regex_replace(file_name, std::regex("/"), "--"); + file_name = make_filename(file_name); file_name = report_directory_ + "/" + file_name; file.open(file_name + "net.txt"); @@ -2375,7 +2380,7 @@ void HierRTLMP::runHierarchicalMacroPlacementWithoutBusPlanning(Cluster* parent) // Write the connections between macros std::ofstream file; std::string file_name = parent->getName(); - file_name = std::regex_replace(file_name, std::regex("/"), "--"); + file_name = make_filename(file_name); file_name = report_directory_ + "/" + file_name; file.open(file_name + ".net.txt"); @@ -2874,7 +2879,7 @@ void HierRTLMP::runEnhancedHierarchicalMacroPlacement(Cluster* parent) // Write the connections between macros std::ofstream file; std::string file_name = parent->getName(); - file_name = std::regex_replace(file_name, std::regex("/"), "--"); + file_name = make_filename(file_name); file_name = report_directory_ + "/" + file_name; file.open(file_name + ".net.txt"); From dd1037d2e023af9ad83840ad9e53f8a46f6238b9 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 22 Jul 2024 00:14:55 +0300 Subject: [PATCH 17/26] clang-format Signed-off-by: osamahammad21 --- src/drt/src/dr/FlexDR_init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index 85be2f7cef7..f3303f49af0 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -3079,7 +3079,7 @@ void FlexDRWorker::route_queue_update_queue( if (checkingObj != nullptr && checkingObj->typeId() == frBlockObjectEnum::drcNet) { checkingObj = static_cast(checkingObj)->getFrNet(); - } + } for (auto& uMarker : markers) { auto marker = uMarker.get(); route_queue_update_from_marker( From 2fd40718b463a842080a37e0833a3bf71ac75028 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sun, 21 Jul 2024 17:30:34 -0400 Subject: [PATCH 18/26] gui: add mterm descriptor Signed-off-by: Peter Gadfort --- src/gui/src/dbDescriptors.cpp | 133 ++++++++++++++++++++++++++++++---- src/gui/src/dbDescriptors.h | 22 ++++++ src/gui/src/mainWindow.cpp | 1 + 3 files changed, 143 insertions(+), 13 deletions(-) diff --git a/src/gui/src/dbDescriptors.cpp b/src/gui/src/dbDescriptors.cpp index 2a34ee6bb4a..b019849d1f0 100644 --- a/src/gui/src/dbDescriptors.cpp +++ b/src/gui/src/dbDescriptors.cpp @@ -797,9 +797,9 @@ Descriptor::Properties DbMasterDescriptor::getProperties(std::any object) const if (site != nullptr) { props.push_back({"Site", gui->makeSelected(site)}); } - std::vector mterms; + SelectionSet mterms; for (auto mterm : master->getMTerms()) { - mterms.emplace_back(mterm->getConstName()); + mterms.insert(gui->makeSelected(mterm)); } props.push_back({"MTerms", mterms}); @@ -1687,21 +1687,11 @@ Descriptor::Properties DbITermDescriptor::getProperties(std::any object) const aps.insert(gui->makeSelected(iap)); } } - SelectionSet layers; - for (auto* mpin : iterm->getMTerm()->getMPins()) { - for (auto* geom : mpin->getGeometry()) { - auto* layer = geom->getTechLayer(); - if (layer != nullptr) { - layers.insert(gui->makeSelected(layer)); - } - } - } Properties props{{"Instance", gui->makeSelected(iterm->getInst())}, {"IO type", iterm->getIoType().getString()}, {"Net", std::move(net_value)}, {"Special", iterm->isSpecial()}, - {"MTerm", iterm->getMTerm()->getConstName()}, - {"Layers", layers}, + {"MTerm", gui->makeSelected(iterm->getMTerm())}, {"Access Points", aps}}; populateODBProperties(props, iterm); @@ -1859,6 +1849,123 @@ bool DbBTermDescriptor::getAllObjects(SelectionSet& objects) const ////////////////////////////////////////////////// +DbMTermDescriptor::DbMTermDescriptor(odb::dbDatabase* db) : db_(db) +{ +} + +std::string DbMTermDescriptor::getName(std::any object) const +{ + auto mterm = std::any_cast(object); + return mterm->getMaster()->getName() + "/" + mterm->getName(); +} + +std::string DbMTermDescriptor::getShortName(std::any object) const +{ + auto mterm = std::any_cast(object); + return mterm->getName(); +} + +std::string DbMTermDescriptor::getTypeName() const +{ + return "MTerm"; +} + +bool DbMTermDescriptor::getBBox(std::any object, odb::Rect& bbox) const +{ + auto mterm = std::any_cast(object); + bbox = mterm->getBBox(); + return true; +} + +void DbMTermDescriptor::highlight(std::any object, Painter& painter) const +{ + auto mterm = std::any_cast(object); + + auto* chip = db_->getChip(); + if (chip == nullptr) { + return; + } + auto* block = chip->getBlock(); + if (block == nullptr) { + return; + } + + std::set mterm_rects; + + for (auto mpin : mterm->getMPins()) { + for (auto box : mpin->getGeometry()) { + mterm_rects.insert(box->getBox()); + } + } + for (auto* iterm : block->getITerms()) { + if (iterm->getMTerm() == mterm) { + if (!iterm->getInst()->getPlacementStatus().isPlaced()) { + continue; + } + const odb::dbTransform inst_xfm = iterm->getInst()->getTransform(); + + for (odb::Rect rect : mterm_rects) { + inst_xfm.apply(rect); + painter.drawRect(rect); + } + } + } +} + +Descriptor::Properties DbMTermDescriptor::getProperties(std::any object) const +{ + auto gui = Gui::get(); + auto mterm = std::any_cast(object); + SelectionSet layers; + for (auto* mpin : mterm->getMPins()) { + for (auto* geom : mpin->getGeometry()) { + auto* layer = geom->getTechLayer(); + if (layer != nullptr) { + layers.insert(gui->makeSelected(layer)); + } + } + } + Properties props{{"Master", gui->makeSelected(mterm->getMaster())}, + {"IO type", mterm->getIoType().getString()}, + {"Signal type", mterm->getSigType().getString()}, + {"# Pins", mterm->getMPins().size()}, + {"Layers", layers}}; + + populateODBProperties(props, mterm); + + return props; +} + +Selected DbMTermDescriptor::makeSelected(std::any object) const +{ + if (auto mterm = std::any_cast(&object)) { + return Selected(*mterm, this); + } + return Selected(); +} + +bool DbMTermDescriptor::lessThan(std::any l, std::any r) const +{ + auto l_mterm = std::any_cast(l); + auto r_mterm = std::any_cast(r); + return l_mterm->getId() < r_mterm->getId(); +} + +bool DbMTermDescriptor::getAllObjects(SelectionSet& objects) const +{ + for (auto* lib : db_->getLibs()) { + for (auto* master : lib->getMasters()) { + for (auto* mterm : master->getMTerms()) { + objects.insert(makeSelected(mterm)); + } + } + } + + return true; +} + +////////////////////////////////////////////////// + DbViaDescriptor::DbViaDescriptor(odb::dbDatabase* db) : db_(db) { } diff --git a/src/gui/src/dbDescriptors.h b/src/gui/src/dbDescriptors.h index ea98fd0ee5f..878af9daa96 100644 --- a/src/gui/src/dbDescriptors.h +++ b/src/gui/src/dbDescriptors.h @@ -272,6 +272,28 @@ class DbBTermDescriptor : public Descriptor odb::dbDatabase* db_; }; +class DbMTermDescriptor : public Descriptor +{ + public: + DbMTermDescriptor(odb::dbDatabase* db); + + std::string getName(std::any object) const override; + std::string getShortName(std::any object) const override; + std::string getTypeName() const override; + bool getBBox(std::any object, odb::Rect& bbox) const override; + + void highlight(std::any object, Painter& painter) const override; + + Properties getProperties(std::any object) const override; + Selected makeSelected(std::any object) const override; + bool lessThan(std::any l, std::any r) const override; + + bool getAllObjects(SelectionSet& objects) const override; + + private: + odb::dbDatabase* db_; +}; + class DbViaDescriptor : public Descriptor { public: diff --git a/src/gui/src/mainWindow.cpp b/src/gui/src/mainWindow.cpp index 91fbc4048d7..d74072a4979 100644 --- a/src/gui/src/mainWindow.cpp +++ b/src/gui/src/mainWindow.cpp @@ -479,6 +479,7 @@ void MainWindow::init(sta::dbSta* sta) viewers_->getNetTracks())); gui->registerDescriptor(new DbITermDescriptor(db_)); gui->registerDescriptor(new DbBTermDescriptor(db_)); + gui->registerDescriptor(new DbMTermDescriptor(db_)); gui->registerDescriptor(new DbViaDescriptor(db_)); gui->registerDescriptor(new DbBlockageDescriptor(db_)); gui->registerDescriptor( From 7d13be675baa433059220e412283c69f789556e6 Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Sun, 21 Jul 2024 22:08:39 -0400 Subject: [PATCH 19/26] gui: remove io type from iterm descriptor as it is now in mterm Signed-off-by: Peter Gadfort --- src/gui/src/dbDescriptors.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/src/dbDescriptors.cpp b/src/gui/src/dbDescriptors.cpp index b019849d1f0..a79671d0b7a 100644 --- a/src/gui/src/dbDescriptors.cpp +++ b/src/gui/src/dbDescriptors.cpp @@ -1688,7 +1688,6 @@ Descriptor::Properties DbITermDescriptor::getProperties(std::any object) const } } Properties props{{"Instance", gui->makeSelected(iterm->getInst())}, - {"IO type", iterm->getIoType().getString()}, {"Net", std::move(net_value)}, {"Special", iterm->isSpecial()}, {"MTerm", gui->makeSelected(iterm->getMTerm())}, From 341c0fb738a0a679d60ec97c158a6a8641b3fc6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Mon, 22 Jul 2024 07:06:01 +0200 Subject: [PATCH 20/26] rcx: tweak progress message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- src/rcx/src/extFlow.cpp | 8 +++++--- src/rcx/test/45_gcd.ok | 4 ++-- src/rcx/test/ext_pattern.ok | 13 +++++++------ src/rcx/test/gcd.ok | 4 ++-- src/rcx/test/names.ok | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/rcx/src/extFlow.cpp b/src/rcx/src/extFlow.cpp index f06f2cee3da..e9bae029f25 100644 --- a/src/rcx/src/extFlow.cpp +++ b/src/rcx/src/extFlow.cpp @@ -1346,12 +1346,14 @@ uint extMain::couplingFlow(Rect& extRect, = lround(100.0 * (1.0 * totalWiresExtracted / totWireCnt)); if ((totWireCnt > 0) && (totalWiresExtracted > 0) - && (percent_extracted - _previous_percent_extracted >= 5.0)) { + && (((totWireCnt == totalWiresExtracted) + && (percent_extracted > _previous_percent_extracted)) + || (percent_extracted - _previous_percent_extracted >= 5.0))) { logger_->info(RCX, 442, - "{:d}% completion -- {:d} wires have been extracted", + "{:d}% of {:d} wires extracted", (int) (100.0 * (1.0 * totalWiresExtracted / totWireCnt)), - totalWiresExtracted); + totWireCnt); _previous_percent_extracted = percent_extracted; } diff --git a/src/rcx/test/45_gcd.ok b/src/rcx/test/45_gcd.ok index 3c5318cf9ca..a1abc1b3af9 100644 --- a/src/rcx/test/45_gcd.ok +++ b/src/rcx/test/45_gcd.ok @@ -11,8 +11,8 @@ [INFO RCX-0040] Final 2656 rc segments [INFO RCX-0439] Coupling Cap extraction gcd ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0442] 48% completion -- 954 wires have been extracted -[INFO RCX-0442] 100% completion -- 1954 wires have been extracted +[INFO RCX-0442] 48% of 1954 wires extracted +[INFO RCX-0442] 100% of 1954 wires extracted [INFO RCX-0045] Extract 350 nets, 2972 rsegs, 2972 caps, 2876 ccs [INFO RCX-0443] 350 nets finished No differences found. diff --git a/src/rcx/test/ext_pattern.ok b/src/rcx/test/ext_pattern.ok index 7eb3c8dda01..41c252b5dfa 100644 --- a/src/rcx/test/ext_pattern.ok +++ b/src/rcx/test/ext_pattern.ok @@ -9,12 +9,13 @@ [INFO RCX-0040] Final 70552 rc segments [INFO RCX-0439] Coupling Cap extraction blk ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0442] 28% completion -- 20072 wires have been extracted -[INFO RCX-0442] 36% completion -- 25945 wires have been extracted -[INFO RCX-0442] 75% completion -- 53088 wires have been extracted -[INFO RCX-0442] 81% completion -- 57308 wires have been extracted -[INFO RCX-0442] 85% completion -- 60420 wires have been extracted -[INFO RCX-0442] 95% completion -- 67547 wires have been extracted +[INFO RCX-0442] 28% of 70552 wires extracted +[INFO RCX-0442] 36% of 70552 wires extracted +[INFO RCX-0442] 75% of 70552 wires extracted +[INFO RCX-0442] 81% of 70552 wires extracted +[INFO RCX-0442] 85% of 70552 wires extracted +[INFO RCX-0442] 95% of 70552 wires extracted +[INFO RCX-0442] 100% of 70552 wires extracted [INFO RCX-0045] Extract 70550 nets, 141104 rsegs, 141104 caps, 68533 ccs [INFO RCX-0443] 9 nets finished No differences found. diff --git a/src/rcx/test/gcd.ok b/src/rcx/test/gcd.ok index 27c61973234..5467a556ba1 100644 --- a/src/rcx/test/gcd.ok +++ b/src/rcx/test/gcd.ok @@ -12,8 +12,8 @@ [INFO RCX-0040] Final 3221 rc segments [INFO RCX-0439] Coupling Cap extraction gcd ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0442] 50% completion -- 1197 wires have been extracted -[INFO RCX-0442] 100% completion -- 2368 wires have been extracted +[INFO RCX-0442] 50% of 2368 wires extracted +[INFO RCX-0442] 100% of 2368 wires extracted [INFO RCX-0045] Extract 411 nets, 3632 rsegs, 3632 caps, 2237 ccs [INFO RCX-0443] 411 nets finished No differences found. diff --git a/src/rcx/test/names.ok b/src/rcx/test/names.ok index d78a7dca780..ac3f1ce5056 100644 --- a/src/rcx/test/names.ok +++ b/src/rcx/test/names.ok @@ -72,6 +72,6 @@ [INFO RCX-0040] Final 1 rc segments [INFO RCX-0439] Coupling Cap extraction top ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0442] 100% completion -- 3 wires have been extracted +[INFO RCX-0442] 100% of 3 wires extracted [INFO RCX-0045] Extract -1 nets, 2 rsegs, 2 caps, 0 ccs [INFO RCX-0443] 1 nets finished From 3c4cb379012660e837d11039816d9c88188426c0 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 22 Jul 2024 12:06:30 +0300 Subject: [PATCH 21/26] drt: undo repair_pdn_layer range Signed-off-by: osamahammad21 --- src/drt/include/triton_route/TritonRoute.h | 89 +-- src/drt/src/TritonRoute.cpp | 389 +++++----- src/drt/src/TritonRoute.i | 8 +- src/drt/src/TritonRoute.tcl | 92 +-- src/drt/src/gc/FlexGC_cut.cpp | 297 ++++++-- src/drt/src/gc/FlexGC_impl.h | 85 ++- src/drt/src/gc/FlexGC_main.cpp | 838 ++++++++++++--------- src/drt/src/global.cpp | 18 +- src/drt/src/global.h | 120 ++- 9 files changed, 1134 insertions(+), 802 deletions(-) diff --git a/src/drt/include/triton_route/TritonRoute.h b/src/drt/include/triton_route/TritonRoute.h index 375a0dccdba..7143ab525ed 100644 --- a/src/drt/include/triton_route/TritonRoute.h +++ b/src/drt/include/triton_route/TritonRoute.h @@ -40,17 +40,6 @@ #include #include "odb/geom.h" -namespace fr { -class frDesign; -class DesignCallBack; -class FlexDR; -class FlexDRWorker; -class drUpdate; -struct frDebugSettings; -class FlexDR; -struct FlexDRViaData; -class frMarker; -} // namespace fr namespace odb { class dbDatabase; @@ -58,19 +47,34 @@ class dbInst; class dbBTerm; class dbNet; } // namespace odb + namespace utl { class Logger; } + namespace gui { class Gui; } + namespace stt { class SteinerTreeBuilder; } + namespace dst { class Distributed; } -namespace triton_route { + +namespace drt { + +class frDesign; +class DesignCallBack; +class FlexDR; +class FlexDRWorker; +class drUpdate; +struct frDebugSettings; +class FlexDR; +struct FlexDRViaData; +class frMarker; struct ParamStruct { @@ -94,8 +98,7 @@ struct ParamStruct bool singleStepDR = false; int minAccessPoints = -1; bool saveGuideUpdates = false; - std::string repairPDNLayerBeginName; - std::string repairPDNLayerEndName; + std::string repairPDNLayerName; }; class TritonRoute @@ -109,11 +112,11 @@ class TritonRoute dst::Distributed* dist, stt::SteinerTreeBuilder* stt_builder); - fr::frDesign* getDesign() const { return design_.get(); } + frDesign* getDesign() const { return design_.get(); } int main(); void endFR(); - void pinAccess(std::vector target_insts + void pinAccess(const std::vector& target_insts = std::vector()); void stepDR(int size, int offset, @@ -158,17 +161,16 @@ class TritonRoute void setParams(const ParamStruct& params); void addUserSelectedVia(const std::string& viaName); void setUnidirectionalLayer(const std::string& layerName); - fr::frDebugSettings* getDebugSettings() const { return debug_.get(); } + frDebugSettings* getDebugSettings() const { return debug_.get(); } // This runs a serialized worker from file_name. It is intended // for debugging and not general usage. - std::string runDRWorker(const std::string& workerStr, - fr::FlexDRViaData* viaData); + std::string runDRWorker(const std::string& workerStr, FlexDRViaData* viaData); void debugSingleWorker(const std::string& dumpDir, const std::string& drcRpt); void updateGlobals(const char* file_name); void resetDb(const char* file_name); void clearDesign(); void updateDesign(const std::vector& updates); - void updateDesign(const std::string& updates); + void updateDesign(const std::string& path); void addWorkerResults( const std::vector>& results); bool getWorkerResults(std::vector>& results); @@ -179,40 +181,41 @@ class TritonRoute void sendGlobalsUpdates(const std::string& globals_path, const std::string& serializedViaData); void reportDRC(const std::string& file_name, - const std::list>& markers, - odb::Rect bbox = odb::Rect(0, 0, 0, 0)); - void checkDRC(const char* drc_file, int x0, int y0, int x1, int y1); + const std::list>& markers, + odb::Rect drcBox = odb::Rect(0, 0, 0, 0)); + void checkDRC(const char* filename, int x1, int y1, int x2, int y2); bool initGuide(); void prep(); void processBTermsAboveTopLayer(bool has_routing = false); + odb::dbDatabase* getDb() const { return db_; } private: - std::unique_ptr design_; - std::unique_ptr debug_; - std::unique_ptr db_callback_; - odb::dbDatabase* db_; - utl::Logger* logger_; - std::unique_ptr dr_; // kept for single stepping - stt::SteinerTreeBuilder* stt_builder_; - int num_drvs_; - gui::Gui* gui_; - dst::Distributed* dist_; - bool distributed_; + std::unique_ptr design_; + std::unique_ptr debug_; + std::unique_ptr db_callback_; + odb::dbDatabase* db_{nullptr}; + utl::Logger* logger_{nullptr}; + std::unique_ptr dr_; // kept for single stepping + stt::SteinerTreeBuilder* stt_builder_{nullptr}; + int num_drvs_{-1}; + gui::Gui* gui_{nullptr}; + dst::Distributed* dist_{nullptr}; + bool distributed_{false}; std::string dist_ip_; - unsigned short dist_port_; + uint16_t dist_port_{0}; std::string shared_volume_; std::vector> workers_results_; std::mutex results_mutex_; - int results_sz_; - unsigned int cloud_sz_; - boost::asio::thread_pool dist_pool_; + int results_sz_{0}; + unsigned int cloud_sz_{0}; + boost::asio::thread_pool dist_pool_{1}; void initDesign(); void gr(); void ta(); void dr(); - void applyUpdates(const std::vector>& updates); - void getDRCMarkers(std::list>& markers, + void applyUpdates(const std::vector>& updates); + void getDRCMarkers(std::list>& markers, const odb::Rect& requiredDrcBox); void stackVias(odb::dbBTerm* bterm, int top_layer_idx, @@ -220,6 +223,8 @@ class TritonRoute bool has_routing); int countNetBTermsAboveMaxLayer(odb::dbNet* net); bool netHasStackedVias(odb::dbNet* net); - friend class fr::FlexDR; + void repairPDNVias(); + friend class FlexDR; }; -} // namespace triton_route + +} // namespace drt diff --git a/src/drt/src/TritonRoute.cpp b/src/drt/src/TritonRoute.cpp index 3622d1b00d2..acaffe987ea 100644 --- a/src/drt/src/TritonRoute.cpp +++ b/src/drt/src/TritonRoute.cpp @@ -57,8 +57,6 @@ #include "sta/StaMain.hh" #include "stt/SteinerTreeBuilder.h" #include "ta/FlexTA.h" -using namespace fr; -using namespace triton_route; namespace sta { // Tcl files encoded into strings. @@ -69,26 +67,16 @@ extern "C" { extern int Drt_Init(Tcl_Interp* interp); } +namespace drt { + TritonRoute::TritonRoute() : debug_(std::make_unique()), db_callback_(std::make_unique(this)), - db_(nullptr), - logger_(nullptr), - stt_builder_(nullptr), - num_drvs_(-1), - gui_(gui::Gui::get()), - dist_(nullptr), - distributed_(false), - dist_port_(0), - results_sz_(0), - cloud_sz_(0), - dist_pool_(1) + gui_(gui::Gui::get()) { } -TritonRoute::~TritonRoute() -{ -} +TritonRoute::~TritonRoute() = default; void TritonRoute::setDebugDR(bool on) { @@ -187,8 +175,10 @@ RipUpMode getMode(int ripupMode) return RipUpMode::DRC; case 1: return RipUpMode::ALL; - default: + case 2: return RipUpMode::NEARDRC; + default: + return RipUpMode::INCR; } } @@ -230,8 +220,9 @@ std::string TritonRoute::runDRWorker(const std::string& workerStr, worker->setViaData(viaData); worker->setSharedVolume(shared_volume_); worker->setDebugSettings(debug_.get()); - if (graphics_) + if (graphics_) { graphics_->startIter(worker->getDRIter()); + } std::string result = worker->reloadedMain(); return result; } @@ -240,7 +231,7 @@ void TritonRoute::debugSingleWorker(const std::string& dumpDir, const std::string& drcRpt) { { - io::Writer writer(design_.get(), logger_); + io::Writer writer(this, logger_); writer.updateTrackAssignment(db_->getChip()->getBlock()); } bool on = debug_->debugDR; @@ -261,26 +252,33 @@ void TritonRoute::debugSingleWorker(const std::string& dumpDir, workerFile.close(); auto worker = FlexDRWorker::load(workerStr, logger_, design_.get(), graphics_.get()); - if (debug_->mazeEndIter != -1) + if (debug_->mazeEndIter != -1) { worker->setMazeEndIter(debug_->mazeEndIter); - if (debug_->markerCost != -1) + } + if (debug_->markerCost != -1) { worker->setMarkerCost(debug_->markerCost); - if (debug_->drcCost != -1) + } + if (debug_->drcCost != -1) { worker->setDrcCost(debug_->drcCost); - if (debug_->fixedShapeCost != -1) + } + if (debug_->fixedShapeCost != -1) { worker->setFixedShapeCost(debug_->fixedShapeCost); - if (debug_->markerDecay != -1) + } + if (debug_->markerDecay != -1) { worker->setMarkerDecay(debug_->markerDecay); + } if (debug_->ripupMode != -1) { worker->setRipupMode(getMode(debug_->ripupMode)); } - if (debug_->followGuide != -1) + if (debug_->followGuide != -1) { worker->setFollowGuide((debug_->followGuide == 1)); + } worker->setSharedVolume(shared_volume_); worker->setDebugSettings(debug_.get()); worker->setViaData(&viaData); - if (graphics_) + if (graphics_) { graphics_->startIter(worker->getDRIter()); + } std::string result = worker->reloadedMain(); bool updated = worker->end(design_.get()); debugPrint(logger_, @@ -290,16 +288,18 @@ void TritonRoute::debugSingleWorker(const std::string& dumpDir, "End number of markers {}. Updated={}", worker->getBestNumMarkers(), updated); - if (updated && !drcRpt.empty()) + if (updated && !drcRpt.empty()) { reportDRC( drcRpt, design_->getTopBlock()->getMarkers(), worker->getDrcBox()); + } } void TritonRoute::updateGlobals(const char* file_name) { std::ifstream file(file_name); - if (!file.good()) + if (!file.good()) { return; + } frIArchive ar(file); registerTypes(ar); serializeGlobals(ar); @@ -373,10 +373,11 @@ void TritonRoute::applyUpdates( auto regionQuery = design_->getRegionQuery(); const auto maxSz = updates[0].size(); for (int j = 0; j < maxSz; j++) { - for (int i = 0; i < updates.size(); i++) { - if (updates[i].size() <= j) + for (const auto& update_batch : updates) { + if (update_batch.size() <= j) { continue; - const auto& update = updates[i][j]; + } + const auto& update = update_batch[j]; switch (update.getType()) { case drUpdate::REMOVE_FROM_BLOCK: { auto id = update.getIndexInOwner(); @@ -394,22 +395,25 @@ void TritonRoute::applyUpdates( case frcPathSeg: { auto seg = static_cast(pinfig); regionQuery->removeDRObj(seg); - if (update.getType() == drUpdate::REMOVE_FROM_NET) + if (update.getType() == drUpdate::REMOVE_FROM_NET) { net->removeShape(seg); + } break; } case frcPatchWire: { auto pwire = static_cast(pinfig); regionQuery->removeDRObj(pwire); - if (update.getType() == drUpdate::REMOVE_FROM_NET) + if (update.getType() == drUpdate::REMOVE_FROM_NET) { net->removePatchWire(pwire); + } break; } case frcVia: { auto via = static_cast(pinfig); regionQuery->removeDRObj(via); - if (update.getType() == drUpdate::REMOVE_FROM_NET) + if (update.getType() == drUpdate::REMOVE_FROM_NET) { net->removeVia(via); + } break; } default: @@ -429,8 +433,9 @@ void TritonRoute::applyUpdates( = std::make_unique(seg); auto sptr = uShape.get(); net->addShape(std::move(uShape)); - if (update.getType() == drUpdate::ADD_SHAPE) + if (update.getType() == drUpdate::ADD_SHAPE) { regionQuery->addDRObj(sptr); + } break; } case frcPatchWire: { @@ -440,8 +445,9 @@ void TritonRoute::applyUpdates( = std::make_unique(pwire); auto sptr = uShape.get(); net->addPatchWire(std::move(uShape)); - if (update.getType() == drUpdate::ADD_SHAPE) + if (update.getType() == drUpdate::ADD_SHAPE) { regionQuery->addDRObj(sptr); + } break; } case frcVia: { @@ -450,8 +456,9 @@ void TritonRoute::applyUpdates( auto uVia = std::make_unique(via); auto sptr = uVia.get(); net->addVia(std::move(uVia)); - if (update.getType() == drUpdate::ADD_SHAPE) + if (update.getType() == drUpdate::ADD_SHAPE) { regionQuery->addDRObj(sptr); + } break; } default: { @@ -473,12 +480,13 @@ void TritonRoute::applyUpdates( std::vector> tmp; tmp.push_back(std::move(uSeg)); auto idx = update.getIndexInOwner(); - if (idx < 0 || idx >= net->getGuides().size()) + if (idx < 0 || idx >= net->getGuides().size()) { logger_->error(DRT, 9199, "Guide {} out of range {}", idx, net->getGuides().size()); + } const auto& guide = net->getGuides().at(idx); guide->setRoutes(tmp); break; @@ -535,11 +543,11 @@ bool TritonRoute::initGuide() } void TritonRoute::initDesign() { + io::Parser parser(db_, getDesign(), logger_); if (getDesign()->getTopBlock() != nullptr) { - getDesign()->getTopBlock()->removeDeletedInsts(); + parser.updateDesign(); return; } - io::Parser parser(db_, getDesign(), logger_); parser.readTechAndLibs(db_); processBTermsAboveTopLayer(); parser.readDesign(db_); @@ -569,28 +577,20 @@ void TritonRoute::initDesign() } } - if (!REPAIR_PDN_LAYER_BEGIN_NAME.empty()) { - frLayer* layer = tech->getLayer(REPAIR_PDN_LAYER_BEGIN_NAME); - if (layer) { - GC_IGNORE_PDN_BEGIN_LAYER = layer->getLayerNum(); - } else { - logger_->warn(utl::DRT, - 617, - "PDN layer {} not found.", - REPAIR_PDN_LAYER_BEGIN_NAME); - } - layer = tech->getLayer(REPAIR_PDN_LAYER_END_NAME); + if (!REPAIR_PDN_LAYER_NAME.empty()) { + frLayer* layer = tech->getLayer(REPAIR_PDN_LAYER_NAME); if (layer) { - GC_IGNORE_PDN_END_LAYER = layer->getLayerNum(); + GC_IGNORE_PDN_LAYER_NUM = layer->getLayerNum(); } else { logger_->warn( - utl::DRT, 619, "PDN layer {} not found.", REPAIR_PDN_LAYER_END_NAME); + utl::DRT, 617, "PDN layer {} not found.", REPAIR_PDN_LAYER_NAME); } } parser.postProcess(); if (db_ != nullptr && db_->getChip() != nullptr - && db_->getChip()->getBlock() != nullptr) + && db_->getChip()->getBlock() != nullptr) { db_callback_->addOwner(db_->getChip()->getBlock()); + } } void TritonRoute::prep() @@ -617,8 +617,9 @@ void TritonRoute::dr() num_drvs_ = -1; dr_ = std::make_unique(this, getDesign(), logger_, db_); dr_->setDebug(debug_.get()); - if (distributed_) + if (distributed_) { dr_->setDistributed(dist_, dist_ip_, dist_port_, shared_volume_); + } if (SINGLE_STEP_DR) { dr_->init(); } else { @@ -654,95 +655,133 @@ void TritonRoute::endFR() dr_->end(/* done */ true); } dr_.reset(); - io::Writer writer(getDesign(), logger_); + io::Writer writer(this, logger_); writer.updateDb(db_); - if (debug_->writeNetTracks) + if (debug_->writeNetTracks) { writer.updateTrackAssignment(db_->getChip()->getBlock()); + } num_drvs_ = design_->getTopBlock()->getNumMarkers(); - if (!REPAIR_PDN_LAYER_BEGIN_NAME.empty()) { - auto dbBlock = db_->getChip()->getBlock(); - auto pdnBeginLayer - = design_->getTech()->getLayer(REPAIR_PDN_LAYER_BEGIN_NAME); - auto pdnEndLayer = design_->getTech()->getLayer(REPAIR_PDN_LAYER_END_NAME); - frList> markers; - auto blockBox = design_->getTopBlock()->getBBox(); - GC_IGNORE_PDN_BEGIN_LAYER = -1; - GC_IGNORE_PDN_END_LAYER = -1; - getDRCMarkers(markers, blockBox); - std::vector>> allWires; - for (auto* net : dbBlock->getNets()) { - if (!net->getSigType().isSupply()) - continue; - for (auto* swire : net->getSWires()) { - for (auto* wire : swire->getWires()) { - if (wire->isVia()) { - std::vector via_boxes; - wire->getViaBoxes(via_boxes); - for (const auto& via_box : via_boxes) { - auto* layer = getDesign()->getTech()->getLayer( - via_box.getTechLayer()->getName()); - if (layer->getLayerNum() < pdnBeginLayer->getLayerNum() - || layer->getLayerNum() > pdnEndLayer->getLayerNum()) - continue; - allWires.push_back({via_box.getBox(), wire->getId()}); - } + + repairPDNVias(); +} + +void TritonRoute::repairPDNVias() +{ + if (REPAIR_PDN_LAYER_NAME.empty()) { + return; + } + + auto dbBlock = db_->getChip()->getBlock(); + auto pdnLayer = design_->getTech()->getLayer(REPAIR_PDN_LAYER_NAME); + frLayerNum pdnLayerNum = pdnLayer->getLayerNum(); + frList> markers; + auto blockBox = design_->getTopBlock()->getBBox(); + REPAIR_PDN_LAYER_NUM = pdnLayerNum; + GC_IGNORE_PDN_LAYER_NUM = -1; + getDRCMarkers(markers, blockBox); + markers.erase(std::remove_if(markers.begin(), + markers.end(), + [pdnLayerNum](const auto& marker) { + if (marker->getLayerNum() != pdnLayerNum) { + return true; + } + for (auto src : marker->getSrcs()) { + if (src->typeId() == frcNet) { + frNet* net = static_cast(src); + if (net->getType().isSupply()) { + return false; + } + } + } + return true; + }), + markers.end()); + + if (markers.empty()) { + // nothing to do + return; + } + + std::vector>> all_vias; + std::vector>> block_vias; + for (auto* net : dbBlock->getNets()) { + if (!net->getSigType().isSupply()) { + continue; + } + for (auto* swire : net->getSWires()) { + for (auto* wire : swire->getWires()) { + if (!wire->isVia()) { + continue; + } + // + std::vector via_boxes; + wire->getViaBoxes(via_boxes); + for (const auto& via_box : via_boxes) { + auto* layer = via_box.getTechLayer(); + if (layer != pdnLayer->getDbLayer()) { + continue; + } + + if (wire->getTechVia() != nullptr) { + all_vias.emplace_back(via_box.getBox(), wire->getId()); } else { - auto layer = getDesign()->getTech()->getLayer( - wire->getTechLayer()->getName()); - if (layer->getLayerNum() < pdnBeginLayer->getLayerNum() - || layer->getLayerNum() > pdnEndLayer->getLayerNum()) - continue; - allWires.push_back({wire->getBox(), wire->getId()}); + block_vias.emplace_back(via_box.getBox(), wire->getId()); } } } } - RTree> pdnTree(allWires); - std::set> removedBoxes; - int cnt = 0; - for (const auto& marker : markers) { - if (marker->getLayerNum() < pdnBeginLayer->getLayerNum() - || marker->getLayerNum() > pdnEndLayer->getLayerNum()) - continue; - bool supply = false; - for (auto src : marker->getSrcs()) { - if (src->typeId() == frcNet) { - frNet* net = static_cast(src); - if (net->getType().isSupply()) { - supply = true; - break; + } + + const RTree> pdnBlockViaTree(block_vias); + std::set> removedBoxes; + for (const auto& marker : markers) { + odb::Rect queryBox; + marker->getBBox().bloat(1, queryBox); + std::vector>> results; + pdnBlockViaTree.query(bgi::intersects(queryBox), back_inserter(results)); + for (auto& [rect, bid] : results) { + if (removedBoxes.find(bid) == removedBoxes.end()) { + removedBoxes.insert(bid); + auto boxPtr = odb::dbSBox::getSBox(dbBlock, bid); + + const auto new_vias = boxPtr->smashVia(); + for (auto* new_via : new_vias) { + std::vector via_boxes; + new_via->getViaBoxes(via_boxes); + for (const auto& via_box : via_boxes) { + auto* layer = via_box.getTechLayer(); + if (layer != pdnLayer->getDbLayer()) { + continue; + } + all_vias.emplace_back(via_box.getBox(), new_via->getId()); } } - } - if (!supply) - continue; - auto markerBox = marker->getBBox(); - odb::Rect queryBox; - markerBox.bloat(1, queryBox); - std::vector>> results; - pdnTree.query(bgi::intersects(queryBox), back_inserter(results)); - for (auto& [rect, bid] : results) { - if (removedBoxes.find(bid) == removedBoxes.end()) { - removedBoxes.insert(bid); - auto boxPtr = odb::dbSBox::getSBox(dbBlock, bid); - std::vector>> subResults; - pdnTree.query(bgi::intersects(boxPtr->getBox()), - back_inserter(subResults)); + + if (!new_vias.empty()) { odb::dbSBox::destroy(boxPtr); - cnt++; - for (auto& [subRect, subBid] : subResults) { - if (removedBoxes.find(subBid) == removedBoxes.end()) { - removedBoxes.insert(subBid); - auto subBoxPtr = odb::dbSBox::getSBox(dbBlock, subBid); - odb::dbSBox::destroy(subBoxPtr); - } - } } } } - logger_->report("Removed {} pdn vias", cnt); } + removedBoxes.clear(); + + const RTree> pdnTree(all_vias); + for (const auto& marker : markers) { + odb::Rect queryBox; + marker->getBBox().bloat(1, queryBox); + std::vector>> results; + pdnTree.query(bgi::intersects(queryBox), back_inserter(results)); + for (auto& [rect, bid] : results) { + if (removedBoxes.find(bid) == removedBoxes.end()) { + removedBoxes.insert(bid); + odb::dbSBox::destroy(odb::dbSBox::getSBox(dbBlock, bid)); + } + } + } + logger_->report("Removed {} pdn vias on layer {}", + removedBoxes.size(), + pdnLayer->getName()); } void TritonRoute::reportConstraints() @@ -753,8 +792,9 @@ void TritonRoute::reportConstraints() bool TritonRoute::writeGlobals(const std::string& name) { std::ofstream file(name); - if (!file.good()) + if (!file.good()) { return false; + } frOArchive ar(file); registerTypes(ar); serializeGlobals(ar); @@ -768,7 +808,7 @@ void TritonRoute::sendDesignDist() std::string design_path = fmt::format("{}DESIGN.db", shared_volume_); std::string globals_path = fmt::format("{}DESIGN.globals", shared_volume_); ord::OpenRoad::openRoad()->writeDb(design_path.c_str()); - writeGlobals(globals_path.c_str()); + writeGlobals(globals_path); dst::JobMessage msg(dst::JobMessage::UPDATE_DESIGN, dst::JobMessage::BROADCAST), result(dst::JobMessage::NONE); @@ -782,8 +822,9 @@ void TritonRoute::sendDesignDist() rjd->setDesignUpdate(false); msg.setJobDescription(std::move(desc)); bool ok = dist_->sendJob(msg, dist_ip_.c_str(), dist_port_, result); - if (!ok) + if (!ok) { logger_->error(DRT, 12304, "Updating design remotely failed"); + } } design_->clearUpdates(); } @@ -800,8 +841,9 @@ static void serializeUpdatesBatch(const std::vector& batch, void TritonRoute::sendGlobalsUpdates(const std::string& globals_path, const std::string& serializedViaData) { - if (!distributed_) + if (!distributed_) { return; + } ProfileTask task("DIST: SENDING GLOBALS"); dst::JobMessage msg(dst::JobMessage::UPDATE_DESIGN, dst::JobMessage::BROADCAST), @@ -814,21 +856,25 @@ void TritonRoute::sendGlobalsUpdates(const std::string& globals_path, rjd->setViaData(serializedViaData); msg.setJobDescription(std::move(desc)); bool ok = dist_->sendJob(msg, dist_ip_.c_str(), dist_port_, result); - if (!ok) + if (!ok) { logger_->error(DRT, 9504, "Updating globals remotely failed"); + } } void TritonRoute::sendDesignUpdates(const std::string& globals_path) { - if (!distributed_) + if (!distributed_) { return; - if (!design_->hasUpdates()) + } + if (!design_->hasUpdates()) { return; + } std::unique_ptr serializeTask; - if (design_->getVersion() == 0) + if (design_->getVersion() == 0) { serializeTask = std::make_unique("DIST: SERIALIZE_TA"); - else + } else { serializeTask = std::make_unique("DIST: SERIALIZE_UPDATES"); + } const auto& designUpdates = design_->getUpdates(); omp_set_num_threads(MAX_THREADS); std::vector updates(designUpdates.size()); @@ -839,10 +885,11 @@ void TritonRoute::sendDesignUpdates(const std::string& globals_path) } serializeTask->done(); std::unique_ptr task; - if (design_->getVersion() == 0) + if (design_->getVersion() == 0) { task = std::make_unique("DIST: SENDING_TA"); - else + } else { task = std::make_unique("DIST: SENDING_UDPATES"); + } dst::JobMessage msg(dst::JobMessage::UPDATE_DESIGN, dst::JobMessage::BROADCAST), result(dst::JobMessage::NONE); @@ -855,8 +902,9 @@ void TritonRoute::sendDesignUpdates(const std::string& globals_path) rjd->setDesignUpdate(true); msg.setJobDescription(std::move(desc)); bool ok = dist_->sendJob(msg, dist_ip_.c_str(), dist_port_, result); - if (!ok) + if (!ok) { logger_->error(DRT, 304, "Updating design remotely failed"); + } task->done(); design_->clearUpdates(); design_->incrementVersion(); @@ -868,8 +916,9 @@ int TritonRoute::main() USENONPREFTRACKS = false; } asio::thread_pool pa_pool(1); - if (!distributed_) + if (!distributed_) { pa_pool.join(); + } if (debug_->debugDumpDR) { std::string globals_path = fmt::format("{}/init_globals.bin", debug_->dumpDir); @@ -877,7 +926,7 @@ int TritonRoute::main() } MAX_THREADS = ord::OpenRoad::openRoad()->getThreadCount(); if (distributed_) { - if (DO_PA) + if (DO_PA) { asio::post(pa_pool, [this]() { sendDesignDist(); dst::JobMessage msg(dst::JobMessage::PIN_ACCESS, @@ -888,8 +937,9 @@ int TritonRoute::main() msg.setJobDescription(std::move(uDesc)); dist_->sendJob(msg, dist_ip_.c_str(), dist_port_, result); }); - else + } else { asio::post(dist_pool_, boost::bind(&TritonRoute::sendDesignDist, this)); + } } initDesign(); if (DO_PA) { @@ -899,7 +949,7 @@ int TritonRoute::main() pa_pool.join(); pa.main(); if (distributed_ || debug_->debugDR || debug_->debugDumpDR) { - io::Writer writer(getDesign(), logger_); + io::Writer writer(this, logger_); writer.updateDb(db_, true); } if (distributed_) { @@ -935,7 +985,7 @@ int TritonRoute::main() return 0; } -void TritonRoute::pinAccess(std::vector target_insts) +void TritonRoute::pinAccess(const std::vector& target_insts) { if (distributed_) { asio::post(dist_pool_, [this]() { @@ -961,7 +1011,7 @@ void TritonRoute::pinAccess(std::vector target_insts) dist_pool_.join(); } pa.main(); - io::Writer writer(getDesign(), logger_); + io::Writer writer(this, logger_); writer.updateDb(db_, true); } @@ -989,14 +1039,16 @@ void TritonRoute::getDRCMarkers(frList>& markers, Rect drcBox; routeBox.bloat(DRCSAFEDIST, drcBox); routeBox.bloat(MTSAFEDIST, extBox); - if (!drcBox.intersects(requiredDrcBox)) + if (!drcBox.intersects(requiredDrcBox)) { continue; + } auto gcWorker = std::make_unique(design_->getTech(), logger_); gcWorker->setDrcBox(drcBox); gcWorker->setExtBox(extBox); - if (workersBatches.back().size() >= BATCHSIZE) - workersBatches.push_back(std::vector>()); + if (workersBatches.back().size() >= BATCHSIZE) { + workersBatches.emplace_back(); + } workersBatches.back().push_back(std::move(gcWorker)); } } @@ -1004,33 +1056,24 @@ void TritonRoute::getDRCMarkers(frList>& markers, omp_set_num_threads(MAX_THREADS); for (auto& workers : workersBatches) { #pragma omp parallel for schedule(dynamic) - for (int i = 0; i < workers.size(); i++) { + for (int i = 0; i < workers.size(); i++) { // NOLINT workers[i]->init(design_.get()); workers[i]->main(); } for (const auto& worker : workers) { for (auto& marker : worker->getMarkers()) { Rect bbox = marker->getBBox(); - if (!bbox.intersects(requiredDrcBox)) + if (!bbox.intersects(requiredDrcBox)) { continue; + } auto layerNum = marker->getLayerNum(); auto con = marker->getConstraint(); - std::vector srcs(2, nullptr); - int i = 0; - for (auto& src : marker->getSrcs()) { - srcs.at(i) = src; - i++; - } - if (mapMarkers.find({bbox, layerNum, con, srcs[0], srcs[1]}) - != mapMarkers.end()) { - continue; - } - if (mapMarkers.find({bbox, layerNum, con, srcs[1], srcs[0]}) + if (mapMarkers.find({bbox, layerNum, con, marker->getSrcs()}) != mapMarkers.end()) { continue; } markers.push_back(std::make_unique(*marker)); - mapMarkers[{bbox, layerNum, con, srcs[0], srcs[1]}] + mapMarkers[{bbox, layerNum, con, marker->getSrcs()}] = markers.back().get(); } } @@ -1040,8 +1083,8 @@ void TritonRoute::getDRCMarkers(frList>& markers, void TritonRoute::checkDRC(const char* filename, int x1, int y1, int x2, int y2) { - GC_IGNORE_PDN_BEGIN_LAYER = -1; - GC_IGNORE_PDN_END_LAYER = -1; + GC_IGNORE_PDN_LAYER_NUM = -1; + REPAIR_PDN_LAYER_NUM = -1; initDesign(); auto gcellGrid = db_->getChip()->getBlock()->getGCellGrid(); if (gcellGrid != nullptr && gcellGrid->getNumGridPatternsX() == 1 @@ -1275,8 +1318,7 @@ void TritonRoute::setParams(const ParamStruct& params) MINNUMACCESSPOINT_MACROCELLPIN = params.minAccessPoints; } SAVE_GUIDE_UPDATES = params.saveGuideUpdates; - REPAIR_PDN_LAYER_BEGIN_NAME = params.repairPDNLayerBeginName; - REPAIR_PDN_LAYER_END_NAME = params.repairPDNLayerEndName; + REPAIR_PDN_LAYER_NAME = params.repairPDNLayerName; } void TritonRoute::addWorkerResults( @@ -1292,8 +1334,9 @@ bool TritonRoute::getWorkerResults( std::vector>& results) { std::unique_lock lock(results_mutex_); - if (workers_results_.empty()) + if (workers_results_.empty()) { return false; + } results = workers_results_; workers_results_.clear(); results_sz_ = 0; @@ -1325,8 +1368,9 @@ void TritonRoute::reportDRC(const std::string& file_name, for (const auto& marker : markers) { // get violation bbox Rect bbox = marker->getBBox(); - if (drcBox != Rect() && !drcBox.intersects(bbox)) + if (drcBox != Rect() && !drcBox.intersects(bbox)) { continue; + } auto tech = getDesign()->getTech(); auto layer = tech->getLayer(marker->getLayerNum()); auto layerType = layer->getType(); @@ -1336,10 +1380,11 @@ void TritonRoute::reportDRC(const std::string& file_name, if (con) { std::string violName; if (con->typeId() == frConstraintTypeEnum::frcShortConstraint - && layerType == dbTechLayerType::CUT) + && layerType == dbTechLayerType::CUT) { violName = "Cut Short"; - else + } else { violName = con->getViolName(); + } drcRpt << violName; } else { drcRpt << "nullptr"; @@ -1398,3 +1443,5 @@ void TritonRoute::reportDRC(const std::string& file_name, std::cout << "Error: Fail to open DRC report file\n"; } } + +} // namespace drt diff --git a/src/drt/src/TritonRoute.i b/src/drt/src/TritonRoute.i index b319d759419..ed10006eb52 100644 --- a/src/drt/src/TritonRoute.i +++ b/src/drt/src/TritonRoute.i @@ -94,8 +94,7 @@ void detailed_route_cmd(const char* outputMazeFile, bool singleStepDR, int minAccessPoints, bool saveGuideUpdates, - const char* repairPDNLayerBeginName, - const char* repairPDNLayerEndName, + const char* repairPDNLayerName, int drcReportIterStep) { auto* router = ord::OpenRoad::openRoad()->getTritonRoute(); @@ -123,8 +122,7 @@ void detailed_route_cmd(const char* outputMazeFile, singleStepDR, minAccessPoints, saveGuideUpdates, - repairPDNLayerBeginName, - repairPDNLayerEndName}); + repairPDNLayerName}); router->main(); router->setDistributed(false); } @@ -136,7 +134,7 @@ void pin_access_cmd(const char* dbProcessNode, int minAccessPoints) { auto* router = ord::OpenRoad::openRoad()->getTritonRoute(); - triton_route::ParamStruct params; + drt::ParamStruct params; params.dbProcessNode = dbProcessNode; params.bottomRoutingLayer = bottomRoutingLayer; params.topRoutingLayer = topRoutingLayer; diff --git a/src/drt/src/TritonRoute.tcl b/src/drt/src/TritonRoute.tcl index 9b53251a350..7354dc66e90 100644 --- a/src/drt/src/TritonRoute.tcl +++ b/src/drt/src/TritonRoute.tcl @@ -45,7 +45,7 @@ sta::define_cmd_args "detailed_route" { [-via_in_pin_bottom_layer layer] [-via_in_pin_top_layer layer] [-or_seed seed] - [-or_k_ k] + [-or_k k] [-bottom_routing_layer layer] [-top_routing_layer layer] [-verbose level] @@ -58,7 +58,8 @@ sta::define_cmd_args "detailed_route" { [-no_pin_access] [-min_access_points count] [-save_guide_updates] - [-repair_pdn_vias begin_layer end_layer] + [-repair_pdn_vias layer] + [-single_step_dr] } proc detailed_route { args } { @@ -68,7 +69,8 @@ proc detailed_route { args } { -via_in_pin_top_layer -or_seed -or_k -bottom_routing_layer \ -top_routing_layer -verbose -remote_host -remote_port -shared_volume \ -cloud_size -min_access_points -repair_pdn_vias -drc_report_iter_step} \ - flags {-disable_via_gen -distributed -clean_patches -no_pin_access -single_step_dr -save_guide_updates} + flags {-disable_via_gen -distributed -clean_patches -no_pin_access \ + -single_step_dr -save_guide_updates} sta::check_argc_eq0 "detailed_route" $args set enable_via_gen [expr ![info exists flags(-disable_via_gen)]] @@ -76,21 +78,14 @@ proc detailed_route { args } { set no_pin_access [expr [info exists flags(-no_pin_access)]] # single_step_dr is not a user option but is intended for algorithm # development. It is not listed in the help string intentionally. - set single_step_dr [expr [info exists flags(-single_step_dr)]] - set save_guide_updates [expr [info exists flags(-save_guide_updates)]] + set single_step_dr [expr [info exists flags(-single_step_dr)]] + set save_guide_updates [expr [info exists flags(-save_guide_updates)]] - if {[info exists keys(-repair_pdn_vias)]} { - set repair_pdn_vias $keys(-repair_pdn_vias) - if {[llength $repair_pdn_vias] != 2} { - utl::error DRT 556 "-repair_pdn_vias should be a list of 2 layers; the begin via layer and end via layer" - } else { - lassign $keys(-repair_pdn_vias) repair_pdn_vias_begin repair_pdn_vias_end - } + if { [info exists keys(-repair_pdn_vias)] } { + set repair_pdn_vias $keys(-repair_pdn_vias) } else { - set repair_pdn_vias_begin "" - set repair_pdn_vias_end "" + set repair_pdn_vias "" } - if { [info exists keys(-output_maze)] } { set output_maze $keys(-output_maze) } else { @@ -202,7 +197,7 @@ proc detailed_route { args } { $via_in_pin_bottom_layer $via_in_pin_top_layer \ $or_seed $or_k $bottom_routing_layer $top_routing_layer $verbose \ $clean_patches $no_pin_access $single_step_dr $min_access_points \ - $save_guide_updates $repair_pdn_vias_begin $repair_pdn_vias_end $drc_report_iter_step + $save_guide_updates $repair_pdn_vias $drc_report_iter_step } proc detailed_route_num_drvs { args } { @@ -230,8 +225,9 @@ sta::define_cmd_args "detailed_route_debug" { proc detailed_route_debug { args } { sta::parse_key_args "detailed_route_debug" args \ - keys {-net -iter -pin -dump_dir -box} \ - flags {-dr -maze -pa -pa_markers -pa_edge -pa_commit -dump_dr -ta -write_net_tracks -dump_last_worker} + keys {-net -iter -pin -dump_dir -box} \ + flags {-dr -maze -pa -pa_markers -pa_edge -pa_commit -dump_dr -ta \ + -write_net_tracks -dump_last_worker} sta::check_argc_eq0 "detailed_route_debug" $args @@ -270,7 +266,7 @@ proc detailed_route_debug { args } { set box_y1 -1 set box_x2 -1 set box_y2 -1 - if [info exists keys(-box)] { + if {[info exists keys(-box)]} { set box $keys(-box) if { [llength $box] != 4 } { utl::error DRT 118 "-box is a list of 4 coordinates." @@ -287,7 +283,8 @@ proc detailed_route_debug { args } { } drt::set_detailed_route_debug_cmd $net_name $pin_name $dr $dump_dr $pa $maze \ - $box_x1 $box_y1 $box_x2 $box_y2 $iter $pa_markers $pa_edge $pa_commit $dump_dir $ta $write_net_tracks $dump_last_worker + $box_x1 $box_y1 $box_x2 $box_y2 $iter $pa_markers $pa_edge $pa_commit \ + $dump_dir $ta $write_net_tracks $dump_last_worker } sta::define_cmd_args "pin_access" { @@ -304,11 +301,11 @@ sta::define_cmd_args "pin_access" { } proc pin_access { args } { sta::parse_key_args "pin_access" args \ - keys {-db_process_node -bottom_routing_layer -top_routing_layer -verbose \ - -min_access_points -remote_host -remote_port -shared_volume -cloud_size } \ - flags {-distributed} + keys {-db_process_node -bottom_routing_layer -top_routing_layer -verbose \ + -min_access_points -remote_host -remote_port -shared_volume -cloud_size } \ + flags {-distributed} sta::check_argc_eq0 "detailed_route_debug" $args - if [info exists keys(-db_process_node)] { + if {[info exists keys(-db_process_node)]} { set db_process_node $keys(-db_process_node) } else { set db_process_node "" @@ -358,19 +355,20 @@ proc pin_access { args } { } drt::detailed_route_distributed $rhost $rport $vol $cloudsz } - drt::pin_access_cmd $db_process_node $bottom_routing_layer $top_routing_layer $verbose $min_access_points + drt::pin_access_cmd $db_process_node $bottom_routing_layer \ + $top_routing_layer $verbose $min_access_points } sta::define_cmd_args "detailed_route_run_worker" { [-dump_dir dir] [-worker_dir dir] [-drc_rpt drc] -} +};# checker off proc detailed_route_run_worker { args } { sta::parse_key_args "detailed_route_run_worker" args \ - keys {-dump_dir -worker_dir -drc_rpt} \ - flags {} + keys {-dump_dir -worker_dir -drc_rpt} \ + flags {};# checker off sta::check_argc_eq0 "detailed_route_run_worker" $args if { [info exists keys(-dump_dir)] } { set dump_dir $keys(-dump_dir) @@ -389,7 +387,7 @@ proc detailed_route_run_worker { args } { } else { set drc_rpt "" } - drt::run_worker_cmd $dump_dir $worker_dir $drc_rpt + drt::run_worker_cmd $dump_dir $worker_dir $drc_rpt } sta::define_cmd_args "detailed_route_worker_debug" { @@ -400,54 +398,56 @@ sta::define_cmd_args "detailed_route_worker_debug" { [-marker_decay m_decay] [-ripup_mode mode] [-follow_guide f_guide] -} +};# checker off proc detailed_route_worker_debug { args } { sta::parse_key_args "detailed_route_worker_debug" args \ - keys {-maze_end_iter -drc_cost -marker_cost -fixed_shape_cost -marker_decay -ripup_mode -follow_guide} \ - flags {} - if [info exists keys(-maze_end_iter)] { + keys {-maze_end_iter -drc_cost -marker_cost -fixed_shape_cost \ + -marker_decay -ripup_mode -follow_guide} \ + flags {};# checker off + if {[info exists keys(-maze_end_iter)]} { set maze_end_iter $keys(-maze_end_iter) } else { set maze_end_iter -1 } - if [info exists keys(-drc_cost)] { + if {[info exists keys(-drc_cost)]} { set drc_cost $keys(-drc_cost) } else { set drc_cost -1 } - if [info exists keys(-marker_cost)] { + if {[info exists keys(-marker_cost)]} { set marker_cost $keys(-marker_cost) } else { set marker_cost -1 } - if [info exists keys(-fixed_shape_cost)] { + if {[info exists keys(-fixed_shape_cost)]} { set fixed_shape_cost $keys(-fixed_shape_cost) } else { set fixed_shape_cost -1 } - if [info exists keys(-marker_decay)] { + if {[info exists keys(-marker_decay)]} { set marker_decay $keys(-marker_decay) } else { set marker_decay -1 } - if [info exists keys(-ripup_mode)] { + if {[info exists keys(-ripup_mode)]} { set ripup_mode $keys(-ripup_mode) } else { set ripup_mode -1 } - if [info exists keys(-follow_guide)] { + if {[info exists keys(-follow_guide)]} { set follow_guide $keys(-follow_guide) } else { set follow_guide -1 } - drt::set_worker_debug_params $maze_end_iter $drc_cost $marker_cost $fixed_shape_cost $marker_decay $ripup_mode $follow_guide + drt::set_worker_debug_params $maze_end_iter $drc_cost $marker_cost \ + $fixed_shape_cost $marker_decay $ripup_mode $follow_guide } proc detailed_route_set_default_via { args } { @@ -474,21 +474,21 @@ proc step_dr { args } { sta::define_cmd_args "check_drc" { [-box box] [-output_file filename] -} +};# checker off proc check_drc { args } { sta::parse_key_args "check_drc" args \ - keys { -box -output_file } \ - flags {} + keys { -box -output_file } \ + flags {};# checker off sta::check_argc_eq0 "check_drc" $args set box { 0 0 0 0 } - if [info exists keys(-box)] { + if {[info exists keys(-box)]} { set box $keys(-box) if { [llength $box] != 4 } { utl::error DRT 612 "-box is a list of 4 coordinates." - } + } } lassign $box x1 y1 x2 y2 - if { [info exists keys(-output_file)] } { + if { [info exists keys(-output_file)] } { set output_file $keys(-output_file) } else { utl::error DRT 613 "-output_file is required for check_drc command" diff --git a/src/drt/src/gc/FlexGC_cut.cpp b/src/drt/src/gc/FlexGC_cut.cpp index 9b250a02d3a..e4222e539dc 100644 --- a/src/drt/src/gc/FlexGC_cut.cpp +++ b/src/drt/src/gc/FlexGC_cut.cpp @@ -30,8 +30,8 @@ #include "gc/FlexGC_impl.h" #include "odb/db.h" -using namespace fr; -typedef odb::dbTechLayerCutSpacingTableDefRule::LOOKUP_STRATEGY LOOKUP_STRATEGY; +namespace drt { +using LOOKUP_STRATEGY = odb::dbTechLayerCutSpacingTableDefRule::LOOKUP_STRATEGY; inline frSquaredDistance getC2CDistSquare( const gtl::rectangle_data& rect1, @@ -47,8 +47,8 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_prlValid( const gtl::rectangle_data& viaRect1, const gtl::rectangle_data& viaRect2, const gtl::rectangle_data& markerRect, - std::string cutClass1, - std::string cutClass2, + const std::string& cutClass1, + const std::string& cutClass2, frCoord& prl, odb::dbTechLayerCutSpacingTableDefRule* dbRule) { @@ -70,15 +70,15 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_prlValid( if (prlX > reqPrl || prlY > reqPrl) { prl = std::max(prlX, prlY); return true; - } else - return false; + } + return false; } bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_helper( gcRect* viaRect1, gcRect* viaRect2, - frString class1, - frString class2, + const frString& class1, + const frString& class2, const frDirEnum dir, frSquaredDistance distSquare, frSquaredDistance c2cSquare, @@ -110,25 +110,25 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_helper( reqSpcSqr *= reqSpcSqr; if (c2cSquare < reqSpcSqr) { return true; - } else { - reqSpcSqr - = dbRule->getSpacing(class1, - isSide1, - class2, - isSide2, - odb::dbTechLayerCutSpacingTableDefRule::MIN); - reqSpcSqr *= reqSpcSqr; - if (distSquare < reqSpcSqr) - return true; + } + reqSpcSqr = dbRule->getSpacing(class1, + isSide1, + class2, + isSide2, + odb::dbTechLayerCutSpacingTableDefRule::MIN); + reqSpcSqr *= reqSpcSqr; + if (distSquare < reqSpcSqr) { + return true; } return false; } if (class1 == class2 && !dbRule->isLayerValid()) { bool exactlyAligned = false; - if (dir == frDirEnum::N || dir == frDirEnum::S) + if (dir == frDirEnum::N || dir == frDirEnum::S) { exactlyAligned = (prl == deltaH1) && !dbRule->isHorizontal(); - else + } else { exactlyAligned = (prl == deltaV1) && !dbRule->isVertical(); + } auto exAlSpc = dbRule->getExactAlignedSpacing(class1); if (exactlyAligned && exAlSpc != -1) { @@ -161,8 +161,9 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_helper( auto& workerRegionQuery = getWorkerRegionQuery(); workerRegionQuery.queryPolygonEdge( qb, viaRect2->getLayerNum() + 1, results); - if (results.size() == 0) + if (results.empty()) { spcIdx = LOOKUP_STRATEGY::FIRST; + } } frCoord reqSpc = dbRule->getSpacing(class1, isSide1, class2, isSide2, spcIdx); @@ -175,8 +176,9 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_helper( == dbRule->getSpacing( class1, isSide1, class2, isSide2, LOOKUP_STRATEGY::MAX)); if (useCenter) { - if (c2cSquare < reqSpcSqr) + if (c2cSquare < reqSpcSqr) { return true; + } } else if (distSquare < reqSpcSqr) { return true; } @@ -193,9 +195,11 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_sameMetal(gcRect* viaRect1, workerRegionQuery.queryMaxRectangle(qb, viaRect1->getLayerNum() - 1, results); for (const auto& res : results) { auto metalRect = res.second; - if (gtl::intersects(*metalRect, *viaRect1, false)) - if (gtl::intersects(*metalRect, *viaRect2, false)) + if (gtl::intersects(*metalRect, *viaRect1, false)) { + if (gtl::intersects(*metalRect, *viaRect2, false)) { return true; + } + } } return false; } @@ -203,8 +207,9 @@ bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_sameMetal(gcRect* viaRect1, bool FlexGCWorker::Impl::checkLef58CutSpacingTbl_stacked(gcRect* viaRect1, gcRect* viaRect2) { - if (*viaRect1 == *viaRect2) + if (*viaRect1 == *viaRect2) { return true; + } return gtl::contains(*viaRect1, *viaRect2) || gtl::contains(*viaRect2, *viaRect1); } @@ -222,16 +227,20 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl_main( bool viol = false; if (dbRule->isLayerValid()) { if (dbRule->isSameNet()) { - if (viaRect1->getNet() != viaRect2->getNet()) + if (viaRect1->getNet() != viaRect2->getNet()) { return; + } if (layer1->hasLef58SameMetalInterCutSpcTblConstraint() - && checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2)) + && checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2)) { return; + } } else if (dbRule->isSameMetal()) { - if (viaRect1->getNet() != viaRect2->getNet()) + if (viaRect1->getNet() != viaRect2->getNet()) { return; - if (!checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2)) + } + if (!checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2)) { return; + } } else { if (viaRect1->getNet() == viaRect2->getNet()) { return; @@ -239,20 +248,25 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl_main( } } else { if (dbRule->isSameNet()) { - if (viaRect1->getNet() != viaRect2->getNet()) + if (viaRect1->getNet() != viaRect2->getNet()) { return; + } } else if (dbRule->isSameMetal()) { - if (viaRect1->getNet() != viaRect2->getNet()) + if (viaRect1->getNet() != viaRect2->getNet()) { return; - if (!checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2)) + } + if (!checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2)) { return; + } } else { if (viaRect1->getNet() == viaRect2->getNet()) { - if (layer1->hasLef58SameNetCutSpcTblConstraint()) + if (layer1->hasLef58SameNetCutSpcTblConstraint()) { return; - else if (checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2) - && layer1->hasLef58SameMetalCutSpcTblConstraint()) + } + if (checkLef58CutSpacingTbl_sameMetal(viaRect1, viaRect2) + && layer1->hasLef58SameMetalCutSpcTblConstraint()) { return; + } } } } @@ -260,26 +274,30 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl_main( = layer1->getCutClassIdx(viaRect1->width(), viaRect1->length()); auto cutClassIdx2 = layer2->getCutClassIdx(viaRect2->width(), viaRect2->length()); - frString class1 = ""; - frString class2 = ""; - if (cutClassIdx1 != -1) + frString class1; + frString class2; + if (cutClassIdx1 != -1) { class1 = layer1->getCutClass(cutClassIdx1)->getName(); - if (cutClassIdx2 != -1) + } + if (cutClassIdx2 != -1) { class2 = layer2->getCutClass(cutClassIdx2)->getName(); + } gtl::rectangle_data markerRect(*viaRect1); gtl::generalized_intersect(markerRect, *viaRect2); frSquaredDistance distSquare = gtl::square_euclidean_distance(*viaRect1, *viaRect2); if (distSquare == 0) { - if (dbRule->getMaxSpacing(class1, class2) == 0) + if (dbRule->getMaxSpacing(class1, class2) == 0) { return; - if (!dbRule->isLayerValid()) + } + if (!dbRule->isLayerValid()) { checkCutSpacing_short(viaRect1, viaRect2, markerRect); - else if (dbRule->isNoStack()) + } else if (dbRule->isNoStack()) { viol = true; - else + } else { viol = !checkLef58CutSpacingTbl_stacked(viaRect1, viaRect2); + } } frSquaredDistance c2cSquare = getC2CDistSquare(*viaRect1, *viaRect2); @@ -354,14 +372,25 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl_main( } } -bool FlexGCWorker::Impl::isSkipVia(gcRect* rect) +inline bool isSupplyVia(gcRect* rect) { - return rect->getLayerNum() >= GC_IGNORE_PDN_BEGIN_LAYER - && rect->getLayerNum() <= GC_IGNORE_PDN_END_LAYER && rect->isFixed() - && rect->hasNet() && rect->getNet()->getFrNet() + return rect->isFixed() && rect->hasNet() && rect->getNet()->getFrNet() && rect->getNet()->getFrNet()->getType().isSupply(); } +inline bool isSkipVia(gcRect* rect) +{ + return rect->getLayerNum() == GC_IGNORE_PDN_LAYER_NUM && isSupplyVia(rect); +} + +inline bool isFixedVia(gcRect* rect) +{ + if (rect->getLayerNum() == REPAIR_PDN_LAYER_NUM && isSupplyVia(rect)) { + return false; + } + return rect->isFixed(); +} + void FlexGCWorker::Impl::checkLef58CutSpacingTbl( gcRect* viaRect, frLef58CutSpacingTableConstraint* con) @@ -371,29 +400,34 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl( auto width = viaRect->width(); auto length = viaRect->length(); auto cutClassIdx = layer1->getCutClassIdx(width, length); - frString cutClass = ""; - if (cutClassIdx != -1) + frString cutClass; + if (cutClassIdx != -1) { cutClass = layer1->getCutClass(cutClassIdx)->getName(); + } auto dbRule = con->getODBRule(); - if (isSkipVia(viaRect)) + if (isSkipVia(viaRect)) { return; + } bool isUpperVia = true; frLayerNum queryLayerNum; if (dbRule->isLayerValid()) { - if (dbRule->getSecondLayer()->getName() == layer1->getName()) + if (dbRule->getSecondLayer()->getName() == layer1->getName()) { isUpperVia = false; - if (isUpperVia) + } + if (isUpperVia) { queryLayerNum = getTech() ->getLayer(dbRule->getSecondLayer()->getName()) ->getLayerNum(); - else + } else { queryLayerNum = getTech() ->getLayer(dbRule->getTechLayer()->getName()) ->getLayerNum(); - } else + } + } else { queryLayerNum = layerNum1; + } frCoord maxSpc; if (width == length) { @@ -409,34 +443,37 @@ void FlexGCWorker::Impl::checkLef58CutSpacingTbl( auto& workerRegionQuery = getWorkerRegionQuery(); workerRegionQuery.queryMaxRectangle(queryBox, queryLayerNum, results); for (auto& [box, ptr] : results) { - if (ptr->isFixed() && viaRect->isFixed()) + if (isFixedVia(ptr) && isFixedVia(viaRect)) { continue; - if (ptr->getPin() == viaRect->getPin()) + } + if (ptr->getPin() == viaRect->getPin()) { continue; - if (isSkipVia(ptr)) + } + if (isSkipVia(ptr)) { continue; - queryLayerNum = layerNum1; - - if (isUpperVia) + } + if (isUpperVia) { checkLef58CutSpacingTbl_main(viaRect, ptr, con); - else + } else { checkLef58CutSpacingTbl_main(ptr, viaRect, con); + } } } - void FlexGCWorker::Impl::checKeepOutZone_main(gcRect* rect, frLef58KeepOutZoneConstraint* con) { auto layer = getTech()->getLayer(rect->getLayerNum()); - if (isSkipVia(rect)) + if (isSkipVia(rect)) { return; + } auto dbRule = con->getODBRule(); Rect viaBox(gtl::xl(*rect), gtl::yl(*rect), gtl::xh(*rect), gtl::yh(*rect)); Rect sideQueryBox(viaBox), endQueryBox(viaBox); auto viaCutClass = layer->getCutClass(rect->width(), rect->length()); if (viaCutClass == nullptr - || viaCutClass->getName() != dbRule->getFirstCutClass()) + || viaCutClass->getName() != dbRule->getFirstCutClass()) { return; + } if (viaBox.dx() > viaBox.dy()) { sideQueryBox = sideQueryBox.bloat(dbRule->getSideForwardExtension(), @@ -475,21 +512,26 @@ void FlexGCWorker::Impl::checKeepOutZone_main(gcRect* rect, allResults.insert(allResults.end(), results.begin(), results.end()); } for (auto& [box, ptr] : allResults) { - if (ptr->isFixed() && rect->isFixed()) + if (isFixedVia(ptr) && isFixedVia(rect)) { continue; - if (ptr->getPin() == rect->getPin()) + } + if (ptr->getPin() == rect->getPin()) { continue; - if (isSkipVia(ptr)) + } + if (isSkipVia(ptr)) { continue; + } auto via2CutClass = layer->getCutClass(ptr->width(), ptr->length()); if (!dbRule->getSecondCutClass().empty() && (via2CutClass == nullptr - || dbRule->getSecondCutClass() != via2CutClass->getName())) + || dbRule->getSecondCutClass() != via2CutClass->getName())) { continue; + } odb::Rect ptrBox( gtl::xl(*ptr), gtl::yl(*ptr), gtl::xh(*ptr), gtl::yh(*ptr)); - if (!sideQueryBox.overlaps(ptrBox) && !endQueryBox.overlaps(ptrBox)) + if (!sideQueryBox.overlaps(ptrBox) && !endQueryBox.overlaps(ptrBox)) { continue; + } gtl::rectangle_data markerRect(*rect); gtl::generalized_intersect(markerRect, *ptr); Rect markerBox(gtl::xl(markerRect), @@ -524,8 +566,9 @@ void FlexGCWorker::Impl::checkMetalWidthViaTable_main(gcRect* rect) auto required_viadef = getTech()->getVia(rule->getViaName()); frVia required_via(required_viadef); if (rect->width() == required_via.getCutBBox().minDXDY() - && rect->length() == required_via.getCutBBox().maxDXDY()) + && rect->length() == required_via.getCutBBox().maxDXDY()) { continue; + } auto checkEnclosure = [this](gcRect* rect, odb::dbMetalWidthViaMap* rule, bool above) { std::vector> results; @@ -535,16 +578,18 @@ void FlexGCWorker::Impl::checkMetalWidthViaTable_main(gcRect* rect) *rect, rect->getLayerNum() + ((above) ? 1 : -1), results); gcRect* chosen_rect = nullptr; for (auto& [box, obj] : results) { - if (!gtl::contains(*obj, *rect)) + if (!gtl::contains(*obj, *rect)) { continue; + } auto above_width = box.minDXDY(); if (above_width >= ((above) ? rule->getAboveLayerWidthLow() : rule->getBelowLayerWidthLow()) && above_width <= ((above) ? rule->getAboveLayerWidthHigh() : rule->getBelowLayerWidthHigh())) { chosen_rect = obj; - if (!obj->isFixed()) + if (!obj->isFixed()) { break; + } } } return chosen_rect; @@ -552,15 +597,18 @@ void FlexGCWorker::Impl::checkMetalWidthViaTable_main(gcRect* rect) // check above Metal Layer Width gcRect* above_rect = checkEnclosure(rect, rule, true); - if (above_rect == nullptr) + if (above_rect == nullptr) { continue; + } // check below Metal Layer Width gcRect* below_rect = checkEnclosure(rect, rule, true); - if (below_rect == nullptr) + if (below_rect == nullptr) { continue; - if (below_rect->isFixed() && above_rect->isFixed() && rect->isFixed()) + } + if (below_rect->isFixed() && above_rect->isFixed() && rect->isFixed()) { continue; + } Rect markerBox( gtl::xl(*rect), gtl::yl(*rect), gtl::xh(*rect), gtl::yh(*rect)); auto net1 = above_rect->getNet(); @@ -642,3 +690,102 @@ void FlexGCWorker::Impl::checkMetalWidthViaTable() } } } + +void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* viaRect, + gcRect* encRect) +{ + auto layer = getTech()->getLayer(viaRect->getLayerNum()); + auto cutClassIdx = layer->getCutClassIdx(viaRect->width(), viaRect->length()); + bool above = encRect->getLayerNum() > viaRect->getLayerNum(); + frCoord sideOverhang = 0; + frCoord endOverhang = 0; + sideOverhang = std::min(gtl::xh(*encRect) - gtl::xh(*viaRect), + gtl::xl(*viaRect) - gtl::xl(*encRect)); + endOverhang = std::min(gtl::yh(*encRect) - gtl::yh(*viaRect), + gtl::yl(*viaRect) - gtl::yl(*encRect)); + if (gtl::delta(*viaRect, gtl::orientation_2d_enum::HORIZONTAL) + > gtl::delta(*viaRect, gtl::orientation_2d_enum::VERTICAL)) { + std::swap(sideOverhang, endOverhang); + } + frLef58EnclosureConstraint* lastCon = nullptr; + for (auto con : layer->getLef58EnclosureConstraints( + cutClassIdx, encRect->width(), above)) { + lastCon = con; + if (con->isValidOverhang(endOverhang, sideOverhang)) { + return; // valid overhangs + } + } + Rect markerBox(gtl::xl(*viaRect), + gtl::yl(*viaRect), + gtl::xh(*viaRect), + gtl::yh(*viaRect)); + auto net = viaRect->getNet(); + auto marker = std::make_unique(); + marker->setBBox(markerBox); + marker->setLayerNum(encRect->getLayerNum()); + marker->setConstraint(lastCon); + marker->addSrc(net->getOwner()); + frCoord llx = gtl::xl(*encRect); + frCoord lly = gtl::yl(*encRect); + frCoord urx = gtl::xh(*encRect); + frCoord ury = gtl::xh(*encRect); + marker->addAggressor(net->getOwner(), + std::make_tuple(encRect->getLayerNum(), + Rect(llx, lly, urx, ury), + encRect->isFixed())); + llx = gtl::xl(*viaRect); + lly = gtl::yl(*viaRect); + urx = gtl::xh(*viaRect); + ury = gtl::xh(*viaRect); + marker->addVictim(net->getOwner(), + std::make_tuple(viaRect->getLayerNum(), + Rect(llx, lly, urx, ury), + viaRect->isFixed())); + marker->addSrc(net->getOwner()); + addMarker(std::move(marker)); +} +void FlexGCWorker::Impl::checkLef58Enclosure_main(gcRect* rect) +{ + if (rect->isFixed()) { + return; + } + auto layer = getTech()->getLayer(rect->getLayerNum()); + auto cutClassIdx = layer->getCutClassIdx(rect->width(), rect->length()); + bool hasAboveConstraints + = layer->hasLef58EnclosureConstraint(cutClassIdx, true); + bool hasBelowConstraints + = layer->hasLef58EnclosureConstraint(cutClassIdx, false); + if (!hasAboveConstraints && !hasBelowConstraints) { + return; + } + auto getEnclosure = [this](gcRect* rect, frLayerNum layerNum) { + std::vector> results; + auto& workerRegionQuery = getWorkerRegionQuery(); + workerRegionQuery.queryMaxRectangle(*rect, layerNum, results); + gcRect* encRect = nullptr; + for (auto& [box, ptr] : results) { + if (ptr->getNet() != rect->getNet()) { + continue; + } + if (!gtl::contains(*ptr, *rect)) { + continue; + } + if (encRect == nullptr) { + encRect = ptr; + } else if (ptr->width() > encRect->width()) { + encRect = ptr; + } + } + return encRect; + }; + if (hasBelowConstraints) { + gcRect* belowEnc = getEnclosure(rect, layer->getLayerNum() - 1); + checkLef58Enclosure_main(rect, belowEnc); + } + if (hasAboveConstraints) { + gcRect* aboveEnc = getEnclosure(rect, layer->getLayerNum() + 1); + checkLef58Enclosure_main(rect, aboveEnc); + } +} + +} // namespace drt diff --git a/src/drt/src/gc/FlexGC_impl.h b/src/drt/src/gc/FlexGC_impl.h index fb31423576d..af046f56e67 100644 --- a/src/drt/src/gc/FlexGC_impl.h +++ b/src/drt/src/gc/FlexGC_impl.h @@ -39,7 +39,7 @@ namespace odb { class dbTechLayerCutSpacingTableDefRule; } -namespace fr { +namespace drt { class FlexGCWorkerRegionQuery { public: @@ -49,28 +49,28 @@ class FlexGCWorkerRegionQuery void addPolygonEdge(gcSegment* edge); void addMaxRectangle(gcRect* rect); void addSpcRectangle(gcRect* rect); - void removePolygonEdge(gcSegment* connFig); - void removeMaxRectangle(gcRect* connFig); + void removePolygonEdge(gcSegment* edge); + void removeMaxRectangle(gcRect* rect); void removeSpcRectangle(gcRect* rect); void queryPolygonEdge( const box_t& box, - const frLayerNum layerNum, + frLayerNum layerNum, std::vector>& result) const; void queryPolygonEdge( const Rect& box, - const frLayerNum layerNum, + frLayerNum layerNum, std::vector>& result) const; void queryMaxRectangle(const box_t& box, - const frLayerNum layerNum, + frLayerNum layerNum, std::vector>& result) const; void querySpcRectangle(const box_t& box, - const frLayerNum layerNum, + frLayerNum layerNum, std::vector>& result) const; void queryMaxRectangle(const Rect& box, - const frLayerNum layerNum, + frLayerNum layerNum, std::vector>& result) const; void queryMaxRectangle(const gtl::rectangle_data& box, - const frLayerNum layerNum, + frLayerNum layerNum, std::vector>& result) const; void init(int numLayers); void addToRegionQuery(gcNet* net); @@ -225,14 +225,12 @@ class FlexGCWorker::Impl gcSegment* ptr, const gtl::orientation_2d& orient) const; void checkMetalSpacing_wrongDir(gcPin* pin, frLayer* layer); - void checkMetalSpacingRange(gcRect* rect); - void checkMetalSpacingRange(gcRect* rect, frSpacingRangeConstraint* con); - frCoord checkMetalSpacing_getMaxSpcVal(frLayerNum layerNum, bool checkNDRs = true); void myBloat(const gtl::rectangle_data& rect, frCoord val, box_t& box); + bool hasRoute(gcRect* rect, gtl::rectangle_data markerRect); void checkMetalSpacing_main(gcRect* rect, bool checkNDRs = true, bool isSpcRect = false); @@ -260,7 +258,8 @@ class FlexGCWorker::Impl const gtl::rectangle_data& markerRect); frCoord checkMetalSpacing_prl_getReqSpcVal(gcRect* rect1, gcRect* rect2, - frCoord prl); + frCoord prl, + bool& isSpcRange); bool checkMetalSpacing_prl_hasPolyEdge( gcRect* rect1, gcRect* rect2, @@ -275,6 +274,22 @@ class FlexGCWorker::Impl frCoord distY, bool checkNDRs = true, bool checkPolyEdge = true); + void checkForbiddenSpc_main(gcRect* rect1, + gcRect* rect2, + frLef58ForbiddenSpcConstraint* con, + bool isH); + Rect checkForbiddenSpc_queryBox(gcRect* rect, + frCoord minSpc, + frCoord maxSpc, + bool isH, + bool right); + bool checkForbiddenSpc_twoedges(gcRect* rect, + frLef58ForbiddenSpcConstraint* con, + bool isH); + void checkForbiddenSpc_main(gcRect* rect, frLef58ForbiddenSpcConstraint* con); + void checkTwoWiresForbiddenSpc_main( + gcRect* rect, + frLef58TwoWiresForbiddenSpcConstraint* con); box_t checkMetalCornerSpacing_getQueryBox(gcCorner* corner, frCoord& maxSpcValX, frCoord& maxSpcValY); @@ -332,10 +347,11 @@ class FlexGCWorker::Impl frLef58EolExtensionConstraint* constraint); void checkMetalEndOfLine_ext(gcSegment* edge, frLef58EolExtensionConstraint* constraint); - void checkMetalEOLkeepout_helper(gcSegment* edge, - gcRect* rect, - gtl::rectangle_data queryRect, - frLef58EolKeepOutConstraint* constraint); + void checkMetalEOLkeepout_helper( + gcSegment* edge, + gcRect* rect, + const gtl::rectangle_data& queryRect, + frLef58EolKeepOutConstraint* constraint); void checkMetalEOLkeepout_main(gcSegment* edge, frLef58EolKeepOutConstraint* constraint); void getEolKeepOutExceptWithinRects(gcSegment* edge, @@ -411,8 +427,8 @@ class FlexGCWorker::Impl const gtl::rectangle_data& viaRect1, const gtl::rectangle_data& viaRect2, const gtl::rectangle_data& markerRect, - std::string cutClass1, - std::string cutClass2, + const std::string& cutClass1, + const std::string& cutClass2, frCoord& prl, odb::dbTechLayerCutSpacingTableDefRule* dbRule); bool checkLef58CutSpacingTbl_sameMetal(gcRect* viaRect1, gcRect* viaRect2); @@ -423,9 +439,9 @@ class FlexGCWorker::Impl bool checkLef58CutSpacingTbl_helper( gcRect* viaRect1, gcRect* viaRect2, - frString cutClass1, - frString cutClass2, - const frDirEnum dir, + const frString& cutClass1, + const frString& cutClass2, + frDirEnum dir, frSquaredDistance distSquare, frSquaredDistance c2cSquare, bool prlValid, @@ -451,15 +467,12 @@ class FlexGCWorker::Impl gcRect* rect2, const gtl::rectangle_data& markerRect, frCutSpacingConstraint* con); - frCoord checkCutSpacing_spc_getReqSpcVal(gcRect* ptr1, - gcRect* ptr2, - frCutSpacingConstraint* con); // LEF58 void checkLef58CutSpacing_main(gcRect* rect); void checkLef58CutSpacing_main(gcRect* rect, frLef58CutSpacingConstraint* con, - bool skipSameNet = false); + bool skipDiffNet = false); void checkLef58CutSpacing_spc_parallelOverlap( gcRect* rect1, gcRect* rect2, @@ -486,10 +499,9 @@ class FlexGCWorker::Impl bool checkLef58CutSpacing_spc_hasTwoCuts_helper( gcRect* rect, frLef58CutSpacingConstraint* con); - frCoord checkLef58CutSpacing_spc_getReqSpcVal( - gcRect* ptr1, - gcRect* ptr2, - frLef58CutSpacingConstraint* con); + // LEF58_ENCLOSURE + void checkLef58Enclosure_main(gcRect* rect); + void checkLef58Enclosure_main(gcRect* via, gcRect* enc); // LEF58_KEEPOUTZONE void checKeepOutZone_main(gcRect* rect, frLef58KeepOutZoneConstraint* con); @@ -497,16 +509,18 @@ class FlexGCWorker::Impl void checkMetalShape_lef58MinStep(gcPin* pin); void checkMetalShape_lef58MinStep_noBetweenEol(gcPin* pin, frLef58MinStepConstraint* con); + void checkMetalShape_lef58MinStep_minAdjLength(gcPin* pin, + frLef58MinStepConstraint* con); void checkMetalSpacingTableInfluence(); void checkPinMetSpcTblInf(gcPin*); void checkRectMetSpcTblInf(gcRect*, frSpacingTableInfluenceConstraint*); void checkOrthRectsMetSpcTblInf(const std::vector& rects, const gtl::rectangle_data& queryRect, - const frCoord spacing, - const gtl::orientation_2d orient); + frCoord spacing, + const gtl::orientation_2d& orient); void checkRectMetSpcTblInf_queryBox(const gtl::rectangle_data& rect, - const frCoord dist, - const frDirEnum dir, + frCoord dist, + frDirEnum dir, box_t& box); void checkMinimumCut_marker(gcRect* wideRect, gcRect* viaRect, @@ -537,6 +551,5 @@ class FlexGCWorker::Impl const gtl::rectangle_data& rect); bool isOppositeDir(gcCorner* corner, gcSegment* seg); bool isWrongDir(gcSegment* edge); - bool isSkipVia(gcRect* rect); }; -} // namespace fr +} // namespace drt diff --git a/src/drt/src/gc/FlexGC_main.cpp b/src/drt/src/gc/FlexGC_main.cpp index 24bac8921b5..c7718e0d200 100644 --- a/src/drt/src/gc/FlexGC_main.cpp +++ b/src/drt/src/gc/FlexGC_main.cpp @@ -32,9 +32,10 @@ #include "frProfileTask.h" #include "gc/FlexGC_impl.h" -using namespace fr; -typedef bg::model::polygon polygon_t; -typedef bg::model::multi_polygon mpolygon_t; +namespace drt { + +using polygon_t = bg::model::polygon; +using mpolygon_t = bg::model::multi_polygon; bool FlexGCWorker::Impl::isCornerOverlap(gcCorner* corner, const Rect& box) { @@ -108,6 +109,27 @@ void FlexGCWorker::Impl::myBloat(const gtl::rectangle_data& rect, bg::set(box, gtl::yh(rect) + val); } +bool FlexGCWorker::Impl::hasRoute(gcRect* rect, + gtl::rectangle_data markerRect) +{ + // marker enlarged by width + auto width = rect->width(); + gtl::bloat(markerRect, width); + // widthrect + gtl::polygon_90_set_data tmpPoly; + using boost::polygon::operators::operator+=; + using boost::polygon::operators::operator&=; + tmpPoly += markerRect; + tmpPoly &= *rect; // tmpPoly now is widthrect + auto targetArea = gtl::area(tmpPoly); + // get fixed shapes + tmpPoly &= rect->getNet()->getPolygons(rect->getLayerNum(), true); + if (gtl::area(tmpPoly) < targetArea) { + return true; + } + return false; +} + frCoord FlexGCWorker::Impl::checkMetalSpacing_getMaxSpcVal(frLayerNum layerNum, bool checkNDRs) { @@ -128,9 +150,10 @@ frCoord FlexGCWorker::Impl::checkMetalSpacing_getMaxSpcVal(frLayerNum layerNum, default: logger_->warn(DRT, 41, "Unsupported metSpc rule."); } - if (checkNDRs) + if (checkNDRs) { return std::max(maxSpcVal, getTech()->getMaxNondefaultSpacing(layerNum / 2 - 1)); + } } return maxSpcVal; } @@ -150,7 +173,6 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing_getMaxSpcVal( maxSpcValY = std::max(maxSpcValY, con->findMax(false)); } } - return; } bool FlexGCWorker::Impl::isOppositeDir(gcCorner* corner, gcSegment* seg) @@ -166,9 +188,8 @@ bool FlexGCWorker::Impl::isOppositeDir(gcCorner* corner, gcSegment* seg) || (cornerDir == frCornerDirEnum::NW && (segDir == frDirEnum::N || segDir == frDirEnum::E))) { return true; - } else { - return false; } + return false; } box_t FlexGCWorker::Impl::checkMetalCornerSpacing_getQueryBox( @@ -232,11 +253,12 @@ bool isPG(frBlockObject* obj) } } -frCoord FlexGCWorker::Impl::checkMetalSpacing_prl_getReqSpcVal( - gcRect* rect1, - gcRect* rect2, - frCoord prl /*, bool &hasRoute*/) +frCoord FlexGCWorker::Impl::checkMetalSpacing_prl_getReqSpcVal(gcRect* rect1, + gcRect* rect2, + frCoord prl, + bool& isSpcRange) { + isSpcRange = false; auto layerNum = rect1->getLayerNum(); frCoord reqSpcVal = 0; auto currLayer = getTech()->getLayer(layerNum); @@ -288,10 +310,22 @@ frCoord FlexGCWorker::Impl::checkMetalSpacing_prl_getReqSpcVal( if (!isObs && rect1->getNet() == rect2->getNet()) { if (currLayer->hasSpacingSamenet()) { auto conSamenet = currLayer->getSpacingSamenet(); - if (!conSamenet->hasPGonly()) + if (!conSamenet->hasPGonly()) { reqSpcVal = std::max(conSamenet->getMinSpacing(), minSpcVal); - else if (isPG(rect1->getNet()->getOwner())) + } else if (isPG(rect1->getNet()->getOwner())) { reqSpcVal = std::max(conSamenet->getMinSpacing(), minSpcVal); + } + } + } + } + } + if (currLayer->hasSpacingRangeConstraints() + && rect2->getNet() != rect1->getNet()) { + for (const auto& con : currLayer->getSpacingRangeConstraints()) { + if (con->inRange(width1) || con->inRange(width2)) { + if (con->getMinSpacing() > reqSpcVal) { + isSpcRange = true; + reqSpcVal = con->getMinSpacing(); } } } @@ -378,11 +412,11 @@ bool FlexGCWorker::Impl::checkMetalSpacing_prl_hasPolyEdge( } if ((type == 0 || type == 2) && (flagB && flagT)) { return true; - } else if ((type == 1 || type == 2) && (flagL && flagR)) { + } + if ((type == 1 || type == 2) && (flagL && flagR)) { return true; - } else { - return false; } + return false; } std::string rectToString(gcRect& r) { @@ -409,17 +443,19 @@ void FlexGCWorker::Impl::checkMetalSpacing_prl( auto layerNum = rect1->getLayerNum(); auto net1 = rect1->getNet(); auto net2 = rect2->getNet(); - - auto reqSpcVal = checkMetalSpacing_prl_getReqSpcVal(rect1, rect2, prl); + bool isSpcRange = false; + auto reqSpcVal + = checkMetalSpacing_prl_getReqSpcVal(rect1, rect2, prl, isSpcRange); if (checkNDRs) { frCoord ndrSpc1 = 0, ndrSpc2 = 0; - if (!rect1->isFixed() && net1->isNondefault() && !rect1->isTapered()) + if (!rect1->isFixed() && net1->isNondefault() && !rect1->isTapered()) { ndrSpc1 = net1->getFrNet()->getNondefaultRule()->getSpacing(layerNum / 2 - 1); - if (!rect2->isFixed() && net2->isNondefault() && !rect2->isTapered()) + } + if (!rect2->isFixed() && net2->isNondefault() && !rect2->isTapered()) { ndrSpc2 = net2->getFrNet()->getNondefaultRule()->getSpacing(layerNum / 2 - 1); - + } reqSpcVal = std::max(reqSpcVal, std::max(ndrSpc1, ndrSpc2)); } @@ -445,46 +481,12 @@ void FlexGCWorker::Impl::checkMetalSpacing_prl( return; } // no violation if bloat width cannot find non-fixed route shapes - bool hasRoute = false; - if (!hasRoute) { - // marker enlarged by width - auto width = rect1->width(); - gtl::rectangle_data enlargedMarkerRect(markerRect); - gtl::bloat(enlargedMarkerRect, width); - // widthrect - gtl::polygon_90_set_data tmpPoly; - using namespace boost::polygon::operators; - tmpPoly += enlargedMarkerRect; - tmpPoly &= *rect1; // tmpPoly now is widthrect - auto targetArea = gtl::area(tmpPoly); - // get fixed shapes - tmpPoly &= net1->getPolygons(layerNum, true); - if (gtl::area(tmpPoly) < targetArea) { - hasRoute = true; - } - } - if (!hasRoute) { - // marker enlarged by width - auto width = rect2->width(); - gtl::rectangle_data enlargedMarkerRect(markerRect); - gtl::bloat(enlargedMarkerRect, width); - // widthrect - gtl::polygon_90_set_data tmpPoly; - using namespace boost::polygon::operators; - tmpPoly += enlargedMarkerRect; - tmpPoly &= *rect2; // tmpPoly now is widthrect - auto targetArea = gtl::area(tmpPoly); - // get fixed shapes - tmpPoly &= net2->getPolygons(layerNum, true); - if (gtl::area(tmpPoly) < targetArea) { - hasRoute = true; - } - } - if (!hasRoute) { + if (!hasRoute(rect1, markerRect) && !hasRoute(rect2, markerRect)) { return; } } else { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; + using boost::polygon::operators::operator-=; auto& netPoly = net1->getPolygons( layerNum, false); // consider net1 since spc rect is always rect1 gtl::polygon_90_set_data markerPoly; @@ -504,8 +506,9 @@ void FlexGCWorker::Impl::checkMetalSpacing_prl( } markerPoly += mRect; markerPoly -= netPoly; - if (markerPoly.size() == 0) + if (markerPoly.empty()) { return; + } // check if the edge related to the 0 width is within the net shape (this // is an indirect check) std::vector> rects; @@ -513,19 +516,22 @@ void FlexGCWorker::Impl::checkMetalSpacing_prl( if (rects.size() == 1) { if (isX) { if (gtl::xl(rects[0]) == gtl::xl(markerRect) - || gtl::xh(rects[0]) == gtl::xl(markerRect)) + || gtl::xh(rects[0]) == gtl::xl(markerRect)) { return; + } } else { if (gtl::yl(rects[0]) == gtl::yl(markerRect) - || gtl::yh(rects[0]) == gtl::yl(markerRect)) + || gtl::yh(rects[0]) == gtl::yl(markerRect)) { return; + } } } } else { markerPoly += mRect; markerPoly -= netPoly; - if (markerPoly.size() == 0) + if (markerPoly.empty()) { return; + } } } auto marker = std::make_unique(); @@ -535,7 +541,12 @@ void FlexGCWorker::Impl::checkMetalSpacing_prl( gtl::yh(markerRect)); marker->setBBox(box); marker->setLayerNum(layerNum); - marker->setConstraint(getTech()->getLayer(layerNum)->getMinSpacing()); + if (isSpcRange) { + marker->setConstraint( + getTech()->getLayer(layerNum)->getSpacingRangeConstraints().at(0)); + } else { + marker->setConstraint(getTech()->getLayer(layerNum)->getMinSpacing()); + } marker->addSrc(net1->getOwner()); marker->addVictim(net1->getOwner(), std::make_tuple(rect1->getLayerNum(), @@ -572,10 +583,10 @@ inline gtl::polygon_90_set_data bg2gtl(const polygon_t& p) gtl::polygon_90_data poly; std::vector> points; for (const auto& pt : p.outer()) { - points.push_back(gtl::point_data(pt.x(), pt.y())); + points.emplace_back(pt.x(), pt.y()); } poly.set(points.begin(), points.end()); - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; set += poly; return set; } @@ -584,8 +595,9 @@ void FlexGCWorker::Impl::checkMetalSpacing_short_obs( gcRect* rect2, const gtl::rectangle_data& markerRect) { - if (rect1->isFixed() && rect2->isFixed()) + if (rect1->isFixed() && rect2->isFixed()) { return; + } bool isRect1Obs = rect1->getNet()->isBlockage(); bool isRect2Obs = rect2->getNet()->isBlockage(); if (isRect1Obs && isRect2Obs) { @@ -646,7 +658,7 @@ bool FlexGCWorker::Impl::checkMetalSpacing_short_skipFixed( if (gtl::delta(markerRect, gtl::VERTICAL) == 0) { gtl::bloat(bloatMarkerRect, gtl::VERTICAL, 1); } - using namespace boost::polygon::operators; + using boost::polygon::operators::operator&; auto& polys1 = net1->getPolygons(layerNum, false); auto intersection_polys1 = polys1 & bloatMarkerRect; auto& polys2 = net2->getPolygons(layerNum, false); @@ -733,15 +745,18 @@ void FlexGCWorker::Impl::checkMetalSpacing_short( auto layerNum = rect1->getLayerNum(); auto net1 = rect1->getNet(); auto net2 = rect2->getNet(); - if (rect1->isFixed() && rect2->isFixed()) + if (rect1->isFixed() && rect2->isFixed()) { return; + } // skip if marker area does not have route shape, must exclude touching - if (checkMetalSpacing_short_skipFixed(rect1, rect2, markerRect)) + if (checkMetalSpacing_short_skipFixed(rect1, rect2, markerRect)) { return; + } // skip same-net sufficient metal - if (checkMetalSpacing_short_skipSameNet(rect1, rect2, markerRect)) + if (checkMetalSpacing_short_skipSameNet(rect1, rect2, markerRect)) { return; + } auto marker = std::make_unique(); Rect box(gtl::xl(markerRect), @@ -775,24 +790,21 @@ void FlexGCWorker::Impl::checkMetalSpacing_short( addMarker(std::move(marker)); } -void FlexGCWorker::Impl::checkMetalSpacing_main(gcRect* ptr1, - gcRect* ptr2, +void FlexGCWorker::Impl::checkMetalSpacing_main(gcRect* rect1, + gcRect* rect2, bool checkNDRs, bool isSpcRect) { // NSMetal does not need self-intersection // Minimum width rule handled outside this function - if (ptr1 == ptr2) { - return; - } - if (isSkipVia(ptr1) || isSkipVia(ptr2)) { + if (rect1 == rect2) { return; } - gtl::rectangle_data markerRect(*ptr1); - auto distX = gtl::euclidean_distance(markerRect, *ptr2, gtl::HORIZONTAL); - auto distY = gtl::euclidean_distance(markerRect, *ptr2, gtl::VERTICAL); + gtl::rectangle_data markerRect(*rect1); + auto distX = gtl::euclidean_distance(markerRect, *rect2, gtl::HORIZONTAL); + auto distY = gtl::euclidean_distance(markerRect, *rect2, gtl::VERTICAL); - gtl::generalized_intersect(markerRect, *ptr2); + gtl::generalized_intersect(markerRect, *rect2); auto prlX = gtl::delta(markerRect, gtl::HORIZONTAL); auto prlY = gtl::delta(markerRect, gtl::VERTICAL); @@ -814,15 +826,15 @@ void FlexGCWorker::Impl::checkMetalSpacing_main(gcRect* ptr1, if (prlY == 0) { gtl::bloat(markerRect, gtl::VERTICAL, 1); } - if (ptr1->getNet()->isBlockage() || ptr2->getNet()->isBlockage()) { - checkMetalSpacing_short_obs(ptr1, ptr2, markerRect); + if (rect1->getNet()->isBlockage() || rect2->getNet()->isBlockage()) { + checkMetalSpacing_short_obs(rect1, rect2, markerRect); } else { - checkMetalSpacing_short(ptr1, ptr2, markerRect); + checkMetalSpacing_short(rect1, rect2, markerRect); } // prl } else { - checkMetalSpacing_prl(ptr1, - ptr2, + checkMetalSpacing_prl(rect1, + rect2, markerRect, std::max(prlX, prlY), distX, @@ -832,78 +844,18 @@ void FlexGCWorker::Impl::checkMetalSpacing_main(gcRect* ptr1, } } -void FlexGCWorker::Impl::checkMetalSpacingRange(gcRect* rect, - frSpacingRangeConstraint* con) -{ - auto minSpc = con->getMinSpacing(); - frSquaredDistance reqSpcValSquare = minSpc * (frSquaredDistance) minSpc; - box_t queryBox; - myBloat(*rect, minSpc, queryBox); - auto& workerRegionQuery = getWorkerRegionQuery(); - std::vector> result; - workerRegionQuery.queryMaxRectangle(queryBox, rect->getLayerNum(), result); - for (auto& [objBox, ptr] : result) { - if (ptr == rect) { - continue; - } - if (ptr->isFixed() && rect->isFixed()) { - continue; - } - if (!con->inRange(ptr->width())) { - continue; - } - frSquaredDistance distSquare = gtl::square_euclidean_distance(*rect, *ptr); - if (distSquare >= reqSpcValSquare) { - continue; - } - // Make marker - auto net1 = rect->getNet(); - auto net2 = ptr->getNet(); - gtl::rectangle_data markerRect(*rect); - gtl::generalized_intersect(markerRect, *ptr); - auto marker = std::make_unique(); - Rect box(gtl::xl(markerRect), - gtl::yl(markerRect), - gtl::xh(markerRect), - gtl::yh(markerRect)); - marker->setBBox(box); - marker->setLayerNum(rect->getLayerNum()); - marker->setConstraint(con); - marker->addSrc(net1->getOwner()); - marker->addVictim( - net1->getOwner(), - std::make_tuple( - rect->getLayerNum(), - Rect( - gtl::xl(*rect), gtl::yl(*rect), gtl::xh(*rect), gtl::yh(*rect)), - rect->isFixed())); - marker->addSrc(net2->getOwner()); - marker->addAggressor( - net2->getOwner(), - std::make_tuple( - ptr->getLayerNum(), - Rect(gtl::xl(*ptr), gtl::yl(*ptr), gtl::xh(*ptr), gtl::yh(*ptr)), - ptr->isFixed())); - addMarker(std::move(marker)); - } -} - -void FlexGCWorker::Impl::checkMetalSpacingRange(gcRect* rect) -{ - auto layer = getTech()->getLayer(rect->getLayerNum()); - for (auto con : layer->getSpacingRangeConstraints()) { - if (con->inRange(rect->width())) { - checkMetalSpacingRange(rect, con); - } - } -} - void FlexGCWorker::Impl::checkMetalSpacing_main(gcRect* rect, bool checkNDRs, bool isSpcRect) { auto layerNum = rect->getLayerNum(); auto maxSpcVal = checkMetalSpacing_getMaxSpcVal(layerNum, checkNDRs); + for (const auto& con : + getTech()->getLayer(layerNum)->getSpacingRangeConstraints()) { + if (con->inRange(rect->width())) { + maxSpcVal = std::max(maxSpcVal, con->getMinSpacing()); + } + } box_t queryBox; myBloat(*rect, maxSpcVal, queryBox); @@ -944,14 +896,23 @@ void FlexGCWorker::Impl::checkMetalSpacing() for (auto& maxrect : pin->getMaxRectangles()) { checkMetalSpacing_main(maxrect.get(), getDRWorker() || !AUTO_TAPER_NDR_NETS); - if (currLayer->hasSpacingRangeConstraints()) { - checkMetalSpacingRange(maxrect.get()); + if (currLayer->hasTwoWiresForbiddenSpacingConstraints()) { + for (auto con : + currLayer->getTwoWiresForbiddenSpacingConstraints()) { + checkTwoWiresForbiddenSpc_main(maxrect.get(), con); + } + } + if (currLayer->hasForbiddenSpacingConstraints()) { + for (auto con : currLayer->getForbiddenSpacingConstraints()) { + checkForbiddenSpc_main(maxrect.get(), con); + } } } } - for (auto& sr : targetNet_->getSpecialSpcRects()) + for (auto& sr : targetNet_->getSpecialSpcRects()) { checkMetalSpacing_main( sr.get(), getDRWorker() || !AUTO_TAPER_NDR_NETS, true); + } } } else { // layer --> net --> polygon --> maxrect @@ -973,14 +934,23 @@ void FlexGCWorker::Impl::checkMetalSpacing() // Short, NSMetal, metSpc checkMetalSpacing_main(maxrect.get(), getDRWorker() || !AUTO_TAPER_NDR_NETS); - if (currLayer->hasSpacingRangeConstraints()) { - checkMetalSpacingRange(maxrect.get()); + if (currLayer->hasTwoWiresForbiddenSpacingConstraints()) { + for (auto con : + currLayer->getTwoWiresForbiddenSpacingConstraints()) { + checkTwoWiresForbiddenSpc_main(maxrect.get(), con); + } + } + if (currLayer->hasForbiddenSpacingConstraints()) { + for (auto con : currLayer->getForbiddenSpacingConstraints()) { + checkForbiddenSpc_main(maxrect.get(), con); + } } } } - for (auto& sr : net->getSpecialSpcRects()) + for (auto& sr : net->getSpecialSpcRects()) { checkMetalSpacing_main( sr.get(), getDRWorker() || !AUTO_TAPER_NDR_NETS, true); + } } } } @@ -1180,29 +1150,38 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing_main( if (con->getCornerType() == frCornerTypeEnum::CONVEX) { if (cornerX >= (candX = gtl::xh(*rect))) { if (cornerY >= (candY = gtl::yh(*rect))) { - if (corner->getDir() != frCornerDirEnum::SW) + if (corner->getDir() != frCornerDirEnum::SW) { return; + } } else if (cornerY <= (candY = gtl::yl(*rect))) { - if (corner->getDir() != frCornerDirEnum::NW) + if (corner->getDir() != frCornerDirEnum::NW) { return; - } else + } + } else { return; + } } else if (cornerX <= (candX = gtl::xl(*rect))) { if (cornerY >= (candY = gtl::yh(*rect))) { - if (corner->getDir() != frCornerDirEnum::SE) + if (corner->getDir() != frCornerDirEnum::SE) { return; + } } else if (cornerY <= (candY = gtl::yl(*rect))) { - if (corner->getDir() != frCornerDirEnum::NE) + if (corner->getDir() != frCornerDirEnum::NE) { return; - } else + } + } else { return; - } else + } + } else { return; + } // The corner of the rect has to be convex // TODO: detect concave corners if (rect->getNet() - && !rect->getNet()->hasPolyCornerAt(candX, candY, rect->getLayerNum())) + && !rect->getNet()->hasPolyCornerAt( + candX, candY, rect->getLayerNum())) { return; + } } // skip for EXCEPTEOL eolWidth if (con->hasExceptEol()) { @@ -1262,8 +1241,9 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing_main( = gtl::square_euclidean_distance(*rect, point); frSquaredDistance reqSpcValSquare = reqSpcVal * (frSquaredDistance) reqSpcVal; - if (distSquare >= reqSpcValSquare) + if (distSquare >= reqSpcValSquare) { continue; + } } else if (maxXY >= reqSpcVal) { continue; } @@ -1282,7 +1262,8 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing_main( gtl::bloat(enlargedMarkerRect, width); // widthrect gtl::polygon_90_set_data tmpPoly; - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; + using boost::polygon::operators::operator&=; tmpPoly += enlargedMarkerRect; tmpPoly &= *objPtr; // tmpPoly now is widthrect auto targetArea = gtl::area(tmpPoly); @@ -1300,7 +1281,8 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing_main( gtl::bloat(enlargedMarkerRect, width); // widthrect gtl::polygon_90_set_data tmpPoly; - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; + using boost::polygon::operators::operator&=; tmpPoly += enlargedMarkerRect; tmpPoly &= *rect; // tmpPoly now is widthrect auto targetArea = gtl::area(tmpPoly); @@ -1341,8 +1323,6 @@ void FlexGCWorker::Impl::checkMetalCornerSpacing_main( rect->isFixed())); addMarker(std::move(marker)); return; - } else { - // TODO: implement others if necessary } } } @@ -1438,7 +1418,7 @@ void FlexGCWorker::Impl::checkMetalShape_minWidth( } // only show marker if fixed area < marker area { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator&; auto& fixedPolys = net->getPolygons(layerNum, true); auto intersection_fixedPolys = fixedPolys & rect; if (gtl::area(intersection_fixedPolys) == gtl::area(rect)) { @@ -1522,12 +1502,15 @@ bool isConvex(gcSegment* s) } gcSegment* bestSuitable(gcSegment* a, gcSegment* b) { - if (isConvex(a) && !isConvex(b)) + if (isConvex(a) && !isConvex(b)) { return a; - if (isConvex(b) && !isConvex(a)) + } + if (isConvex(b) && !isConvex(a)) { return b; - if (gtl::length(*a) > gtl::length(*b)) + } + if (gtl::length(*a) > gtl::length(*b)) { return a; + } return b; } void FlexGCWorker::Impl::checkMetalShape_minArea(gcPin* pin) @@ -1553,12 +1536,14 @@ void FlexGCWorker::Impl::checkMetalShape_minArea(gcPin* pin) gtl::rectangle_data bbox; gtl::extents(bbox, *pin->getPolygon()); Rect bbox2(gtl::xl(bbox), gtl::yl(bbox), gtl::xh(bbox), gtl::yh(bbox)); - if (!drWorker_->getDrcBox().contains(bbox2)) + if (!drWorker_->getDrcBox().contains(bbox2)) { return; + } for (auto& edges : pin->getPolygonEdges()) { for (auto& edge : edges) { - if (edge->isFixed()) + if (edge->isFixed()) { return; + } } } @@ -1645,6 +1630,95 @@ void FlexGCWorker::Impl::checkMetalShape_lef58MinStep_noBetweenEol( } } +inline void joinSegmentCoords(gcSegment* seg, + frCoord& llx, + frCoord& lly, + frCoord& urx, + frCoord& ury) +{ + llx = std::min(llx, seg->low().x()); + lly = std::min(lly, seg->low().y()); + urx = std::max(urx, seg->low().x()); + ury = std::max(ury, seg->low().y()); + + llx = std::min(llx, seg->high().x()); + lly = std::min(lly, seg->high().y()); + urx = std::max(urx, seg->high().x()); + ury = std::max(ury, seg->high().y()); +} + +void FlexGCWorker::Impl::checkMetalShape_lef58MinStep_minAdjLength( + gcPin* pin, + frLef58MinStepConstraint* con) +{ + auto poly = pin->getPolygon(); + auto layerNum = poly->getLayerNum(); + auto net = poly->getNet(); + if (poly->size() == 4 && con->isExceptRectangle()) { + return; + } + + std::vector startEdges; + auto minStepLength = con->getMinStepLength(); + for (auto& edges : pin->getPolygonEdges()) { + // get the first edge that is >= minstep length + for (auto& e : edges) { + if (gtl::length(*e) < minStepLength) { + startEdges.push_back(e.get()); + } + } + } + for (auto startEdge : startEdges) { + bool violating = false; + auto nextEdge = startEdge->getNextEdge(); + auto prevEdge = startEdge->getPrevEdge(); + if (gtl::length(*(nextEdge)) < con->getMinAdjacentLength() + || gtl::length(*(prevEdge)) < con->getMinAdjacentLength()) { + violating = true; + } + if (con->getNoAdjEol() > -1) { + if (nextEdge->getLowCorner()->getType() == frCornerTypeEnum::CONVEX + && nextEdge->getHighCorner()->getType() == frCornerTypeEnum::CONVEX + && gtl::length(*(nextEdge)) < con->getNoAdjEol()) { + violating = true; + } + if (prevEdge->getLowCorner()->getType() == frCornerTypeEnum::CONVEX + && prevEdge->getHighCorner()->getType() == frCornerTypeEnum::CONVEX + && gtl::length(*(prevEdge)) < con->getNoAdjEol()) { + violating = true; + } + } + // skip if all edges are fixed + if (startEdge->isFixed() && nextEdge->isFixed() && prevEdge->isFixed()) { + continue; + } + if (!violating) { + continue; + } + + // real violation + frCoord llx = startEdge->low().x(); + frCoord lly = startEdge->low().y(); + frCoord urx = startEdge->low().x(); + frCoord ury = startEdge->low().y(); + + joinSegmentCoords(startEdge, llx, lly, urx, ury); + joinSegmentCoords(nextEdge, llx, lly, urx, ury); + joinSegmentCoords(prevEdge, llx, lly, urx, ury); + + auto marker = std::make_unique(); + Rect box(llx, lly, urx, ury); + marker->setBBox(box); + marker->setLayerNum(layerNum); + marker->setConstraint(con); + marker->addSrc(net->getOwner()); + marker->addVictim(net->getOwner(), std::make_tuple(layerNum, box, false)); + marker->addAggressor(net->getOwner(), + std::make_tuple(layerNum, box, false)); + addMarker(std::move(marker)); + } +} + // currently only support nobetweeneol void FlexGCWorker::Impl::checkMetalShape_lef58MinStep(gcPin* pin) { @@ -1653,10 +1727,12 @@ void FlexGCWorker::Impl::checkMetalShape_lef58MinStep(gcPin* pin) // auto net = poly->getNet(); for (auto con : getTech()->getLayer(layerNum)->getLef58MinStepConstraints()) { - if (!con->hasEolWidth()) { - continue; + if (con->hasEolWidth()) { + checkMetalShape_lef58MinStep_noBetweenEol(pin, con); + } + if (con->hasMinAdjacentLength()) { + checkMetalShape_lef58MinStep_minAdjLength(pin, con); } - checkMetalShape_lef58MinStep_noBetweenEol(pin, con); } } @@ -1773,7 +1849,7 @@ void FlexGCWorker::Impl::checkMetalShape_rectOnly(gcPin* pin) std::vector> rects; gtl::polygon_90_set_data polySet; { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; polySet += *poly; } gtl::get_max_rectangles(rects, polySet); @@ -1801,7 +1877,7 @@ void FlexGCWorker::Impl::checkMetalShape_rectOnly(gcPin* pin) gtl::x(corner) + layerMinWidth, gtl::y(corner) + layerMinWidth); { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator&; auto intersectionPolySet = polySet & rect; auto intersectionFixedPolySet = intersectionPolySet & fixedPolys; if (gtl::area(intersectionFixedPolySet) @@ -1846,7 +1922,7 @@ void FlexGCWorker::Impl::checkMetalShape_offGrid(gcPin* pin) // continue if the marker area does not have route shape auto& polys = net->getPolygons(layerNum, false); gtl::rectangle_data markerRect(*maxRect); - using namespace boost::polygon::operators; + using boost::polygon::operators::operator&; auto intersection_polys = polys & markerRect; if (gtl::empty(intersection_polys)) { continue; @@ -1883,7 +1959,7 @@ void FlexGCWorker::Impl::checkMetalShape_minEnclosedArea(gcPin* pin) auto reqArea = con->getArea(); if (gtl::area(hole_poly) < reqArea) { auto& polys = net->getPolygons(layerNum, false); - using namespace boost::polygon::operators; + using boost::polygon::operators::operator&; auto intersection_polys = polys & (*poly); if (gtl::empty(intersection_polys)) { continue; @@ -1954,12 +2030,14 @@ void FlexGCWorker::Impl::checkMetalShape_lef58Area(gcPin* pin) gtl::rectangle_data bbox; gtl::extents(bbox, *pin->getPolygon()); Rect bbox2(gtl::xl(bbox), gtl::yl(bbox), gtl::xh(bbox), gtl::yh(bbox)); - if (!drWorker_->getDrcBox().contains(bbox2)) + if (!drWorker_->getDrcBox().contains(bbox2)) { continue; + } for (auto& edges : pin->getPolygonEdges()) { for (auto& edge : edges) { - if (edge->isFixed()) + if (edge->isFixed()) { continue; + } } } @@ -2010,16 +2088,15 @@ bool FlexGCWorker::Impl::checkMetalShape_lef58Area_exceptRectangle( std::vector> rects; gtl::polygon_90_set_data polySet; { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; polySet += *poly; } gtl::get_max_rectangles(rects, polySet); // rect only is true if (rects.size() == 1) { return false; - } else { - return true; } + return true; } return false; @@ -2034,7 +2111,7 @@ bool FlexGCWorker::Impl::checkMetalShape_lef58Area_rectWidth( std::vector> rects; gtl::polygon_90_set_data polySet; { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; polySet += *poly; } gtl::get_max_rectangles(rects, polySet); @@ -2047,9 +2124,8 @@ bool FlexGCWorker::Impl::checkMetalShape_lef58Area_rectWidth( apply_rect_width_area = std::min(xLen, yLen) <= min_width; check_rect_width = !apply_rect_width_area; return apply_rect_width_area; - } else { - return false; } + return false; } return false; @@ -2069,8 +2145,9 @@ void FlexGCWorker::Impl::checkMetalShape_addPatch(gcPin* pin, int min_area) for (auto& edges : pin->getPolygonEdges()) { for (auto& e : edges) { if (e->isVertical() != prefDirIsVert - && (!chosenEdg || bestSuitable(e.get(), chosenEdg) == e.get())) + && (!chosenEdg || bestSuitable(e.get(), chosenEdg) == e.get())) { chosenEdg = e.get(); + } } } frCoord length = ceil((float) gapArea / chosenEdg->length() @@ -2081,26 +2158,28 @@ void FlexGCWorker::Impl::checkMetalShape_addPatch(gcPin* pin, int min_area) if (prefDirIsVert) { patchBx.set_xlo(-chosenEdg->length() / 2); patchBx.set_xhi(chosenEdg->length() / 2); - patchBx.set_yhi(length); offset.setX((chosenEdg->low().x() + chosenEdg->high().x()) / 2); + offset.setY(chosenEdg->low().y()); if (chosenEdg->getOuterDir() == frDirEnum::N) { - offset.setY(chosenEdg->low().y()); + patchBx.set_yhi(length); } else if (chosenEdg->getOuterDir() == frDirEnum::S) { - offset.setY(chosenEdg->low().y() - length); - } else + patchBx.set_ylo(-length); + } else { logger_->error( DRT, 4500, "Edge outer dir should be either North or South"); + } } else { - patchBx.set_xhi(length); patchBx.set_ylo(-chosenEdg->length() / 2); patchBx.set_yhi(chosenEdg->length() / 2); + offset.setX(chosenEdg->low().x()); offset.setY((chosenEdg->low().y() + chosenEdg->high().y()) / 2); if (chosenEdg->getOuterDir() == frDirEnum::E) { - offset.setX(chosenEdg->low().x()); + patchBx.set_xhi(length); } else if (chosenEdg->getOuterDir() == frDirEnum::W) { - offset.setX(chosenEdg->low().x() - length); - } else + patchBx.set_xlo(-length); + } else { logger_->error(DRT, 4501, "Edge outer dir should be either East or West"); + } } auto patch = std::make_unique(); patch->setLayerNum(layer_idx); @@ -2125,11 +2204,10 @@ void FlexGCWorker::Impl::checkMetalShape_addPatch(gcPin* pin, int min_area) // detect what drNet has objects overlapping with the patch checkMetalShape_patchOwner_helper(patch.get(), dr_nets); } - if (!patch->hasNet()) + if (!patch->hasNet()) { return; + } - Rect shiftedPatch = patchBx; - shiftedPatch.moveTo(offset.x(), offset.y()); pwires_.push_back(std::move(patch)); } @@ -2171,7 +2249,7 @@ void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin, bool allow_patching) std::vector> rects; gtl::polygon_90_set_data polySet; { - using namespace boost::polygon::operators; + using boost::polygon::operators::operator+=; polySet += *poly; } polySet.get_rectangles(rects, gtl::HORIZONTAL); @@ -2185,8 +2263,9 @@ void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin, bool allow_patching) } // min area - if (allow_patching) + if (allow_patching) { checkMetalShape_minArea(pin); + } // min step checkMetalShape_minStep(pin); @@ -2204,8 +2283,9 @@ void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin, bool allow_patching) checkMetalShape_minEnclosedArea(pin); // lef58 area - if (allow_patching) + if (allow_patching) { checkMetalShape_lef58Area(pin); + } } void FlexGCWorker::Impl::checkMetalShape(bool allow_patching) @@ -2271,40 +2351,6 @@ frCoord FlexGCWorker::Impl::checkLef58CutSpacing_getMaxSpcVal( return maxSpcVal; } -frCoord FlexGCWorker::Impl::checkCutSpacing_spc_getReqSpcVal( - gcRect* ptr1, - gcRect* ptr2, - frCutSpacingConstraint* con) -{ - frCoord maxSpcVal = 0; - if (con) { - maxSpcVal = con->getCutSpacing(); - if (con->isAdjacentCuts()) { - auto ptr1LayerNum = ptr1->getLayerNum(); - auto ptr1Layer = getTech()->getLayer(ptr1LayerNum); - if (ptr1->getNet()->isBlockage()) { - frCoord width1 = ptr1->width(); - if (ptr1->getNet()->getDesignRuleWidth() != -1) { - width1 = ptr1->getNet()->getDesignRuleWidth(); - } - if (width1 > int(ptr1Layer->getWidth())) - maxSpcVal = con->getCutWithin(); - } - auto ptr2LayerNum = ptr2->getLayerNum(); - auto ptr2Layer = getTech()->getLayer(ptr2LayerNum); - if (ptr2->getNet()->isBlockage()) { - frCoord width2 = ptr2->width(); - if (ptr2->getNet()->getDesignRuleWidth() != -1) { - width2 = ptr2->getNet()->getDesignRuleWidth(); - } - if (width2 > int(ptr2Layer->getWidth())) - maxSpcVal = con->getCutWithin(); - } - } - } - return maxSpcVal; -} - void FlexGCWorker::Impl::checkCutSpacing_short( gcRect* rect1, gcRect* rect2, @@ -2393,31 +2439,30 @@ void FlexGCWorker::Impl::checkCutSpacing_spc( if (prl <= 0) { return; // skip if parallel overlap but shares the same above/below metal - } else { - box_t queryBox; - myBloat(markerRect, 0, queryBox); - auto& workerRegionQuery = getWorkerRegionQuery(); - std::vector> result; - auto secondLayerNum = rect1->getLayerNum() - 1; - if (secondLayerNum >= getTech()->getBottomLayerNum() - && secondLayerNum <= getTech()->getTopLayerNum()) { - workerRegionQuery.queryMaxRectangle(queryBox, secondLayerNum, result); - } - secondLayerNum = rect1->getLayerNum() + 1; - if (secondLayerNum >= getTech()->getBottomLayerNum() - && secondLayerNum <= getTech()->getTopLayerNum()) { - workerRegionQuery.queryMaxRectangle(queryBox, secondLayerNum, result); - } - for (auto& [objBox, objPtr] : result) { - // TODO why isn't this auto-converted from Rect to box_t? - Rect queryRect(queryBox.min_corner().get<0>(), - queryBox.min_corner().get<1>(), - queryBox.max_corner().get<0>(), - queryBox.max_corner().get<1>()); - if ((objPtr->getNet() == net1 || objPtr->getNet() == net2) - && objBox.contains(queryRect)) { - return; - } + } + box_t queryBox; + myBloat(markerRect, 0, queryBox); + auto& workerRegionQuery = getWorkerRegionQuery(); + std::vector> result; + auto secondLayerNum = rect1->getLayerNum() - 1; + if (secondLayerNum >= getTech()->getBottomLayerNum() + && secondLayerNum <= getTech()->getTopLayerNum()) { + workerRegionQuery.queryMaxRectangle(queryBox, secondLayerNum, result); + } + secondLayerNum = rect1->getLayerNum() + 1; + if (secondLayerNum >= getTech()->getBottomLayerNum() + && secondLayerNum <= getTech()->getTopLayerNum()) { + workerRegionQuery.queryMaxRectangle(queryBox, secondLayerNum, result); + } + for (auto& [objBox, objPtr] : result) { + // TODO why isn't this auto-converted from Rect to box_t? + Rect queryRect(queryBox.min_corner().get<0>(), + queryBox.min_corner().get<1>(), + queryBox.max_corner().get<0>(), + queryBox.max_corner().get<1>()); + if ((objPtr->getNet() == net1 || objPtr->getNet() == net2) + && objBox.contains(queryRect)) { + return; } } } @@ -2428,8 +2473,7 @@ void FlexGCWorker::Impl::checkCutSpacing_spc( } // no violation if spacing satisfied - frSquaredDistance reqSpcValSquare - = checkCutSpacing_spc_getReqSpcVal(rect1, rect2, con); + frSquaredDistance reqSpcValSquare = con->getCutSpacing(); reqSpcValSquare *= reqSpcValSquare; gtl::point_data center1, center2; @@ -2497,8 +2541,7 @@ void FlexGCWorker::Impl::checkCutSpacing_spc_diff_layer( } // no violation if spacing satisfied - frSquaredDistance reqSpcValSquare - = checkCutSpacing_spc_getReqSpcVal(rect1, rect2, con); + frSquaredDistance reqSpcValSquare = con->getCutSpacing(); reqSpcValSquare *= reqSpcValSquare; gtl::point_data center1, center2; @@ -2598,8 +2641,7 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_parallelOverlap( } // no violation if spacing satisfied - frSquaredDistance reqSpcValSquare - = checkLef58CutSpacing_spc_getReqSpcVal(rect1, rect2, con); + frSquaredDistance reqSpcValSquare = con->getCutSpacing(); reqSpcValSquare *= reqSpcValSquare; frSquaredDistance distSquare = 0; @@ -2719,15 +2761,15 @@ bool FlexGCWorker::Impl::checkLef58CutSpacing_spc_hasAdjCuts( if (no_prl || distSquare == 0) { cnt++; } - } else + } else { cnt++; + } } } if (cnt >= reqNumCut) { return true; - } else { - return false; } + return false; } bool FlexGCWorker::Impl::checkLef58CutSpacing_spc_hasTwoCuts( @@ -2738,9 +2780,8 @@ bool FlexGCWorker::Impl::checkLef58CutSpacing_spc_hasTwoCuts( if (checkLef58CutSpacing_spc_hasTwoCuts_helper(rect1, con) && checkLef58CutSpacing_spc_hasTwoCuts_helper(rect2, con)) { return true; - } else { - return false; } + return false; } bool FlexGCWorker::Impl::checkLef58CutSpacing_spc_hasTwoCuts_helper( @@ -2784,43 +2825,8 @@ bool FlexGCWorker::Impl::checkLef58CutSpacing_spc_hasTwoCuts_helper( if (cnt >= reqNumCut) { return true; - } else { - return false; } -} - -frCoord FlexGCWorker::Impl::checkLef58CutSpacing_spc_getReqSpcVal( - gcRect* ptr1, - gcRect* ptr2, - frLef58CutSpacingConstraint* con) -{ - frCoord maxSpcVal = 0; - if (con) { - maxSpcVal = con->getCutSpacing(); - if (con->hasAdjacentCuts()) { - auto ptr1LayerNum = ptr1->getLayerNum(); - auto ptr1Layer = getTech()->getLayer(ptr1LayerNum); - if (ptr1->getNet()->isBlockage()) { - frCoord width1 = ptr1->width(); - if (ptr1->getNet()->getDesignRuleWidth() != -1) { - width1 = ptr1->getNet()->getDesignRuleWidth(); - } - if (width1 > int(ptr1Layer->getWidth())) - maxSpcVal = con->getCutWithin(); - } - auto ptr2LayerNum = ptr2->getLayerNum(); - auto ptr2Layer = getTech()->getLayer(ptr2LayerNum); - if (ptr2->getNet()->isBlockage()) { - frCoord width2 = ptr2->width(); - if (ptr2->getNet()->getDesignRuleWidth() != -1) { - width2 = ptr2->getNet()->getDesignRuleWidth(); - } - if (width2 > int(ptr2Layer->getWidth())) - maxSpcVal = con->getCutWithin(); - } - } - } - return maxSpcVal; + return false; } // only works for GF14 syntax (i.e., TWOCUTS), not full rule support @@ -2917,8 +2923,7 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_adjCut( ; } - frSquaredDistance reqSpcValSquare - = checkLef58CutSpacing_spc_getReqSpcVal(rect1, rect2, con); + frSquaredDistance reqSpcValSquare = con->getCutSpacing(); reqSpcValSquare *= reqSpcValSquare; gtl::point_data center1, center2; @@ -2984,21 +2989,23 @@ void FlexGCWorker::Impl::checkLef58CutSpacing_spc_layer( logger_->warn( DRT, 54, "Unsupported branch STACK in checkLef58CutSpacing_spc_layer."); return; - } else if (con->hasOrthogonalSpacing()) { + } + if (con->hasOrthogonalSpacing()) { logger_->warn(DRT, 55, "Unsupported branch ORTHOGONALSPACING in " "checkLef58CutSpacing_spc_layer."); return; - } else if (con->hasCutClass()) { - ; + } + if (con->hasCutClass()) { if (con->isShortEdgeOnly()) { logger_->warn(DRT, 56, "Unsupported branch SHORTEDGEONLY in " "checkLef58CutSpacing_spc_layer."); return; - } else if (con->isConcaveCorner()) { + } + if (con->isConcaveCorner()) { if (con->hasWidth()) { logger_->warn( DRT, @@ -3358,11 +3365,7 @@ bool FlexGCWorker::Impl::checkCutSpacing_main_hasAdjCuts( cnt++; } } - if (cnt >= reqNumCut) { - return true; - } else { - return false; - } + return cnt >= reqNumCut; } void FlexGCWorker::Impl::checkLef58CutSpacing_main( @@ -3468,34 +3471,43 @@ void FlexGCWorker::Impl::checkCutSpacing_main(gcRect* rect) } // LEF58_SPACINGTABLE - if (layer->hasLef58SameMetalCutSpcTblConstraint()) + if (layer->hasLef58SameMetalCutSpcTblConstraint()) { checkLef58CutSpacingTbl(rect, layer->getLef58SameMetalCutSpcTblConstraint()); - if (layer->hasLef58SameNetCutSpcTblConstraint()) + } + if (layer->hasLef58SameNetCutSpcTblConstraint()) { checkLef58CutSpacingTbl(rect, layer->getLef58SameNetCutSpcTblConstraint()); - if (layer->hasLef58DiffNetCutSpcTblConstraint()) + } + if (layer->hasLef58DiffNetCutSpcTblConstraint()) { checkLef58CutSpacingTbl(rect, layer->getLef58DiffNetCutSpcTblConstraint()); - if (layer->hasLef58SameNetInterCutSpcTblConstraint()) + } + if (layer->hasLef58SameNetInterCutSpcTblConstraint()) { checkLef58CutSpacingTbl(rect, layer->getLef58SameNetInterCutSpcTblConstraint()); - if (layer->hasLef58SameMetalInterCutSpcTblConstraint()) + } + if (layer->hasLef58SameMetalInterCutSpcTblConstraint()) { checkLef58CutSpacingTbl(rect, layer->getLef58SameMetalInterCutSpcTblConstraint()); - if (layer->hasLef58DefaultInterCutSpcTblConstraint()) + } + if (layer->hasLef58DefaultInterCutSpcTblConstraint()) { checkLef58CutSpacingTbl(rect, layer->getLef58DefaultInterCutSpcTblConstraint()); + } if (layer->getLayerNum() + 2 < TOP_ROUTING_LAYER && layer->getLayerNum() + 2 < getTech()->getLayers().size()) { auto aboveLayer = getTech()->getLayer(layer->getLayerNum() + 2); - if (aboveLayer->hasLef58SameNetInterCutSpcTblConstraint()) + if (aboveLayer->hasLef58SameNetInterCutSpcTblConstraint()) { checkLef58CutSpacingTbl( rect, aboveLayer->getLef58SameNetInterCutSpcTblConstraint()); - if (aboveLayer->hasLef58SameMetalInterCutSpcTblConstraint()) + } + if (aboveLayer->hasLef58SameMetalInterCutSpcTblConstraint()) { checkLef58CutSpacingTbl( rect, aboveLayer->getLef58SameMetalInterCutSpcTblConstraint()); - if (aboveLayer->hasLef58DefaultInterCutSpcTblConstraint()) + } + if (aboveLayer->hasLef58DefaultInterCutSpcTblConstraint()) { checkLef58CutSpacingTbl( rect, aboveLayer->getLef58DefaultInterCutSpcTblConstraint()); + } } } @@ -3515,6 +3527,7 @@ void FlexGCWorker::Impl::checkCutSpacing() for (auto& pin : targetNet_->getPins(i)) { for (auto& maxrect : pin->getMaxRectangles()) { checkCutSpacing_main(maxrect.get()); + checkLef58Enclosure_main(maxrect.get()); } } } @@ -3533,6 +3546,7 @@ void FlexGCWorker::Impl::checkCutSpacing() for (auto& pin : net->getPins(i)) { for (auto& maxrect : pin->getMaxRectangles()) { checkCutSpacing_main(maxrect.get()); + checkLef58Enclosure_main(maxrect.get()); } } } @@ -3671,8 +3685,9 @@ void FlexGCWorker::Impl::patchMetalShape_minStep() drNet* net = nullptr; auto& workerRegionQuery = getDRWorker()->getWorkerRegionQuery(); Rect markerBBox = marker->getBBox(); - if ((int) markerBBox.maxDXDY() < (frCoord) layer->getWidth()) + if ((int) markerBBox.maxDXDY() < (frCoord) layer->getWidth()) { continue; + } workerRegionQuery.query(markerBBox, lNum, results); std::map> vias; for (auto& connFig : results) { @@ -3697,10 +3712,11 @@ void FlexGCWorker::Impl::patchMetalShape_minStep() bool downViaFound = false; for (auto obj : objs) { frLayerNum cutLayerNum = obj->getViaDef()->getCutLayerNum(); - if (cutLayerNum == lNum + 1) + if (cutLayerNum == lNum + 1) { upViaFound = true; - else + } else { downViaFound = true; + } if (upViaFound && downViaFound) { net = obj->getNet(); origin = tmpOrigin; @@ -3762,14 +3778,17 @@ void FlexGCWorker::Impl::checkMinimumCut_main(gcRect* rect) auto width = rect->width(); auto length = rect->length(); for (auto con : layer->getMinimumcutConstraints()) { - if (width < con->getWidth()) + if (width < con->getWidth()) { continue; - if (con->hasLength() && length < con->getLength()) + } + if (con->hasLength() && length < con->getLength()) { continue; + } auto& workerRegionQuery = getWorkerRegionQuery(); gtl::rectangle_data queryBox = *rect; - if (con->hasLength()) + if (con->hasLength()) { gtl::bloat(queryBox, con->getDistance()); + } std::vector> result; if (con->getConnection() != frMinimumcutConnectionEnum::FROMABOVE && layerNum > getTech()->getBottomLayerNum()) { @@ -3787,12 +3806,15 @@ void FlexGCWorker::Impl::checkMinimumCut_main(gcRect* rect) Rect wideRect( gtl::xl(*rect), gtl::yl(*rect), gtl::xh(*rect), gtl::yh(*rect)); for (auto [viaBox, via] : result) { - if (via->getNet() != rect->getNet()) + if (via->getNet() != rect->getNet()) { continue; - if (via->isFixed() && rect->isFixed()) + } + if (via->isFixed() && rect->isFixed()) { continue; - if (con->hasLength() && wideRect.contains(viaBox)) + } + if (con->hasLength() && wideRect.contains(viaBox)) { continue; + } if (!con->hasLength()) { checkMinimumCut_marker(rect, via, con); continue; @@ -3802,16 +3824,18 @@ void FlexGCWorker::Impl::checkMinimumCut_main(gcRect* rect) bool viol = false; for (auto [encBox, encObj] : encResult) { - if (encObj->getNet() != via->getNet()) + if (encObj->getNet() != via->getNet()) { continue; + } if (encBox.intersects(viaBox) && encBox.intersects(wideRect)) { viol = true; break; } } - if (viol) + if (viol) { checkMinimumCut_marker(rect, via, con); + } } } } @@ -3826,10 +3850,12 @@ void FlexGCWorker::Impl::checkMinimumCut() <= std::min((frLayerNum) (getTech()->getTopLayerNum()), maxLayerNum_); i++) { auto currLayer = getTech()->getLayer(i); - if (currLayer->getType() != dbTechLayerType::ROUTING) + if (currLayer->getType() != dbTechLayerType::ROUTING) { continue; - if (!currLayer->hasMinimumcut()) + } + if (!currLayer->hasMinimumcut()) { continue; + } for (auto& pin : targetNet_->getPins(i)) { for (auto& maxrect : pin->getMaxRectangles()) { checkMinimumCut_main(maxrect.get()); @@ -3844,10 +3870,12 @@ void FlexGCWorker::Impl::checkMinimumCut() <= std::min((frLayerNum) (getTech()->getTopLayerNum()), maxLayerNum_); i++) { auto currLayer = getTech()->getLayer(i); - if (currLayer->getType() != dbTechLayerType::ROUTING) + if (currLayer->getType() != dbTechLayerType::ROUTING) { continue; - if (!currLayer->hasMinimumcut()) + } + if (!currLayer->hasMinimumcut()) { continue; + } for (auto& net : getNets()) { for (auto& pin : net->getPins(i)) { for (auto& maxrect : pin->getMaxRectangles()) { @@ -3859,13 +3887,115 @@ void FlexGCWorker::Impl::checkMinimumCut() } } +void FlexGCWorker::Impl::checkTwoWiresForbiddenSpc_main( + gcRect* rect, + frLef58TwoWiresForbiddenSpcConstraint* con) +{ + bool isH = getTech()->getLayer(rect->getLayerNum())->getDir() + == odb::dbTechLayerDir::HORIZONTAL; + auto width1 = rect->width(); + bool validMinSpanLength1 = con->isValidForMinSpanLength(width1); + bool validMaxSpanLength1 = con->isValidForMaxSpanLength(width1); + if (!validMinSpanLength1 && !validMaxSpanLength1) { + return; + } + box_t queryBox; + myBloat(*rect, con->getODBRule()->getMaxSpacing(), queryBox); + auto& workerRegionQuery = getWorkerRegionQuery(); + std::vector> result; + workerRegionQuery.queryMaxRectangle(queryBox, rect->getLayerNum(), result); + for (auto& [objBox, ptr] : result) { + if (rect == ptr) { + continue; + } + if (rect->isFixed() && ptr->isFixed()) { + continue; + } + auto width2 = ptr->width(); + bool validMinSpanLength2 = con->isValidForMinSpanLength(width2); + bool validMaxSpanLength2 = con->isValidForMaxSpanLength(width2); + if (!(validMinSpanLength1 && validMaxSpanLength2) + && !(validMaxSpanLength1 && validMinSpanLength2)) { + continue; + } + gtl::rectangle_data markerRect(*rect); + gtl::generalized_intersect(markerRect, *ptr); + auto prlX = gtl::delta(markerRect, gtl::HORIZONTAL); + auto prlY = gtl::delta(markerRect, gtl::VERTICAL); + auto distX = gtl::euclidean_distance(*rect, *ptr, gtl::HORIZONTAL); + auto distY = gtl::euclidean_distance(*rect, *ptr, gtl::VERTICAL); + // skip short violations + if (distX == 0 && distY == 0) { + continue; + } + if (distX) { + prlX = -prlX; + } + if (distY) { + prlY = -prlY; + } + if (!con->isValidPrl(isH ? prlX : prlY)) { + continue; + } + if (!con->isForbiddenSpacing(isH ? distY : distX)) { + continue; + } + + int type = 0; + if (std::max(prlX, prlY) <= 0) { + type = 2; + } else { + if (distX == 0) { + type = 0; + } else if (distY == 0) { + type = 1; + } + } + if (!checkMetalSpacing_prl_hasPolyEdge( + rect, ptr, markerRect, type, std::max(prlX, prlY))) { + continue; + ; + } + if (!hasRoute(rect, markerRect) && !hasRoute(ptr, markerRect)) { + continue; + } + // add violation + auto marker = std::make_unique(); + Rect box(gtl::xl(markerRect), + gtl::yl(markerRect), + gtl::xh(markerRect), + gtl::yh(markerRect)); + marker->setBBox(box); + marker->setLayerNum(rect->getLayerNum()); + marker->setConstraint(con); + marker->addSrc(rect->getNet()->getOwner()); + marker->addVictim( + rect->getNet()->getOwner(), + std::make_tuple( + rect->getLayerNum(), + Rect( + gtl::xl(*rect), gtl::yl(*rect), gtl::xh(*rect), gtl::yh(*rect)), + rect->isFixed())); + marker->addSrc(ptr->getNet()->getOwner()); + marker->addAggressor( + ptr->getNet()->getOwner(), + std::make_tuple( + ptr->getLayerNum(), + Rect(gtl::xl(*ptr), gtl::yl(*ptr), gtl::xh(*ptr), gtl::yh(*ptr)), + ptr->isFixed())); + addMarker(std::move(marker)); + } +} + void FlexGCWorker::Impl::modifyMarkers() { - if (!surgicalFixEnabled_ || pwires_.empty()) + if (!surgicalFixEnabled_ || pwires_.empty()) { return; + } for (auto& pwire : pwires_) { - if (!pwire->hasNet()) + if (!pwire->hasNet()) { continue; + } Point origin = pwire->getOrigin(); auto net = pwire->getNet()->getFrNet(); for (auto& marker : markers_) { @@ -3899,10 +4029,12 @@ int FlexGCWorker::Impl::main() if (surgicalFixEnabled_ && getDRWorker()) { checkMetalShape(true); // minStep patching for GF14 - if (tech_->hasVia2ViaMinStep() || tech_->hasCornerSpacingConstraint()) + if (tech_->hasVia2ViaMinStep() || tech_->hasCornerSpacingConstraint()) { patchMetalShape(); - if (!pwires_.empty()) + } + if (!pwires_.empty()) { updateGCWorker(); + } } // clear existing markers clearMarkers(); @@ -3914,7 +4046,7 @@ int FlexGCWorker::Impl::main() checkMetalShape(false); // check eolSpc based on polygon checkMetalEndOfLine(); - // check CShort, cutSpc + // check CShort, cutSpc, enclosure checkCutSpacing(); // check SpacingTable Influence checkMetalSpacingTableInfluence(); @@ -3926,3 +4058,5 @@ int FlexGCWorker::Impl::main() modifyMarkers(); return 0; } + +} // namespace drt diff --git a/src/drt/src/global.cpp b/src/drt/src/global.cpp index d40cf88fe11..14b4578f084 100644 --- a/src/drt/src/global.cpp +++ b/src/drt/src/global.cpp @@ -38,7 +38,7 @@ #include "db/obj/frMaster.h" #include "frDesign.h" -using namespace fr; +namespace drt { std::string OUT_MAZE_FILE; std::string DRC_RPT_FILE; @@ -50,7 +50,7 @@ std::string GUIDE_REPORT_FILE; int OR_SEED = -1; double OR_K = 0; -std::string DBPROCESSNODE = ""; +std::string DBPROCESSNODE; int MAX_THREADS = 1; int BATCHSIZE = 1024; int BATCHSIZETA = 8; @@ -93,7 +93,6 @@ int CLOCK_NETS_LEAF_RIPUP_HARDINESS = 10; bool AUTO_TAPER_NDR_NETS = true; int TAPERBOX_RADIUS = 3; -frUInt4 TAVIACOST = 1; frUInt4 TAPINCOST = 4; frUInt4 TAALIGNCOST = 4; frUInt4 TADRCCOST = 32; @@ -108,15 +107,12 @@ frUInt4 MARKERBLOATWIDTH = 1; frUInt4 BLOCKCOST = 32; frUInt4 GUIDECOST = 1; // disabled change getNextPathCost to enable float SHAPEBLOATWIDTH = 3; -int MISALIGNMENTCOST = 8; int CONGCOST = 8; int HISTCOST = 32; -std::string REPAIR_PDN_LAYER_BEGIN_NAME; -std::string REPAIR_PDN_LAYER_END_NAME; -frLayerNum GC_IGNORE_PDN_BEGIN_LAYER = -1; -frLayerNum GC_IGNORE_PDN_END_LAYER = -1; -namespace fr { +std::string REPAIR_PDN_LAYER_NAME; +frLayerNum REPAIR_PDN_LAYER_NUM = -1; +frLayerNum GC_IGNORE_PDN_LAYER_NUM = -1; std::ostream& operator<<(std::ostream& os, const frRect& pinFigIn) { @@ -246,7 +242,7 @@ std::ostream& operator<<(std::ostream& os, const frInst& instIn) { Point tmpPoint = instIn.getOrigin(); auto tmpOrient = instIn.getOrient(); - frString tmpName = instIn.getName(); + const frString& tmpName = instIn.getName(); frString tmpString = instIn.getMaster()->getName(); os << "- " << tmpName << " " << tmpString << " + STATUS + ( " << tmpPoint.x() << " " << tmpPoint.y() << " ) " << tmpOrient.getString() << std::endl; @@ -496,4 +492,4 @@ std::ostream& operator<<(std::ostream& os, const frMarker& m) } } -} // end namespace fr +} // end namespace drt diff --git a/src/drt/src/global.h b/src/drt/src/global.h index aa5beb5b615..180af0eb830 100644 --- a/src/drt/src/global.h +++ b/src/drt/src/global.h @@ -37,6 +37,13 @@ #include "db/obj/frMarker.h" #include "frBaseTypes.h" +namespace odb { +class Point; +class Rect; +} // namespace odb + +namespace drt { + extern std::string DBPROCESSNODE; extern std::string OUT_MAZE_FILE; extern std::string DRC_RPT_FILE; @@ -66,13 +73,12 @@ extern bool CLEAN_PATCHES; extern bool DO_PA; extern bool SINGLE_STEP_DR; extern bool SAVE_GUIDE_UPDATES; -// extern int TEST; extern std::string VIAINPIN_BOTTOMLAYER_NAME; extern std::string VIAINPIN_TOPLAYER_NAME; -extern fr::frLayerNum VIAINPIN_BOTTOMLAYERNUM; -extern fr::frLayerNum VIAINPIN_TOPLAYERNUM; +extern frLayerNum VIAINPIN_BOTTOMLAYERNUM; +extern frLayerNum VIAINPIN_TOPLAYERNUM; -extern fr::frLayerNum VIA_ACCESS_LAYERNUM; +extern frLayerNum VIA_ACCESS_LAYERNUM; extern int MINNUMACCESSPOINT_MACROCELLPIN; extern int MINNUMACCESSPOINT_STDCELLPIN; @@ -90,95 +96,81 @@ extern int TAPERBOX_RADIUS; extern int NDR_NETS_ABS_PRIORITY; extern int CLOCK_NETS_ABS_PRIORITY; -extern fr::frUInt4 TAVIACOST; -extern fr::frUInt4 TAPINCOST; -extern fr::frUInt4 TAALIGNCOST; -extern fr::frUInt4 TADRCCOST; +extern frUInt4 TAPINCOST; +extern frUInt4 TAALIGNCOST; +extern frUInt4 TADRCCOST; extern float TASHAPEBLOATWIDTH; -extern fr::frUInt4 VIACOST; +extern frUInt4 VIACOST; -extern fr::frUInt4 GRIDCOST; -extern fr::frUInt4 ROUTESHAPECOST; -extern fr::frUInt4 MARKERCOST; -extern fr::frUInt4 MARKERBLOATWIDTH; -extern fr::frUInt4 BLOCKCOST; -extern fr::frUInt4 GUIDECOST; +extern frUInt4 GRIDCOST; +extern frUInt4 ROUTESHAPECOST; +extern frUInt4 MARKERCOST; +extern frUInt4 MARKERBLOATWIDTH; +extern frUInt4 BLOCKCOST; +extern frUInt4 GUIDECOST; extern float SHAPEBLOATWIDTH; -extern int MISALIGNMENTCOST; // GR extern int HISTCOST; extern int CONGCOST; -extern std::string REPAIR_PDN_LAYER_BEGIN_NAME; -extern std::string REPAIR_PDN_LAYER_END_NAME; -extern fr::frLayerNum GC_IGNORE_PDN_BEGIN_LAYER; -extern fr::frLayerNum GC_IGNORE_PDN_END_LAYER; +extern std::string REPAIR_PDN_LAYER_NAME; +extern frLayerNum REPAIR_PDN_LAYER_NUM; +extern frLayerNum GC_IGNORE_PDN_LAYER_NUM; -#define DIRBITSIZE 3 -#define WAVEFRONTBUFFERSIZE 2 -#define WAVEFRONTBITSIZE (WAVEFRONTBUFFERSIZE * DIRBITSIZE) -#define WAVEFRONTBUFFERHIGHMASK \ - (111 << ((WAVEFRONTBUFFERSIZE - 1) * DIRBITSIZE)) +constexpr int DIRBITSIZE = 3; +constexpr int WAVEFRONTBUFFERSIZE = 2; +constexpr int WAVEFRONTBITSIZE = (WAVEFRONTBUFFERSIZE * DIRBITSIZE); +constexpr int WAVEFRONTBUFFERHIGHMASK + = (111 << ((WAVEFRONTBUFFERSIZE - 1) * DIRBITSIZE)); // GR -#define GRWAVEFRONTBUFFERSIZE 2 -#define GRWAVEFRONTBITSIZE (GRWAVEFRONTBUFFERSIZE * DIRBITSIZE) -#define GRWAVEFRONTBUFFERHIGHMASK \ - (111 << ((GRWAVEFRONTBUFFERSIZE - 1) * DIRBITSIZE)) +constexpr int GRWAVEFRONTBUFFERSIZE = 2; +constexpr int GRWAVEFRONTBITSIZE = (GRWAVEFRONTBUFFERSIZE * DIRBITSIZE); +constexpr int GRWAVEFRONTBUFFERHIGHMASK + = (111 << ((GRWAVEFRONTBUFFERSIZE - 1) * DIRBITSIZE)); -namespace odb { -class Point; -class Rect; -} // namespace odb - -namespace fr { -frCoord getGCELLGRIDX(); -frCoord getGCELLGRIDY(); -frCoord getGCELLOFFSETX(); -frCoord getGCELLOFFSETY(); - -class frViaDef; +class drConnFig; +class drNet; +class frBPin; +class frBTerm; class frBlock; -class frMaster; +class frBlockObject; +class frConnFig; +class frGuide; class frInst; class frInstTerm; -class frTerm; -class frBTerm; class frMTerm; +class frMaster; +class frNet; +class frPathSeg; class frPin; -class frBPin; -class frRect; class frPolygon; -class frNet; -class drNet; -class drConnFig; +class frRect; class frShape; -class frConnFig; -class frPathSeg; -class frGuide; -class frBlockObject; +class frTerm; +class frViaDef; // These need to be in the fr namespace to support argument-dependent // lookup -std::ostream& operator<<(std::ostream& os, const fr::frViaDef& viaDefIn); -std::ostream& operator<<(std::ostream& os, const fr::frBlock& blockIn); -std::ostream& operator<<(std::ostream& os, const fr::frInst& instIn); -std::ostream& operator<<(std::ostream& os, const fr::frInstTerm& instTermIn); -std::ostream& operator<<(std::ostream& os, const fr::frBTerm& termIn); -std::ostream& operator<<(std::ostream& os, const fr::frRect& pinFig); -std::ostream& operator<<(std::ostream& os, const fr::frPolygon& pinFig); -std::ostream& operator<<(std::ostream& os, const fr::drConnFig& fig); +std::ostream& operator<<(std::ostream& os, const frViaDef& viaDefIn); +std::ostream& operator<<(std::ostream& os, const frBlock& blockIn); +std::ostream& operator<<(std::ostream& os, const frInst& instIn); +std::ostream& operator<<(std::ostream& os, const frInstTerm& instTermIn); +std::ostream& operator<<(std::ostream& os, const frBTerm& termIn); +std::ostream& operator<<(std::ostream& os, const frRect& pinFig); +std::ostream& operator<<(std::ostream& os, const frPolygon& pinFig); +std::ostream& operator<<(std::ostream& os, const drConnFig& fig); std::ostream& operator<<(std::ostream& os, const frShape& fig); std::ostream& operator<<(std::ostream& os, const frConnFig& fig); -std::ostream& operator<<(std::ostream& os, const frPathSeg& fig); +std::ostream& operator<<(std::ostream& os, const frPathSeg& p); std::ostream& operator<<(std::ostream& os, const frGuide& p); std::ostream& operator<<(std::ostream& os, const frBlockObject& fig); -std::ostream& operator<<(std::ostream& os, const frNet& fig); +std::ostream& operator<<(std::ostream& os, const frNet& n); std::ostream& operator<<(std::ostream& os, const drNet& n); std::ostream& operator<<(std::ostream& os, const frMarker& m); using utl::format_as; -} // namespace fr +} // namespace drt From e0f76b6061e35c9265ffaacff905409e7d4224e1 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Mon, 22 Jul 2024 13:00:03 +0300 Subject: [PATCH 22/26] drt: clang-tidy Signed-off-by: osamahammad21 --- src/drt/src/dr/FlexDR_init.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index 459b6298f50..4da00ce4537 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -3472,8 +3472,9 @@ void FlexDRWorker::initMazeCost_planarTerm(const frDesign* design) for (int i = 0; i < pin->getNumPinAccess(); i++) { const auto& pa = pin->getPinAccess(i); for (const auto& ap : pa->getAccessPoints()) { - if (ap->getLayerNum() != layerNum) + if (ap->getLayerNum() != layerNum) { continue; + } hasVerticalAccess |= ap->hasAccess(frDirEnum::N); hasVerticalAccess |= ap->hasAccess(frDirEnum::S); hasHorizontalAccess |= ap->hasAccess(frDirEnum::W); From 8839389815c5b9e301379b4fa2c3d2c8d938b15f Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Mon, 22 Jul 2024 11:39:37 -0400 Subject: [PATCH 23/26] odb: minor fix dbBox operators Signed-off-by: Peter Gadfort --- src/odb/src/db/dbBox.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/odb/src/db/dbBox.cpp b/src/odb/src/db/dbBox.cpp index b7c1daa4563..1628f28508b 100644 --- a/src/odb/src/db/dbBox.cpp +++ b/src/odb/src/db/dbBox.cpp @@ -94,10 +94,10 @@ bool _dbBox::operator==(const _dbBox& rhs) const if (_flags._octilinear != rhs._flags._octilinear) { return false; } - if (isOct() && _shape._oct != _shape._oct) { + if (isOct() && _shape._oct != rhs._shape._oct) { return false; } - if (_shape._rect != _shape._rect) { + if (_shape._rect != rhs._shape._rect) { return false; } @@ -163,10 +163,10 @@ int _dbBox::equal(const _dbBox& rhs) const if (design_rule_width_ != rhs.design_rule_width_) { return false; } - if (isOct() && _shape._oct != _shape._oct) { + if (isOct() && _shape._oct != rhs._shape._oct) { return false; } - if (_shape._rect != _shape._rect) { + if (_shape._rect != rhs._shape._rect) { return false; } From 0481d50e42eb1589fb0339dd9a2176a901b6cdb6 Mon Sep 17 00:00:00 2001 From: luis201420 Date: Mon, 22 Jul 2024 16:21:15 +0000 Subject: [PATCH 24/26] grt: adding clang-format Signed-off-by: luis201420 --- src/grt/src/fastroute/src/utility.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index b28c98465ab..1bf91db0c12 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -1885,7 +1885,6 @@ void FastRouteCore::copyBR(void) int i, j, edgeID, numEdges, numNodes, min_y, min_x, edgeCost; if (!sttrees_bk_.empty()) { - // Reduce usage with last routes before update for (const int& netID : net_ids_) { numEdges = sttrees_[netID].num_edges(); From 4c9d6fce66295bf6625443e3f027f2c5bb00aa14 Mon Sep 17 00:00:00 2001 From: luis201420 Date: Mon, 22 Jul 2024 17:31:34 +0000 Subject: [PATCH 25/26] grt: adding suggested modifications Signed-off-by: luis201420 --- src/grt/src/fastroute/src/utility.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index 1bf91db0c12..bdc6c47c2c1 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -1892,9 +1892,9 @@ void FastRouteCore::copyBR(void) for (edgeID = 0; edgeID < numEdges; edgeID++) { if (sttrees_[netID].edges[edgeID].len > 0) { - const std::vector& gridsX + const std::vector& gridsX = sttrees_[netID].edges[edgeID].route.gridsX; - const std::vector& gridsY + const std::vector& gridsY = sttrees_[netID].edges[edgeID].route.gridsY; for (i = 0; i < sttrees_[netID].edges[edgeID].route.routelen; i++) { if (gridsX[i] == gridsX[i + 1] && gridsY[i] == gridsY[i + 1]) { @@ -1982,9 +1982,9 @@ void FastRouteCore::copyBR(void) for (edgeID = 0; edgeID < numEdges; edgeID++) { if (sttrees_[netID].edges[edgeID].len > 0) { - const std::vector& gridsX + const std::vector& gridsX = sttrees_[netID].edges[edgeID].route.gridsX; - const std::vector& gridsY + const std::vector& gridsY = sttrees_[netID].edges[edgeID].route.gridsY; for (i = 0; i < sttrees_[netID].edges[edgeID].route.routelen; i++) { if (gridsX[i] == gridsX[i + 1] && gridsY[i] == gridsY[i + 1]) { From 8a7a0ebb7b42b66aa1029970fef1f8ef8e39c12a Mon Sep 17 00:00:00 2001 From: luis201420 Date: Mon, 22 Jul 2024 18:15:41 +0000 Subject: [PATCH 26/26] grt: adding requested modifications Signed-off-by: luis201420 --- src/grt/src/fastroute/src/utility.cpp | 34 +++++++++++---------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index bdc6c47c2c1..66f48813cf5 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -1891,21 +1891,18 @@ void FastRouteCore::copyBR(void) edgeCost = nets_[netID]->getEdgeCost(); for (edgeID = 0; edgeID < numEdges; edgeID++) { - if (sttrees_[netID].edges[edgeID].len > 0) { - const std::vector& gridsX - = sttrees_[netID].edges[edgeID].route.gridsX; - const std::vector& gridsY - = sttrees_[netID].edges[edgeID].route.gridsY; - for (i = 0; i < sttrees_[netID].edges[edgeID].route.routelen; i++) { + const TreeEdge& edge = sttrees_[netID].edges[edgeID]; + if (edge.len > 0) { + const std::vector& gridsX = edge.route.gridsX; + const std::vector& gridsY = edge.route.gridsY; + for (i = 0; i < edge.route.routelen; i++) { if (gridsX[i] == gridsX[i + 1] && gridsY[i] == gridsY[i + 1]) { continue; } - if (gridsX[i] == gridsX[i + 1]) // a vertical edge - { + if (gridsX[i] == gridsX[i + 1]) { min_y = std::min(gridsY[i], gridsY[i + 1]); v_edges_[min_y][gridsX[i]].usage -= edgeCost; - } else /// if(gridsY[i]==gridsY[i+1])// a horizontal edge - { + } else { min_x = std::min(gridsX[i], gridsX[i + 1]); h_edges_[gridsY[i]][min_x].usage -= edgeCost; } @@ -1981,22 +1978,19 @@ void FastRouteCore::copyBR(void) edgeCost = nets_[netID]->getEdgeCost(); for (edgeID = 0; edgeID < numEdges; edgeID++) { - if (sttrees_[netID].edges[edgeID].len > 0) { - const std::vector& gridsX - = sttrees_[netID].edges[edgeID].route.gridsX; - const std::vector& gridsY - = sttrees_[netID].edges[edgeID].route.gridsY; - for (i = 0; i < sttrees_[netID].edges[edgeID].route.routelen; i++) { + const TreeEdge& edge = sttrees_[netID].edges[edgeID]; + if (edge.len > 0) { + const std::vector& gridsX = edge.route.gridsX; + const std::vector& gridsY = edge.route.gridsY; + for (i = 0; i < edge.route.routelen; i++) { if (gridsX[i] == gridsX[i + 1] && gridsY[i] == gridsY[i + 1]) { continue; } - if (gridsX[i] == gridsX[i + 1]) // a vertical edge - { + if (gridsX[i] == gridsX[i + 1]) { min_y = std::min(gridsY[i], gridsY[i + 1]); v_edges_[min_y][gridsX[i]].usage += edgeCost; v_used_ggrid_.insert(std::make_pair(min_y, gridsX[i])); - } else /// if(gridsY[i]==gridsY[i+1])// a horizontal edge - { + } else { min_x = std::min(gridsX[i], gridsX[i + 1]); h_edges_[gridsY[i]][min_x].usage += edgeCost; h_used_ggrid_.insert(std::make_pair(gridsY[i], min_x));