@@ -94,6 +94,13 @@ def makeDict():
9494stack = []
9595stack_line = None
9696
97+ # For segment mode.
98+ layer_segments = defaultdict (
99+ lambda : {"lengths" : [], "resistances" : [], "capacitances" : []}
100+ )
101+ routing_layers = []
102+ routing_layers_line = None
103+
97104# indices of relevant layers (routable layers or via layers)
98105active_layers = set ()
99106
@@ -104,6 +111,17 @@ def makeDict():
104111 with open (rc_file ) as f :
105112 nonGrtNets = 0
106113 for line in f :
114+ if line .startswith ("# routing layers: " ):
115+ if routing_layers_line is not None and routing_layers_line != line :
116+ print (f"layer stack inconsistent" , file = stderr )
117+ exit (1 )
118+ elif routing_layers_line is None :
119+ routing_layers = (
120+ line .removeprefix ("# routing layers: " ).strip ().split (" " )
121+ )
122+ routing_layers_line = line
123+ continue
124+
107125 if line .startswith ("# stack: " ):
108126 if stack_line is not None and stack_line != line :
109127 print (f"layer stack inconsistent" , file = stderr )
@@ -129,7 +147,9 @@ def makeDict():
129147 tokens = line .strip ().split ("," )
130148
131149 if args .mode == "segment" :
132- pass
150+ layer_segments [tokens [2 ]]["lengths" ].append (float (tokens [3 ]))
151+ layer_segments [tokens [2 ]]["resistances" ].append (float (tokens [4 ]))
152+ layer_segments [tokens [2 ]]["capacitances" ].append (float (tokens [5 ]))
133153 else :
134154 netName = tokens [0 ]
135155
@@ -350,4 +370,34 @@ def generic_rc_fit(type_sieve):
350370################################################################
351371
352372if args .mode == "segment" :
353- pass
373+ print (
374+ "# Updated layer resistance {}/um capacitance {}/um" .format (res_unit , cap_unit )
375+ )
376+
377+ for layer_name in routing_layers :
378+ # There may be routing layers with no segments, so we check if the
379+ # layer exists in the dict.
380+ if layer_name not in layer_segments :
381+ continue
382+
383+ # sklearn requires the input to be 2D, so we reshape to add a dimension
384+ # to the list.
385+ lengths = np .array (layer_segments [layer_name ]["lengths" ]).reshape (- 1 , 1 )
386+ resistances = np .array (layer_segments [layer_name ]["resistances" ])
387+ capacitances_ff = np .array (layer_segments [layer_name ]["capacitances" ])
388+
389+ res_model = LinearRegression (fit_intercept = False ).fit (lengths , resistances )
390+ cap_model = LinearRegression (fit_intercept = False ).fit (lengths , capacitances_ff )
391+
392+ r_sq = res_model .score (lengths , resistances )
393+ print ("# Resistance coefficient of determination: {:.4f}" .format (r_sq ))
394+ r_sq = cap_model .score (lengths , capacitances_ff )
395+ print ("# Capacitance coefficient of determination: {:.4f}" .format (r_sq ))
396+
397+ print (
398+ "set_layer_rc -layer {} -resistance {:.5E} -capacitance {:.5E}" .format (
399+ layer_name ,
400+ res_model .coef_ [0 ] / res_scale ,
401+ cap_model .coef_ [0 ] * 1e-15 / cap_scale ,
402+ )
403+ )
0 commit comments