Skip to content

Commit ce5b0c5

Browse files
committed
gpl: preserve user clock latency in virtual CTS
Signed-off-by: Eder Monteiro <emrmonteiro@precisioninno.com>
1 parent 12ca866 commit ce5b0c5

6 files changed

Lines changed: 219 additions & 0 deletions

File tree

src/gpl/src/clockBase.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ void ClockBase::buildVirtualTreeForClock(const sta::Clock* clk)
229229
sta::Sdc* sdc = sta_->cmdSdc();
230230

231231
for (int i = 0; i < n; ++i) {
232+
// Preserve user-specified clock latency; do not overwrite or delete it.
233+
if (hasUserClockLatency(clk, sinks[i].pin)) {
234+
continue;
235+
}
232236
const float delay = static_cast<float>(tree_dist[i] * scale);
233237
// Use setClockLatency (network latency) rather than setClockInsertion
234238
// (source latency). During global placement the clock is ideal
@@ -299,4 +303,22 @@ bool ClockBase::getPinLocation(const sta::Pin* pin, int& x, int& y) const
299303
return false;
300304
}
301305

306+
bool ClockBase::hasUserClockLatency(const sta::Clock* clk,
307+
const sta::Pin* pin) const
308+
{
309+
sta::Sdc* sdc = sta_->cmdSdc();
310+
for (const sta::RiseFall* rf :
311+
{sta::RiseFall::rise(), sta::RiseFall::fall()}) {
312+
for (const sta::MinMax* mm : {sta::MinMax::min(), sta::MinMax::max()}) {
313+
float latency = 0.0f;
314+
bool exists = false;
315+
sdc->clockLatency(clk, pin, rf, mm, latency, exists);
316+
if (exists) {
317+
return true;
318+
}
319+
}
320+
}
321+
return false;
322+
}
323+
302324
} // namespace gpl

src/gpl/src/clockBase.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class ClockBase
6969
// Get the instance origin (in DBU) for a given STA pin.
7070
// Returns false if the pin has no placement location.
7171
bool getPinLocation(const sta::Pin* pin, int& x, int& y) const;
72+
73+
// True if the user already set a clock latency on this clk/pin.
74+
bool hasUserClockLatency(const sta::Clock* clk, const sta::Pin* pin) const;
7275
};
7376

7477
} // namespace gpl

