1616from sklearn .linear_model import LinearRegression
1717import matplotlib .pyplot as plt
1818
19+ LAYER_HEADER_RE = re .compile ("^([^\\ (]+)\\ (([^\\ )]+)\\ )$" )
20+
1921# Parse and validate arguments
2022# =============================================================================
2123
22-
2324def parse_args ():
2425 parser = argparse .ArgumentParser (
2526 description = "Determines layer capacitance and resistance values for OpenROAD flow designs"
@@ -101,9 +102,19 @@ def makeDict():
101102 exit (1 )
102103 elif stack_line is None :
103104 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 ))
105+ name = layer
106+ is_routing = False
107+ via_resist = 0.0
108+ if layer .endswith (")" ):
109+ # layer name has extra data
110+ match = LAYER_HEADER_RE .match (layer )
111+ assert match
112+ name = match .group (1 )
113+ if match .group (2 ) == "routing" :
114+ is_routing = True
115+ else :
116+ via_resist = float (match .group (2 ))
117+ stack .append ((name , is_routing , via_resist ))
107118 continue
108119
109120 tokens = line .strip ().split ("," )
@@ -125,12 +136,23 @@ def makeDict():
125136 active_layers .add (i )
126137
127138 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+ ]
128145 data [design ][netName ]["wire_length" ] = sum (
129146 length
130147 for i , length in enumerate (layer_lengths )
131- # ignore contribution from via layers
148+ # ignore non-routable layers
132149 if stack [i ][1 ]
133150 )
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+ )
134156
135157################################################################
136158
@@ -227,15 +249,15 @@ def makeDict():
227249 for net in data [design ]:
228250 rcx_res = data [design ][net ]["rcx_res" ]
229251 if rcx_res > 0 :
230- x .append (data [design ][net ]["layer_lengths " ])
231- y .append (rcx_res )
252+ x .append (data [design ][net ]["routable_layer_lengths " ])
253+ y .append (rcx_res - data [ design ][ net ][ "grt_via_res" ] )
232254
233255x = np .array (x )
234256y = np .array (y )
235257
236258res_model = LinearRegression (fit_intercept = False ).fit (x , y )
237259r_sq = res_model .score (x , y )
238- print ("Resistance coefficient of determination: {:.4f}" .format (r_sq ))
260+ print ("# Resistance coefficient of determination: {:.4f}" .format (r_sq ))
239261
240262################################################################
241263
@@ -245,39 +267,25 @@ def makeDict():
245267y = []
246268for design in data :
247269 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 ]])
270+ x .append (data [design ][net ]["routable_layer_lengths" ])
250271 y .append (data [design ][net ]["rcx_cap" ])
251272
252273x = np .array (x )
253274y = np .array (y )
254275
255276cap_model = LinearRegression (fit_intercept = False ).fit (x , y )
256277r_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 :
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 :
278286 print (
279- "set_layer_rc -via {} -resistance {:.5E}" .format (
280- layer [0 ], res_coeff / res_scale
287+ "set_layer_rc -layer {} -resistance {:.5E} -capacitance {:.5E}" .format (
288+ layer [0 ], res_coeff / res_scale , cap_coeff / cap_scale
281289 )
282290 )
283291
0 commit comments