Skip to content

Commit b6ed935

Browse files
committed
util: Take via resistances for fixed in RC correlation
OR has single per-layer via resistance setting (`set_layer_rc -via`) which applies to both estimation and final parasitics extraction. Given this the via resistances must enter the RC fit as constants, not variables. Signed-off-by: Martin Povišer <[email protected]>
1 parent acc382a commit b6ed935

File tree

2 files changed

+48
-32
lines changed

2 files changed

+48
-32
lines changed

flow/util/correlateRC.py

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from sklearn.linear_model import LinearRegression
1717
import matplotlib.pyplot as plt
1818

19+
LAYER_HEADER_RE = re.compile("^([^\\(]+)\\(([^\\)]+)\\)$")
20+
1921
# Parse and validate arguments
2022
# =============================================================================
2123

@@ -101,9 +103,19 @@ def makeDict():
101103
exit(1)
102104
elif stack_line is None:
103105
for layer in line.removeprefix("# stack: ").strip().split(" "):
104-
name = layer.removesuffix("(routing)")
105-
is_routing = layer.endswith("(routing)")
106-
stack.append((name, is_routing))
106+
name = layer
107+
is_routing = False
108+
via_resist = 0.0
109+
if layer.endswith(")"):
110+
# layer name has extra data
111+
match = LAYER_HEADER_RE.match(layer)
112+
assert match
113+
name = match.group(1)
114+
if match.group(2) == "routing":
115+
is_routing = True
116+
else:
117+
via_resist = float(match.group(2))
118+
stack.append((name, is_routing, via_resist))
107119
continue
108120

109121
tokens = line.strip().split(",")
@@ -125,12 +137,23 @@ def makeDict():
125137
active_layers.add(i)
126138

127139
data[design][netName]["layer_lengths"] = layer_lengths
140+
data[design][netName]["routable_layer_lengths"] = [
141+
length
142+
for i, length in enumerate(layer_lengths)
143+
# ignore non-routable layers
144+
if stack[i][1]
145+
]
128146
data[design][netName]["wire_length"] = sum(
129147
length
130148
for i, length in enumerate(layer_lengths)
131-
# ignore contribution from via layers
149+
# ignore non-routable layers
132150
if stack[i][1]
133151
)
152+
data[design][netName]["grt_via_res"] = sum(
153+
(length * stack[i][2])
154+
for i, length in enumerate(layer_lengths)
155+
if not stack[i][1]
156+
)
134157

135158
################################################################
136159

@@ -227,15 +250,15 @@ def makeDict():
227250
for net in data[design]:
228251
rcx_res = data[design][net]["rcx_res"]
229252
if rcx_res > 0:
230-
x.append(data[design][net]["layer_lengths"])
231-
y.append(rcx_res)
253+
x.append(data[design][net]["routable_layer_lengths"])
254+
y.append(rcx_res - data[design][net]["grt_via_res"])
232255

233256
x = np.array(x)
234257
y = np.array(y)
235258

236259
res_model = LinearRegression(fit_intercept=False).fit(x, y)
237260
r_sq = res_model.score(x, y)
238-
print("Resistance coefficient of determination: {:.4f}".format(r_sq))
261+
print("# Resistance coefficient of determination: {:.4f}".format(r_sq))
239262

240263
################################################################
241264

@@ -245,39 +268,25 @@ def makeDict():
245268
y = []
246269
for design in data:
247270
for net in data[design]:
248-
lengths = data[design][net]["layer_lengths"]
249-
x.append([length for length, layer in zip(lengths, stack) if layer[1]])
271+
x.append(data[design][net]["routable_layer_lengths"])
250272
y.append(data[design][net]["rcx_cap"])
251273

252274
x = np.array(x)
253275
y = np.array(y)
254276

255277
cap_model = LinearRegression(fit_intercept=False).fit(x, y)
256278
r_sq = cap_model.score(x, y)
257-
print("Capacitance coefficient of determination: {:.4f}".format(r_sq))
258-
259-
print("Updated layer resistance {}/um capacitance {}/um".format(res_unit, cap_unit))
260-
routable_layer_no = 0
261-
for i, layer, res_coeff in zip(range(len(stack)), stack, res_model.coef_):
262-
if not layer[1] or i not in active_layers:
263-
# skip non-routable and non-active layers
264-
continue
265-
cap_coeff = cap_model.coef_[routable_layer_no]
266-
print(
267-
"set_layer_rc -layer {} -resistance {:.5E} -capacitance {:.5E}".format(
268-
layer[0], res_coeff / res_scale, cap_coeff / cap_scale
269-
)
270-
)
271-
routable_layer_no += 1
272-
273-
for i, layer, res_coeff in zip(range(len(stack)), stack, res_model.coef_):
274-
if layer[1] or i not in active_layers:
275-
# skip routable and non-active layers
276-
continue
277-
if res_coeff != 0.0:
279+
print("# Capacitance coefficient of determination: {:.4f}".format(r_sq))
280+
print("# Updated layer resistance {}/um capacitance {}/um".format(res_unit, cap_unit))
281+
282+
routable_layers = [layer for layer in stack if layer[1]]
283+
for i, layer in enumerate(routable_layers):
284+
res_coeff = res_model.coef_[i]
285+
cap_coeff = cap_model.coef_[i]
286+
if res_coeff != 0.0 or cap_coeff != 0.0:
278287
print(
279-
"set_layer_rc -via {} -resistance {:.5E}".format(
280-
layer[0], res_coeff / res_scale
288+
"set_layer_rc -layer {} -resistance {:.5E} -capacitance {:.5E}".format(
289+
layer[0], res_coeff / res_scale, cap_coeff / cap_scale
281290
)
282291
)
283292

flow/util/write_net_rc.tcl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,16 @@ proc write_rc_csv { filename } {
4444
foreach layer [[ord::get_db_tech] getLayers] {
4545
set routing [expr [$layer getRoutingLevel] != 0]
4646
set is_routing([$layer getNumber]) $routing
47+
set is_routing([$layer getNumber]) $routing
4748
puts -nonewline $stream " [$layer getName]"
4849
if $routing {
4950
puts -nonewline $stream "(routing)"
51+
} else {
52+
# insert via resistance information
53+
set via_resist [$layer getResistance]
54+
if { $via_resist != 0.0 } {
55+
puts -nonewline $stream "([format %.4e $via_resist])"
56+
}
5057
}
5158
}
5259
puts $stream ""

0 commit comments

Comments
 (0)