Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rsz: Add option for Steiner tree amending in net repair #5487

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions src/rsz/include/rsz/Resizer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class RecoverPower;
class RepairDesign;
class RepairSetup;
class RepairHold;
class TreeAmending;

class NetHash
{
Expand Down Expand Up @@ -322,6 +323,7 @@ class Resizer : public dbStaState
double max_wire_length, // max_wire_length zero for none (meters)
double slew_margin, // 0.0-1.0
double cap_margin, // 0.0-1.0
bool amend_tree,
bool verbose);
int repairDesignBufferCount() const;
// for debugging
Expand Down Expand Up @@ -630,6 +632,7 @@ class Resizer : public dbStaState
RepairDesign* repair_design_;
RepairSetup* repair_setup_;
RepairHold* repair_hold_;
TreeAmending* tree_amending_;
std::unique_ptr<AbstractSteinerRenderer> steiner_renderer_;

// Layer RC per wire length indexed by layer->getNumber(), corner->index
Expand Down Expand Up @@ -721,6 +724,7 @@ class Resizer : public dbStaState
friend class RepairSetup;
friend class RepairHold;
friend class SteinerTree;
friend class TreeAmending;
};

} // namespace rsz
17 changes: 16 additions & 1 deletion src/rsz/src/BufferedNet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,21 @@ int BufferedNet::bufferCount() const
return 0;
}

int BufferedNet::wireLength() const
{
switch (type_) {
case BufferedNetType::wire:
return length() + ref_->wireLength();
case BufferedNetType::junction:
return ref_->wireLength() + ref2_->wireLength();
case BufferedNetType::load:
return 0;
case BufferedNetType::buffer:
return ref_->wireLength();
}
return 0;
}

int BufferedNet::maxLoadWireLength() const
{
switch (type_) {
Expand Down Expand Up @@ -457,7 +472,7 @@ static BufferedNetPtr makeBufferedNetFromTree(
}
}
if (bnet && from != SteinerTree::null_pt
&& tree->location(to) != tree->location(from)) {
/* && tree->location(to) != tree->location(from)*/) {
bnet = make_shared<BufferedNet>(BufferedNetType::wire,
tree->location(from),
BufferedNet::null_layer,
Expand Down
17 changes: 17 additions & 0 deletions src/rsz/src/BufferedNet.hh
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ class BufferedNet
// repairNet
int maxLoadWireLength() const;

int wireLength() const;

// Rebuffer
Required required(const StaState* sta) const;
const PathRef& requiredPath() const { return required_path_; }
Expand Down Expand Up @@ -187,6 +189,21 @@ class BufferedNet
PathRef required_path_;
// Max delay from here to the loads.
Delay required_delay_;

public:
// tree amending annotations
BufferedNetPtr pairing_candidate_;
std::vector<BufferedNetPtr> pending_candidates_;

BufferedNet *place_ = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: use nullptr [modernize-use-nullptr]

Suggested change
BufferedNet *place_ = NULL;
BufferedNet *place_ = nullptr;


BufferedNet *upstream_ = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: use nullptr [modernize-use-nullptr]

Suggested change
BufferedNet *upstream_ = NULL;
BufferedNet *upstream_ = nullptr;

void setUpstream(BufferedNet *upstream) {
upstream_ = upstream;
}
BufferedNet *upstream() {
return upstream_;
}
};

} // namespace rsz
1 change: 1 addition & 0 deletions src/rsz/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ add_library(rsz_lib
SteinerTree.cc
EstimateWireParasitics.cc
Resizer.cc
TreeAmending.cc
)

target_sources(rsz
Expand Down
103 changes: 101 additions & 2 deletions src/rsz/src/Rebuffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,87 @@ int RepairSetup::rebuffer(const Pin* drvr_pin)
return inserted_buffer_count;
}

int RepairSetup::rebuffer(const Pin* drvr_pin, BufferedNetPtr bnet)
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: the parameter 'bnet' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param]

Suggested change
int RepairSetup::rebuffer(const Pin* drvr_pin, BufferedNetPtr bnet)
int RepairSetup::rebuffer(const Pin* drvr_pin, const BufferedNetPtr& bnet)

src/rsz/src/RepairSetup.hh:195:

-   int rebuffer(const Pin* drvr_pin, BufferedNetPtr bnet);
+   int rebuffer(const Pin* drvr_pin, const BufferedNetPtr& bnet);

