diff --git a/src/drt/src/dr/FlexDR.h b/src/drt/src/dr/FlexDR.h index 7eb2e75476c..40db121961e 100644 --- a/src/drt/src/dr/FlexDR.h +++ b/src/drt/src/dr/FlexDR.h @@ -539,6 +539,9 @@ class FlexDRWorker bool isCongested_; bool save_updates_; + // hellpers + bool isRoutePatchWire(const frPatchWire* pwire) const; + bool isRouteVia(const frVia* via) const; // init void init(const frDesign* design); void initNets(const frDesign* design); diff --git a/src/drt/src/dr/FlexDR_end.cpp b/src/drt/src/dr/FlexDR_end.cpp index 5de2f504319..24eca2db4cb 100644 --- a/src/drt/src/dr/FlexDR_end.cpp +++ b/src/drt/src/dr/FlexDR_end.cpp @@ -233,24 +233,15 @@ void FlexDRWorker::endRemoveNets_pathSeg(frDesign* design, void FlexDRWorker::endRemoveNets_via(frDesign* design, frVia* via) { - auto gridBBox = getRouteBox(); - auto regionQuery = design->getRegionQuery(); - auto net = via->getNet(); - Point viaPoint = via->getOrigin(); - if (isInitDR() - && (viaPoint.x() == gridBBox.xMin() || viaPoint.x() == gridBBox.xMax() - || viaPoint.y() == gridBBox.yMin() - || viaPoint.y() == gridBBox.yMax())) { - return; - } - if (viaPoint.x() >= gridBBox.xMin() && viaPoint.y() >= gridBBox.yMin() - && viaPoint.x() <= gridBBox.xMax() && viaPoint.y() <= gridBBox.yMax()) { + if (isRouteVia(via)) { + auto net = via->getNet(); if (save_updates_) { drUpdate update(drUpdate::REMOVE_FROM_NET); update.setNet(net); update.setIndexInOwner(via->getIndexInOwner()); design_->addUpdate(update); } + auto regionQuery = design->getRegionQuery(); regionQuery->removeDRObj(via); // delete rq net->removeVia(via); } @@ -258,23 +249,15 @@ void FlexDRWorker::endRemoveNets_via(frDesign* design, frVia* via) void FlexDRWorker::endRemoveNets_patchWire(frDesign* design, frPatchWire* pwire) { - auto gridBBox = getRouteBox(); - auto regionQuery = design->getRegionQuery(); - auto net = pwire->getNet(); - Point origin = pwire->getOrigin(); - if (isInitDR() - && (origin.x() == gridBBox.xMin() || origin.x() == gridBBox.xMax() - || origin.y() == gridBBox.yMin() || origin.y() == gridBBox.yMax())) { - return; - } - if (origin.x() >= gridBBox.xMin() && origin.y() >= gridBBox.yMin() - && origin.x() <= gridBBox.xMax() && origin.y() <= gridBBox.yMax()) { + if (isRoutePatchWire(pwire)) { + auto net = pwire->getNet(); if (save_updates_) { drUpdate update(drUpdate::REMOVE_FROM_NET); update.setNet(net); update.setIndexInOwner(pwire->getIndexInOwner()); design_->addUpdate(update); } + auto regionQuery = design->getRegionQuery(); regionQuery->removeDRObj(pwire); // delete rq net->removePatchWire(pwire); } @@ -286,7 +269,7 @@ void FlexDRWorker::endRemoveNets( map>, frBlockObjectComp>& boundPts) { vector result; - design->getRegionQuery()->queryDRObj(getRouteBox(), result); + design->getRegionQuery()->queryDRObj(getExtBox(), result); for (auto rptr : result) { if (rptr->typeId() == frcPathSeg) { auto cptr = static_cast(rptr); diff --git a/src/drt/src/dr/FlexDR_graphics.cpp b/src/drt/src/dr/FlexDR_graphics.cpp index 1d2a63c07e5..c0abf0fae0f 100644 --- a/src/drt/src/dr/FlexDR_graphics.cpp +++ b/src/drt/src/dr/FlexDR_graphics.cpp @@ -692,7 +692,7 @@ void FlexDRGraphics::startNet(drNet* net) } } -void FlexDRGraphics::endNet(drNet* net) +void FlexDRGraphics::midNet(drNet* net) { if (!net_) { return; @@ -704,7 +704,7 @@ void FlexDRGraphics::endNet(drNet* net) point_cnt += pts.size(); } - status("End net: " + net->getFrNet()->getName() + " searched " + status("Mid net: " + net->getFrNet()->getName() + " searched " + std::to_string(point_cnt) + " points"); if (settings_->draw) { @@ -718,6 +718,25 @@ void FlexDRGraphics::endNet(drNet* net) for (auto& points : points_by_layer_) { points.clear(); } +} + +void FlexDRGraphics::endNet(drNet* net) +{ + if (!net_) { + return; + } + gui_->removeSelected(); + assert(net == net_); + + status("End net: " + net->getFrNet()->getName() + " After GC"); + + if (settings_->draw) { + gui_->redraw(); + } + + if (settings_->allowPause) { + gui_->pause(); + } net_ = nullptr; } diff --git a/src/drt/src/dr/FlexDR_graphics.h b/src/drt/src/dr/FlexDR_graphics.h index 524479dd974..6be531e93aa 100644 --- a/src/drt/src/dr/FlexDR_graphics.h +++ b/src/drt/src/dr/FlexDR_graphics.h @@ -63,6 +63,8 @@ class FlexDRGraphics : public gui::Renderer void startNet(drNet* net); + void midNet(drNet* net); + void endNet(drNet* net); void searchNode(const FlexGridGraph* grid_graph, diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index 70198137edc..7501b069eac 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -35,6 +35,20 @@ using namespace std; using namespace fr; namespace bgi = boost::geometry::index; +bool FlexDRWorker::isRoutePatchWire(const frPatchWire* pwire) const +{ + const auto& gridBBox = getRouteBox(); + Point origin = pwire->getOrigin(); + return isInitDR() ? gridBBox.overlaps(origin) : gridBBox.intersects(origin); +} + +bool FlexDRWorker::isRouteVia(const frVia* via) const +{ + const auto& gridBBox = getRouteBox(); + Point origin = via->getOrigin(); + return isInitDR() ? gridBBox.overlaps(origin) : gridBBox.intersects(origin); +} + void FlexDRWorker::initNetObjs_pathSeg( frPathSeg* pathSeg, set& nets, @@ -147,8 +161,10 @@ void FlexDRWorker::initNetObjs_via( { auto net = via->getNet(); nets.insert(net); - if (getRouteBox().intersects(via->getOrigin())) { - netRouteObjs[net].push_back(make_unique(*via)); + if (isRouteVia(via)) { + auto uVia = make_unique(*via); + unique_ptr uDRObj(std::move(uVia)); + netRouteObjs[net].push_back(std::move(uDRObj)); } else { netExtObjs[net].push_back(make_unique(*via)); } @@ -162,8 +178,10 @@ void FlexDRWorker::initNetObjs_patchWire( { auto net = pwire->getNet(); nets.insert(net); - if (getRouteBox().intersects(pwire->getOrigin())) { - netRouteObjs[net].push_back(make_unique(*pwire)); + if (isRoutePatchWire(pwire)) { + auto uPWire = make_unique(*pwire); + unique_ptr uDRObj(std::move(uPWire)); + netRouteObjs[net].push_back(std::move(uDRObj)); } else { netExtObjs[net].push_back(make_unique(*pwire)); } @@ -255,13 +273,6 @@ static bool segOnBorder(const Rect& routeBox, } } -// The origin is strictly inside the routeBox and not on an edge -static bool viaInInterior(const Rect& routeBox, const Point& origin) -{ - return routeBox.xMin() < origin.x() && origin.x() < routeBox.xMax() - && routeBox.yMin() < origin.y() && origin.y() < routeBox.yMax(); -} - void FlexDRWorker::initNets_segmentTerms( const Point& bp, const frLayerNum lNum, @@ -349,12 +360,7 @@ void FlexDRWorker::initNets_initDR( vExtObjs.push_back(std::move(netRouteObjs[net][i])); } } else if (obj->typeId() == drcVia) { - auto via = static_cast(obj.get()); - if (viaInInterior(getRouteBox(), via->getOrigin())) { - vRouteObjs.push_back(std::move(netRouteObjs[net][i])); - } else { - vExtObjs.push_back(std::move(netRouteObjs[net][i])); - } + vRouteObjs.push_back(std::move(netRouteObjs[net][i])); } else if (obj->typeId() == drcPatchWire) { vRouteObjs.push_back(std::move(netRouteObjs[net][i])); } diff --git a/src/drt/src/dr/FlexDR_maze.cpp b/src/drt/src/dr/FlexDR_maze.cpp index b7a4ecd17d1..6e7991124e5 100644 --- a/src/drt/src/dr/FlexDR_maze.cpp +++ b/src/drt/src/dr/FlexDR_maze.cpp @@ -1752,6 +1752,9 @@ void FlexDRWorker::route_queue_main(queue& rerouteQueue) net->getFrNet()->getName(), routeBoxStringStream.str()); } + if (graphics_) { + graphics_->midNet(net); + } mazeNetEnd(net); net->addNumReroutes(); didRoute = true; @@ -1781,6 +1784,7 @@ void FlexDRWorker::route_queue_main(queue& rerouteQueue) workerRegionQuery.add(tmp.get()); net->addRoute(std::move(tmp)); } + gcWorker_->clearPWires(); if (getDRIter() >= beginDebugIter && !getGCWorker()->getMarkers().empty()) { logger_->info(DRT, @@ -3143,7 +3147,10 @@ void FlexDRWorker::routeNet_postAstarPatchMinAreaVio( layerNum = gridGraph_.getLayerNum(currIdx.z()); minAreaConstraint = getTech()->getLayer(layerNum)->getAreaConstraint(); frArea reqArea = (minAreaConstraint) ? minAreaConstraint->getMinArea() : 0; - if (areaMap.find(currIdx) != areaMap.end()) { + if (currArea < reqArea && areaMap.find(currIdx) != areaMap.end()) { + if (!prev_is_wire) { + currArea /= 2; + } currArea += areaMap.find(currIdx)->second; } endViaHalfEncArea = 0; diff --git a/src/drt/src/gc/FlexGC.cpp b/src/drt/src/gc/FlexGC.cpp index 49e3aeefe5c..e285ad082c7 100644 --- a/src/drt/src/gc/FlexGC.cpp +++ b/src/drt/src/gc/FlexGC.cpp @@ -157,6 +157,11 @@ const std::vector>& FlexGCWorker::getPWires() const return impl_->pwires_; } +void FlexGCWorker::clearPWires() +{ + impl_->pwires_.clear(); +} + bool FlexGCWorker::setTargetNet(frBlockObject* in) { auto& owner2nets = impl_->owner2nets_; diff --git a/src/drt/src/gc/FlexGC.h b/src/drt/src/gc/FlexGC.h index 27daa6f87b6..a819d862f88 100644 --- a/src/drt/src/gc/FlexGC.h +++ b/src/drt/src/gc/FlexGC.h @@ -71,6 +71,7 @@ class FlexGCWorker void init(const frDesign* design); int main(); void end(); + void clearPWires(); // initialization from FlexPA, initPA0 --> addPAObj --> initPA1 void initPA0(const frDesign* design); void initPA1(); diff --git a/src/drt/src/gc/FlexGC_impl.h b/src/drt/src/gc/FlexGC_impl.h index e057f156cc3..e182932f383 100644 --- a/src/drt/src/gc/FlexGC_impl.h +++ b/src/drt/src/gc/FlexGC_impl.h @@ -170,6 +170,7 @@ class FlexGCWorker::Impl FlexGCWorkerRegionQuery& getWorkerRegionQuery() { return rq_; } + void modifyMarkers(); // init gcNet* getNet(frBlockObject* obj); gcNet* getNet(frNet* net); @@ -277,8 +278,8 @@ class FlexGCWorker::Impl gcRect* rect, frLef58CornerSpacingConstraint* con); - void checkMetalShape(); - void checkMetalShape_main(gcPin* pin); + void checkMetalShape(bool allow_patching = false); + void checkMetalShape_main(gcPin* pin, bool allow_patching); void checkMetalShape_minWidth(const gtl::rectangle_data& rect, frLayerNum layerNum, gcNet* net, diff --git a/src/drt/src/gc/FlexGC_main.cpp b/src/drt/src/gc/FlexGC_main.cpp index 54378b5c94f..276c00697ad 100644 --- a/src/drt/src/gc/FlexGC_main.cpp +++ b/src/drt/src/gc/FlexGC_main.cpp @@ -1866,6 +1866,8 @@ 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()) + return; Rect shiftedPatch = patchBx; shiftedPatch.moveTo(offset.x(), offset.y()); @@ -1900,7 +1902,7 @@ void FlexGCWorker::Impl::checkMetalShape_patchOwner_helper( } } -void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin) +void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin, bool allow_patching) { auto poly = pin->getPolygon(); auto layerNum = poly->getLayerNum(); @@ -1924,7 +1926,8 @@ void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin) } // min area - checkMetalShape_minArea(pin); + if (allow_patching) + checkMetalShape_minArea(pin); // min step checkMetalShape_minStep(pin); @@ -1942,10 +1945,11 @@ void FlexGCWorker::Impl::checkMetalShape_main(gcPin* pin) checkMetalShape_minEnclosedArea(pin); // lef58 area - checkMetalShape_lef58Area(pin); + if (allow_patching) + checkMetalShape_lef58Area(pin); } -void FlexGCWorker::Impl::checkMetalShape() +void FlexGCWorker::Impl::checkMetalShape(bool allow_patching) { if (targetNet_) { // layer --> net --> polygon @@ -1959,7 +1963,7 @@ void FlexGCWorker::Impl::checkMetalShape() continue; } for (auto& pin : targetNet_->getPins(i)) { - checkMetalShape_main(pin.get()); + checkMetalShape_main(pin.get(), allow_patching); } } } else { @@ -1975,7 +1979,7 @@ void FlexGCWorker::Impl::checkMetalShape() } for (auto& net : getNets()) { for (auto& pin : net->getPins(i)) { - checkMetalShape_main(pin.get()); + checkMetalShape_main(pin.get(), allow_patching); } } } @@ -3277,10 +3281,6 @@ void FlexGCWorker::Impl::checkCutSpacing() void FlexGCWorker::Impl::patchMetalShape() { - pwires_.clear(); - clearMarkers(); - - checkMetalShape(); patchMetalShape_minStep(); checkMetalCornerSpacing(); @@ -3374,6 +3374,8 @@ void FlexGCWorker::Impl::patchMetalShape_cornerSpacing() } } + if (!net) + continue; markerBBox.moveDelta(-origin.x(), -origin.y()); auto patch = make_unique(); patch->setLayerNum(lNum); @@ -3591,19 +3593,51 @@ void FlexGCWorker::Impl::checkMinimumCut() } } -int FlexGCWorker::Impl::main() +void FlexGCWorker::Impl::modifyMarkers() { - // ProfileTask profile("GC:main"); - // printMarker = true; - // minStep patching for GF14 - if (surgicalFixEnabled_ && getDRWorker() - && (tech_->hasVia2ViaMinStep() || tech_->hasCornerSpacingConstraint())) { - patchMetalShape(); + if (!surgicalFixEnabled_ || pwires_.empty()) + return; + for (auto& pwire : pwires_) { + if (!pwire->hasNet()) + continue; + Point origin = pwire->getOrigin(); + auto net = pwire->getNet()->getFrNet(); + for (auto& marker : markers_) { + if (marker->getLayerNum() != pwire->getLayerNum()) { + continue; + } + if (!marker->getBBox().intersects(pwire->getBBox())) { + continue; + } + if (marker->getSrcs().find(net) == marker->getSrcs().end()) { + continue; + } + if (marker->getBBox().intersects(origin)) { + continue; + } + auto bbox = marker->getBBox(); + bbox.merge(Rect(origin, origin)); + marker->setBBox(bbox); + } } +} + +int FlexGCWorker::Impl::main() +{ // incremental updates - if (!modifiedDRNets_.empty() || !pwires_.empty()) { + pwires_.clear(); + clearMarkers(); + if (!modifiedDRNets_.empty()) { updateGCWorker(); } + if (surgicalFixEnabled_ && getDRWorker()) { + checkMetalShape(true); + // minStep patching for GF14 + if (tech_->hasVia2ViaMinStep() || tech_->hasCornerSpacingConstraint()) + patchMetalShape(); + if (!pwires_.empty()) + updateGCWorker(); + } // clear existing markers clearMarkers(); // check LEF58CornerSpacing @@ -3611,7 +3645,7 @@ int FlexGCWorker::Impl::main() // check Short, NSMet, MetSpc based on max rectangles checkMetalSpacing(); // check MinWid, MinStp, RectOnly based on polygon - checkMetalShape(); + checkMetalShape(false); // check eolSpc based on polygon checkMetalEndOfLine(); // check CShort, cutSpc @@ -3622,5 +3656,7 @@ int FlexGCWorker::Impl::main() checkMinimumCut(); // check LEF58_METALWIDTHVIATABLE checkMetalWidthViaTable(); + // modify markers for pwires + modifyMarkers(); return 0; }