Skip to content

Commit 425338b

Browse files
committed
prepare correlateRC.py for regression model based on segments
Signed-off-by: Arthur Koucher <arthurkoucher@precisioninno.com>
1 parent a7b0ff2 commit 425338b

File tree

1 file changed

+129
-112
lines changed

1 file changed

+129
-112
lines changed

flow/util/correlateRC.py

Lines changed: 129 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env python3
22

3-
# Read grt/rcx capacitance/wire length files for multiple designs and
4-
# use linear regression to fit layer capacitances to rcx net capacitances.
5-
# Use ORFS 'make write_net_rc' to write cap files.
3+
# Script for generating and comparing per-layer parasitics values.
4+
# These values are used by set_layer_rc and will be the base
5+
# values for the parasitics estimations across the flow.
66

77
import os
88
from sys import exit, stderr
@@ -46,6 +46,13 @@ def parse_args():
4646
default=False,
4747
help="Plot grt/rcx resistance differences",
4848
)
49+
parser.add_argument(
50+
"--mode",
51+
required=False,
52+
choices=["net", "segment"],
53+
default="net",
54+
help="Input mode: 'net' for net-level RC (make write_net_rc), 'segment' for segment-level RC (make write_segment_rc)",
55+
)
4956
parser.add_argument(
5057
"rc_file", nargs="+", help="rc csv file written by make compare_rc"
5158
)
@@ -120,43 +127,47 @@ def makeDict():
120127
continue
121128

122129
tokens = line.strip().split(",")
123-
netName = tokens[0]
124-
125-
data[design][netName] = {
126-
"type": tokens[1],
127-
"grt_res": float(tokens[2]),
128-
"grt_cap": float(tokens[3]),
129-
"rcx_res": float(tokens[4]),
130-
"rcx_cap": float(tokens[5]),
131-
}
132-
133-
layer_lengths = [float(tok) for tok in tokens[6:]]
134-
for i, length in enumerate(layer_lengths):
135-
if length > 0:
136-
active_layers.add(i)
137-
138-
data[design][netName]["layer_lengths"] = layer_lengths
139-
data[design][netName]["routable_layer_lengths"] = [
140-
length
141-
for i, length in enumerate(layer_lengths)
142-
# ignore non-routable layers
143-
if stack[i][1]
144-
]
145-
data[design][netName]["wire_length"] = sum(
146-
length
147-
for i, length in enumerate(layer_lengths)
148-
# ignore non-routable layers
149-
if stack[i][1]
150-
)
151-
data[design][netName]["grt_via_res"] = sum(
152-
(length * stack[i][2])
153-
for i, length in enumerate(layer_lengths)
154-
if not stack[i][1]
155-
)
130+
131+
if args.mode == "segment":
132+
pass
133+
else:
134+
netName = tokens[0]
135+
136+
data[design][netName] = {
137+
"type": tokens[1],
138+
"grt_res": float(tokens[2]),
139+
"grt_cap": float(tokens[3]),
140+
"rcx_res": float(tokens[4]),
141+
"rcx_cap": float(tokens[5]),
142+
}
143+
144+
layer_lengths = [float(tok) for tok in tokens[6:]]
145+
for i, length in enumerate(layer_lengths):
146+
if length > 0:
147+
active_layers.add(i)
148+
149+
data[design][netName]["layer_lengths"] = layer_lengths
150+
data[design][netName]["routable_layer_lengths"] = [
151+
length
152+
for i, length in enumerate(layer_lengths)
153+
# ignore non-routable layers
154+
if stack[i][1]
155+
]
156+
data[design][netName]["wire_length"] = sum(
157+
length
158+
for i, length in enumerate(layer_lengths)
159+
# ignore non-routable layers
160+
if stack[i][1]
161+
)
162+
data[design][netName]["grt_via_res"] = sum(
163+
(length * stack[i][2])
164+
for i, length in enumerate(layer_lengths)
165+
if not stack[i][1]
166+
)
156167

