Skip to content

Commit 1532ac1

Browse files
authored
Merge pull request #10744 from The-OpenROAD-Project-staging/test-resizer6-apply
[DO NOT MERGE] Remove redundant STA calls in RepairDesign
2 parents d046747 + 4fef6fc commit 1532ac1

9 files changed

Lines changed: 498 additions & 84 deletions

src/rsz/src/RepairDesign.cc

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ void RepairDesign::performEarlySizingRound(int& repaired_net_count)
188188
2,
189189
"Annotating slew for driver {}",
190190
network_->pathName(drvr->pin()));
191-
for (auto rf : {sta::RiseFall::rise(), sta::RiseFall::fall()}) {
191+
for (auto rf : sta::RiseFall::range()) {
192192
if (!drvr->slewAnnotated(rf, min_) && !drvr->slewAnnotated(rf, max_)) {
193193
sta_->setAnnotatedSlew(drvr,
194194
resizer_->tgt_slew_corner_,
@@ -271,12 +271,12 @@ void RepairDesign::performEarlySizingRound(int& repaired_net_count)
271271
}
272272
}
273273

274-
for (auto mm : sta::MinMaxAll::all()->range()) {
275-
for (auto rf : sta::RiseFallBoth::riseFall()->range()) {
276-
if (!slew_user_annotated.contains(std::make_pair(drvr, rf->index()))) {
277-
drvr->setSlewAnnotated(
278-
false, rf, resizer_->tgt_slew_corner_->dcalcAnalysisPtIndex(mm));
279-
}
274+
for (auto rf : sta::RiseFall::range()) {
275+
if (!slew_user_annotated.contains(std::make_pair(drvr, rf->index()))) {
276+
sta_->unsetAnnotatedSlew(drvr,
277+
resizer_->tgt_slew_corner_,
278+
sta::MinMaxAll::all(),
279+
rf->asRiseFallBoth());
280280
}
281281
}
282282
}
@@ -428,12 +428,11 @@ void RepairDesign::repairDesign(
428428
for (auto vertex : annotations_to_clean_up) {
429429
for (auto corner : sta_->scenes()) {
430430
for (const sta::RiseFall* rf : sta::RiseFall::range()) {
431-
vertex->setSlewAnnotated(
432-
false, rf, corner->dcalcAnalysisPtIndex(max_));
431+
sta_->unsetAnnotatedSlew(
432+
vertex, corner, sta::MinMaxAll::max(), rf->asRiseFallBoth());
433433
}
434434
}
435435
}
436-
sta_->delaysInvalid();
437436
}
438437

439438
printProgress(print_iteration,

src/rsz/src/RepairTargetCollector.cc

Lines changed: 84 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -436,39 +436,47 @@ sta::Slack RepairTargetCollector::getPathSlackByIndex(
436436
const sta::Pin* endpoint_pin,
437437
int path_index)
438438
{
439+
// Worst path only: pure read via vertexWorstSlackPath, no findPathEnds /
440+
// ExceptionTo. All shipping callers pass 0; findPathEnds path below is k>1.
441+
if (path_index == 0) {
442+
sta::Path* path = worstSlackPathForPin(endpoint_pin);
443+
return path ? path->slack(search_) : static_cast<sta::Slack>(sta::INF);
444+
}
445+
439446
// Create ExceptionTo for this endpoint
440447
sta::PinSet* to_pins = new sta::PinSet(network_);
441448
to_pins->insert(endpoint_pin);
442-
sta::ExceptionTo* to = sdc_->makeExceptionTo(to_pins,
449+
sta::ExceptionTo* to = sta_->makeExceptionTo(to_pins,
443450
nullptr,
444451
nullptr,
445452
sta::RiseFallBoth::riseFall(),
446-
sta::RiseFallBoth::riseFall());
453+
sta::RiseFallBoth::riseFall(),
454+
sdc_);
447455

448456
// Find paths to the endpoint - request only up to path_index+1 paths
449457
sta::StringSeq group_names;
450458
int num_paths_needed = path_index + 1;
451459
sta::PathEndSeq path_ends
452-
= search_->findPathEnds(nullptr, // from
453-
nullptr, // thrus
454-
to, // to
455-
false, // unconstrained
456-
sta_->scenes(), // scene
457-
sta::MinMaxAll::all(), // min_max
458-
num_paths_needed, // group_path_count
459-
num_paths_needed, // endpoint_path_count
460-
false, // unique_pins
461-
false, // unique_edges
462-
-sta::INF, // slack_min
463-
sta::INF, // slack_max
464-
true, // sort_by_slack
465-
group_names, // group_names
466-
true,
467-
false,
468-
true,
469-
true,
470-
true,
471-
true); // checks
460+
= sta_->findPathEnds(nullptr, // from
461+
nullptr, // thrus
462+
to, // to
463+
false, // unconstrained
464+
sta_->scenes(), // scene
465+
sta::MinMaxAll::all(), // min_max
466+
num_paths_needed, // group_path_count
467+
num_paths_needed, // endpoint_path_count
468+
false, // unique_pins
469+
false, // unique_edges
470+
-sta::INF, // slack_min
471+
sta::INF, // slack_max
472+
true, // sort_by_slack
473+
group_names, // group_names
474+
true,
475+
false,
476+
true,
477+
true,
478+
true,
479+
true); // checks
472480

473481
// Return the slack of the requested path index
474482
if (std::cmp_less(path_index, path_ends.size())) {
@@ -919,6 +927,13 @@ void RepairTargetCollector::collectExpandedPathDriverPins(
919927
}
920928
}
921929

930+
sta::Path* RepairTargetCollector::worstSlackPathForPin(
931+
const sta::Pin* endpoint_pin) const
932+
{
933+
sta::Vertex* endpoint = graph_->pinLoadVertex(endpoint_pin);
934+
return endpoint ? findWorstSlackPath(endpoint) : nullptr;
935+
}
936+
922937
std::vector<Target> RepairTargetCollector::collectPathDriverTargets(
923938
sta::Path* path,
924939
const sta::Slack path_slack) const
@@ -1138,74 +1153,69 @@ set<const sta::Pin*> RepairTargetCollector::collectPinsByPathEndpoint(
11381153
// Create a set to remove duplciates
11391154
set<const sta::Pin*> viol_pins;
11401155

1141-
// This uses the old method for a single path at a time
1142-
/*if (paths_per_endpoint == 1) {
1143-
Vertex* end = graph_->pinDrvrVertex(endpoint_pin);
1144-
Path* end_path = sta_->vertexWorstSlackPath(end, max_);
1145-
PathExpanded expanded(end_path, sta_);
1146-
if (expanded.size() > 1) {
1147-
const int path_length = expanded.size();
1148-
const int start_index = expanded.startIndex();
1149-
for (int i = start_index; i < path_length; i++) {
1150-
const Path* path = expanded.path(i);
1151-
const Pin* path_pin = path->pin(sta_);
1152-
Vertex* path_vertex = path->vertex(sta_);
1153-
if (!path_vertex->isDriver(network_)
1154-
|| network_->isTopLevelPort(path_pin)) {
1155-
continue;
1156-
}
1157-
viol_pins.insert(path_pin);
1158-
debugPrint(logger_,
1159-
RSZ,
1160-
"violator_collector",
1161-
3,
1162-
" - Pin: {}",
1163-
network_->pathName(path_pin));
1164-
}
1156+
// Worst path only: pure read via vertexWorstSlackPath, no findPathEnds /
1157+
// ExceptionTo. All shipping callers pass 1; findPathEnds path below is k>1.
1158+
if (paths_per_endpoint == 1) {
1159+
sta::Path* path = worstSlackPathForPin(endpoint_pin);
1160+
if (path == nullptr || path->slack(search_) > 0.0) {
11651161
return viol_pins;
11661162
}
1167-
} else {
1168-
// FIXME later
1163+
sta::PathExpanded expanded(path, sta_);
1164+
for (size_t i = 0; i < expanded.size(); i++) {
1165+
const sta::Pin* pin = expanded.path(i)->pin(graph_);
1166+
if (!network_->direction(pin)->isOutput() || network_->isTopLevelPort(pin)
1167+
|| sta_->isClock(pin, sta_->cmdMode())) {
1168+
continue;
1169+
}
1170+
viol_pins.insert(pin);
1171+
}
1172+
// A latch-through path starts at latch Q in OpenSTA; expand the latch D
1173+
// fanin paths as well, matching the k>1 branch below.
1174+
visitLatchFaninSegments(
1175+
expanded, sta_, [&](const sta::Path*, sta::PathExpanded& d_expanded) {
1176+
collectExpandedPathDriverPins(d_expanded, viol_pins);
1177+
return false;
1178+
});
11691179
return viol_pins;
11701180
}
1171-
*/
11721181

1173-
// This code does not behave properly for single path case. At some points it
1174-
// does not match the above vertexWorstSlackPath method. It seems to be
1175-
// related to the use of the ExceptionTo object.
1182+
// The k>1 path below does not behave properly for the single path case: at
1183+
// some points it does not match the vertexWorstSlackPath fast path above. It
1184+
// seems to be related to the use of the ExceptionTo object.
11761185
// 1. Define the single endpoint for the path search.
11771186
sta::PinSet* to_pins = new sta::PinSet(network_);
11781187
to_pins->insert(endpoint_pin);
11791188
// The ExceptionTo object will be owned and deleted by the SDC.
1180-
sta::ExceptionTo* to = sdc_->makeExceptionTo(to_pins,
1189+
sta::ExceptionTo* to = sta_->makeExceptionTo(to_pins,
11811190
nullptr,
11821191
nullptr,
11831192
sta::RiseFallBoth::riseFall(),
1184-
sta::RiseFallBoth::riseFall());
1193+
sta::RiseFallBoth::riseFall(),
1194+
sdc_);
11851195

11861196
// 2. Find paths to the endpoint.
11871197
sta::StringSeq group_names;
11881198
sta::PathEndSeq path_ends
1189-
= search_->findPathEnds(nullptr, // from
1190-
nullptr, // thrus
1191-
to, // to
1192-
false, // unconstrained
1193-
sta_->scenes(), // scene
1194-
sta::MinMaxAll::all(), // min_max
1195-
paths_per_endpoint, // group_path_count
1196-
paths_per_endpoint, // endpoint_path_count
1197-
false, // unique_pins
1198-
false, // unique_edges
1199-
-sta::INF, // slack_min
1200-
sta::INF, // slack_max
1201-
true, // sort_by_slack
1202-
group_names, // group_names
1203-
true,
1204-
false,
1205-
true,
1206-
true,
1207-
true,
1208-
true); // checks
1199+
= sta_->findPathEnds(nullptr, // from
1200+
nullptr, // thrus
1201+
to, // to
1202+
false, // unconstrained
1203+
sta_->scenes(), // scene
1204+
sta::MinMaxAll::all(), // min_max
1205+
paths_per_endpoint, // group_path_count
1206+
paths_per_endpoint, // endpoint_path_count
1207+
false, // unique_pins
1208+
false, // unique_edges
1209+
-sta::INF, // slack_min
1210+
sta::INF, // slack_max
1211+
true, // sort_by_slack
1212+
group_names, // group_names
1213+
true,
1214+
false,
1215+
true,
1216+
true,
1217+
true,
1218+
true); // checks
12091219

12101220
int path_num = 1;
12111221
for (const sta::PathEnd* path_end : path_ends) {

src/rsz/src/RepairTargetCollector.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ class RepairTargetCollector
272272
// === Internal collection helpers =========================================
273273
set<const sta::Pin*> collectPinsByPathEndpoint(const sta::Pin* endpoint_pin,
274274
size_t paths_per_endpoint = 1);
275+
// Worst-slack path to an endpoint pin (pure read, nullptr if none).
276+
sta::Path* worstSlackPathForPin(const sta::Pin* endpoint_pin) const;
275277
void collectBySlack();
276278
void collectByPaths(int endPointIndex = 1,
277279
int numEndpoints = 1,

src/rsz/test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ TESTS = [
3737
"gain_buffering1",
3838
"gain_buffering1_hier",
3939
"gain_buffering2",
40+
"gain_buffering3",
4041
"gcd_resize",
4142
"insert_buffer",
4243
"insert_buffer_hier",

src/rsz/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ or_integration_tests(
2828
fanin_fanout1
2929
gain_buffering1
3030
gain_buffering2
31+
gain_buffering3
3132
gcd_resize
3233
insert_buffer
3334
insert_buffer_hier

src/rsz/test/gain_buffering3.ok

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[INFO ODB-0227] LEF file: sky130hd/sky130hd.tlef, created 13 layers, 25 vias
2+
[INFO ODB-0227] LEF file: sky130hd/sky130hd_std_cell.lef, created 437 library cells
3+
[WARNING EST-0027] no estimated parasitics. Using wire load models.
4+
Iteration | Area | Resized | Buffers | Nets repaired | Remaining
5+
---------------------------------------------------------------------
6+
0 | +1.1% | 0 | 1 | 2 | 53
7+
final | +1.1% | 0 | 1 | 2 | 0
8+
---------------------------------------------------------------------
9+
[INFO RSZ-0038] Inserted 1 buffers in 2 nets.
10+
Startpoint: f_src (rising edge-triggered flip-flop clocked by clk)
11+
Endpoint: fa0 (rising edge-triggered flip-flop clocked by clk)
12+
Path Group: clk
13+
Path Type: max
14+
15+
Fanout Delay Time Description
16+
---------------------------------------------------------------
17+
0.00 0.00 clock clk (rise edge)
18+
0.00 0.00 clock network delay (ideal)
19+
0.00 0.00 ^ f_src/CLK (sky130_fd_sc_hd__dfxtp_1)
20+
1 0.27 0.27 v f_src/Q (sky130_fd_sc_hd__dfxtp_1)
21+
2 0.05 0.32 ^ GB/Y (sky130_fd_sc_hd__inv_1)
22+
8 0.21 0.53 ^ gain1/X (sky130_fd_sc_hd__buf_1)
23+
1 0.08 0.61 v s_thru/Y (sky130_fd_sc_hd__inv_1)
24+
8 0.15 0.76 ^ GA/Y (sky130_fd_sc_hd__clkinvlp_2)
25+
1 0.05 0.81 v a0/Y (sky130_fd_sc_hd__inv_1)
26+
0.00 0.81 v fa0/D (sky130_fd_sc_hd__dfxtp_1)
27+
0.81 data arrival time
28+
29+
1.00 1.00 clock clk (rise edge)
30+
0.00 1.00 clock network delay (ideal)
31+
0.00 1.00 clock reconvergence pessimism
32+
1.00 ^ fa0/CLK (sky130_fd_sc_hd__dfxtp_1)
33+
-0.12 0.88 library setup time
34+
0.88 data required time
35+
---------------------------------------------------------------
36+
0.88 data required time
37+
-0.81 data arrival time
38+
---------------------------------------------------------------
39+
0.07 slack (MET)
40+
41+
42+
s_thru/A net: net1
43+
d7/A net: nb
44+
No differences found.

src/rsz/test/gain_buffering3.tcl

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Gain buffering sink-required ordering vs incremental STA update discipline.
2+
#
3+
# performGainBuffering() sorts the sinks of each net by required time and
4+
# buffers the least-critical prefix (bounded here by set_max_fanout 8), so
5+
# the sink at the group boundary is decided by the required times seen at
6+
# that moment. Net "nb" has nine sinks: s_thru, whose required path runs
7+
# through GA and the buffer tree inserted on net "na" earlier in the same
8+
# early-sizing pass, and d0-d7, whose paths run through private inverter
9+
# chains. The required times of s_thru and d7 are close enough that the
10+
# choice of which one joins the buffered group depends on how fresh the
11+
# delays behind them are (bounded cone refresh vs full findAllArrivals
12+
# refresh between nets).
13+
#
14+
# Expected behavior (no golden files yet -- inspect the output):
15+
#
16+
# current code (bounded incremental STA: upfront findAllArrivals seed,
17+
# per-driver findRequireds(level+1), end-of-net cone-bounded
18+
# findDelays/findArrivals -- the fdedc4be STA-discipline changes were
19+
# reverted; see rebuffer_sta_findings.md sections 9-10):
20+
# - buffered group on nb = {d0..d6, s_thru}: s_thru is buffered,
21+
# d7 stays directly on nb
22+
# - report_checks: worst slack 0.07 (endpoint fa0; the nb gain buffer
23+
# stacks onto the s_thru -> GA -> na path)
24+
#
25+
# with a per-net full refresh instead (sta_->findRequired(drvr), as in
26+
# commit fdedc4be):
27+
# - buffered group on nb = {d0..d7}: d7 is buffered,
28+
# s_thru stays directly on nb
29+
# - report_checks: worst slack 0.16 (endpoint fd7)
30+
#
31+
# The 90 ps WNS delta between the two disciplines is the QoR deviation.
32+
source "helpers.tcl"
33+
read_lef sky130hd/sky130hd.tlef
34+
read_lef sky130hd/sky130hd_std_cell.lef
35+
read_liberty sky130hd/sky130hd_tt.lib
36+
37+
read_verilog gain_buffering3.v
38+
link_design top
39+
40+
create_clock -name clk -period 1.0 [get_ports clk]
41+
42+
set_dont_use {sky130_fd_sc_hd__probe_*
43+
sky130_fd_sc_hd__lpflow_*
44+
sky130_fd_sc_hd__clkdly*
45+
sky130_fd_sc_hd__dlygate*
46+
sky130_fd_sc_hd__dlymetal*
47+
sky130_fd_sc_hd__clkbuf_*
48+
sky130_fd_sc_hd__bufbuf_*
49+
sky130_fd_sc_hd__buf_2
50+
sky130_fd_sc_hd__buf_4
51+
sky130_fd_sc_hd__buf_6
52+
sky130_fd_sc_hd__buf_8
53+
sky130_fd_sc_hd__buf_12
54+
sky130_fd_sc_hd__buf_16
55+
sky130_fd_sc_hd__inv_2
56+
sky130_fd_sc_hd__inv_4
57+
sky130_fd_sc_hd__inv_6
58+
sky130_fd_sc_hd__inv_8
59+
sky130_fd_sc_hd__inv_12
60+
sky130_fd_sc_hd__inv_16}
61+
62+
set_max_fanout 8 [current_design]
63+
64+
repair_design -pre_placement
65+
report_checks -fields {fanout}
66+
67+
# Show which sink ended up behind the gain buffer (d7 with current code,
68+
# s_thru with the legacy bounded-refresh code).
69+
puts "s_thru/A net: [get_full_name [get_nets -of_objects [get_pins s_thru/A]]]"
70+
puts "d7/A net: [get_full_name [get_nets -of_objects [get_pins d7/A]]]"
71+
72+
set test_name "gain_buffering3"
73+
set verilog_file [make_result_file "${test_name}.v"]
74+
write_verilog $verilog_file
75+
diff_files ${test_name}.vok $verilog_file

0 commit comments

Comments
 (0)