@@ -269,12 +269,10 @@ def run_sim(char, dirpath, device, temp):
269269
270270 netlist_path = f"{ dirpath } /{ dev } _netlists" + f"/netlist_{ device } _t{ temp_str } .spice"
271271
272- result_path_ib = f"{ dirpath } /ib_simulated/" + f"simulated_{ device } _t{ temp_str } .csv"
273- result_path_ic = f"{ dirpath } /ic_simulated/" + f"simulated_{ device } _t{ temp_str } .csv"
274-
275- for c in char :
276- os .makedirs (f"{ dirpath } /{ c } _simulated" , exist_ok = True )
272+ result_path_ib = f"{ dirpath } /{ dev } _netlists/" + f"ib_simulated_{ device } _t{ temp_str } .csv"
273+ result_path_ic = f"{ dirpath } /{ dev } _netlists/" + f"ic_simulated_{ device } _t{ temp_str } .csv"
277274
275+
278276 with open (netlist_tmp ) as f :
279277 tmpl = Template (f .read ())
280278 os .makedirs (f"{ dirpath } /{ dev } _netlists" , exist_ok = True )
@@ -325,43 +323,44 @@ def run_sims(char, df, dirpath, num_workers=mp.cpu_count()):
325323 logging .info (f"Test case generated an exception: { exc } " )
326324
327325 for c in char :
328- sf = glob .glob (f"{ dirpath } /{ c } _simulated/ *.csv" ) # stored simulated data files
326+ sf = glob .glob (f"{ dirpath } /*_netlists/ { c } *.csv" ) # stored simulated data files
329327
330328 for i in range (len (sf )):
331- sdf = pd .read_csv (
329+ df = pd .read_csv (
332330 sf [i ],
333- header = None ,
334331 delimiter = r"\s+" ,
335332 )
336333
337- sweep = len (pd .read_csv (glob .glob (f"{ dirpath } /{ c } _measured/*.csv" )[1 ]))
338-
339- new_array = np .empty ((sweep , 1 + int (sdf .shape [0 ] / sweep )))
340- new_array [:, 0 ] = sdf .iloc [:sweep , 0 ]
341- times = int (sdf .shape [0 ] / sweep )
342-
343- for j in range (times ):
344- new_array [:, (j + 1 )] = sdf .iloc [j * sweep : (j + 1 ) * sweep , 1 ]
345-
346- # Writing final simulated data 1
347- sdf = pd .DataFrame (new_array )
348- sdf .to_csv (
349- sf [i ],
350- index = False ,
351- )
352-
353- sdf .rename (
354- columns = {
355- 0 : "simulated_base_volt" ,
356- 1 : f"simulated_{ c } _vcp_step1" ,
357- 2 : f"simulated_{ c } _vcp_step2" ,
358- 3 : f"simulated_{ c } _vcp_step3" ,
359- },
360- inplace = True ,
361- )
362-
363- sdf .to_csv (sf [i ])
364-
334+ if c == "ib" and dirpath == "bjt_beta_regr/npn" :
335+ i_vds = "-i(Vbp)"
336+ elif c == "ic" and dirpath == "bjt_beta_regr/npn" :
337+ i_vds = "-i(Vcp)"
338+ elif c == "ib" and dirpath == "bjt_beta_regr/pnp" :
339+ i_vds = "i(Vbp)"
340+ else :
341+ i_vds = "i(Vcp)"
342+ sdf = df .pivot (index = "v-sweep" , columns = "v(c)" , values = i_vds )
343+ if dirpath == "bjt_beta_regr/npn" :
344+ sdf .rename (
345+ columns = {
346+ 1.0 : f"simulated_{ c } _vcp_step1" ,
347+ 2.0 : f"simulated_{ c } _vcp_step2" ,
348+ 3.0 : f"simulated_{ c } _vcp_step3" ,
349+ },
350+ inplace = True ,
351+ )
352+ else :
353+ sdf .rename (
354+ columns = {
355+ - 1.0 : f"simulated_{ c } _vcp_step1" ,
356+ - 2.0 : f"simulated_{ c } _vcp_step2" ,
357+ - 3.0 : f"simulated_{ c } _vcp_step3" ,
358+ },
359+ inplace = True ,
360+ )
361+ # reverse the rows
362+ sdf = sdf .iloc [::- 1 ]
363+ sdf .to_csv (sf [i ], index = True , header = True , sep = "," )
365364 df = pd .DataFrame (results )
366365
367366 df = df [["device" , "temp" , "beta_sim_ib_unscaled" , "beta_sim_ic_unscaled" ]]
@@ -456,7 +455,7 @@ def main():
456455 sim_df = run_sims (char , meas_df , dev_path , 3 )
457456
458457 sim_len = len (
459- pd .read_csv (glob .glob (f"{ dev_path } /{ char [1 ]} _simulated/ *.csv" )[1 ])
458+ pd .read_csv (glob .glob (f"{ dev_path } /{ dev } _netlists/ { char [1 ]} *.csv" )[1 ])
460459 )
461460
462461 logging .info (
@@ -469,15 +468,25 @@ def main():
469468
470469 merged_all = []
471470 for c in char :
472-
471+ # create a new dataframe for rms error
472+ rms_df = pd .DataFrame (columns = ["device" , "temp" ,"corner" , "rms_error" ])
473+
473474 merged_dfs = []
474475
475476 for i in range (len (merged_df )):
476477
477478 measured_data = pd .read_csv (merged_df [f"{ c } _measured" ][i ])
478479 simulated_data = pd .read_csv (merged_df [f"beta_{ c } _sim" ][i ])
479-
480+ measured_data [ "v-sweep" ] = simulated_data [ "v-sweep" ]
480481 result_data = simulated_data .merge (measured_data , how = "left" )
482+ # clipping all the values to lowest_curr
483+ lowest_curr = 5e-12
484+ result_data [f"simulated_{ c } _vcp_step1" ] = result_data [f"simulated_{ c } _vcp_step1" ].clip (lower = lowest_curr )
485+ result_data [f"simulated_{ c } _vcp_step2" ] = result_data [f"simulated_{ c } _vcp_step2" ].clip (lower = lowest_curr )
486+ result_data [f"simulated_{ c } _vcp_step3" ] = result_data [f"simulated_{ c } _vcp_step3" ].clip (lower = lowest_curr )
487+ result_data [f"measured_{ c } _vcp_step1" ] = result_data [f"measured_{ c } _vcp_step1" ].clip (lower = lowest_curr )
488+ result_data [f"measured_{ c } _vcp_step2" ] = result_data [f"measured_{ c } _vcp_step2" ].clip (lower = lowest_curr )
489+ result_data [f"measured_{ c } _vcp_step3" ] = result_data [f"measured_{ c } _vcp_step3" ].clip (lower = lowest_curr )
481490
482491 result_data ["corner" ] = "typical"
483492 result_data ["device" ] = (
@@ -529,7 +538,18 @@ def main():
529538 )
530539 / 3
531540 )
532-
541+ # get rms error
542+ result_data ["rms_error" ] = np .sqrt (
543+ np .mean (result_data ["error" ] ** 2 )
544+ )
545+ # fill rms dataframe
546+ rms_df .loc [i ] = [
547+ result_data ["device" ][0 ],
548+ result_data ["temp" ][0 ],
549+ result_data ["corner" ][0 ],
550+ result_data ["rms_error" ][0 ],
551+ ]
552+
533553 result_data = result_data [
534554 [
535555 "device" ,
@@ -554,56 +574,40 @@ def main():
554574 merged_out = pd .concat (merged_dfs )
555575
556576 merged_out .to_csv (f"{ dev_path } /error_analysis_{ c } .csv" , index = False )
557-
558- merged_all .append (merged_out )
559-
560- merged_all = pd .concat (merged_all )
561- list_dev = npn_devices
562- if dev == "pnp" :
563- list_dev = pnp_devices
564- # calculating the error of each device and reporting it
565- for dev in list_dev :
566- min_error_total = float ()
567- max_error_total = float ()
568- error_total = float ()
569- number_of_existance = int ()
570-
571- # number of rows in the final excel sheet
572- num_rows = merged_all ["device" ].count ()
573-
574- for n in range (num_rows ):
575- if dev == merged_all ["device" ].iloc [n ]:
576- number_of_existance += 1
577- error_total += merged_all ["error" ].iloc [n ]
578- if merged_all ["error" ].iloc [n ] > max_error_total :
579- max_error_total = merged_all ["error" ].iloc [n ]
580- elif merged_all ["error" ].iloc [n ] < min_error_total :
581- min_error_total = merged_all ["error" ].iloc [n ]
582-
583- mean_error_total = error_total / number_of_existance
584-
585- # Making sure that min, max, mean errors are not > 100%
586- if min_error_total > 100 :
587- min_error_total = 100
588-
589- if max_error_total > 100 :
590- max_error_total = 100
591-
592- if mean_error_total > 100 :
593- mean_error_total = 100
594-
595- # logging.infoing min, max, mean errors to the consol
596- logging .info (
597- f"# Device { dev } min error: { min_error_total :.2f} , max error: { max_error_total :.2f} , mean error { mean_error_total :.2f} "
598- )
599-
600- if max_error_total < PASS_THRESH :
601- logging .info (f"# Device { dev } has passed regression." )
602- else :
577+ rms_df .to_csv (f"{ dev_path } /finalerror_analysis_{ c } .csv" , index = False )
578+
579+ # calculating the error of each device and reporting it
580+ for dev in list_dev :
581+ min_error_total = float ()
582+ max_error_total = float ()
583+ mean_error_total = float ()
584+ # number of rows in the final excel sheet
585+ rms_df = pd .read_csv (f"{ dev_path } /finalerror_analysis_{ c } .csv" )
586+ min_error_total = rms_df ["rms_error" ].min ()
587+ max_error_total = rms_df ["rms_error" ].max ()
588+ mean_error_total = rms_df ["rms_error" ].mean ()
589+ # Making sure that min, max, mean errors are not > 100%
590+ if min_error_total > 100 :
591+ min_error_total = 100
592+
593+ if max_error_total > 100 :
594+ max_error_total = 100
595+
596+ if mean_error_total > 100 :
597+ mean_error_total = 100
598+
599+ # logging.infoing min, max, mean errors to the consol
603600 logging .info (
604- f"# Device { dev } has failed regression. Needs more analysis. "
601+ f"# Device { dev } { c } min error: { min_error_total :.2f } , max error: { max_error_total :.2f } , mean error { mean_error_total :.2f } "
605602 )
606603
604+ if max_error_total < PASS_THRESH :
605+ logging .info (f"# Device { dev } { c } has passed regression." )
606+ else :
607+ logging .error (
608+ f"# Device { dev } { c } has failed regression. Needs more analysis."
609+ )
610+
607611
608612# # ================================================================
609613# -------------------------- MAIN --------------------------------
0 commit comments