src/gpl/test/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ TESTS = [
3333
"simple01-vcts",
3434
"simple01-vcts-clamp",
3535
"simple01-vcts-noclk",
36+
"simple01-vcts-userlat",
3637
"simple02",
3738
"simple02-rd",
3839
"simple03",

src/gpl/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ or_integration_tests(
2929
simple01-vcts
3030
simple01-vcts-clamp
3131
simple01-vcts-noclk
32+
simple01-vcts-userlat
3233
simple02
3334
simple02-rd
3435
simple03
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
[INFO ODB-0227] LEF file: ./nangate45.lef, created 22 layers, 27 vias, 134 library cells
2+
[INFO ODB-0128] Design: gcd
3+
[INFO ODB-0130] Created 54 pins.
4+
[INFO ODB-0131] Created 286 components and 1624 component-terminals.
5+
[INFO ODB-0133] Created 356 nets and 1052 connections.
6+
[INFO GPL-0001] ---- Initialize GPL Main Data Structures
7+
[INFO GPL-0002] DBU: 2000
8+
[INFO GPL-0003] SiteSize: ( 0.190 1.400 ) um
9+
[INFO GPL-0004] CoreBBox: ( 0.000 0.000 ) ( 30.970 30.800 ) um
10+
[INFO GPL-0036] Movable instances area: 553.280 um^2
11+
[INFO GPL-0037] Total instances area: 553.280 um^2
12+
[INFO GPL-0035] Pin density area adjust: 47.712 um^2
13+
[INFO GPL-0032] ---- Initialize Region: Top-level
14+
[INFO GPL-0006] Number of instances: 286
15+
[INFO GPL-0007] Movable instances: 286
16+
[INFO GPL-0008] Fixed instances: 0
17+
[INFO GPL-0009] Dummy instances: 0
18+
[INFO GPL-0010] Number of nets: 356
19+
[INFO GPL-0011] Number of pins: 1106
20+
[INFO GPL-0012] Die BBox: ( 0.000 0.000 ) ( 30.970 30.800 ) um
21+
[INFO GPL-0013] Core BBox: ( 0.000 0.000 ) ( 30.970 30.800 ) um
22+
[INFO GPL-0016] Core area: 953.876 um^2
23+
[INFO GPL-0014] Region name: top-level.
24+
[INFO GPL-0015] Region area: 953.876 um^2
25+
[INFO GPL-0017] Fixed instances area: 0.000 um^2
26+
[INFO GPL-0018] Movable instances area: 600.992 um^2
27+
[INFO GPL-0019] Utilization: 63.005 %
28+
[INFO GPL-0020] Standard cells area: 600.992 um^2
29+
[INFO GPL-0021] Large instances area: 0.000 um^2
30+
[INFO GPL-0005] ---- Execute Conjugate Gradient Initial Placement.
31+
[INFO GPL-0051] Source of initial instance position counters:
32+
Odb location = 0 Core center = 286 Region center = 0
33+
[InitialPlace] Iter: 1 conjugate gradient residual: 0.00000011 HPWL: 5614340
34+
[InitialPlace] Iter: 2 conjugate gradient residual: 0.00000011 HPWL: 4998803
35+
[InitialPlace] Iter: 3 conjugate gradient residual: 0.00000010 HPWL: 4991131
36+
[InitialPlace] Iter: 4 conjugate gradient residual: 0.00000010 HPWL: 4997865
37+
[InitialPlace] Iter: 5 conjugate gradient residual: 0.00000009 HPWL: 5002847
38+
[INFO GPL-0033] ---- Initialize Nesterov Region: Top-level
39+
[INFO GPL-0023] Placement target density: 0.7000
40+
[INFO GPL-0024] Movable insts average area: 2.101 um^2
41+
[INFO GPL-0025] Ideal bin area: 3.002 um^2
42+
[INFO GPL-0026] Ideal bin count: 317
43+
[INFO GPL-0027] Total bin area: 953.876 um^2
44+
[INFO GPL-0028] Bin count (X, Y): 16 , 16
45+
[INFO GPL-0029] Bin size (W * H): 1.936 * 1.925 um
46+
[INFO GPL-0030] Number of bins: 256
47+
[INFO GPL-0084] ---- Execute Nesterov Global Placement.
48+
[INFO GPL-0031] HPWL: Half-Perimeter Wirelength
49+
Iteration | Overflow | HPWL (um) | HPWL(%) | Penalty | Group
50+
---------------------------------------------------------------
51+
0 | 0.8415 | 1.823749e+03 | +0.00% | 6.86e-14 |
52+
10 | 0.7168 | 2.047757e+03 | +12.28% | 1.12e-13 |
53+
20 | 0.7223 | 2.039114e+03 | -0.42% | 1.82e-13 |
54+
30 | 0.7242 | 2.039052e+03 | -0.00% | 2.96e-13 |
55+
40 | 0.7231 | 2.039403e+03 | +0.02% | 4.83e-13 |
56+
50 | 0.7231 | 2.039349e+03 | -0.00% | 7.86e-13 |
57+
60 | 0.7231 | 2.039443e+03 | +0.00% | 1.28e-12 |
58+
70 | 0.7232 | 2.039536e+03 | +0.00% | 2.09e-12 |
59+
80 | 0.7229 | 2.039703e+03 | +0.01% | 3.40e-12 |
60+
90 | 0.7226 | 2.040133e+03 | +0.02% | 5.54e-12 |
61+
100 | 0.7222 | 2.040652e+03 | +0.03% | 9.02e-12 |
62+
110 | 0.7216 | 2.041562e+03 | +0.04% | 1.47e-11 |
63+
120 | 0.7205 | 2.042977e+03 | +0.07% | 2.39e-11 |
64+
130 | 0.7187 | 2.045267e+03 | +0.11% | 3.90e-11 |
65+
140 | 0.7159 | 2.048748e+03 | +0.17% | 6.35e-11 |
66+
150 | 0.7115 | 2.054013e+03 | +0.26% | 1.03e-10 |
67+
160 | 0.7043 | 2.062230e+03 | +0.40% | 1.68e-10 |
68+
170 | 0.6948 | 2.073365e+03 | +0.54% | 2.74e-10 |
69+
180 | 0.6842 | 2.089633e+03 | +0.78% | 4.47e-10 |
70+
190 | 0.6686 | 2.111814e+03 | +1.06% | 7.28e-10 |
71+
200 | 0.6478 | 2.138892e+03 | +1.28% | 1.19e-09 |
72+
[INFO GPL-0162] Virtual CTS: set 33 virtual clock insertion delays.
73+
[INFO GPL-0164] Virtual CTS iteration 1, overflow: 0.634.
74+
[INFO GPL-0100] Timing-driven iteration 1/2, virtual: false.
75+
[INFO GPL-0101] Iter: 206, overflow: 0.634, keep resizer changes at: 1, HPWL: 4312728
76+
Iteration | Area | Resized | Buffers | Nets repaired | Remaining
77+
---------------------------------------------------------------------
78+
0 | +0.0% | 0 | 0 | 0 | 356
79+
final | +0.0% | 0 | 0 | 0 | 0
80+
---------------------------------------------------------------------
81+
Iter | Area | Removed | Inserted | Pins
82+
| | Buffers | Buffers | Remaining
83+
-------------------------------------------------------
84+
0 | +0.0% | 0 | 0 | 320
85+
32 | +0.0% | 0 | 0 | 288
86+
64 | +0.0% | 0 | 0 | 256
87+
96 | +0.0% | 0 | 0 | 224
88+
128 | +0.0% | 0 | 0 | 192
89+
160 | +0.0% | 0 | 0 | 160
90+
192 | +0.0% | 0 | 0 | 128
91+
224 | +0.0% | 0 | 0 | 96
92+
256 | +0.0% | 0 | 0 | 64
93+
288 | +0.2% | 0 | 1 | 32
94+
final | +0.9% | 0 | 5 | 0
95+
-------------------------------------------------------
96+
[INFO GPL-0106] Timing-driven: worst slack 1.0516223e-09
97+
[INFO GPL-0107] Timing-driven: repair_design delta area: 5.054 um^2 (+0.84%)
98+
[INFO GPL-0108] Timing-driven: repair_design, gpl delta gcells: 5 (+1.75%)
99+
[INFO GPL-0109] Timing-driven: repair_design, gcells created: 5, deleted: 0
100+
[INFO GPL-0110] Timing-driven: new target density: 0.70529836
101+
Iteration | Overflow | HPWL (um) | HPWL(%) | Penalty | Group
102+
---------------------------------------------------------------
103+
210 | 0.7002 | 2.200066e+03 | +2.86% | 1.93e-09 |
104+
220 | 0.6337 | 2.251557e+03 | +2.34% | 3.15e-09 |
105+
230 | 0.5973 | 2.271468e+03 | +0.88% | 5.13e-09 |
106+
240 | 0.5463 | 2.339269e+03 | +2.98% | 8.35e-09 |
107+
250 | 0.4911 | 2.367852e+03 | +1.22% | 1.36e-08 |
108+
260 | 0.4318 | 2.407081e+03 | +1.66% | 2.22e-08 |
109+
270 | 0.3718 | 2.428369e+03 | +0.88% | 3.61e-08 |
110+
280 | 0.3194 | 2.442180e+03 | +0.57% | 5.59e-08 |
111+
290 | 0.2751 | 2.451771e+03 | +0.39% | 8.23e-08 |
112+
300 | 0.2390 | 2.478613e+03 | +1.09% | 1.21e-07 |
113+
310 | 0.2142 | 2.507873e+03 | +1.18% | 1.79e-07 |
114+
[INFO GPL-0162] Virtual CTS: set 33 virtual clock insertion delays.
115+
[INFO GPL-0164] Virtual CTS iteration 2, overflow: 0.194.
116+
[INFO GPL-0100] Timing-driven iteration 2/2, virtual: false.
117+
[INFO GPL-0101] Iter: 320, overflow: 0.194, keep resizer changes at: 1, HPWL: 5057951
118+
Iteration | Area | Resized | Buffers | Nets repaired | Remaining
119+
---------------------------------------------------------------------
120+
0 | +0.0% | 0 | 0 | 0 | 361
121+
final | +0.0% | 0 | 0 | 0 | 0
122+
---------------------------------------------------------------------
123+
Iter | Area | Removed | Inserted | Pins
124+
| | Buffers | Buffers | Remaining
125+
-------------------------------------------------------
126+
0 | +0.0% | 0 | 0 | 320
127+
32 | +0.0% | 0 | 0 | 288
128+
64 | +0.0% | 0 | 0 | 256
129+
96 | +0.0% | 0 | 0 | 224
130+
128 | +0.0% | 0 | 0 | 192
131+
160 | +0.0% | 0 | 0 | 160
132+
192 | +0.0% | 0 | 0 | 128
133+
224 | +0.0% | 0 | 0 | 96
134+
256 | +0.1% | 0 | 1 | 64
135+
288 | +0.1% | 1 | 2 | 32
136+
final | +0.1% | 5 | 6 | 0
137+
-------------------------------------------------------
138+
[INFO GPL-0106] Timing-driven: worst slack 1.0292465e-09
139+
[INFO GPL-0107] Timing-driven: repair_design delta area: 0.798 um^2 (+0.13%)
140+
[INFO GPL-0108] Timing-driven: repair_design, gpl delta gcells: 1 (+0.34%)
141+
[INFO GPL-0109] Timing-driven: repair_design, gcells created: 6, deleted: 5
142+
[INFO GPL-0110] Timing-driven: new target density: 0.706135
143+
Iteration | Overflow | HPWL (um) | HPWL(%) | Penalty | Group
144+
---------------------------------------------------------------
145+
320 | 0.1926 | 2.568155e+03 | +2.40% | 2.63e-07 |
146+
330 | 0.1731 | 2.574847e+03 | +0.26% | 3.88e-07 |
147+
340 | 0.1410 | 2.584419e+03 | +0.37% | 5.71e-07 |
148+
350 | 0.1286 | 2.604276e+03 | +0.77% | 8.41e-07 |
149+
360 | 0.1037 | 2.617003e+03 | +0.49% | 1.24e-06 |
150+
362 | 0.0986 | 2.619848e+03 | | 1.39e-06 |
151+
---------------------------------------------------------------
152+
[INFO GPL-1001] Global placement finished at iteration 362
153+
[INFO GPL-1002] Placed Cell Area 606.8444
154+
[INFO GPL-1003] Available Free Area 953.8760
155+
[INFO GPL-1004] Minimum Feasible Density 0.6400 (cell_area / free_area)
156+
[INFO GPL-1006] Suggested Target Densities:
157+
[INFO GPL-1007] - For 90% usage of free space: 0.7069
158+
[INFO GPL-1008] - For 80% usage of free space: 0.7952
159+
[INFO GPL-1011] Original area (um^2): 600.99
160+
[INFO GPL-1013] Total timing-driven delta area: 5.85 (+0.97%)
161+
[INFO GPL-1014] Final placement area: 606.84 (+0.97%)
162+
worst slack max 1.02
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
source helpers.tcl
2+
read_liberty ./library/nangate45/NangateOpenCellLibrary_typical.lib
3+
4+
read_lef ./nangate45.lef
5+
read_def ./simple01-td.def
6+
7+
create_clock -name core_clock -period 2 clk
8+
9+
set_wire_rc -signal -layer metal3
10+
set_wire_rc -clock -layer metal5
11+
12+
# Regression for virtual CTS clobbering user clock-latency constraints.
13+
#
14+
# Virtual CTS temporarily sets a per-pin network latency on every register
15+
# clock sink, then removes it before final timing. The removal deletes the
16+
# entry entirely (STA has no restore), so if virtual CTS were allowed to
17+
# write over a pin the user already constrained with set_clock_latency, that
18+
# user constraint would be silently deleted when virtual CTS cleans up.
19+
#
20+
# Here we constrain exactly one of the 34 register clock pins. virtual CTS
21+
# must leave that pin alone and only annotate the other 33. The check is the
22+
# GPL-0162 count: it reports "set 33 ..." (not 34). A regression that resumes
23+
# overwriting user-constrained pins would report 34 and delete the user's
24+
# 0.5ns latency on _569_/CK.
25+
set_clock_latency 0.5 [get_pins _569_/CK]
26+
27+
global_placement -timing_driven -virtual_cts
28+
29+
estimate_parasitics -placement
30+
report_worst_slack

0 commit comments

Comments
 (0)