diff --git a/src/drt/include/triton_route/TritonRoute.h b/src/drt/include/triton_route/TritonRoute.h index 80318e4cf7d..4b5d3e9d2fc 100644 --- a/src/drt/include/triton_route/TritonRoute.h +++ b/src/drt/include/triton_route/TritonRoute.h @@ -20,6 +20,7 @@ class dbDatabase; class dbInst; class dbBTerm; class dbNet; +class dbWire; } // namespace odb namespace utl { @@ -163,6 +164,7 @@ class TritonRoute const std::list>& markers, const std::string& marker_name, odb::Rect drcBox = odb::Rect(0, 0, 0, 0)) const; + std::vector routeLayerLengths(odb::dbWire* wire) const; void checkDRC(const char* filename, int x1, int y1, diff --git a/src/drt/src/TritonRoute.cpp b/src/drt/src/TritonRoute.cpp index ce81bd4301d..f17fc2d29fb 100644 --- a/src/drt/src/TritonRoute.cpp +++ b/src/drt/src/TritonRoute.cpp @@ -1385,4 +1385,24 @@ void TritonRoute::reportDRC(const std::string& file_name, tool_category->writeTR(file_name); } +std::vector TritonRoute::routeLayerLengths(odb::dbWire* wire) const +{ + std::vector lengths; + lengths.resize(db_->getTech()->getLayerCount()); + odb::dbWireShapeItr shapes; + odb::dbShape s; + + for (shapes.begin(wire); shapes.next(s);) { + if (!s.isVia()) { + lengths[s.getTechLayer()->getNumber()] += s.getLength(); + } else { + if (s.getTechVia()) { + lengths[s.getTechVia()->getBottomLayer()->getNumber() + 1] += 1; + } + } + } + + return lengths; +} + } // namespace drt diff --git a/src/drt/src/TritonRoute.i b/src/drt/src/TritonRoute.i index c0b82c01ca8..414fd9f0694 100644 --- a/src/drt/src/TritonRoute.i +++ b/src/drt/src/TritonRoute.i @@ -13,6 +13,10 @@ %include "../../Exception.i" +%import +%import +%template(vector_int) std::vector; + %inline %{ int detailed_route_num_drvs() @@ -218,4 +222,12 @@ void check_drc_cmd(const char* drc_file, int x1, int y1, int x2, int y2, const c const int num_threads = ord::OpenRoad::openRoad()->getThreadCount(); router->checkDRC(drc_file, x1, y1, x2, y2, marker_name, num_threads); } + +std::vector +route_layer_lengths(odb::dbWire* db_wire) +{ + auto* router = ord::OpenRoad::openRoad()->getTritonRoute(); + return router->routeLayerLengths(db_wire); +} + %} // inline diff --git a/src/grt/src/GlobalRouter.cpp b/src/grt/src/GlobalRouter.cpp index 300df37be40..2c02bdf060b 100644 --- a/src/grt/src/GlobalRouter.cpp +++ b/src/grt/src/GlobalRouter.cpp @@ -510,7 +510,7 @@ void GlobalRouter::estimateRC(sta::SpefWriter* spef_writer) for (auto& [db_net, route] : routes_) { if (!route.empty()) { Net* net = getNet(db_net); - builder.estimateParasitcs(db_net, net->getPins(), route, spef_writer); + builder.estimateParasitics(db_net, net->getPins(), route, spef_writer); } } } @@ -526,7 +526,7 @@ void GlobalRouter::estimateRC(odb::dbNet* db_net) GRoute& route = iter->second; if (!route.empty()) { Net* net = getNet(db_net); - builder.estimateParasitcs(db_net, net->getPins(), route); + builder.estimateParasitics(db_net, net->getPins(), route); } } @@ -4559,11 +4559,12 @@ void GlobalRouter::reportNetLayerWirelengths(odb::dbNet* db_net, via_count++; } } + out << " " << via_count; for (size_t i = 0; i < lengths.size(); i++) { int64_t length = lengths[i]; odb::dbTechLayer* layer = db_->getTech()->findRoutingLayer(i); if (i > 0 && out.is_open()) { - out << " " << via_count << " " << block_->dbuToMicrons(length); + out << " " << block_->dbuToMicrons(length); } if (length > 0) { logger_->report("\tLayer {:5s}: {:5.2f}um", @@ -4692,11 +4693,12 @@ void GlobalRouter::reportNetDetailedRouteWL(odb::dbWire* wire, } } + out << " " << via_count; for (size_t i = 1; i < lengths.size(); i++) { int64_t length = lengths[i]; odb::dbTechLayer* layer = db_->getTech()->findRoutingLayer(i); if (i > 0 && out.is_open()) { - out << " " << via_count << " " << block_->dbuToMicrons(length); + out << " " << block_->dbuToMicrons(length); } if (length > 0) { logger_->report("\tLayer {:5s}: {:5.2f}um", diff --git a/src/grt/src/MakeWireParasitics.cpp b/src/grt/src/MakeWireParasitics.cpp index b18f2fa926f..58de57b08f3 100644 --- a/src/grt/src/MakeWireParasitics.cpp +++ b/src/grt/src/MakeWireParasitics.cpp @@ -49,10 +49,10 @@ MakeWireParasitics::MakeWireParasitics(utl::Logger* logger, { } -void MakeWireParasitics::estimateParasitcs(odb::dbNet* net, - std::vector& pins, - GRoute& route, - sta::SpefWriter* spef_writer) +void MakeWireParasitics::estimateParasitics(odb::dbNet* net, + std::vector& pins, + GRoute& route, + sta::SpefWriter* spef_writer) { debugPrint(logger_, GRT, "est_rc", 1, "net {}", net->getConstName()); if (logger_->debugCheck(GRT, "est_rc", 2)) { @@ -93,7 +93,7 @@ void MakeWireParasitics::estimateParasitcs(odb::dbNet* net, parasitics_->deleteParasiticNetworks(sta_net); } -void MakeWireParasitics::estimateParasitcs(odb::dbNet* net, GRoute& route) +void MakeWireParasitics::estimateParasitics(odb::dbNet* net, GRoute& route) { debugPrint(logger_, GRT, "est_rc", 1, "net {}", net->getConstName()); if (logger_->debugCheck(GRT, "est_rc", 2)) { @@ -491,19 +491,27 @@ float MakeWireParasitics::getNetSlack(odb::dbNet* net) std::vector MakeWireParasitics::routeLayerLengths(odb::dbNet* db_net) const { NetRouteMap& routes = grouter_->getRoutes(); - std::vector layer_lengths(grouter_->getMaxRoutingLayer() + 1); + + // dbu wirelength for wires, via count for vias + std::vector layer_lengths(tech_->getLayerCount()); + if (!db_net->getSigType().isSupply()) { GRoute& route = routes[db_net]; std::set route_pts; for (GSegment& segment : route) { if (segment.isVia()) { - route_pts.insert( - RoutePt(segment.init_x, segment.init_y, segment.init_layer)); - route_pts.insert( - RoutePt(segment.final_x, segment.final_y, segment.final_layer)); + auto& s = segment; + // Mimic makeRouteParasitics + int min_layer = min(s.init_layer, s.final_layer); + odb::dbTechLayer* cut_layer + = tech_->findRoutingLayer(min_layer)->getUpperLayer(); + layer_lengths[cut_layer->getNumber()] += 1; + route_pts.insert(RoutePt(s.init_x, s.init_y, s.init_layer)); + route_pts.insert(RoutePt(s.final_x, s.final_y, s.final_layer)); } else { int layer = segment.init_layer; - layer_lengths[layer] += segment.length(); + layer_lengths[tech_->findRoutingLayer(layer)->getNumber()] + += segment.length(); route_pts.insert(RoutePt(segment.init_x, segment.init_y, layer)); route_pts.insert(RoutePt(segment.final_x, segment.final_y, layer)); } @@ -530,7 +538,8 @@ std::vector MakeWireParasitics::routeLayerLengths(odb::dbNet* db_net) const layer--; int wire_length_dbu = abs(pt.getX() - grid_pt.getX()) + abs(pt.getY() - grid_pt.getY()); - layer_lengths[layer] += wire_length_dbu; + layer_lengths[tech_->findRoutingLayer(layer)->getNumber()] + += wire_length_dbu; } } return layer_lengths; diff --git a/src/grt/src/MakeWireParasitics.h b/src/grt/src/MakeWireParasitics.h index 8a6d6e3ddae..7c059b5003b 100644 --- a/src/grt/src/MakeWireParasitics.h +++ b/src/grt/src/MakeWireParasitics.h @@ -54,11 +54,11 @@ class MakeWireParasitics : public AbstractMakeWireParasitics odb::dbTech* tech, odb::dbBlock* block, GlobalRouter* grouter); - void estimateParasitcs(odb::dbNet* net, - std::vector& pins, - GRoute& route, - sta::SpefWriter* spef_writer = nullptr); - void estimateParasitcs(odb::dbNet* net, GRoute& route) override; + void estimateParasitics(odb::dbNet* net, + std::vector& pins, + GRoute& route, + sta::SpefWriter* spef_writer = nullptr); + void estimateParasitics(odb::dbNet* net, GRoute& route) override; void clearParasitics() override; // Return GRT layer lengths in dbu's for db_net's route indexed by routing diff --git a/src/grt/src/fastroute/include/AbstractMakeWireParasitics.h b/src/grt/src/fastroute/include/AbstractMakeWireParasitics.h index e4ce003b63c..2d64c342cf5 100644 --- a/src/grt/src/fastroute/include/AbstractMakeWireParasitics.h +++ b/src/grt/src/fastroute/include/AbstractMakeWireParasitics.h @@ -14,7 +14,7 @@ class AbstractMakeWireParasitics public: ~AbstractMakeWireParasitics() = default; - virtual void estimateParasitcs(odb::dbNet* net, GRoute& route) = 0; + virtual void estimateParasitics(odb::dbNet* net, GRoute& route) = 0; virtual void clearParasitics() = 0; diff --git a/src/grt/src/fastroute/src/utility.cpp b/src/grt/src/fastroute/src/utility.cpp index bd2917985ce..1f342ff3795 100644 --- a/src/grt/src/fastroute/src/utility.cpp +++ b/src/grt/src/fastroute/src/utility.cpp @@ -1265,7 +1265,7 @@ float FastRouteCore::CalculatePartialSlack() odb::dbNet* db_net = net_route.first; GRoute& route = net_route.second; if (!route.empty()) { - parasitics_builder_->estimateParasitcs(db_net, route); + parasitics_builder_->estimateParasitics(db_net, route); } } for (const int& netID : net_ids_) { diff --git a/src/grt/test/report_wire_length4.rptok b/src/grt/test/report_wire_length4.rptok index 9af89ba51fe..8609438c8d3 100644 --- a/src/grt/test/report_wire_length4.rptok +++ b/src/grt/test/report_wire_length4.rptok @@ -1,5 +1,5 @@ tool net total_wl #pins #vias li1_wl met1_wl met2_wl met3_wl met4_wl met5_wl -grt: clk 201.6 2 2 0 2 0 2 0 2 144 2 57.6 2 0 -drt: clk 184.95 2 5 0 5 0.215 5 0.185 5 134.97 5 49.58 5 0 -grt: net60 14.4 2 2 0 2 0 2 14.4 2 0 2 0 2 0 -drt: net60 13.39 2 3 0 3 3.77 3 9.62 3 0 3 0 3 0 +grt: clk 201.6 2 2 0 0 0 144 57.6 0 +drt: clk 184.95 2 5 0 0.215 0.185 134.97 49.58 0 +grt: net60 14.4 2 2 0 0 14.4 0 0 0 +drt: net60 13.39 2 3 0 3.77 9.62 0 0 0 diff --git a/src/rsz/src/Resizer.i b/src/rsz/src/Resizer.i index 4741801ddcd..4cb0f0a2a7b 100644 --- a/src/rsz/src/Resizer.i +++ b/src/rsz/src/Resizer.i @@ -7,6 +7,7 @@ #include #include "sta/Liberty.hh" +#include "sta/Parasitics.hh" #include "sta/Network.hh" #include "sta/Corner.hh" #include "rsz/Resizer.hh" @@ -115,6 +116,36 @@ using rsz::ParasiticsSrc; namespace rsz { +void +report_net_parasitic(Net *net) +{ + Resizer *resizer = getResizer(); + Corner *corner = sta::Sta::sta()->cmdCorner(); + const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(sta::MinMax::max()); + auto parasitic = resizer->parasitics()->findParasiticNetwork(net, ap); + if (parasitic) { + resizer->parasitics()->report(parasitic); + } +} + +float +sum_parasitic_network_resist(Net *net) +{ + Resizer *resizer = getResizer(); + Corner *corner = sta::Sta::sta()->cmdCorner(); + const ParasiticAnalysisPt *ap = corner->findParasiticAnalysisPt(sta::MinMax::max()); + auto parasitic = resizer->parasitics()->findParasiticNetwork(net, ap); + if (parasitic) { + float ret = 0.0; + for (auto resist : resizer->parasitics()->resistors(parasitic)) { + ret += resizer->parasitics()->value(resist); + } + return ret; + } else { + return 0.0f; + } +} + void set_layer_rc_cmd(odb::dbTechLayer *layer, const Corner *corner,