Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/drt/include/triton_route/TritonRoute.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class dbDatabase;
class dbInst;
class dbBTerm;
class dbNet;
class dbWire;
} // namespace odb

namespace utl {
Expand Down Expand Up @@ -163,6 +164,7 @@ class TritonRoute
const std::list<std::unique_ptr<frMarker>>& markers,
const std::string& marker_name,
odb::Rect drcBox = odb::Rect(0, 0, 0, 0)) const;
std::vector<int> routeLayerLengths(odb::dbWire* wire) const;
void checkDRC(const char* filename,
int x1,
int y1,
Expand Down
20 changes: 20 additions & 0 deletions src/drt/src/TritonRoute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1385,4 +1385,24 @@ void TritonRoute::reportDRC(const std::string& file_name,
tool_category->writeTR(file_name);
}

std::vector<int> TritonRoute::routeLayerLengths(odb::dbWire* wire) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this in drt as it appears only use odb APIs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to have drt::route_layer_lengths as an analogue to grt::route_layer_lengths. The latter does use grt APIs so it can't be an odb utility. Should I move the drt one into the odb submodule, or just somewhere else in src/drt/src where it's more decoupled from the router itself?

{
std::vector<int> 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
12 changes: 12 additions & 0 deletions src/drt/src/TritonRoute.i
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

%include "../../Exception.i"

%import <stl.i>
%import <std_vector.i>
%template(vector_int) std::vector<int>;

%inline %{

int detailed_route_num_drvs()
Expand Down Expand Up @@ -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<int>
route_layer_lengths(odb::dbWire* db_wire)
{
auto* router = ord::OpenRoad::openRoad()->getTritonRoute();
return router->routeLayerLengths(db_wire);
}

%} // inline
10 changes: 6 additions & 4 deletions src/grt/src/GlobalRouter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
54 changes: 19 additions & 35 deletions src/grt/src/MakeWireParasitics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ MakeWireParasitics::MakeWireParasitics(utl::Logger* logger,
{
}

void MakeWireParasitics::estimateParasitcs(odb::dbNet* net,
std::vector<Pin>& pins,
GRoute& route,
sta::SpefWriter* spef_writer)
void MakeWireParasitics::estimateParasitics(odb::dbNet* net,
std::vector<Pin>& pins,
GRoute& route,
sta::SpefWriter* spef_writer)
{
debugPrint(logger_, GRT, "est_rc", 1, "net {}", net->getConstName());
if (logger_->debugCheck(GRT, "est_rc", 2)) {
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -491,47 +491,31 @@ float MakeWireParasitics::getNetSlack(odb::dbNet* net)
std::vector<int> MakeWireParasitics::routeLayerLengths(odb::dbNet* db_net) const
{
NetRouteMap& routes = grouter_->getRoutes();
std::vector<int> layer_lengths(grouter_->getMaxRoutingLayer() + 1);

// dbu wirelength for wires, via count for vias
std::vector<int> layer_lengths(tech_->getLayerCount());

if (!db_net->getSigType().isSupply()) {
GRoute& route = routes[db_net];
std::set<RoutePt> 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));
}
}
// Mimic MakeWireParasitics::makeParasiticsToPin functionality.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the following code no longer needed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is the grt guides reach the center of the instance not the individual pins, and this code is adding a small patch of route on top of it to meet the pin. In the process it's adding a redundant via (so we overcount), and I'm not sure the wirelength it adds is beneficial either.

If it's true that it doesn't help with the estimation (which can be confirmed empirically) then we should remove the same code from makeParasiticsPin to keep things in sync

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@povik A small clarification, but GRT guides don't reach the center of the instance. They reach the center of the GCell that encloses the pin shape. The distance from the center of the GCell to the pin location might be useful (more than 7 tracks, for example)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the redundant via that is being added?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually the redundant via exists only in makeParasiticsToPin (see via_res in the function). Here it wasn't being counted because we weren't counting vias at all, but now that we do, we would have a redundant via if we updated this piece of code instead of removing it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid I'm not following. My concern is that if estimate RC is creating a redundant via then it is incorrect and should be fixed. Perhaps you and @eder-matheus can review this issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've discussed with @eder-matheus and agreed to put this code back.

My concern is that if estimate RC is creating a redundant via then it is incorrect

There's redundant via in estimate RC but it's a dead end so if STA is considering topology of the parasitic network the extra resistive element is without effect. The length utility doesn't see topology.

Net* net = grouter_->getNet(db_net);
for (Pin& pin : net->getPins()) {
int layer = pin.getConnectionLayer() + 1;
odb::Point grid_pt = pin.getOnGridPosition();
odb::Point pt = pin.getPosition();

std::vector<std::pair<odb::Point, odb::Point>> ap_positions;
bool has_access_points
= grouter_->findPinAccessPointPositions(pin, ap_positions);
if (has_access_points) {
auto ap_position = ap_positions.front();
pt = ap_position.first;
grid_pt = ap_position.second;
}

RoutePt grid_route(grid_pt.getX(), grid_pt.getY(), layer);
auto pt_itr = route_pts.find(grid_route);
if (pt_itr == route_pts.end())
layer--;
int wire_length_dbu
= abs(pt.getX() - grid_pt.getX()) + abs(pt.getY() - grid_pt.getY());
layer_lengths[layer] += wire_length_dbu;
}
}
return layer_lengths;
}
Expand Down
10 changes: 5 additions & 5 deletions src/grt/src/MakeWireParasitics.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ class MakeWireParasitics : public AbstractMakeWireParasitics
odb::dbTech* tech,
odb::dbBlock* block,
GlobalRouter* grouter);
void estimateParasitcs(odb::dbNet* net,
std::vector<Pin>& pins,
GRoute& route,
sta::SpefWriter* spef_writer = nullptr);
void estimateParasitcs(odb::dbNet* net, GRoute& route) override;
void estimateParasitics(odb::dbNet* net,
std::vector<Pin>& 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
Expand Down
2 changes: 1 addition & 1 deletion src/grt/src/fastroute/include/AbstractMakeWireParasitics.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/grt/src/fastroute/src/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_) {
Expand Down
8 changes: 4 additions & 4 deletions src/grt/test/report_wire_length4.rptok
Original file line number Diff line number Diff line change
@@ -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
31 changes: 31 additions & 0 deletions src/rsz/src/Resizer.i
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <fstream>

#include "sta/Liberty.hh"
#include "sta/Parasitics.hh"
#include "sta/Network.hh"
#include "sta/Corner.hh"
#include "rsz/Resizer.hh"
Expand Down Expand Up @@ -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,
Expand Down
Loading