{
int inserted_buffer_count = 0;
Net* net;
if (network_->isTopLevelPort(drvr_pin)) {
net = network_->net(network_->term(drvr_pin));
LibertyCell* buffer_cell = resizer_->buffer_lowest_drive_;
// Should use sdc external driver here.
LibertyPort* input;
buffer_cell->bufferPorts(input, drvr_port_);
} else {
net = network_->net(drvr_pin);
drvr_port_ = network_->libertyPort(drvr_pin);
}
if (drvr_port_
&& net
// Verilog connects by net name, so there is no way to distinguish the
// net from the port.
&& !hasTopLevelOutputPort(net)) {
corner_ = sta_->cmdCorner();
//BufferedNetPtr bnet = resizer_->makeBufferedNet(drvr_pin, corner_);
if (bnet) {
bool debug = (drvr_pin == resizer_->debug_pin_);
if (debug) {
logger_->setDebugLevel(RSZ, "rebuffer", 3);
}
debugPrint(logger_,
RSZ,
"rebuffer",
2,
"driver {}",
sdc_network_->pathName(drvr_pin));
sta_->findRequireds();

const BufferedNetSeq& Z = rebufferBottomUp(bnet, 1);
Required best_slack_penalized = -INF;
BufferedNetPtr best_option = nullptr;
int best_index = 0;
int i = 1;
for (const BufferedNetPtr& p : Z) {
// Find slack for drvr_pin into option.
const PathRef& req_path = p->requiredPath();
if (!req_path.isNull()) {
Slack slack_penalized = slackPenalized(p, i);
if (best_option == nullptr
|| fuzzyGreater(slack_penalized, best_slack_penalized)) {
best_slack_penalized = slack_penalized;
best_option = p;
best_index = i;
}
i++;
}
}
if (best_option) {
debugPrint(logger_, RSZ, "rebuffer", 2, "best option {}", best_index);
inserted_buffer_count = rebufferTopDown(best_option, net, 1);
if (inserted_buffer_count > 0) {
rebuffer_net_count_++;
debugPrint(logger_,
RSZ,
"rebuffer",
2,
"rebuffer {} inserted {}",
network_->pathName(drvr_pin),
inserted_buffer_count);
}
}
if (debug) {
logger_->setDebugLevel(RSZ, "rebuffer", 0);
}
} else {
logger_->warn(RSZ,
10001,
"makeBufferedNet failed for driver {}",
network_->pathName(drvr_pin));
}
}
return inserted_buffer_count;
}


Slack RepairSetup::slackPenalized(const BufferedNetPtr& bnet)
{
return slackPenalized(bnet, -1);
Expand Down Expand Up @@ -194,6 +275,18 @@ void RepairSetup::rebufferNet(const Pin* drvr_pin)
logger_->report("Inserted {} buffers.", inserted_buffer_count_);
}

// For testing.
void RepairSetup::rebufferNet(const Pin* drvr_pin, BufferedNetPtr bnet)
{
init();
resizer_->incrementalParasiticsBegin();
inserted_buffer_count_ = rebuffer(drvr_pin, bnet);
Copy link
Contributor

Choose a reason for hiding this comment

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

warning: parameter 'bnet' is passed by value and only copied once; consider moving it to avoid unnecessary copies [performance-unnecessary-value-param]

src/rsz/src/Rebuffer.cc:35:

- #include "BufferedNet.hh"
+ #include <utility>
+ 
+ #include "BufferedNet.hh"
Suggested change
inserted_buffer_count_ = rebuffer(drvr_pin, bnet);
inserted_buffer_count_ = rebuffer(drvr_pin, std::move(bnet));

// Leave the parasitics up to date.
resizer_->updateParasitics();
resizer_->incrementalParasiticsEnd();
logger_->report("Inserted {} buffers.", inserted_buffer_count_);
}

bool RepairSetup::hasTopLevelOutputPort(Net* net)
{
NetConnectedPinIterator* pin_iter = network_->connectedPinIterator(net);
Expand Down Expand Up @@ -327,7 +420,12 @@ BufferedNetSeq RepairSetup::addWireAndBuffer(const BufferedNetSeq& Z,
: req_path.dcalcAnalysisPt(sta_)->corner();
int wire_layer = bnet_wire->layer();
double layer_res, layer_cap;
bnet_wire->wireRC(corner, resizer_, layer_res, layer_cap);
if (bnet_wire->length()) {
bnet_wire->wireRC(corner, resizer_, layer_res, layer_cap);
} else {
layer_res = 0;
layer_cap = 0;
}
double wire_res = wire_length * layer_res;
double wire_cap = wire_length * layer_cap;
double wire_delay = wire_res * wire_cap;
Expand All @@ -342,9 +440,10 @@ BufferedNetSeq RepairSetup::addWireAndBuffer(const BufferedNetSeq& Z,
RSZ,
"rebuffer",
4,
"{:{}s}wire wl {} {}",
"{:{}s}wire wl {} {} {}",
"",
level,
units_->timeUnit()->asString(wire_delay, 3),
wire_length_dbu,
z->to_string(resizer_));
Z1.push_back(z);
Expand Down
5 changes: 0 additions & 5 deletions src/rsz/src/RecoverPower.hh
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,6 @@ class RecoverPower : public sta::dbStaState
static constexpr int failed_move_threshold_limit_ = 500;

sta::VertexSet bad_vertices_;

static constexpr int decreasing_slack_max_passes_ = 50;
static constexpr int rebuffer_max_fanout_ = 20;
static constexpr int split_load_min_fanout_ = 8;
static constexpr double rebuffer_buffer_penalty_ = .01;
};

} // namespace rsz
Loading
Loading