157168
################################################################
158169

159-
if args.plot_cap:
170+
if args.mode == "net" and args.plot_cap:
160171
# Compare the GRT cap estimate vs. OpenRCX SPEF cap
161172

162173
diff_x = []
@@ -198,7 +209,7 @@ def makeDict():
198209

199210
################################################################
200211

201-
if args.plot_res:
212+
if args.mode == "net" and args.plot_res:
202213
# Compare the GRT res estimate vs. OpenRCX SPEF res
203214

204215
diff_x = []
@@ -241,96 +252,102 @@ def makeDict():
241252

242253
################################################################
243254

244-
# Use linear regression to find updated layer resistances.
245-
246-
x = []
247-
y = []
248-
for design in data:
249-
for net in data[design]:
250-
rcx_res = data[design][net]["rcx_res"]
251-
if rcx_res > 0:
252-
x.append(data[design][net]["routable_layer_lengths"])
253-
y.append(rcx_res - data[design][net]["grt_via_res"])
254-
255-
x = np.array(x)
256-
y = np.array(y)
257-
258-
res_model = LinearRegression(fit_intercept=False).fit(x, y)
259-
r_sq = res_model.score(x, y)
260-
print("# Resistance coefficient of determination: {:.4f}".format(r_sq))
261-
262-
################################################################
263-
264-
# Use linear regression to find updated layer capacitances.
265-
266-
x = []
267-
y = []
268-
for design in data:
269-
for net in data[design]:
270-
x.append(data[design][net]["routable_layer_lengths"])
271-
y.append(data[design][net]["rcx_cap"])
272-
273-
x = np.array(x)
274-
y = np.array(y)
275-
276-
cap_model = LinearRegression(fit_intercept=False).fit(x, y)
277-
r_sq = cap_model.score(x, y)
278-
print("# Capacitance coefficient of determination: {:.4f}".format(r_sq))
279-
print("# Updated layer resistance {}/um capacitance {}/um".format(res_unit, cap_unit))
280-
281-
routable_layers = [layer for layer in stack if layer[1]]
282-
for i, layer in enumerate(routable_layers):
283-
res_coeff = res_model.coef_[i]
284-
cap_coeff = cap_model.coef_[i]
285-
if res_coeff != 0.0 or cap_coeff != 0.0:
286-
print(
287-
"set_layer_rc -layer {} -resistance {:.5E} -capacitance {:.5E}".format(
288-
layer[0], res_coeff / res_scale, cap_coeff / cap_scale
289-
)
290-
)
291-
292-
################################################################
293-
255+
if args.mode == "net":
256+
# Use linear regression to find updated layer resistances.
294257

295-
def generic_rc_fit(type_sieve):
296258
x = []
297259
y = []
298260
for design in data:
299261
for net in data[design]:
300-
net_type = data[design][net]["type"]
301-
wire_res = data[design][net]["rcx_res"]
302-
wire_length = data[design][net]["wire_length"]
303-
if net_type in type_sieve and wire_res != 0.0:
304-
x.append([wire_length])
305-
y.append(wire_res)
262+
rcx_res = data[design][net]["rcx_res"]
263+
if rcx_res > 0:
264+
x.append(data[design][net]["routable_layer_lengths"])
265+
y.append(rcx_res - data[design][net]["grt_via_res"])
266+
306267
x = np.array(x)
307268
y = np.array(y)
308-
wire_res_model = LinearRegression(fit_intercept=False).fit(x, y)
309-
wire_res = wire_res_model.coef_[0]
269+
270+
res_model = LinearRegression(fit_intercept=False).fit(x, y)
271+
r_sq = res_model.score(x, y)
272+
print("# Resistance coefficient of determination: {:.4f}".format(r_sq))
273+
274+
################################################################
275+
276+
# Use linear regression to find updated layer capacitances.
310277

