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
@@ -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
233256x = np .array (x )
234257y = np .array (y )
235258
236259res_model = LinearRegression (fit_intercept = False ).fit (x , y )
237260r_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():
245268y = []
246269for 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
252274x = np .array (x )
253275y = np .array (y )
254276
255277cap_model = LinearRegression (fit_intercept = False ).fit (x , y )
256278r_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
0 commit comments