311278
x = []
312279
y = []
313280
for design in data:
314281
for net in data[design]:
315-
net_type = data[design][net]["type"]
316-
if net_type in type_sieve:
317-
wire_length = data[design][net]["wire_length"]
318-
wire_cap = data[design][net]["rcx_cap"]
319-
x.append([wire_length])
320-
y.append(wire_cap)
282+
x.append(data[design][net]["routable_layer_lengths"])
283+
y.append(data[design][net]["rcx_cap"])
284+
321285
x = np.array(x)
322286
y = np.array(y)
323-
wire_cap_model = LinearRegression(fit_intercept=False).fit(x, y)
324-
wire_cap = wire_cap_model.coef_[0]
325287

326-
return "-resistance {:.5E} -capacitance {:.5E}".format(
327-
wire_res / res_scale, wire_cap / cap_scale
288+
cap_model = LinearRegression(fit_intercept=False).fit(x, y)
289+
r_sq = cap_model.score(x, y)
290+
print("# Capacitance coefficient of determination: {:.4f}".format(r_sq))
291+
print(
292+
"# Updated layer resistance {}/um capacitance {}/um".format(res_unit, cap_unit)
328293
)
329294

295+
routable_layers = [layer for layer in stack if layer[1]]
296+
for i, layer in enumerate(routable_layers):
297+
res_coeff = res_model.coef_[i]
298+
cap_coeff = cap_model.coef_[i]
299+
if res_coeff != 0.0 or cap_coeff != 0.0:
300+
print(
301+
"set_layer_rc -layer {} -resistance {:.5E} -capacitance {:.5E}".format(
302+
layer[0], res_coeff / res_scale, cap_coeff / cap_scale
303+
)
304+
)
305+
306+
################################################################
307+
308+
def generic_rc_fit(type_sieve):
309+
x = []
310+
y = []
311+
for design in data:
312+
for net in data[design]:
313+
net_type = data[design][net]["type"]
314+
wire_res = data[design][net]["rcx_res"]
315+
wire_length = data[design][net]["wire_length"]
316+
if net_type in type_sieve and wire_res != 0.0:
317+
x.append([wire_length])
318+
y.append(wire_res)
319+
x = np.array(x)
320+
y = np.array(y)
321+
wire_res_model = LinearRegression(fit_intercept=False).fit(x, y)
322+
wire_res = wire_res_model.coef_[0]
323+
324+
x = []
325+
y = []
326+
for design in data:
327+
for net in data[design]:
328+
net_type = data[design][net]["type"]
329+
if net_type in type_sieve:
330+
wire_length = data[design][net]["wire_length"]
331+
wire_cap = data[design][net]["rcx_cap"]
332+
x.append([wire_length])
333+
y.append(wire_cap)
334+
x = np.array(x)
335+
y = np.array(y)
336+
wire_cap_model = LinearRegression(fit_intercept=False).fit(x, y)
337+
wire_cap = wire_cap_model.coef_[0]
338+
339+
return "-resistance {:.5E} -capacitance {:.5E}".format(
340+
wire_res / res_scale, wire_cap / cap_scale
341+
)
342+
343+
print("# Combined fit:")
344+
print("set_wire_rc " + generic_rc_fit(["signal", "clock"]))
330345

331-
print("# Combined fit:")
332-
print("set_wire_rc " + generic_rc_fit(["signal", "clock"]))
346+
print("# Split signal/clock fit:")
347+
print("set_wire_rc -signal " + generic_rc_fit(["signal"]))
348+
print("set_wire_rc -clock " + generic_rc_fit(["clock"]))
349+
350+
################################################################
333351

334-
print("# Split signal/clock fit:")
335-
print("set_wire_rc -signal " + generic_rc_fit(["signal"]))
336-
print("set_wire_rc -clock " + generic_rc_fit(["clock"]))
352+
if args.mode == "segment":
353+
pass

0 commit comments

Comments
 (0)