diff --git a/models/ngspice/testing/.spiceinit b/models/ngspice/testing/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_cv_npn.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_cv_npn.nl_out.xlsx new file mode 100644 index 00000000..4910b809 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_cv_npn.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_cv_pnp.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_cv_pnp.nl_out.xlsx new file mode 100644 index 00000000..045b1a33 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_cv_pnp.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_fc_npn.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_fc_npn.nl_out.xlsx new file mode 100644 index 00000000..054b06ab Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_fc_npn.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_fc_pnp.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_fc_pnp.nl_out.xlsx new file mode 100644 index 00000000..d9db37a2 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_fc_pnp.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mc_npn.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mc_npn.nl_out.xlsx new file mode 100644 index 00000000..d8d27d02 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mc_npn.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mc_pnp.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mc_pnp.nl_out.xlsx new file mode 100644 index 00000000..2492ba0e Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mc_pnp.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mm_pnp.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mm_pnp.nl_out.xlsx new file mode 100644 index 00000000..6ac61639 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_mm_pnp.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_f.nl_out.xlsx new file mode 100644 index 00000000..2c7d4549 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_r.nl_out.xlsx new file mode 100644 index 00000000..1b769d4c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_f.nl_out.xlsx new file mode 100644 index 00000000..f5a1c990 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_r.nl_out.xlsx new file mode 100644 index 00000000..6ac941ab Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_f.nl_out.xlsx new file mode 100644 index 00000000..49897472 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_r.nl_out.xlsx new file mode 100644 index 00000000..26898b21 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_f.nl_out.xlsx new file mode 100644 index 00000000..96b07d97 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_r.nl_out.xlsx new file mode 100644 index 00000000..76d04f4b Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_f.nl_out.xlsx new file mode 100644 index 00000000..a80ee451 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_r.nl_out.xlsx new file mode 100644 index 00000000..335d907c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_f.nl_out.xlsx new file mode 100644 index 00000000..364ca478 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_r.nl_out.xlsx new file mode 100644 index 00000000..ac6108ee Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_f.nl_out.xlsx new file mode 100644 index 00000000..af592f16 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_r.nl_out.xlsx new file mode 100644 index 00000000..443c2de9 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_f.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_f.nl_out.xlsx new file mode 100644 index 00000000..8fa1a77b Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_f.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_r.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_r.nl_out.xlsx new file mode 100644 index 00000000..fec8e829 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_r.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx new file mode 100644 index 00000000..1b616417 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Cap/mimcap_mc.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/mimcap_mc.nl_out.xlsx new file mode 100644 index 00000000..0ef13b4a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/mimcap_mc.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx new file mode 100644 index 00000000..4711b881 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx new file mode 100644 index 00000000..3585f1a9 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwps_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwps_cv.nl_out.xlsx new file mode 100644 index 00000000..5582df37 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwps_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwps_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwps_iv.nl_out.xlsx new file mode 100644 index 00000000..d9d62db3 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwps_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwpw_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwpw_cv.nl_out.xlsx new file mode 100644 index 00000000..ccd29089 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwpw_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwpw_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwpw_iv.nl_out.xlsx new file mode 100644 index 00000000..25d7edfc Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/dnwpw_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_3p3_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..cbf4db35 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_3p3_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..f4527e09 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_6p0_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..7023e41c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_6p0_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..08807f63 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/np_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..1b2af926 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..0c964d83 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..5789d79c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9321fb63 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_3p3_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..bed97275 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_3p3_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..c45be6c1 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_6p0_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..2fc2a7c5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_6p0_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9cbce9b0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/pn_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/sc_diode_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/sc_diode_cv.nl_out.xlsx new file mode 100644 index 00000000..a6767fc7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/sc_diode_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Diode/sc_diode_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/sc_diode_iv.nl_out.xlsx new file mode 100644 index 00000000..8b9344f7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Diode/sc_diode_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/hvfet_spec.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/hvfet_spec.nl_out.xlsx new file mode 100644 index 00000000..efd10396 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/hvfet_spec.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_cv.nl_out.xlsx new file mode 100644 index 00000000..c763f6b0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_iv.nl_out.xlsx new file mode 100644 index 00000000..0d975fee Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_noi.nl_out.xlsx new file mode 100644 index 00000000..674174cc Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_scaling_trend.n.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_scaling_trend.n.xlsx new file mode 100644 index 00000000..bbadf6c0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_scaling_trend.n.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_cv.nl_out.xlsx new file mode 100644 index 00000000..dfd13b60 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_iv.nl_out.xlsx new file mode 100644 index 00000000..8e5eb303 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_noi.nl_out.xlsx new file mode 100644 index 00000000..ca38856a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_scaling_trend.n.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_scaling_trend.n.xlsx new file mode 100644 index 00000000..b2f245d1 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_scaling_trend.n.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_1sig.nl.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_1sig.nl.xlsx new file mode 100644 index 00000000..d337742c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_1sig.nl.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_2sig.nl.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_2sig.nl.xlsx new file mode 100644 index 00000000..c6d8642d Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_2sig.nl.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_3sig.nl.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_3sig.nl.xlsx new file mode 100644 index 00000000..bc8639c3 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_3sig.nl.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/3p3_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..813635cd Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/3p3_sab_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/3p3_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..fd139e1f Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/3p3_sab_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..a6d80eec Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_nat_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_nat_cv.nl_out.xlsx new file mode 100644 index 00000000..407129c7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_nat_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_sab_cv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..1dbd85c5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/6p0_sab_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..b6b74f90 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_noi.nl_out.xlsx new file mode 100644 index 00000000..dd48b9d6 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..cba86bee Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv_dsab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..5ceb2a6d Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..b4b36f96 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9842b38a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_iv.nl_out.xlsx new file mode 100644 index 00000000..3a70d17d Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_noi.nl_out.xlsx new file mode 100644 index 00000000..ab51a895 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_noi.nl_out.xlsx new file mode 100644 index 00000000..3662177d Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..3aee7048 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv_dsab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..bb8e4f4f Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..865ff150 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..2fa27975 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_noi.nl_out.xlsx new file mode 100644 index 00000000..f7ba8acf Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..d87ad5dc Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv_dsab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..c7cf1cc0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..16c3a3af Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..a9254cb1 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_noi.nl_out.xlsx new file mode 100644 index 00000000..aebf3e13 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..a8248735 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv_dsab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..10eaca32 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_noi.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..8cb3a2d9 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_noi.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..1416ab96 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..89a74f0f Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..e7085f0c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..ad30f919 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..19118d4a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..48791d7e Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..a85c6c35 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..be21ff61 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/spec_all_fets.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/spec_all_fets.nl_out.xlsx new file mode 100644 index 00000000..3ef61df5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/spec_all_fets.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3.nl_out.xlsx new file mode 100644 index 00000000..0f182735 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..a3030a12 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0.nl_out.xlsx new file mode 100644 index 00000000..f191aaa7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..32629490 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_nmos_6p0_nat.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_nmos_6p0_nat.nl_out.xlsx new file mode 100644 index 00000000..a4830f96 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mc_nmos_6p0_nat.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..51142f05 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..4cafde66 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..274347db Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..a139dced Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..86f46317 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..c4bd3830 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..b9314cc1 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0_sab.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..c081636c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0_sab.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01a-wl-nplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01a-wl-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..bb5c8e7a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01a-wl-nplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nom-nplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nom-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..84cfe2f7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nom-nplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..57c0b79f Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01c-mm-nplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01c-mm-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..623e9bae Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01c-mm-nplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01d-mc-nplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01d-mc-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..40744c42 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01d-mc-nplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01e-cvcor-nplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01e-cvcor-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..cb09382a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES01e-cvcor-nplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02a-wl-pplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02a-wl-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..0dbd2782 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02a-wl-pplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-nom-pplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-nom-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..20315b0c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-nom-pplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-pplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..2df4e8f3 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-pplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02c-mm-pplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02c-mm-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..5640c401 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02c-mm-pplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02d-mc-pplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02d-mc-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..4ba25498 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02d-mc-pplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02e-cvcor-pplus_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02e-cvcor-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..10b193a0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES02e-cvcor-pplus_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03a-wl-nplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03a-wl-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..260a8cad Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03a-wl-nplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03b-temp-nplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03b-temp-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..e65b1fc5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03b-temp-nplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03d-mc-nplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03d-mc-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..ff7ad366 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03d-mc-nplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03e-cvcor-nplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03e-cvcor-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..76fea8b4 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES03e-cvcor-nplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04a-wl-pplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04a-wl-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..1a49e0c3 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04a-wl-pplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04b-temp-pplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04b-temp-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..0fbb6725 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04b-temp-pplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04d-mc-pplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04d-mc-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..6e0a4b1b Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04d-mc-pplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04e-cvcor-pplus_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04e-cvcor-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..b0438256 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES04e-cvcor-pplus_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05a-wl-nwell.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05a-wl-nwell.nl_out.xlsx new file mode 100644 index 00000000..64089955 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05a-wl-nwell.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05b-temp-nwell.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05b-temp-nwell.nl_out.xlsx new file mode 100644 index 00000000..7cbd7767 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05b-temp-nwell.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05e-cvcor-nwell.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05e-cvcor-nwell.nl_out.xlsx new file mode 100644 index 00000000..12f2d079 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES05e-cvcor-nwell.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06a-wl-npolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06a-wl-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..0d06e5e9 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06a-wl-npolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06b-temp-npolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06b-temp-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..2687b8c5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06b-temp-npolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06c-mm-npolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06c-mm-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..c624220a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06c-mm-npolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06d-mc-npolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06d-mc-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..e06c435f Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06d-mc-npolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06e-cvcor-npolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06e-cvcor-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..d48576b9 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06e-cvcor-npolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06f-noise-npolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06f-noise-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..fa0909e5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES06f-noise-npolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07a-wl-ppolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07a-wl-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..479a205f Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07a-wl-ppolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07b-temp-ppolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07b-temp-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..6d890fae Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07b-temp-ppolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07c-mm-ppolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07c-mm-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..fba4fbc2 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07c-mm-ppolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07d-mc-ppolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07d-mc-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..31fcb16b Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07d-mc-ppolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07e-cvcor-ppolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07e-cvcor-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..a4188bd5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07e-cvcor-ppolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07f-noise-ppolyf_u.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07f-noise-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..a26d9baa Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES07f-noise-ppolyf_u.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08a-wl-npolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08a-wl-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..64025b9d Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08a-wl-npolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08b-temp-npolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08b-temp-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..d9c246d7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08b-temp-npolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08d-mc-npolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08d-mc-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..5bb22314 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08d-mc-npolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08e-cvcor-npolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08e-cvcor-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..77df6d2b Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08e-cvcor-npolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08f-noise-npolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08f-noise-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..da255dfa Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES08f-noise-npolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09a-wl-ppolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09a-wl-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..68965182 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09a-wl-ppolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09b-temp-ppolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09b-temp-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..04bb357c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09b-temp-ppolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09d-mc-ppolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09d-mc-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..d7d005b9 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09d-mc-ppolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09e-cvcor-ppolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09e-cvcor-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..02146f86 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09e-cvcor-ppolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09f-noise-ppolyf_s.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09f-noise-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..2d1275da Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES09f-noise-ppolyf_s.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10a-wl-ppolyf_u_1k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10a-wl-ppolyf_u_1k.nl_out.xlsx new file mode 100644 index 00000000..7c03c8a0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10a-wl-ppolyf_u_1k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10b-temp-ppolyf_u_1k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10b-temp-ppolyf_u_1k.nl_out.xlsx new file mode 100644 index 00000000..de70746e Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10b-temp-ppolyf_u_1k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10d-mc-ppolyf_u_1k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10d-mc-ppolyf_u_1k.nl_out.xlsx new file mode 100644 index 00000000..758a7f4d Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10d-mc-ppolyf_u_1k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10e-cvcor-ppolyf_u_1k.nl_ou.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10e-cvcor-ppolyf_u_1k.nl_ou.xlsx new file mode 100644 index 00000000..76c959ab Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10e-cvcor-ppolyf_u_1k.nl_ou.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10f-noise-ppolyf_u_1k.nl_ou.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10f-noise-ppolyf_u_1k.nl_ou.xlsx new file mode 100644 index 00000000..5ad8dfef Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES10f-noise-ppolyf_u_1k.nl_ou.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11a-wl-ppolyf_u_2k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11a-wl-ppolyf_u_2k.nl_out.xlsx new file mode 100644 index 00000000..71aa86d7 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11a-wl-ppolyf_u_2k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11b-temp-ppolyf_u_2k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11b-temp-ppolyf_u_2k.nl_out.xlsx new file mode 100644 index 00000000..1e91eb03 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11b-temp-ppolyf_u_2k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11d-mc-ppolyf_u_2k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11d-mc-ppolyf_u_2k.nl_out.xlsx new file mode 100644 index 00000000..8347b1ca Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11d-mc-ppolyf_u_2k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11e-cvcor-ppolyf_u_2k.nl_ou.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11e-cvcor-ppolyf_u_2k.nl_ou.xlsx new file mode 100644 index 00000000..4b15b257 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11e-cvcor-ppolyf_u_2k.nl_ou.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11f-noise-ppolyf_u_2k.nl_ou.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11f-noise-ppolyf_u_2k.nl_ou.xlsx new file mode 100644 index 00000000..430db7b3 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES11f-noise-ppolyf_u_2k.nl_ou.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12a-wl-ppolyf_u_1k_6p0.nl_o.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12a-wl-ppolyf_u_1k_6p0.nl_o.xlsx new file mode 100644 index 00000000..bbcecca1 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12a-wl-ppolyf_u_1k_6p0.nl_o.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12b-temp-ppolyf_u_1k_6p0.nl.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12b-temp-ppolyf_u_1k_6p0.nl.xlsx new file mode 100644 index 00000000..6632263a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12b-temp-ppolyf_u_1k_6p0.nl.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12d-mc-ppolyf_u_1k_6p0.nl_o.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12d-mc-ppolyf_u_1k_6p0.nl_o.xlsx new file mode 100644 index 00000000..0c2cd974 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12d-mc-ppolyf_u_1k_6p0.nl_o.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12e-cvcor-ppolyf_u_1k_6p0.n.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12e-cvcor-ppolyf_u_1k_6p0.n.xlsx new file mode 100644 index 00000000..26afc556 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12e-cvcor-ppolyf_u_1k_6p0.n.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12f-noise-ppolyf_u_1k_6p0.n.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12f-noise-ppolyf_u_1k_6p0.n.xlsx new file mode 100644 index 00000000..d587bc97 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES12f-noise-ppolyf_u_1k_6p0.n.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13a-wl-ppolyf_u_2k_6p0.nl_o.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13a-wl-ppolyf_u_2k_6p0.nl_o.xlsx new file mode 100644 index 00000000..75bb7db5 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13a-wl-ppolyf_u_2k_6p0.nl_o.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13b-temp-ppolyf_u_2k_6p0.nl.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13b-temp-ppolyf_u_2k_6p0.nl.xlsx new file mode 100644 index 00000000..f258c605 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13b-temp-ppolyf_u_2k_6p0.nl.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13d-mc-ppolyf_u_2k_6p0.nl_o.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13d-mc-ppolyf_u_2k_6p0.nl_o.xlsx new file mode 100644 index 00000000..f3039060 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13d-mc-ppolyf_u_2k_6p0.nl_o.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13e-cvcor-ppolyf_u_2k_6p0.n.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13e-cvcor-ppolyf_u_2k_6p0.n.xlsx new file mode 100644 index 00000000..7fb23308 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13e-cvcor-ppolyf_u_2k_6p0.n.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13f-noise-ppolyf_u_2k_6p0.n.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13f-noise-ppolyf_u_2k_6p0.n.xlsx new file mode 100644 index 00000000..731c3cea Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES13f-noise-ppolyf_u_2k_6p0.n.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14a-wl-ppolyf_u_3k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14a-wl-ppolyf_u_3k.nl_out.xlsx new file mode 100644 index 00000000..e11f941c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14a-wl-ppolyf_u_3k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14b-temp-ppolyf_u_3k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14b-temp-ppolyf_u_3k.nl_out.xlsx new file mode 100644 index 00000000..40b1ff22 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14b-temp-ppolyf_u_3k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14d-mc-ppolyf_u_3k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14d-mc-ppolyf_u_3k.nl_out.xlsx new file mode 100644 index 00000000..332dbc3a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14d-mc-ppolyf_u_3k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14e-cvcor-ppolyf_u_3k.nl_ou.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14e-cvcor-ppolyf_u_3k.nl_ou.xlsx new file mode 100644 index 00000000..63866694 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14e-cvcor-ppolyf_u_3k.nl_ou.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14f-noise-ppolyf_u_3k.nl_ou.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14f-noise-ppolyf_u_3k.nl_ou.xlsx new file mode 100644 index 00000000..359b06cd Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES14f-noise-ppolyf_u_3k.nl_ou.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES15a-wl-rm1.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES15a-wl-rm1.nl_out.xlsx new file mode 100644 index 00000000..597ed2ab Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES15a-wl-rm1.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES15b-temp-rm1.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES15b-temp-rm1.nl_out.xlsx new file mode 100644 index 00000000..7af7d6b3 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES15b-temp-rm1.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES16a-wl-rm2.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES16a-wl-rm2.nl_out.xlsx new file mode 100644 index 00000000..8e224e27 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES16a-wl-rm2.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES16b-temp-rm2.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES16b-temp-rm2.nl_out.xlsx new file mode 100644 index 00000000..7400b884 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES16b-temp-rm2.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES17a-wl-rm3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES17a-wl-rm3.nl_out.xlsx new file mode 100644 index 00000000..7d5f551e Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES17a-wl-rm3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES17b-temp-rm3.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES17b-temp-rm3.nl_out.xlsx new file mode 100644 index 00000000..18592fa4 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES17b-temp-rm3.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES18a-wl-tm6k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES18a-wl-tm6k.nl_out.xlsx new file mode 100644 index 00000000..214f5609 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES18a-wl-tm6k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES18b-temp-tm6k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES18b-temp-tm6k.nl_out.xlsx new file mode 100644 index 00000000..acbbf897 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES18b-temp-tm6k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES19a-wl-tm9k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES19a-wl-tm9k.nl_out.xlsx new file mode 100644 index 00000000..c7701c81 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES19a-wl-tm9k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES19b-temp-tm9k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES19b-temp-tm9k.nl_out.xlsx new file mode 100644 index 00000000..88ec343e Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES19b-temp-tm9k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES20a-wl-tm11k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES20a-wl-tm11k.nl_out.xlsx new file mode 100644 index 00000000..b4148481 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES20a-wl-tm11k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES20b-temp-tm11k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES20b-temp-tm11k.nl_out.xlsx new file mode 100644 index 00000000..5dc8f38a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES20b-temp-tm11k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES21a-wl-tm30k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES21a-wl-tm30k.nl_out.xlsx new file mode 100644 index 00000000..8639044c Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES21a-wl-tm30k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES21b-temp-tm30k.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES21b-temp-tm30k.nl_out.xlsx new file mode 100644 index 00000000..aab88bd0 Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/RES21b-temp-tm30k.nl_out.xlsx differ diff --git a/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/efuse.nl_out.xlsx b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/efuse.nl_out.xlsx new file mode 100644 index 00000000..596dfb6a Binary files /dev/null and b/models/ngspice/testing/180MCU_SPICE_DATA/Resistor/efuse.nl_out.xlsx differ diff --git a/models/ngspice/testing/Makefile b/models/ngspice/testing/Makefile new file mode 100644 index 00000000..e22efb4b --- /dev/null +++ b/models/ngspice/testing/Makefile @@ -0,0 +1,182 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#================================================================= +# ------------------------ models_ngspice ------------------------ +#================================================================= + +SHELL := /bin/bash +Testing_DIR ?= $(shell pwd) +run_folder := $(shell date +'run_%Y_%m_%d_%H:%M:%S') + + +.DEFAULT_GOAL := all + +all : test-models_ngspice + +test-models_ngspice: smoke-test models-MOS models-BJT models-diode models-MOSCAP models-MIMCAP models-RES + +#================================ +#---------- Create Run ---------- +#================================ + +.ONESHELL: +Add_run-dir: + @cd $(Testing_DIR) + @ [ ! -d "$(run_folder)/" ] && cp -rf $(Testing_DIR)/regression $(Testing_DIR)/$(run_folder) + +#================================ +#---------- smoke-test ---------- +#================================ + +.ONESHELL: +smoke-test: + @cd $(Testing_DIR)/smoke_test + @python3 ng_smoke_test.py + + +#================================ +# ---------- models-MOS---------- +#================================ + +.ONESHELL: +models-MOS: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/mos_iv_vgs + @echo "========== Runing models_ngspice-MOS regression ==========" |& tee -a ../run_log.log + @python3 models_regression.py |& tee -a ../run_log.log +# @cd ../mos_iv_vbs +# @python3 models_regression.py |& tee -a ../run_log.log + +# .ONESHELL: +# clean-models-MOS: +# @echo "==== Cleaning models-MOS old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/mos_iv_vgs && rm -rf nmos_* pmos_* + +#================================ +# ---------- models-BJT---------- +#================================ + +.ONESHELL: +models-BJT: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/bjt_cj + @echo "========== Runing models_ngspice-BJT regression ==========" |& tee -a ../run_log.log + @python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-BJT: +# @echo "==== Cleaning models-BJT old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/bjt_cj && rm -rf vnpn_* vpnp_* + +#================================ +# --------- models-diode -------- +#================================ + +.ONESHELL: +models-diode: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/diode + @echo "========== Runing models_ngspice-didoe regression ==========" |& tee -a ../run_log.log + @python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-diode: +# @echo "==== Cleaning models-diode old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/diode && rm -rf np_* pn_* nwp* dnw* sc_* + +#================================ +# -------- models-MOSCAP -------- +#================================ + +.ONESHELL: +models-MOSCAP: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/moscap_c + @echo "========== Runing models_ngspice-MOSCAP regression ==========" |& tee -a ../run_log.log + @python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-MOSCAP: +# @echo "==== Cleaning models-MOSCAP old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/moscap_c && rm -rf nmoscap_* pmoscap_* + +#================================ +# -------- models-MIMCAP -------- +#================================ + +.ONESHELL: +models-MIMCAP: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/mimcap_c + @echo "========== Runing models_ngspice-MIMCAP regression ==========" |& tee -a ../run_log.log + @python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-MIMCAP: +# @echo "==== Cleaning models-MIMCAP old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/mimcap_c && rm -rf mim* + + +#================================ +# --------- models-RES ---------- +#================================ + +.ONESHELL: +models-RES: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/resistor_r + @echo "========== Runing models_ngspice-RES regression ==========" |& tee -a ../run_log.log + @python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-RES: +# @echo "==== Cleaning models-RES old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/resistor_r && rm -rf nplus* pplus* npoly* ppoly* rm* tm* nwell + + + +# #=============================== +# # --------- Clean ALL ---------- +# #=============================== + +# .ONESHELL: +# clean: clean-models-MOS clean-models-BJT clean-models-diode clean-models-MOSCAP clean-models-MIMCAP clean-models-RES +# @echo "==== Cleaning all runs is done ====" + + +#========================== +# --------- HELP ---------- +#========================== + +# Help Target +help: + @echo "\n ==== The following are some of the valid targets for this Makefile ====\n" + @echo "... all (the default if no target is provided)" + @echo "... smoke-test (To run smoke test for an inverter)" + @echo "... test-models_ngspice (To run regression for all devices)" + @echo "... models-MOS (To run regression for MOS devices)" + @echo "... models-BJT (To run regression for BJT devices)" + @echo "... models-diode (To run regression for diode devices)" + @echo "... models-MOSCAP (To run regression for MOSCAP devices)" + @echo "... models-MIMCAP (To run regression for MIMCAP devices)" + @echo "... models-RES (To run regression for RES devices)" +# @echo "... clean-models-MOS (To clean old runs for MOS devices)" +# @echo "... clean-models-BJT (To clean old runs for BJT devices)" +# @echo "... clean-models-diode (To clean old runs for diode devices)" +# @echo "... clean-models-MOSCAP (To clean old runs for MOSCAP devices)" +# @echo "... clean-models-MIMCAP (To clean old runs for MIMCAP devices)" +# @echo "... clean-models-RES (To run regression for RES devices)" +# @echo "... clean (To clean all old runs) " + +.PHONY : help diff --git a/models/ngspice/testing/README.md b/models/ngspice/testing/README.md new file mode 100644 index 00000000..2205747f --- /dev/null +++ b/models/ngspice/testing/README.md @@ -0,0 +1,51 @@ +# Globalfoundries 180nm MCU models-ngspice regression + +Explains how to run GF180nm models-ngspice regression. + +## Folder Structure + +```text +📦testing + ┣ 📜Makefile + ┣ 📜README.md + ┣ 📦regression + ┣ 📦smoke_test + ┣ 📦180MCU_SPICE_Models + ``` + +## Prerequisites + +At a minimum: + +- Git 2.35+ +- Python 3.6+ +- ngspice-36+ + +### On Ubuntu, you can just + +`apt install -y build-essential python3` + +- Check this [ngspice](http://ngspice.sourceforge.net/download.html) for ngspice installation. + +## Regression Usage + +To make a full test for GF180nm models-ngspice, you could use the following command in testing directory: + +```bash +make all +``` + +- You could also check allowed targets in the Makefile, using the following command: + + ```bash + make help + ``` + +## **Regression Outputs** + +- The resulting files are in `regression//` with name of `` that contains: + + 1. A final report file of all results. + 2. measured folder that contains measured data used in regression. + 3. simulated folder that contains simulated data used in regression. + 4. netlists folder that contains spice files used in simulation. diff --git a/models/ngspice/testing/regression/.spiceinit b/models/ngspice/testing/regression/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/regression/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/bjt_beta/.spiceinit b/models/ngspice/testing/regression/bjt_beta/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_beta/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/bjt_beta/device_netlists/npn.spice b/models/ngspice/testing/regression/bjt_beta/device_netlists/npn.spice new file mode 100644 index 00000000..e25a8d21 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_beta/device_netlists/npn.spice @@ -0,0 +1,29 @@ +***************** +** main netlist +***************** + +Vcp c 0 dc 3 +Vbp b 0 dc 1.2 + +.temp {{temp}} +.options tnom={{temp}} + +xq1 c b 0 0 {{device}} + + +***************** +** Analysis +***************** + +.control +set filetype=ascii + +dc Vbp 0.2 1.2 0.01 Vcp 1 3 1 +wrdata npn/simulated_Ic/{{i}}_simulated_{{device}}.csv -i(Vcp) +wrdata npn/simulated_Ib/{{i}}_simulated_{{device}}.csv -i(Vbp) +.endc + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_typical + +.end diff --git a/models/ngspice/testing/regression/bjt_beta/device_netlists/pnp.spice b/models/ngspice/testing/regression/bjt_beta/device_netlists/pnp.spice new file mode 100644 index 00000000..d6a94142 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_beta/device_netlists/pnp.spice @@ -0,0 +1,29 @@ +***************** +** main netlist +***************** + +Vcp c 0 dc -3 +Vbp b 0 dc -1.2 + +.temp {{temp}} +.options tnom={{temp}} + +xq1 c b 0 {{device}} + + +***************** +** Analysis +***************** + +.control +set filetype=ascii + +dc Vbp -0.2 -1.2 -0.01 Vcp -1 -3 -1 +wrdata pnp/simulated_Ic/{{i}}_simulated_{{device}}.csv i(Vcp) +wrdata pnp/simulated_Ib/{{i}}_simulated_{{device}}.csv i(Vbp) +.endc + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_typical + +.end diff --git a/models/ngspice/testing/regression/bjt_beta/device_netlists/run_npn_beta.spice b/models/ngspice/testing/regression/bjt_beta/device_netlists/run_npn_beta.spice new file mode 100644 index 00000000..b21c1155 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_beta/device_netlists/run_npn_beta.spice @@ -0,0 +1,34 @@ + +***************** +** main netlist +***************** + +Vcp c 0 dc 3 +*Ib 0 b 9u +Vbp b 0 dc 1.2 + +.temp 25 +.options tnom=25 + +xq1 c b 0 0 vnpn_10x10 + + +***************** +** Analysis +***************** + +.control +set filetype=ascii + +dc Vbp 0.2 1.2 0.01 Vcp 1 3 1 +print -i(Vcp) +print -i(Vbp) +wrdata result.csv -i(Vcp) +wrdata result.csv -i(Vbp) +.endc + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_typical + +.end + diff --git a/models/ngspice/testing/regression/bjt_beta/models_regression.py b/models/ngspice/testing/regression/bjt_beta/models_regression.py new file mode 100644 index 00000000..6d8c5f2c --- /dev/null +++ b/models/ngspice/testing/regression/bjt_beta/models_regression.py @@ -0,0 +1,243 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from cmath import inf +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vb,step,Id_sim,list_devices,vc): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + + # Extracting measured values for each Device + for i in range (loops): + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + # Special case for 1st measured values + if i == 0 : + if device == "pnp": + temp_vb = vb + vb = "-vb " + # measured Id_sim 0 + col_list = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[0]}/{i}_measured_{list_devices[k]}.csv", index = False) + + if device == "pnp": + vb = temp_vb + + # measured Id_sim 1 + col_list = [f"{vb}",f"{vc}{step[0]}.{2*i+1}",f"{vc}{step[1]}.{2*i+1}",f"{vc}{step[2]}.{2*i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[1]}/{i}_measured_{list_devices[k]}.csv", index = False) + else: + # measured Id_sim 0 + col_list = [f"{vb}",f"{vc}{step[0]}.{2*i}",f"{vc}{step[1]}.{2*i}",f"{vc}{step[2]}.{2*i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[0]}/{i}_measured_{list_devices[k]}.csv", index = False) + + # measured Id_sim 1 + col_list = [f"{vb}",f"{vc}{step[0]}.{2*i+1}",f"{vc}{step[1]}.{2*i+1}",f"{vc}{step[2]}.{2*i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[1]}/{i}_measured_{list_devices[k]}.csv", index = False) + +def ext_simulated(device,vc,step,sweep,Id_sim,list_devices,ib): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + netlist_tmp = f"./device_netlists/{device}.spice" + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_sim",exist_ok=True) + with open(f"{device}/{device}_netlists_sim/{i}_{device}_netlist_{list_devices[k]}.spice", "w") as netlist: + netlist.write(tmpl.render(device = list_devices[k], i = i , temp = temp )) + netlist_path = f"{device}/{device}_netlists_sim/{i}_{device}_netlist_{list_devices[k]}.spice" + + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data 0 + df_simulated = pd.read_csv(f"{device}/simulated_{Id_sim[0]}/{i}_simulated_{list_devices[k]}.csv",header=None, delimiter=r"\s+") + + # empty array to append in it shaped (sweep, number of trials + 1) + new_array = np.empty((sweep, 1+int(df_simulated.shape[0]/sweep))) + new_array[:, 0] = df_simulated.iloc[:sweep, 0] + times = int(df_simulated.shape[0]/sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*sweep:(j+1)*sweep, 1] + + # Writing final simulated data 0 + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{Id_sim[0]}/{i}_simulated_{list_devices[k]}.csv",index= False) + df_simulated.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}"] + df_simulated.to_csv(f"{device}/simulated_{Id_sim[0]}/{i}_simulated_{list_devices[k]}.csv",index= False) + + + # Writing simulated data 1 + df_simulated = pd.read_csv(f"{device}/simulated_{Id_sim[1]}/{i}_simulated_{list_devices[k]}.csv",header=None, delimiter=r"\s+") + + # empty array to append in it shaped (sweep, number of trials + 1) + new_array = np.empty((sweep, 1+int(df_simulated.shape[0]/sweep))) + new_array[:, 0] = df_simulated.iloc[:sweep, 0] + times = int(df_simulated.shape[0]/sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*sweep:(j+1)*sweep, 1] + + # Writing final simulated data 1 + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{Id_sim[1]}/{i}_simulated_{list_devices[k]}.csv",index= False) + df_simulated.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}"] + df_simulated.to_csv(f"{device}/simulated_{Id_sim[1]}/{i}_simulated_{list_devices[k]}.csv",index= False) + +def error_cal(device,vb,step,Id_sim,list_devices,vc): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + measured = pd.read_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv") + simulated = pd.read_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[0:, 1]) - abs(simulated.iloc[0:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[0:, 2]) - abs(simulated.iloc[0:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[0:, 3]) - abs(simulated.iloc[0:, 3]))/abs(measured.iloc[:, 3])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3]).transpose() + df_error.replace([np.inf, -np.inf], df_error.max().nlargest(2).iloc[1], inplace=True) + df_error.to_csv(f"{device}/error_{Id_sim}/{i}_{device}_error_{list_devices[k]}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{vc}{step[0]}"].mean() + df_error[f"{vc}{step[1]}"].mean() + df_error[f"{vc}{step[2]}"].mean())/6 + # Max error + max_error = df_error[[f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vc = (df_error == max_error).idxmax(axis=1)[max_index] + if Id_sim == "Ic": + if i == 0 : + if device == "pnp": + temp_vb = vb + vb = "-vb " + else: + if device == "pnp": + vb = temp_vb + max_location_vb = df_error[f"{vb}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'device': f'{list_devices[k]}','Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vc} & Vc (V) = {max_location_vb}'} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["npn","pnp"] + list_devices = [["vnpn_10x10" , "vnpn_5x5" , "vnpn_0p54x16" , "vnpn_0p54x8" , "vnpn_0p54x4", "vnpn_0p54x2"], + ["vpnp_0p42x10" , "vpnp_0p42x5", "vpnp_10x10" , "vpnp_5x5"]] + vb = ["vbp ","-vb (V)"] + vc = ["vcp =","vc =-"] + Id_sim = ["Ic","Ib"] + sweep = 101 + step = [1, 2, 3] + + for i, device in enumerate(devices): + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim[0]}",exist_ok=False) + os.makedirs(f"{device}/measured_{Id_sim[1]}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/bjt_{device}_beta_f.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim[0]}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim[0]}",exist_ok=False) + os.makedirs(f"{device}/simulated_{Id_sim[1]}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim[1]}",exist_ok=False) + + # =========== Simulate ============== + ext_measured (device,vb[i],step,Id_sim,list_devices[i],vc[i]) + + ext_simulated(device,vb[i],step,sweep,Id_sim,list_devices[i],vc[i]) + + # ============ Results ============= + error_cal (device,vb[i],step,Id_sim[0],list_devices[i],vc[i]) + error_cal (device,vb[i],step,Id_sim[1],list_devices[i],vc[i]) + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/bjt_cj/.spiceinit b/models/ngspice/testing/regression/bjt_cj/.spiceinit new file mode 100644 index 00000000..7779a4cc --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/.spiceinit @@ -0,0 +1,2 @@ +* user provided init file +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/.spiceinit b/models/ngspice/testing/regression/bjt_cj/device_netlists/.spiceinit new file mode 100644 index 00000000..7779a4cc --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/.spiceinit @@ -0,0 +1,2 @@ +* user provided init file +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/damping_test.spice b/models/ngspice/testing/regression/bjt_cj/device_netlists/damping_test.spice new file mode 100644 index 00000000..cf16aa36 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/damping_test.spice @@ -0,0 +1,43 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +Vb b 0 dc -3.3 + +.temp 25 +.options tnom=25 + + +xq1 0 b 0 0 vnpn_10x10 + + +.DC Vb 0 -3.3 -0.1 + +.control + +save all @q.xq1.q0[cpi] +run +print @q.xq1.q0[cpi] + +.endc + +** library calling + +.include "../../../../design.ngspice" +.lib "../../../../sm141064.ngspice" bjt_typical + + +.end diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_CBJ.spice b/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_CBJ.spice new file mode 100644 index 00000000..5b9e2519 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_CBJ.spice @@ -0,0 +1,44 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vb b 0 dc -3.3 + +.temp {{temp}} +.options tnom={{temp}} + + +xq1 0 b 0 0 {{device}} + + +.DC Vb 0 -3.3 -0.1 + +.control + +save all @q.xq1.q0[cmu] +run +print @q.xq1.q0[cmu] + +wrdata {{device}}_{{cv_sim}}_{{corner}}_T{{temp}}/simulated_{{cv_sim}}/1_simulated_{{device}}.csv @q.xq1.q0[cmu]*1.0e15 + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_{{corner}} + + +.end diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_CSJ.spice b/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_CSJ.spice new file mode 100644 index 00000000..0a099635 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_CSJ.spice @@ -0,0 +1,44 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vb b 0 dc -3.3 + +.temp {{temp}} +.options tnom={{temp}} + + +xq1 0 0 0 b {{device}} + + +.DC Vb 0 -3.3 -0.1 + +.control + +save all @q.xq1.q0[csub] +run +print @q.xq1.q0[csub] + +wrdata {{device}}_{{cv_sim}}_{{corner}}_T{{temp}}/simulated_{{cv_sim}}/2_simulated_{{device}}.csv @q.xq1.q0[csub]*1.0e15 + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_{{corner}} + + +.end diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_EBJ.spice b/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_EBJ.spice new file mode 100644 index 00000000..e735dbc6 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/npn_EBJ.spice @@ -0,0 +1,44 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vb b 0 dc -3.3 + +.temp {{temp}} +.options tnom={{temp}} + + +xq1 0 b 0 0 {{device}} + + +.DC Vb 0 -3.3 -0.1 + +.control + +save all @q.xq1.q0[cpi] +run +print @q.xq1.q0[cpi] + +wrdata {{device}}_{{cv_sim}}_{{corner}}_T{{temp}}/simulated_{{cv_sim}}/0_simulated_{{device}}.csv @q.xq1.q0[cpi]*1.0e15 + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_{{corner}} + + +.end diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/pnp_CBJ.spice b/models/ngspice/testing/regression/bjt_cj/device_netlists/pnp_CBJ.spice new file mode 100644 index 00000000..9d1a0ee8 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/pnp_CBJ.spice @@ -0,0 +1,44 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vb b 0 dc -3.3 + +.temp {{temp}} +.options tnom={{temp}} + + +xq1 b 0 0 {{device}} + + +.DC Vb 0 -3.3 -0.1 + +.control + +save all @q.xq1.q0[cmu] +run +print @q.xq1.q0[cmu] + +wrdata {{device}}_{{cv_sim}}_{{corner}}_T{{temp}}/simulated_{{cv_sim}}/1_simulated_{{device}}.csv @q.xq1.q0[cmu]*1.0e15 + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_{{corner}} + + +.end diff --git a/models/ngspice/testing/regression/bjt_cj/device_netlists/pnp_EBJ.spice b/models/ngspice/testing/regression/bjt_cj/device_netlists/pnp_EBJ.spice new file mode 100644 index 00000000..521b223d --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/device_netlists/pnp_EBJ.spice @@ -0,0 +1,44 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vb b 0 dc -3.3 + +.temp {{temp}} +.options tnom={{temp}} + + +xq1 0 0 b {{device}} + + +.DC Vb 0 -3.3 -0.1 + +.control + +save all @q.xq1.q0[cpi] +run +print @q.xq1.q0[cpi] + +wrdata {{device}}_{{cv_sim}}_{{corner}}_T{{temp}}/simulated_{{cv_sim}}/0_simulated_{{device}}.csv @q.xq1.q0[cpi]*1.0e15 + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_{{corner}} + + +.end diff --git a/models/ngspice/testing/regression/bjt_cj/models_regression.py b/models/ngspice/testing/regression/bjt_cj/models_regression.py new file mode 100644 index 00000000..aeba47a7 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_cj/models_regression.py @@ -0,0 +1,202 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vn,d_in, cv_sim, corner,start,dirpath): + + # Get dimensions used for each device + if "vnpn" in device: + loops = 3 + else: + loops = 2 + + # Extracting measured values for each W & L + for i in range (start,loops+start): + + # Special case for 1st measured values + if i == 0 : + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_{device}.csv", index = False) + else: + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}.{i}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_{device}.csv", index = False) + +def ext_simulated(device,vn,d_in,cv_sim, corner,temp,dirpath,cap): + + # Get dimensions used for each device + netlist_tmp = f"./device_netlists/{cap}.spice" + + if "EBJ" in cap: i = 0 + elif "CBJ" in cap: i = 1 + else: i =2 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{cv_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i}_{device}_netlist_{device}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, i = i , temp = temp, cv_sim = cv_sim , corner = corner )) + netlist_path = f"{dirpath}/{device}_netlists_{cv_sim}/{i}_{device}_netlist_{device}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv",index= False) + df_simulated.columns = [f"{vn}",f"{d_in}_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv",index= False) + +def error_cal(device,vn,d_in,cv_sim, corner,temp,dirpath): + + # Get dimensions used for each device + loops = 2 + df_final = pd.DataFrame() + for i in range (0,loops): + if i == 0 : cap = "EBJ" + elif i == 1 : cap = "CBJ" + else : cap = "CSJ" + + measured = pd.read_csv(f"{dirpath}/measured_{cv_sim}/{i}_measured_{device}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{cv_sim}/{i}_{device}_error_{device}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{d_in}_{corner}"].mean()) + # Max error + max_error = df_error[f"{d_in}_{corner}"].max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vds = df_error[f"{vn}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'corner': f'{corner}' , 'Junction': f'{cap}', 'Simulated_Val':f'{cv_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & vn (V) = {max_location_vds}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{cv_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{cv_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + corners = ["typical","ff","ss"] + temps = [ 25 , -40 , 175 ] + measure = ["cv","Vj", "bjt", 31] + cv_sim, bjt_vn, bjt_in = measure[0], measure[1], measure[2] + + #vnpn + npn_devices = ["vnpn_10x10" , "vnpn_5x5" , "vnpn_0p54x16" , "vnpn_0p54x8" , "vnpn_0p54x4" , "vnpn_0p54x2"] + npn_start = 0 + + for corner in corners: + for temp in temps: + for device in npn_devices: + # Folder structure of measured values + dirpath = f"{device}_{cv_sim}_{corner}_T{temp}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/{bjt_in}_{cv_sim}_npn.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + ext_measured (device,bjt_vn,bjt_in, cv_sim, corner,npn_start,dirpath) + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"npn_EBJ") + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"npn_CBJ") + # ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"npn_CSJ") + error_cal (device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath) + + npn_start = npn_start + 3 + npn_start = 0 + + # vpnp + pnp_devices = ["vpnp_0p42x10" , "vpnp_0p42x5" , "vpnp_10x10" , "vpnp_5x5"] + pnp_start = 0 + + for corner in corners: + for temp in temps: + for device in pnp_devices: + # Folder structure of measured values + dirpath = f"{device}_{cv_sim}_{corner}_T{temp}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/{bjt_in}_{cv_sim}_pnp.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + ext_measured (device,bjt_vn,bjt_in, cv_sim, corner,pnp_start,dirpath) + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"pnp_EBJ") + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"pnp_CBJ") + error_cal (device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath) + + pnp_start = pnp_start + 2 + pnp_start = 0 + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/bjt_iv/.spiceinit b/models/ngspice/testing/regression/bjt_iv/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_iv/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/bjt_iv/device_netlists/npn.spice b/models/ngspice/testing/regression/bjt_iv/device_netlists/npn.spice new file mode 100644 index 00000000..792e40cd --- /dev/null +++ b/models/ngspice/testing/regression/bjt_iv/device_netlists/npn.spice @@ -0,0 +1,29 @@ +***************** +** main netlist +***************** + +Vcp c 0 dc 6 +Ib 0 b 9u + +.temp {{temp}} +.options tnom={{temp}} + +xq1 c b 0 0 {{device}} + + +***************** +** Analysis +***************** + +.control +set filetype=ascii + +dc Vcp 0 6 0.1 Ib 1u 9u 2u +print -i(Vcp) +wrdata npn/simulated_IcVc/{{i}}_simulated_{{device}}.csv -i(Vcp) +.endc + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_typical + +.end diff --git a/models/ngspice/testing/regression/bjt_iv/device_netlists/pnp.spice b/models/ngspice/testing/regression/bjt_iv/device_netlists/pnp.spice new file mode 100644 index 00000000..0233ac68 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_iv/device_netlists/pnp.spice @@ -0,0 +1,29 @@ +***************** +** main netlist +***************** + +Vcp c 0 dc -3 +Ib 0 b -9u + +.temp {{temp}} +.options tnom={{temp}} + +xq1 c b 0 {{device}} + + +***************** +** Analysis +***************** + +.control +set filetype=ascii + +dc Vcp 0 -3 -0.1 Ib -1u -9u -2u +print -i(Vcp) +wrdata pnp/simulated_IcVc/{{i}}_simulated_{{device}}.csv i(Vcp) +.endc + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_typical + +.end diff --git a/models/ngspice/testing/regression/bjt_iv/device_netlists/run_npn_vcic.spice b/models/ngspice/testing/regression/bjt_iv/device_netlists/run_npn_vcic.spice new file mode 100644 index 00000000..48f9bb3d --- /dev/null +++ b/models/ngspice/testing/regression/bjt_iv/device_netlists/run_npn_vcic.spice @@ -0,0 +1,30 @@ + +***************** +** main netlist +***************** + +Vcp c 0 dc 6 +Ib 0 b 9u + +.temp 25 +.options tnom=25 + +xq1 c b 0 0 vnpn_10x10 + + +***************** +** Analysis +***************** + +.control +set filetype=ascii + +dc Vcp 0 6 0.1 Ib 1u 9u 2u +print -i(Vcp) +wrdata result.csv -i(Vcp) +.endc + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" bjt_typical + +.end diff --git a/models/ngspice/testing/regression/bjt_iv/models_regression.py b/models/ngspice/testing/regression/bjt_iv/models_regression.py new file mode 100644 index 00000000..a6630d03 --- /dev/null +++ b/models/ngspice/testing/regression/bjt_iv/models_regression.py @@ -0,0 +1,208 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vc,step,Id_sim,list_devices,ib): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + + # Extracting measured values for each Device + for i in range (loops): + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + # Special case for 1st measured values + if i == 0 : + if device == "pnp": + temp_vc = vc + vc = "-vc " + # measured Id_sim + col_list = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv", index = False) + else: + if device == "pnp": + vc = temp_vc + # measured Id_sim + col_list = [f"{vc}",f"{ib}{step[0]}.{i}",f"{ib}{step[1]}.{i}",f"{ib}{step[2]}.{i}",f"{ib}{step[3]}.{i}",f"{ib}{step[4]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv", index = False) + +def ext_simulated(device,vc,step,sweep,Id_sim,list_devices,ib): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + netlist_tmp = f"./device_netlists/{device}.spice" + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{Id_sim}",exist_ok=True) + with open(f"{device}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_{list_devices[k]}.spice", "w") as netlist: + netlist.write(tmpl.render(device = list_devices[k], i = i , temp = temp )) + netlist_path = f"{device}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_{list_devices[k]}.spice" + + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv",header=None, delimiter=r"\s+") + + # empty array to append in it shaped (sweep, number of trials + 1) + new_array = np.empty((sweep, 1+int(df_simulated.shape[0]/sweep))) + new_array[:, 0] = df_simulated.iloc[:sweep, 0] + times = int(df_simulated.shape[0]/sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*sweep:(j+1)*sweep, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv",index= False) + df_simulated.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_simulated.to_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv",index= False) + +def error_cal(device,vc,step,Id_sim,list_devices,ib): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + measured = pd.read_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv") + simulated = pd.read_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[0:, 1]) - abs(simulated.iloc[0:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[0:, 2]) - abs(simulated.iloc[0:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[0:, 3]) - abs(simulated.iloc[0:, 3]))/abs(measured.iloc[:, 3])),6) + error_4 = round (100 * abs((abs(measured.iloc[0:, 4]) - abs(simulated.iloc[0:, 4]))/abs(measured.iloc[:, 4])),6) + error_5 = round (100 * abs((abs(measured.iloc[0:, 5]) - abs(simulated.iloc[0:, 5]))/abs(measured.iloc[:, 5])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5]).transpose() + df_error.to_csv(f"{device}/error_{Id_sim}/{i}_{device}_error_{list_devices[k]}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{ib}{step[0]}"].mean() + df_error[f"{ib}{step[1]}"].mean() + df_error[f"{ib}{step[2]}"].mean() + + df_error[f"{ib}{step[3]}"].mean() + df_error[f"{ib}{step[4]}"].mean())/6 + # Max error + max_error = df_error[[f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_ib = (df_error == max_error).idxmax(axis=1)[max_index] + if i == 0 : + if device == "pnp": + temp_vc = vc + vc = "-vc " + else: + if device == "pnp": + vc = temp_vc + max_location_vc = df_error[f"{vc}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'device': f'{list_devices[k]}','Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_ib} & Vc (V) = {max_location_vc}'} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["npn","pnp"] + list_devices = [["vnpn_10x10" , "vnpn_5x5" , "vnpn_0p54x16" , "vnpn_0p54x8" , "vnpn_0p54x4", "vnpn_0p54x2"], + ["vpnp_0p42x10" , "vpnp_0p42x5", "vpnp_10x10" , "vpnp_5x5"]] + vc = ["vcp ","-vc (A)"] + ib = ["ibp =","ib =-"] + Id_sim = "IcVc" + sweep = [61,31] + step = [ "1.000E-06" , "3.000E-06" , "5.000E-06" , "7.000E-06" , "9.000E-06"] + + for i, device in enumerate(devices): + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/bjt_{device}_icvc_f.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False) + + # =========== Simulate ============== + ext_measured (device,vc[i],step,Id_sim,list_devices[i],ib[i]) + + ext_simulated(device,vc[i],step,sweep[i],Id_sim,list_devices[i],ib[i]) + + # ============ Results ============= + error_cal (device,vc[i],step,Id_sim,list_devices[i],ib[i]) + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/diode/.spiceinit b/models/ngspice/testing/regression/diode/.spiceinit new file mode 100644 index 00000000..7779a4cc --- /dev/null +++ b/models/ngspice/testing/regression/diode/.spiceinit @@ -0,0 +1,2 @@ +* user provided init file +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/diode/0_measured_data/dnwps_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/dnwps_cv.nl_out.xlsx new file mode 100644 index 00000000..cdcbf271 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/dnwps_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/dnwps_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/dnwps_iv.nl_out.xlsx new file mode 100644 index 00000000..d9d62db3 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/dnwps_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/dnwpw_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/dnwpw_cv.nl_out.xlsx new file mode 100644 index 00000000..82a005e9 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/dnwpw_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/dnwpw_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/dnwpw_iv.nl_out.xlsx new file mode 100644 index 00000000..25d7edfc Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/dnwpw_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/np_3p3_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/np_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..aea9c001 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/np_3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/np_3p3_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/np_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..f4527e09 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/np_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/np_6p0_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/np_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..cd49396b Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/np_6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/np_6p0_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/np_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..08807f63 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/np_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/nwp_3p3_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/nwp_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..65e5dd5a Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/nwp_3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/nwp_3p3_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/nwp_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..0c964d83 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/nwp_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/nwp_6p0_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/nwp_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..725218c5 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/nwp_6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/nwp_6p0_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/nwp_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9321fb63 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/nwp_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/pn_3p3_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/pn_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..004bb411 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/pn_3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/pn_3p3_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/pn_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..c45be6c1 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/pn_3p3_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/pn_6p0_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/pn_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..b9edd0a3 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/pn_6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/pn_6p0_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/pn_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9cbce9b0 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/pn_6p0_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/sc_diode_cv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/sc_diode_cv.nl_out.xlsx new file mode 100644 index 00000000..05546aee Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/sc_diode_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/0_measured_data/sc_diode_iv.nl_out.xlsx b/models/ngspice/testing/regression/diode/0_measured_data/sc_diode_iv.nl_out.xlsx new file mode 100644 index 00000000..1d60cf54 Binary files /dev/null and b/models/ngspice/testing/regression/diode/0_measured_data/sc_diode_iv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/diode/device_netlists/cv.spice b/models/ngspice/testing/regression/diode/device_netlists/cv.spice new file mode 100644 index 00000000..c53922b9 --- /dev/null +++ b/models/ngspice/testing/regression/diode/device_netlists/cv.spice @@ -0,0 +1,55 @@ +*************************** +** CV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vn n 0 dc 1 + + +.temp {{temp}} +.options tnom={{temp}} + + +dn n 0 {{device}} AREA = {{area}}p PJ = {{pj}}u + +.control +set filetype=ascii + +let vn_min = 0 +let vn_step = -0.2 +let vn_max = -3.2 + +option TEMP={{temp}} + +save @dn[cd] +******************* +** simulation part +******************* +DC Vn $&vn_min $&vn_max $&vn_step + +* ** parameters calculation + +print @dn[cd]*1000000000000000 + +wrdata {{device}}_{{Id_sim}}_{{corner}}/simulated_{{Id_sim}}/{{i}}_simulated_A{{area}}_P{{pj}}.csv @dn[cd]*1000000000000000 + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" diode_{{corner}} + + +.end \ No newline at end of file diff --git a/models/ngspice/testing/regression/diode/device_netlists/iv.spice b/models/ngspice/testing/regression/diode/device_netlists/iv.spice new file mode 100644 index 00000000..e66427c1 --- /dev/null +++ b/models/ngspice/testing/regression/diode/device_netlists/iv.spice @@ -0,0 +1,47 @@ +*************************** +** IV netlist generation ** +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vn n 0 dc 1 + +.temp {{temp}} +.options tnom={{temp}} + + + +dn1 n 0 {{device}} AREA = {{area}}p PJ = {{pj}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vn -12.13 1.13 0.13 +print abs(i(Vn)) +wrdata {{device}}_{{Id_sim}}_{{corner}}/simulated_{{Id_sim}}/{{i}}_simulated_A{{area}}_P{{pj}}.csv abs(i(Vn)) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" diode_{{corner}} + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/diode/models_regression.py b/models/ngspice/testing/regression/diode/models_regression.py new file mode 100644 index 00000000..eddc91a3 --- /dev/null +++ b/models/ngspice/testing/regression/diode/models_regression.py @@ -0,0 +1,196 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vn,d_in, Id_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["W (um)"].iloc[i] + length = dimensions["L (um)"].iloc[i] + + # Special case for 1st measured values + if i == 0 : + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{Id_sim}/{i}_measured_A{width}_P{length}.csv", index = False) + else: + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}.{i}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{Id_sim}/{i}_measured_A{width}_P{length}.csv", index = False) + +def ext_simulated(device,vn,d_in,vn_sweeps,Id_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + netlist_tmp = f"./device_netlists/{Id_sim}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + + if i % 4 == 0: temp = -40 + elif i % 4 == 1: temp = 25 + elif i % 4 == 2: temp = 125 + else: + temp = 175 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{Id_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_A{width}_P{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, area = width, pj = length, i = i , temp = temp, Id_sim = Id_sim , corner = corner )) + netlist_path = f"{dirpath}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_A{width}_P{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",index= False) + + # empty array to append in it shaped (vn_sweeps, number of trials + 1) + new_array = np.empty((vn_sweeps, 1+int(df_simulated.shape[0]/vn_sweeps))) + new_array[:, 0] = df_simulated.iloc[:vn_sweeps, 0] + times = int(df_simulated.shape[0]/vn_sweeps) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vn_sweeps:(j+1)*vn_sweeps, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",index= False) + df_simulated.columns = [f"{vn}",f"{d_in}_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",index= False) + +def error_cal(device,vn,d_in,Id_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i % 4 == 0: temp = -40 + elif i % 4 == 1: temp = 25 + elif i % 4 == 2: temp = 125 + else: + temp = 175 + + measured = pd.read_csv(f"{dirpath}/measured_{Id_sim}/{i}_measured_A{width}_P{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{Id_sim}/{i}_{device}_error_A{width}_P{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{d_in}_{corner}"].mean())/6 + # Max error + max_error = df_error[f"{d_in}_{corner}"].max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vds = df_error[f"{vn}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{dirpath}', 'Area': f'{width}', 'Perimeter': f'{length}', 'Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & vn (V) = {max_location_vds}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["dnwps","dnwpw","np_3p3","np_6p0", "nwp_3p3","nwp_6p0","pn_3p3","pn_6p0","sc_diode"] + corners = ["typical","ff","ss"] + measures = [["iv","Vn1 (V)", " |In1(A)| diode", 103], + ["cv","Vj", "diode", 17]] + + for device in devices: + for measure in measures: + for corner in corners: + # Folder structure of measured values + Id_sim, diode_vn, diode_in, no_of_vn_sweeps = measure[0], measure[1], measure[2], measure[3] + dirpath = f"{device}_{Id_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{Id_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"./0_measured_data/{device}_{Id_sim}.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{Id_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{Id_sim}",exist_ok=False) + + ext_measured (device,diode_vn,diode_in, Id_sim, corner) + + ext_simulated(device,diode_vn,diode_in,no_of_vn_sweeps,Id_sim, corner) + error_cal (device,diode_vn,diode_in,Id_sim, corner) + + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/mimcap_c/.spiceinit b/models/ngspice/testing/regression/mimcap_c/.spiceinit new file mode 100644 index 00000000..7779a4cc --- /dev/null +++ b/models/ngspice/testing/regression/mimcap_c/.spiceinit @@ -0,0 +1,2 @@ +* user provided init file +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/mimcap_c/device_netlists/.spiceinit b/models/ngspice/testing/regression/mimcap_c/device_netlists/.spiceinit new file mode 100644 index 00000000..84222e23 --- /dev/null +++ b/models/ngspice/testing/regression/mimcap_c/device_netlists/.spiceinit @@ -0,0 +1,5 @@ + +* user provided init file +set ngbehavior=hs + + diff --git a/models/ngspice/testing/regression/mimcap_c/device_netlists/mimcap.spice b/models/ngspice/testing/regression/mimcap_c/device_netlists/mimcap.spice new file mode 100644 index 00000000..b2d8736c --- /dev/null +++ b/models/ngspice/testing/regression/mimcap_c/device_netlists/mimcap.spice @@ -0,0 +1,38 @@ +*************************** +** cap +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +.options noacct + +Ich 0 p dc 10u + +.temp 25 +.options tnom=25 + +xcn p 0 {{device}} c_length={{length}}u c_width={{width}}u + +.ic v(p)=0.0 +.tran 10ns 100us + +* .print tran v(p) cj=par('10.0e-6 * time / v(p)') + +.meas tran CV FIND par('(10.0e-6 * time / v(p))*1.0e15') AT=100us + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" mimcap_{{corner}} +.end + diff --git a/models/ngspice/testing/regression/mimcap_c/models_regression.py b/models/ngspice/testing/regression/mimcap_c/models_regression.py new file mode 100644 index 00000000..ee4a8959 --- /dev/null +++ b/models/ngspice/testing/regression/mimcap_c/models_regression.py @@ -0,0 +1,163 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vn,d_in, cv_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 100 ; length = 100 + if i == 1+start: width = 5 ; length = 5 + if i == 2+start: width = 100 ; length = 5 + if i == 3+start: width = 5 ; length = 100 + + # measured cv + col_list = [f"{vn}",f"{d_in}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.loc[i:i].to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_w{width}_l{length}.csv", index=False) + +def ext_simulated(device,vn,d_in,cv_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + netlist_tmp = f"./device_netlists/mimcap.spice" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 100 ; length = 100 + if i == 1+start: width = 5 ; length = 5 + if i == 2+start: width = 100 ; length = 5 + if i == 3+start: width = 5 ; length = 100 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{cv_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, width = width, length = length , corner = corner )) + netlist_path = f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice.log") + clean_data = str(df_simulated.loc[4]).replace("Compatibility modes selected: hs","").replace("\nName: 4, dtype: object","").split("=") + df_clean_ = {vn: [f"moscap_{corner}"],d_in: [clean_data[1]]} + df_clean = pd.DataFrame(df_clean_) + df_clean.to_csv(f"{dirpath}/simulated_{cv_sim}/{i-start}_simulated_w{width}_l{length}.csv",index= False) + +def error_cal(device,vn,d_in,Id_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + df_final = pd.DataFrame() + for i in range (start,4+start): + if i == 0+start: width = 100 ; length = 100 + if i == 1+start: width = 5 ; length = 5 + if i == 2+start: width = 100 ; length = 5 + if i == 3+start: width = 5 ; length = 100 + + measured = pd.read_csv(f"{dirpath}/measured_{Id_sim}/{i-start}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i-start}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{Id_sim}/{i-start}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{d_in}"].mean()) + # Max error + max_error = df_error[f"{d_in}"].max() + + df_final_ = {'Run no.': f'{i-start}', 'Device name': f'{dirpath}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + + +def main(): + + # mim + corners = ["ss" , "typical","ff"] + devices = ["mim_1p5fF" , "mim_1p0fF" , "mim_2p0fF"] + measure = ["cv","corners", "CV (fF)"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + dirpath = f"{device}_{cv_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + + ext_measured (device,cap_vn,cap_in, cv_sim, corner,start) + ext_simulated(device,cap_vn,cap_in,cv_sim, corner,start) + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = start + 24 + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/mos_cv/.spiceinit b/models/ngspice/testing/regression/mos_cv/.spiceinit new file mode 100644 index 00000000..0be699c7 --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/.spiceinit @@ -0,0 +1,4 @@ + +* user provided init file +set ngbehavior=hs + diff --git a/models/ngspice/testing/regression/mos_cv/device_netlists_Cgc/nmos_3p3_cv.spice b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgc/nmos_3p3_cv.spice new file mode 100644 index 00000000..f381eff3 --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgc/nmos_3p3_cv.spice @@ -0,0 +1,74 @@ +*************************** +** nmos_3p3_cv +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=0 +vgs G_tn 0 dc=3.3 +vbs S_tn 0 dc=0 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn nmos_3p3 W = {{width}}u L = {{length}}u nf={{nf}} ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vgs_min = -3.3 +let vgs_step = 0.1 +let vgs_max = 3.3 + +compose vbs_vector start=0 stop=-3.3 step=-0.825 + +set appendwrite + +foreach t 25 + + let vbs_counter = 0 + while vbs_counter < length(vbs_vector) + option TEMP=25 + alter vbs = vbs_vector[vbs_counter] + + save @mn[vs] @mn[vgs] @mn[id] @mn[cgb] + ******************* + ** simulation part + ******************* + DC vgs $&vgs_min $&vgs_max $&vgs_step + + * ** parameters calculation + + print @mn[cgb] + + wrdata nmos_3p3_cv/simulated_Cgc/{{i}}_simulated_W{{width}}_L{{length}}.csv {@mn[cgb]*1e15} + + reset + let vbs_counter = vbs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_cv/device_netlists_Cgc/pmos_3p3_cv.spice b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgc/pmos_3p3_cv.spice new file mode 100644 index 00000000..f7d8b080 --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgc/pmos_3p3_cv.spice @@ -0,0 +1,74 @@ +*************************** +** pmos_3p3_cv +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=0 +vgs G_tn 0 dc=3.3 +vbs S_tn 0 dc=0 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn pmos_3p3 W = {{width}}u L = {{length}}u nf={{nf}} ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vgs_min = -3.3 +let vgs_step = 0.1 +let vgs_max = 3.3 + +compose vbs_vector start=0 stop=3.3 step=0.825 + +set appendwrite + +foreach t 25 + + let vbs_counter = 0 + while vbs_counter < length(vbs_vector) + option TEMP=25 + alter vbs = vbs_vector[vbs_counter] + + save @mn[vs] @mn[vgs] @mn[id] @mn[cgb] + ******************* + ** simulation part + ******************* + DC vgs $&vgs_min $&vgs_max $&vgs_step + + * ** parameters calculation + + print @mn[cgb] + + wrdata pmos_3p3_cv/simulated_Cgc/{{i}}_simulated_W{{width}}_L{{length}}.csv {@mn[cgb]*1e15} + + reset + let vbs_counter = vbs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_cv/device_netlists_Cgd/nmos_3p3_cv.spice b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgd/nmos_3p3_cv.spice new file mode 100644 index 00000000..8d4ed65c --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgd/nmos_3p3_cv.spice @@ -0,0 +1,74 @@ +*************************** +** nmos_3p3_cv +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=3.3 +vgs G_tn 0 dc=3.3 +vs S_tn 0 dc=0.2 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn nmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.1 +let vds_max = 3.3 + +compose vgs_vector start=0 stop=3.3 step=1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgd] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgd] + + wrdata nmos_3p3_cv/simulated_Cgd/{{i}}_simulated_W{{width}}_L{{length}}.csv {@mn[cgd]*1e15} + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_cv/device_netlists_Cgd/pmos_3p3_cv.spice b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgd/pmos_3p3_cv.spice new file mode 100644 index 00000000..ae302a10 --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgd/pmos_3p3_cv.spice @@ -0,0 +1,74 @@ +*************************** +** pmos_3p3_cv +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-3.3 +vgs G_tn 0 dc=-3.3 +vs S_tn 0 dc=0.2 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn pmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.1 +let vds_max = -3.3 + +compose vgs_vector start=0 stop=-3.3 step=-1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgs] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgd] + + wrdata pmos_3p3_cv/simulated_Cgd/{{i}}_simulated_W{{width}}_L{{length}}.csv {@mn[cgd]*1e15} + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_cv/device_netlists_Cgs/nmos_3p3_cv.spice b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgs/nmos_3p3_cv.spice new file mode 100644 index 00000000..6bb276ff --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgs/nmos_3p3_cv.spice @@ -0,0 +1,74 @@ +*************************** +** nmos_3p3_cv +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=3.3 +vgs G_tn 0 dc=3.3 +vs S_tn 0 dc=0.1 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn nmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.1 +let vds_max = 3.3 + +compose vgs_vector start=0 stop=3.3 step=1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgs] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgs] + + wrdata nmos_3p3_cv/simulated_Cgs/{{i}}_simulated_W{{width}}_L{{length}}.csv {@mn[cgs]*1e15} + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_cv/device_netlists_Cgs/pmos_3p3_cv.spice b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgs/pmos_3p3_cv.spice new file mode 100644 index 00000000..eaa97b0a --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/device_netlists_Cgs/pmos_3p3_cv.spice @@ -0,0 +1,74 @@ +*************************** +** pmos_3p3_cv +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-3.3 +vgs G_tn 0 dc=-3.3 +vs S_tn 0 dc=0.1 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn pmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.1 +let vds_max = -3.3 + +compose vgs_vector start=0 stop=-3.3 step=-1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgs] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgs] + + wrdata pmos_3p3_cv/simulated_Cgs/{{i}}_simulated_W{{width}}_L{{length}}.csv {@mn[cgs]*1e15} + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_cv/measured_data/3p3_cv.nl_out.xlsx b/models/ngspice/testing/regression/mos_cv/measured_data/3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..813635cd Binary files /dev/null and b/models/ngspice/testing/regression/mos_cv/measured_data/3p3_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/mos_cv/measured_data/3p3_sab_cv.nl_out.xlsx b/models/ngspice/testing/regression/mos_cv/measured_data/3p3_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..fd139e1f Binary files /dev/null and b/models/ngspice/testing/regression/mos_cv/measured_data/3p3_sab_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/mos_cv/measured_data/6p0_cv.nl_out.xlsx b/models/ngspice/testing/regression/mos_cv/measured_data/6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..a6d80eec Binary files /dev/null and b/models/ngspice/testing/regression/mos_cv/measured_data/6p0_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/mos_cv/measured_data/6p0_nat_cv.nl_out.xlsx b/models/ngspice/testing/regression/mos_cv/measured_data/6p0_nat_cv.nl_out.xlsx new file mode 100644 index 00000000..407129c7 Binary files /dev/null and b/models/ngspice/testing/regression/mos_cv/measured_data/6p0_nat_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/mos_cv/measured_data/6p0_sab_cv.nl_out.xlsx b/models/ngspice/testing/regression/mos_cv/measured_data/6p0_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..1dbd85c5 Binary files /dev/null and b/models/ngspice/testing/regression/mos_cv/measured_data/6p0_sab_cv.nl_out.xlsx differ diff --git a/models/ngspice/testing/regression/mos_cv/models_regression.py b/models/ngspice/testing/regression/mos_cv/models_regression.py new file mode 100644 index 00000000..f4cdf849 --- /dev/null +++ b/models/ngspice/testing/regression/mos_cv/models_regression.py @@ -0,0 +1,293 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,sweep_x,sweep_y,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = int(dimensions["L (um)"].count()/2) + + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + # Special case for 1st measured values + if i == 0 : + # measured Cgc + if sim_val == "Cgc": + col_list = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]] + else: + # measured Cgs & Cgd + if sim_val == "Cgs": + col_list = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]] + else: + col_list = [sweep_x,f"{sweep_y[0]}.1",f"{sweep_y[1]}.1",f"{sweep_y[2]}.1",f"{sweep_y[3]}.1"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]] + df_measured.to_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv", index = False) + else: + # measured Cgc + if sim_val == "Cgc": + col_list = [sweep_x,f"{sweep_y[0]}.{i}",f"{sweep_y[1]}.{i}",f"{sweep_y[2]}.{i}",f"{sweep_y[3]}.{i}",f"{sweep_y[4]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,f"{sweep_y[0]}",f"{sweep_y[1]}",f"{sweep_y[2]}",f"{sweep_y[3]}",f"{sweep_y[4]}"] + else: + # measured Cgs & Cgd + cgs_index = 2*i + cgd_index = cgs_index + 1 + if sim_val == "Cgs": + col_list = [sweep_x,f"{sweep_y[0]}.{cgs_index}",f"{sweep_y[1]}.{cgs_index}",f"{sweep_y[2]}.{cgs_index}",f"{sweep_y[3]}.{cgs_index}"] + else: + col_list = [sweep_x,f"{sweep_y[0]}.{cgd_index}",f"{sweep_y[1]}.{cgd_index}",f"{sweep_y[2]}.{cgd_index}",f"{sweep_y[3]}.{cgd_index}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,f"{sweep_y[0]}",f"{sweep_y[1]}",f"{sweep_y[2]}",f"{sweep_y[3]}"] + + df_measured.to_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv", index = False) + +def ext_simulated(device,sweep_x,sweep_y,vds_sweep,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = int(dimensions["L (um)"].count()/2) + + netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i == 0: + nf = 20 + else: + nf = 1 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True) + with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist: + netlist.write(tmpl.render(width = width,length = length,i = i, nf = nf )) + netlist_path = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + + # empty array to append in it shaped (vds_sweep, number of trials + 1) + new_array = np.empty((vds_sweep, 1+int(df_simulated.shape[0]/vds_sweep))) + new_array[:, 0] = df_simulated.iloc[:vds_sweep, 0] + times = int(df_simulated.shape[0]/vds_sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vds_sweep:(j+1)*vds_sweep, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + if sim_val == "Cgc": + df_simulated.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]] + else: + df_simulated.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]] + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + +def error_cal(device,sweep_x,sweep_y,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = int(dimensions["L (um)"].count()/2) + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + + measured = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv") + simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv") + + error_1 = round (100 * (abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1]),6) + error_2 = round (100 * (abs(measured.iloc[:, 2]) - abs(simulated.iloc[:, 2]))/abs(measured.iloc[:, 2]),6) + error_3 = round (100 * (abs(measured.iloc[:, 3]) - abs(simulated.iloc[:, 3]))/abs(measured.iloc[:, 3]),6) + error_4 = round (100 * (abs(measured.iloc[:, 4]) - abs(simulated.iloc[:, 4]))/abs(measured.iloc[:, 4]),6) + if sim_val == "Cgc": + error_5 = round (100 * (abs(measured.iloc[:, 5]) - abs(simulated.iloc[:, 5]))/abs(measured.iloc[:, 5]),6) + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5]).transpose() + else: + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4]).transpose() + df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False) + + # Mean error + if sim_val == "Cgc": + mean_error = (df_error[sweep_y[0]].mean() + df_error[sweep_y[1]].mean() + df_error[sweep_y[2]].mean() + + df_error[sweep_y[3]].mean() + df_error[sweep_y[4]].mean())/5 + else: + mean_error = (df_error[sweep_y[0]].mean() + df_error[sweep_y[1]].mean() + df_error[sweep_y[2]].mean() + + df_error[sweep_y[3]].mean())/4 + # Max error + if sim_val == "Cgc": + max_error = df_error[[sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]]].max().max() + else: + max_error = df_error[[sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_sweep_y = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_sweep_x = df_error[sweep_x][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'25', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_sweep_y} & {sweep_x}= {max_location_sweep_x}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["nmos_3p3_cv" , "pmos_3p3_cv" ] + measured_data = ["3p3_cv"] + nmos_vds = "Vds (V)" + pmos_vds = "-Vds (V)" + nmos_vgs = "Vgs (V)" + pmos_vgs = "-Vgs (V)" + nmos_rds = "Rds" + cgc_sim = "Cgc" + cgs_sim = "Cgs" + cgd_sim = "Cgd" + Rds_sim = "Rds" + mos_3p3_vbs_sweep = 67 + mos_3p3_vgs_sweep = 34 + + mos_6p0_vgs_sweep = 133 + + nmos3p3_vgs = ["Vgs=0" , "Vgs=1.1" , "Vgs=2.2" , "Vgs=3.3" ] + pmos3p3_vgs = ["Vgs=-0" , "Vgs=-1.1" , "Vgs=-2.2" , "Vgs=-3.3"] + # pmos3p3_vgs = [-0.8 , -1.3 , -1.8 , -2.3 , -2.8 , -3.3] + # nmos6p0_vgs = [ 1 , 2 , 3 , 4 , 5 , 6] + # pmos6p0_vgs = [-1 , -2 , -3 , -4 , -5 , -6] + # nmos6p0_nat_vgs = [ 0.25 , 1.4 , 2.55 , 3.7 , 4.85 , 6] + + nmos3p3_vbs = ["Vbs=0" , "Vbs=-0.825" , "Vbs=-1.65" , "Vbs=-2.475" , "Vbs=-3.3"] + pmos3p3_vbs = ["Vbs=-0" , "Vbs=0.825" , "Vbs=1.65" , "Vbs=2.475" , "Vbs=3.3" ] + # nmos6p0_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + # pmos6p0_vbs = [ 0 , 0.75 , 1.5 , 2.25 , 3] + # nmos6p0_nat_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + + for device in devices: + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{cgc_sim}",exist_ok=False) + os.makedirs(f"{device}/measured_{cgs_sim}",exist_ok=False) + os.makedirs(f"{device}/measured_{cgd_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"./measured_data/{measured_data[0]}.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{cgc_sim}",exist_ok=False) + os.makedirs(f"{device}/simulated_{cgs_sim}",exist_ok=False) + os.makedirs(f"{device}/simulated_{cgd_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{cgc_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{cgs_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{cgd_sim}",exist_ok=False) + + + # =========== nmos_3p3_cv ============== + # Cgc + ext_measured ("nmos_3p3_cv",nmos_vgs,nmos3p3_vbs,cgc_sim) + ext_simulated("nmos_3p3_cv",nmos_vgs,nmos3p3_vbs,mos_3p3_vbs_sweep,cgc_sim) + error_cal ("nmos_3p3_cv",nmos_vgs,nmos3p3_vbs,cgc_sim) + + # Cgs + ext_measured ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgs_sim) + ext_simulated("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,cgs_sim) + error_cal ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgs_sim) + + # Cgd + ext_measured ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgd_sim) + ext_simulated("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,cgd_sim) + error_cal ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgd_sim) + + + # =========== nmos_3p3_cv ============== + # Cgc + ext_measured ("pmos_3p3_cv",pmos_vgs,pmos3p3_vbs,cgc_sim) + ext_simulated("pmos_3p3_cv",pmos_vgs,pmos3p3_vbs,mos_3p3_vbs_sweep,cgc_sim) + error_cal ("pmos_3p3_cv",pmos_vgs,pmos3p3_vbs,cgc_sim) + + # Cgs + ext_measured ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgs_sim) + ext_simulated("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,mos_3p3_vgs_sweep,cgs_sim) + error_cal ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgs_sim) + + # Cgd + ext_measured ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgd_sim) + ext_simulated("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,mos_3p3_vgs_sweep,cgd_sim) + error_cal ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgd_sim) + + # =========== pmos_3p3_iv ============== + + + # =========== nmos_6p0_iv ============== + + + # =========== pmos_6p0_iv ============== + + + # ============ nmos_3p3_sab_iv ============= # Error in ngspice + + + # ============ nmos_6p0_nat_iv ============= + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/mos_iv_vbs/.spiceinit b/models/ngspice/testing/regression/mos_iv_vbs/.spiceinit new file mode 100644 index 00000000..0be699c7 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/.spiceinit @@ -0,0 +1,4 @@ + +* user provided init file +set ngbehavior=hs + diff --git a/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_3p3_iv.spice b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_3p3_iv.spice new file mode 100644 index 00000000..47ce6c1e --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_3p3_iv.spice @@ -0,0 +1,48 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* power supply +Vds D_tn 0 dc=0.05 +Vgs G_tn 0 dc=3.3 +Vbs B_tn 0 dc=0 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 B_tn nmos_3p3 W = {{width}}u L = {{length}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vgs 0 3.3 0.05 Vbs 0 -3.3 -0.825 +print -i(Vds) +wrdata nmos_3p3_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_6p0_iv.spice b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_6p0_iv.spice new file mode 100644 index 00000000..0551cd7f --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_6p0_iv.spice @@ -0,0 +1,48 @@ +*************************** +** nmos_6p0_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* power supply +Vds D_tn 0 dc=0.05 +Vgs G_tn 0 dc=6 +Vbs S_tn 0 dc=0 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 S_tn nmos_6p0 W = {{width}}u L = {{length}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vgs 0 6 0.05 Vbs 0 -3 -0.75 +print -i(Vds) +wrdata nmos_6p0_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_6p0_nat_iv.spice b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_6p0_nat_iv.spice new file mode 100644 index 00000000..3c50e5fc --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_6p0_nat_iv.spice @@ -0,0 +1,48 @@ +*************************** +** nmos_6p0_nat_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* power supply +Vds D_tn 0 dc=0.05 +Vgs G_tn 0 dc=6 +Vbs S_tn 0 dc=0 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 S_tn nmos_6p0_nat W = {{width}}u L = {{length}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vgs -0.5 6 0.05 Vbs 0 -3 -0.75 +print -i(Vds) +wrdata nmos_6p0_nat_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/pmos_3p3_iv.spice b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/pmos_3p3_iv.spice new file mode 100644 index 00000000..5a4a87ab --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/pmos_3p3_iv.spice @@ -0,0 +1,48 @@ +*************************** +** pmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* power supply +Vds D_tn 0 dc=-0.05 +Vgs G_tn 0 dc=-3.3 +Vbs S_tn 0 dc=0 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 S_tn pmos_3p3 W = {{width}}u L = {{length}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vgs 0 -3.3 -0.05 Vbs 0 3.3 0.825 +print -i(Vds) +wrdata pmos_3p3_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/pmos_6p0_iv.spice b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/pmos_6p0_iv.spice new file mode 100644 index 00000000..e2237f21 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/device_netlists_Id/pmos_6p0_iv.spice @@ -0,0 +1,50 @@ +*************************** +** pmos_6p0_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* power supply +Vds D_tn 0 dc=-0.05 +Vgs G_tn 0 dc=-6 +Vbs S_tn 0 dc=0 + + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 S_tn pmos_6p0 W = {{width}}u L = {{length}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vgs 0 -6 -0.05 Vbs 0 3 0.75 +print -i(Vds) +wrdata pmos_6p0_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vbs/models_regression.py b/models/ngspice/testing/regression/mos_iv_vbs/models_regression.py new file mode 100644 index 00000000..675229e5 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vbs/models_regression.py @@ -0,0 +1,237 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vgs,vbs): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops*2,2): + width = dimensions["W (um)"].iloc[int(i/2)] + length = dimensions["L (um)"].iloc[int(i/2)] + + # Special case for 1st measured values + if i == 0 : + # measured Id + if device in ["pmos_3p3_iv" , "pmos_6p0_iv"]: + col_list = ['-vgs ',f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + else: + col_list = ['vgs ',f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vgs}",f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + else: + # measured Id + col_list = [f"{vgs}",f"vbs ={vbs[0]}.{i}",f"vbs ={vbs[1]}.{i}",f"vbs ={vbs[2]}.{i}",f"vbs ={vbs[3]}.{i}",f"vbs ={vbs[4]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vgs}",f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + + +def ext_simulated(device,vgs,vbs,vbs_sweep,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + AD = float(width) * 0.24 + PD = 2 * (float(width) + 0.24) + AS = AD + PS = PD + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: + temp = 125 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True) + with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist: + netlist.write(tmpl.render(width = width,length = length,i = i , temp = temp , AD = AD , PD = PD , AS = AS , PS = PD )) + netlist_path = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + + # empty array to append in it shaped (vbs_sweep, number of trials + 1) + new_array = np.empty((vbs_sweep, 1+int(df_simulated.shape[0]/vbs_sweep))) + new_array[:, 0] = df_simulated.iloc[:vbs_sweep, 0] + times = int(df_simulated.shape[0]/vbs_sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vbs_sweep:(j+1)*vbs_sweep, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + df_simulated.columns = [f"{vgs}",f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + +def error_cal(device,vgs,vbs,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: temp = 125 + + measured = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv") + simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[:, 2]) - abs(simulated.iloc[:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[:, 3]) - abs(simulated.iloc[:, 3]))/abs(measured.iloc[:, 3])),6) + error_4 = round (100 * abs((abs(measured.iloc[:, 4]) - abs(simulated.iloc[:, 4]))/abs(measured.iloc[:, 4])),6) + error_5 = round (100 * abs((abs(measured.iloc[:, 5]) - abs(simulated.iloc[:, 5]))/abs(measured.iloc[:, 5])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5]).transpose() + df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"vbs ={vbs[0]}"].mean() + df_error[f"vbs ={vbs[1]}"].mean() + df_error[f"vbs ={vbs[2]}"].mean() + + df_error[f"vbs ={vbs[3]}"].mean() + df_error[f"vbs ={vbs[4]}"].mean())/6 + # Max error + max_error = df_error[[f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vbs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vgs = df_error[f"{vgs}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & vbs (V) = {max_location_vbs}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["nmos_3p3_iv" , "pmos_3p3_iv" , "nmos_6p0_iv" , "pmos_6p0_iv" , "nmos_6p0_nat_iv"] #"nmos_3p3_sab_iv" + nmos_vgs = "vgs (V)" + pmos_vgs = "-vgs (V)" + nmos_rds = "Rds" + Id_sim = "Id" + Rds_sim = "Rds" + mos_3p3_vbs_sweep = 67 + mos_6p0_vbs_sweep = 121 + mos_6p0_nat_vbs_sweep = 131 + nmos3p3_vbs = [0 , -0.825 , -1.65 , -2.48 , -3.3] + pmos3p3_vbs = [0 , 0.825 , 1.65 , 2.48 , 3.3] + nmos6p0_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + pmos6p0_vbs = [ 0 , 0.75 , 1.5 , 2.25 , 3] + nmos6p0_nat_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + + for device in devices: + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False) + # os.makedirs(f"{device}/measured_{Rds_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/MOS/{device}.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False) + # os.makedirs(f"{device}/simulated_{Rds_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False) + # os.makedirs(f"{device}/error_{Rds_sim}",exist_ok=False) + + # =========== nmos_3p3_iv ============== + ext_measured ("nmos_3p3_iv",nmos_vgs,nmos3p3_vbs) + ext_simulated("nmos_3p3_iv",nmos_vgs,nmos3p3_vbs,mos_3p3_vbs_sweep,Id_sim) + error_cal ("nmos_3p3_iv",nmos_vgs,nmos3p3_vbs,Id_sim) + + # =========== pmos_3p3_iv ============== + ext_measured ("pmos_3p3_iv",pmos_vgs,pmos3p3_vbs) + ext_simulated("pmos_3p3_iv",pmos_vgs,pmos3p3_vbs,mos_3p3_vbs_sweep,Id_sim) + error_cal ("pmos_3p3_iv",pmos_vgs,pmos3p3_vbs,Id_sim) + + # =========== nmos_6p0_iv ============== + ext_measured ("nmos_6p0_iv",nmos_vgs,nmos6p0_vbs) + ext_simulated("nmos_6p0_iv",nmos_vgs,nmos6p0_vbs,mos_6p0_vbs_sweep,Id_sim) + error_cal ("nmos_6p0_iv",nmos_vgs,nmos6p0_vbs,Id_sim) + + # =========== pmos_6p0_iv ============== + ext_measured ("pmos_6p0_iv",pmos_vgs,pmos6p0_vbs) + ext_simulated("pmos_6p0_iv",pmos_vgs,pmos6p0_vbs,mos_6p0_vbs_sweep,Id_sim) + error_cal ("pmos_6p0_iv",pmos_vgs,pmos6p0_vbs,Id_sim) + + # ============ nmos_3p3_sab_iv ============= # Error in ngspice + # ext_measured ("nmos_3p3_sab_iv",nmos_vgs,nmos3p3_vbs) + # ext_simulated("nmos_3p3_sab_iv",nmos_vgs,nmos3p3_vbs,mos_3p3_vbs_sweep,Id_sim) + # error_cal ("nmos_3p3_sab_iv",nmos_vgs,nmos3p3_vbs,Rds_sim) + + # ============ nmos_6p0_nat_iv ============= + ext_measured ("nmos_6p0_nat_iv",nmos_vgs,nmos6p0_nat_vbs) + ext_simulated("nmos_6p0_nat_iv",nmos_vgs,nmos6p0_nat_vbs,mos_6p0_nat_vbs_sweep,Id_sim) + error_cal ("nmos_6p0_nat_iv",nmos_vgs,nmos6p0_nat_vbs,Id_sim) + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() \ No newline at end of file diff --git a/models/ngspice/testing/regression/mos_iv_vgs/.spiceinit b/models/ngspice/testing/regression/mos_iv_vgs/.spiceinit new file mode 100644 index 00000000..0be699c7 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/.spiceinit @@ -0,0 +1,4 @@ + +* user provided init file +set ngbehavior=hs + diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_W0.22_L0.5.ods b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_W0.22_L0.5.ods new file mode 100644 index 00000000..9a12f212 Binary files /dev/null and b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_W0.22_L0.5.ods differ diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_measured_W0.22_L0.5.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_measured_W0.22_L0.5.csv new file mode 100644 index 00000000..b6563074 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_measured_W0.22_L0.5.csv @@ -0,0 +1,68 @@ +vds (V),vgs =0.8_mea,vgs =1.3_mea,vgs =1.8_mea,vgs =2.3_mea,vgs =2.8_mea,vgs =3.3_mea +0,0,0,0,0,0,0 +0.05,0.000000394808,0.00000250744,0.00000415488,0.00000540081,0.00000635234,0.0000070844 +0.1,0.000000599289,0.00000469955,0.00000796984,0.0000104601,0.0000123724,0.0000138509 +0.15,0.000000675551,0.00000659522,0.0000114625,0.0000151936,0.0000180738,0.0000203114 +0.2,0.000000703823,0.00000821193,0.0000146493,0.000019616,0.0000234695,0.000026477 +0.25,0.000000719359,0.00000956596,0.0000175456,0.0000237412,0.0000285717,0.0000323583 +0.3,0.00000073047,0.0000106727,0.0000201655,0.0000275821,0.0000333918,0.0000379655 +0.35,0.000000739448,0.0000115474,0.0000225223,0.0000311509,0.000037941,0.0000433083 +0.4,0.000000747171,0.0000122074,0.000024628,0.0000344592,0.0000422294,0.0000483957 +0.45,0.000000754064,0.0000126791,0.0000264939,0.0000375176,0.0000462669,0.0000532366 +0.5,0.000000760366,0.0000130039,0.0000281296,0.000040336,0.0000500628,0.0000578394 +0.55,0.000000766223,0.0000132304,0.0000295432,0.0000429238,0.0000536257,0.0000622118 +0.6,0.000000771734,0.0000133967,0.0000307404,0.000045289,0.0000569639,0.0000663615 +0.65,0.000000776969,0.0000135258,0.000031726,0.0000474388,0.000060085,0.0000702956 +0.7,0.000000781977,0.000013631,0.0000325086,0.0000493786,0.0000629959,0.0000740209 +0.75,0.000000786795,0.0000137197,0.0000331103,0.0000511113,0.0000657028,0.0000775436 +0.8,0.000000791454,0.0000137967,0.0000335682,0.0000526365,0.000068211,0.0000808698 +0.85,0.000000795976,0.0000138648,0.0000339219,0.0000539506,0.0000705243,0.0000840048 +0.9,0.00000080038,0.0000139261,0.0000342032,0.0000550503,0.0000726444,0.0000869533 +0.95,0.00000080468,0.000013982,0.0000344339,0.0000559425,0.0000745699,0.0000897193 +1,0.000000808889,0.0000140335,0.0000346285,0.0000566516,0.0000762953,0.0000923055 +1.05,0.000000813017,0.0000140813,0.0000347963,0.0000572141,0.0000778115,0.0000947128 +1.1,0.000000817074,0.000014126,0.0000349439,0.0000576666,0.0000791096,0.0000969396 +1.15,0.000000821066,0.0000141682,0.0000350756,0.0000580386,0.0000801907,0.0000989809 +1.2,0.000000825,0.0000142081,0.0000351946,0.0000583513,0.0000810732,0.000100827 +1.25,0.000000828881,0.000014246,0.0000353034,0.0000586196,0.0000817895,0.000102465 +1.3,0.000000832715,0.0000142822,0.0000354036,0.000058854,0.0000823753,0.000103883 +1.35,0.000000836505,0.0000143169,0.0000354967,0.0000590619,0.0000828619,0.000105083 +1.4,0.000000840256,0.0000143502,0.0000355836,0.0000592486,0.0000832735,0.000106079 +1.45,0.00000084397,0.0000143823,0.0000356653,0.0000594181,0.0000836278,0.000106901 +1.5,0.000000847651,0.0000144134,0.0000357424,0.0000595734,0.0000839377,0.000107584 +1.55,0.000000851301,0.0000144434,0.0000358154,0.0000597167,0.0000842125,0.000108158 +1.6,0.000000854924,0.0000144725,0.000035885,0.0000598498,0.0000844591,0.000108648 +1.65,0.00000085852,0.0000145008,0.0000359513,0.0000599743,0.0000846827,0.000109072 +1.7,0.000000862094,0.0000145284,0.0000360149,0.0000600912,0.0000848871,0.000109444 +1.75,0.000000865647,0.0000145552,0.0000360759,0.0000602015,0.0000850756,0.000109776 +1.8,0.00000086918,0.0000145814,0.0000361346,0.000060306,0.0000852504,0.000110073 +1.85,0.000000872698,0.000014607,0.0000361912,0.0000604053,0.0000854135,0.000110344 +1.9,0.000000876202,0.0000146321,0.0000362458,0.0000605,0.0000855663,0.000110591 +1.95,0.000000879694,0.0000146567,0.0000362988,0.0000605906,0.0000857103,0.000110819 +2,0.000000883178,0.0000146808,0.0000363501,0.0000606774,0.0000858464,0.00011103 +2.05,0.000000886656,0.0000147045,0.0000364,0.0000607608,0.0000859756,0.000111227 +2.1,0.000000890133,0.0000147278,0.0000364485,0.0000608412,0.0000860985,0.000111412 +2.15,0.000000893611,0.0000147508,0.0000364957,0.0000609187,0.0000862159,0.000111586 +2.2,0.000000897095,0.0000147734,0.0000365418,0.0000609936,0.0000863281,0.000111751 +2.25,0.000000900589,0.0000147958,0.0000365868,0.0000610661,0.0000864358,0.000111907 +2.3,0.000000904098,0.000014818,0.0000366308,0.0000611364,0.0000865394,0.000112055 +2.35,0.000000907628,0.00001484,0.000036674,0.0000612047,0.0000866391,0.000112196 +2.4,0.000000911185,0.0000148619,0.0000367164,0.0000612711,0.0000867353,0.000112331 +2.45,0.000000914776,0.0000148837,0.0000367581,0.0000613359,0.0000868283,0.000112461 +2.5,0.000000918408,0.0000149056,0.0000367992,0.0000613991,0.0000869184,0.000112585 +2.55,0.000000922089,0.0000149275,0.0000368398,0.0000614608,0.0000870057,0.000112705 +2.6,0.000000925828,0.0000149496,0.0000368801,0.0000615213,0.0000870905,0.000112821 +2.65,0.000000929635,0.0000149719,0.0000369202,0.0000615808,0.0000871731,0.000112932 +2.7,0.000000933521,0.0000149945,0.0000369601,0.0000616392,0.0000872535,0.00011304 +2.75,0.000000937496,0.0000150176,0.0000370002,0.0000616969,0.0000873321,0.000113145 +2.8,0.000000941573,0.0000150412,0.0000370404,0.000061754,0.000087409,0.000113246 +2.85,0.000000945765,0.0000150655,0.0000370811,0.0000618108,0.0000874844,0.000113345 +2.9,0.000000950086,0.0000150906,0.0000371225,0.0000618673,0.0000875586,0.000113441 +2.95,0.000000954551,0.0000151167,0.0000371646,0.000061924,0.0000876318,0.000113535 +3,0.000000959177,0.0000151438,0.000037208,0.0000619811,0.0000877043,0.000113627 +3.05,0.00000096398,0.0000151723,0.0000372527,0.0000620388,0.0000877763,0.000113717 +3.1,0.00000096898,0.0000152021,0.0000372991,0.0000620976,0.0000878482,0.000113805 +3.15,0.000000974195,0.0000152337,0.0000373475,0.0000621577,0.0000879203,0.000113893 +3.2,0.000000979646,0.0000152671,0.0000373982,0.0000622196,0.000087993,0.000113979 +3.25,0.000000985354,0.0000153025,0.0000374518,0.0000622838,0.0000880667,0.000114066 +3.3,0.000000991344,0.0000153403,0.0000375085,0.0000623507,0.000088142,0.000114152 diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_simulated_W0.22_L0.5.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_simulated_W0.22_L0.5.csv new file mode 100644 index 00000000..559bf1da --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/48_W0.22_L0.5_id/48_simulated_W0.22_L0.5.csv @@ -0,0 +1,68 @@ +vds (V),vgs =0.8,vgs =1.3,vgs =1.8,vgs =2.3,vgs =2.8,vgs =3.3 +0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0 +0.05,3.22975818e-07,2.43157729e-06,4.09284118e-06,5.34817009e-06,6.3062549e-06,7.04303691e-06 +0.1,4.73071201e-07,4.55021762e-06,7.84708646e-06,1.03557458e-05,1.22809248e-05,1.37688149e-05 +0.15,5.22055208e-07,6.374768e-06,1.1280361e-05,1.50384049e-05,1.79376507e-05,2.01890947e-05 +0.2,5.40679521e-07,7.92268471e-06,1.44090676e-05,1.9410865e-05,2.32893288e-05,2.6315059e-05 +0.25,5.51695359e-07,9.21026143e-06,1.72484754e-05,2.348695e-05,2.83481576e-05,3.21573459e-05 +0.3,5.59915347e-07,1.02530145e-05,1.9812787e-05,2.72796465e-05,3.31256801e-05,3.77260797e-05 +0.35,5.66722321e-07,1.10666892e-05,2.21151771e-05,3.08011505e-05,3.76328221e-05,4.30308996e-05 +0.4,5.72672907e-07,1.16704247e-05,2.41677853e-05,3.40629013e-05,4.18799238e-05,4.80809843e-05 +0.45,5.78045815e-07,1.20941843e-05,2.59816266e-05,3.70755973e-05,4.58767664e-05,5.2885075e-05 +0.5,5.83001365e-07,1.23833907e-05,2.75663671e-05,3.98491846e-05,4.963259e-05,5.74514943e-05 +0.55,5.87640754e-07,1.25858737e-05,2.89299281e-05,4.23928002e-05,5.31561019e-05,6.17881613e-05 +0.6,5.92032203e-07,1.27359725e-05,3.00781939e-05,4.47146361e-05,5.64554683e-05,6.59026025e-05 +0.65,5.96224007e-07,1.28537477e-05,3.10163684e-05,4.68216674e-05,5.95382827e-05,6.98019558e-05 +0.7,6.00251662e-07,1.29504451e-05,3.17551904e-05,4.87191541e-05,6.24114941e-05,7.34929653e-05 +0.75,6.04142056e-07,1.30325963e-05,3.23200019e-05,5.04098419e-05,6.508127e-05,7.69819631e-05 +0.8,6.07916057e-07,1.31042102e-05,3.27494245e-05,5.18930755e-05,6.75527479e-05,8.02748297e-05 +0.85,6.11590195e-07,1.31678835e-05,3.30822055e-05,5.31651395e-05,6.98296037e-05,8.33769212e-05 +0.9,6.15177791e-07,1.32253787e-05,3.33480736e-05,5.42239257e-05,7.19133463e-05,8.62929434e-05 +0.95,6.18689737e-07,1.32779404e-05,3.35671619e-05,5.5078809e-05,7.38023091e-05,8.90267371e-05 +1.0,6.22135057e-07,1.33264769e-05,3.37526468e-05,5.57566042e-05,7.54907048e-05,9.15809225e-05 +1.05,6.25521309e-07,1.33716705e-05,3.3913231e-05,5.6294539e-05,7.69692357e-05,9.39563273e-05 +1.1,6.28854889e-07,1.34140451e-05,3.40548112e-05,5.67282911e-05,7.82300418e-05,9.61511324e-05 +1.15,6.32141255e-07,1.3454012e-05,3.41815036e-05,5.70858708e-05,7.92762668e-05,9.81598107e-05 +1.2,6.35385106e-07,1.34918993e-05,3.42962667e-05,5.73873704e-05,8.01284864e-05,9.99724573e-05 +1.25,6.38590517e-07,1.35279731e-05,3.44012836e-05,5.76468022e-05,8.08200577e-05,0.000101576191 +1.3,6.41761046e-07,1.35624516e-05,3.44982045e-05,5.78739646e-05,8.13864272e-05,0.000102960854 +1.35,6.44899828e-07,1.35955165e-05,3.45883026e-05,5.807582e-05,8.18578436e-05,0.00010412798 +1.4,6.48009642e-07,1.36273203e-05,3.46725789e-05,5.825742e-05,8.22574483e-05,0.000105095839 +1.45,6.51092978e-07,1.36579922e-05,3.47518332e-05,5.84225099e-05,8.26021608e-05,0.000105895033 +1.5,6.54152089e-07,1.36876428e-05,3.48267139e-05,5.85739247e-05,8.29042181e-05,0.000106559196 +1.55,6.5718904e-07,1.37163674e-05,3.48977531e-05,5.87138513e-05,8.31725263e-05,0.000107118221 +1.6,6.60205754e-07,1.37442488e-05,3.49653929e-05,5.88440069e-05,8.3413658e-05,0.000107595914 +1.65,6.63204051e-07,1.37713594e-05,3.50300041e-05,5.89657603e-05,8.36325464e-05,0.000108010297 +1.7,6.66185693e-07,1.37977631e-05,3.50919009e-05,5.90802185e-05,8.38329589e-05,0.000108374781 +1.75,6.69152418e-07,1.38235168e-05,3.51513515e-05,5.91882878e-05,8.40178207e-05,0.000108699352 +1.8,6.72105985e-07,1.38486714e-05,3.52085868e-05,5.92907191e-05,8.41894393e-05,0.000108991508 +1.85,6.75048205e-07,1.38732733e-05,3.52638071e-05,5.93881403e-05,8.43496608e-05,0.000109256959 +1.9,6.77980985e-07,1.38973652e-05,3.53171876e-05,5.9481082e-05,8.4499982e-05,0.000109500113 +1.95,6.80906363e-07,1.39209872e-05,3.53688826e-05,5.9569996e-05,8.46416309e-05,0.000109724423 +2.0,6.83826546e-07,1.39441772e-05,3.54190291e-05,5.96552703e-05,8.47756258e-05,0.000109932633 +2.05,6.8674395e-07,1.39669725e-05,3.54677501e-05,5.97372405e-05,8.49028197e-05,0.00011012695 +2.1,6.89661232e-07,1.39894098e-05,3.55151576e-05,5.98161993e-05,8.50239335e-05,0.000110309173 +2.15,6.92581334e-07,1.40115264e-05,3.55613544e-05,5.98924037e-05,8.51395817e-05,0.000110480783 +2.2,6.95507514e-07,1.40333611e-05,3.56064371e-05,5.99660814e-05,8.52502917e-05,0.000110643012 +2.25,6.98443385e-07,1.40549546e-05,3.56504979e-05,6.00374362e-05,8.53565205e-05,0.000110796896 +2.3,7.01392952e-07,1.40763505e-05,3.56936266e-05,6.01066527e-05,8.54586659e-05,0.000110943311 +2.35,7.04360645e-07,1.40975957e-05,3.57359129e-05,6.01739001e-05,8.55570779e-05,0.000111083007 +2.4,7.07351354e-07,1.41187416e-05,3.57774479e-05,6.02393365e-05,8.56520665e-05,0.000111216627 +2.45,7.10370467e-07,1.41398444e-05,3.58183266e-05,6.03031122e-05,8.57439093e-05,0.000111344731 +2.5,7.13423899e-07,1.41609658e-05,3.5858649e-05,6.03653733e-05,8.58328577e-05,0.000111467806 +2.55,7.16518129e-07,1.4182174e-05,3.58985226e-05,6.04262647e-05,8.59191429e-05,0.000111586281 +2.6,7.1966023e-07,1.42035438e-05,3.59380641e-05,6.04859337e-05,8.60029808e-05,0.000111700538 +2.65,7.22857903e-07,1.42251578e-05,3.59774005e-05,6.05445331e-05,8.60845775e-05,0.000111810918 +2.7,7.26119505e-07,1.42471066e-05,3.60166719e-05,6.06022241e-05,8.61641334e-05,0.000111917733 +2.75,7.29454081e-07,1.42694895e-05,3.60560323e-05,6.06591795e-05,8.62418485e-05,0.000112021269 +2.8,7.32871395e-07,1.42924152e-05,3.60956516e-05,6.07155868e-05,8.63179265e-05,0.000112121795 +2.85,7.36381953e-07,1.4316002e-05,3.61357172e-05,6.07716507e-05,8.63925793e-05,0.00011221957 +2.9,7.39997036e-07,1.43403788e-05,3.61764354e-05,6.08275968e-05,8.64660314e-05,0.000112314846 +2.95,7.43728719e-07,1.43656853e-05,3.6218033e-05,6.08836737e-05,8.65385243e-05,0.000112407877 +3.0,7.47589903e-07,1.43920724e-05,3.62607589e-05,6.0940156e-05,8.66103205e-05,0.000112498923 +3.05,7.51594332e-07,1.44197029e-05,3.6304885e-05,6.09973468e-05,8.66817079e-05,0.000112588255 +3.1,7.55756619e-07,1.44487519e-05,3.63507081e-05,6.10555808e-05,8.67530037e-05,0.000112676164 +3.15,7.60092264e-07,1.44794069e-05,3.63985508e-05,6.11152262e-05,8.68245585e-05,0.000112762962 +3.2,7.64617674e-07,1.45118686e-05,3.64487628e-05,6.11766874e-05,8.68967599e-05,0.000112848992 +3.25,7.69350179e-07,1.4546351e-05,3.65017222e-05,6.12404072e-05,8.69700366e-05,0.000112934629 +3.3,7.74308048e-07,1.45830818e-05,3.65578365e-05,6.13068695e-05,8.70448619e-05,0.000113020288 diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_W0.22_L0.28.ods b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_W0.22_L0.28.ods new file mode 100644 index 00000000..46c102bc Binary files /dev/null and b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_W0.22_L0.28.ods differ diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_measured_W0.22_L0.28.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_measured_W0.22_L0.28.csv new file mode 100644 index 00000000..7a22f998 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_measured_W0.22_L0.28.csv @@ -0,0 +1,80 @@ +vds (V),vgs =0.8,vgs =1.3,vgs =1.8,vgs =2.3,vgs =2.8,vgs =3.3 +0.0,0.0,0.0,0.0,0.0,0.0,0.0 +0.05,9.63741e-07,4.4867e-06,6.8598e-06,8.50294e-06,9.69135e-06,1.05788e-05 +0.1,1.53924e-06,8.34359e-06,1.30622e-05,1.63683e-05,1.878e-05,2.05934e-05 +0.15,1.83889e-06,1.16297e-05,1.8658e-05,2.36382e-05,2.73005e-05,3.00724e-05 +0.2,1.99847e-06,1.43967e-05,2.36926e-05,3.03509e-05,3.5285e-05,3.90427e-05 +0.25,2.10372e-06,1.66898e-05,2.82063e-05,3.65412e-05,4.27629e-05,4.75291e-05 +0.3,2.18687e-06,1.8549e-05,3.22351e-05,4.22407e-05,4.97614e-05,5.5555e-05 +0.35,2.25925e-06,2.00126e-05,3.58101e-05,4.74783e-05,5.63057e-05,6.31421e-05 +0.4,2.32554e-06,2.11271e-05,3.89574e-05,5.22795e-05,6.24188e-05,7.03105e-05 +0.45,2.38801e-06,2.19584e-05,4.16972e-05,5.66669e-05,6.81219e-05,7.70792e-05 +0.5,2.44795e-06,2.25849e-05,4.40432e-05,6.06592e-05,7.3434e-05,8.34656e-05 +0.55,2.50611e-06,2.30746e-05,4.6006e-05,6.42711e-05,7.83719e-05,8.94857e-05 +0.6,2.56302e-06,2.34745e-05,4.7604e-05,6.7511e-05,8.29498e-05,9.5154e-05 +0.65,2.61901e-06,2.38141e-05,4.88771e-05,7.03809e-05,8.7179e-05,0.000100484 +0.7,2.67433e-06,2.41117e-05,4.98869e-05,7.28776e-05,9.10661e-05,0.000105486 +0.75,2.72917e-06,2.43789e-05,5.06992e-05,7.49994e-05,9.46128e-05,0.000110169 +0.8,2.78366e-06,2.46232e-05,5.13687e-05,7.67607e-05,9.78138e-05,0.000114539 +0.85,2.8379e-06,2.48499e-05,5.19356e-05,7.82005e-05,0.000100658,0.000118598 +0.9,2.89199e-06,2.50627e-05,5.24274e-05,7.93761e-05,0.000103136,0.000122343 +0.95,2.94599e-06,2.52642e-05,5.2863e-05,8.03467e-05,0.000105248,0.000125764 +1.0,2.99996e-06,2.54564e-05,5.32556e-05,8.11628e-05,0.000107016,0.000128846 +1.05,3.05394e-06,2.56408e-05,5.36145e-05,8.1863e-05,0.000108485,0.000131575 +1.1,3.10797e-06,2.58187e-05,5.39464e-05,8.24752e-05,0.000109709,0.000133942 +1.15,3.16209e-06,2.5991e-05,5.42564e-05,8.30196e-05,0.000110742,0.000135961 +1.2,3.2163e-06,2.61584e-05,5.45482e-05,8.35109e-05,0.000111626,0.000137665 +1.25,3.27065e-06,2.63216e-05,5.48247e-05,8.39596e-05,0.000112396,0.000139101 +1.3,3.32515e-06,2.6481e-05,5.50883e-05,8.43738e-05,0.000113077,0.000140319 +1.35,3.37982e-06,2.66372e-05,5.53407e-05,8.47594e-05,0.000113687,0.000141365 +1.4,3.43466e-06,2.67904e-05,5.55835e-05,8.51213e-05,0.00011424,0.000142275 +1.45,3.4897e-06,2.6941e-05,5.58178e-05,8.5463e-05,0.000114747,0.000143078 +1.5,3.54494e-06,2.70892e-05,5.60447e-05,8.57874e-05,0.000115216,0.000143794 +1.55,3.6004e-06,2.72353e-05,5.6265e-05,8.60969e-05,0.000115654,0.000144442 +1.6,3.65608e-06,2.73795e-05,5.64794e-05,8.63934e-05,0.000116064,0.000145034 +1.65,3.71199e-06,2.75219e-05,5.66884e-05,8.66785e-05,0.000116452,0.000145579 +1.7,3.76815e-06,2.76627e-05,5.68928e-05,8.69534e-05,0.00011682,0.000146085 +1.75,3.82455e-06,2.7802e-05,5.70927e-05,8.72194e-05,0.000117171,0.000146558 +1.8,3.88121e-06,2.794e-05,5.72888e-05,8.74773e-05,0.000117506,0.000147003 +1.85,3.93813e-06,2.80767e-05,5.74813e-05,8.77279e-05,0.000117829,0.000147424 +1.9,3.99533e-06,2.82124e-05,5.76704e-05,8.7972e-05,0.000118139,0.000147823 +1.95,4.05281e-06,2.83469e-05,5.78566e-05,8.82101e-05,0.000118439,0.000148204 +2.0,4.11059e-06,2.84806e-05,5.804e-05,8.84428e-05,0.000118729,0.000148569 +2.05,4.16867e-06,2.86134e-05,5.82208e-05,8.86706e-05,0.000119011,0.000148919 +2.1,4.22709e-06,2.87454e-05,5.83992e-05,8.88937e-05,0.000119285,0.000149256 +2.15,4.28585e-06,2.88768e-05,5.85756e-05,8.91127e-05,0.000119552,0.000149582 +2.2,4.34497e-06,2.90076e-05,5.87499e-05,8.93278e-05,0.000119812,0.000149897 +2.25,4.40448e-06,2.9138e-05,5.89225e-05,8.95394e-05,0.000120066,0.000150203 +2.3,4.46441e-06,2.9268e-05,5.90935e-05,8.97478e-05,0.000120315,0.0001505 +2.35,4.52479e-06,2.93978e-05,5.92631e-05,8.99532e-05,0.000120559,0.000150789 +2.4,4.58566e-06,2.95275e-05,5.94315e-05,9.01558e-05,0.000120798,0.000151071 +2.45,4.64706e-06,2.96573e-05,5.95989e-05,9.03561e-05,0.000121033,0.000151346 +2.5,4.70903e-06,2.97874e-05,5.97655e-05,9.05542e-05,0.000121264,0.000151615 +2.55,4.77164e-06,2.99179e-05,5.99317e-05,9.07505e-05,0.000121492,0.000151879 +2.6,4.83494e-06,3.0049e-05,6.00976e-05,9.09452e-05,0.000121716,0.000152137 +2.65,4.899e-06,3.0181e-05,6.02637e-05,9.11387e-05,0.000121938,0.000152391 +2.7,4.9639e-06,3.03142e-05,6.04302e-05,9.13314e-05,0.000122157,0.00015264 +2.75,5.02973e-06,3.04488e-05,6.05975e-05,9.15236e-05,0.000122374,0.000152886 +2.8,5.09657e-06,3.05852e-05,6.07661e-05,9.17159e-05,0.000122589,0.000153128 +2.85,5.16454e-06,3.07237e-05,6.09364e-05,9.19086e-05,0.000122804,0.000153367 +2.9,5.23375e-06,3.08646e-05,6.1109e-05,9.21025e-05,0.000123018,0.000153604 +2.95,5.30433e-06,3.10086e-05,6.12845e-05,9.2298e-05,0.000123232,0.000153838 +3.0,5.37641e-06,3.11559e-05,6.14634e-05,9.24958e-05,0.000123446,0.000154072 +3.05,5.45016e-06,3.13072e-05,6.16466e-05,9.26968e-05,0.000123662,0.000154305 +3.1,5.52572e-06,3.14629e-05,6.18347e-05,9.29017e-05,0.00012388,0.000154537 +3.15,5.6033e-06,3.16238e-05,6.20287e-05,9.31115e-05,0.0001241,0.000154771 +3.2,5.68307e-06,3.17904e-05,6.22294e-05,9.33272e-05,0.000124325,0.000155006 +3.25,5.76525e-06,3.19634e-05,6.24379e-05,9.355e-05,0.000124555,0.000155243 +3.3,5.85006e-06,3.21437e-05,6.26553e-05,9.37809e-05,0.000124791,0.000155484 +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_simulated_W0.22_L0.28.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_simulated_W0.22_L0.28.csv new file mode 100644 index 00000000..0b155935 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Id/49_W0.22_L0.28_id/49_simulated_W0.22_L0.28.csv @@ -0,0 +1,68 @@ +vds (V),vgs =0.8,vgs =1.3,vgs =1.8,vgs =2.3,vgs =2.8,vgs =3.3 +0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0 +0.05,7.45110275e-07,4.30992195e-06,6.73573635e-06,8.40973068e-06,9.61747374e-06,1.05177665e-05 +0.1,1.14787859e-06,7.99557834e-06,1.28149982e-05,1.61814243e-05,1.86313228e-05,2.04703056e-05 +0.15,1.3378652e-06,1.1116265e-05,1.82889138e-05,2.33574517e-05,2.70764632e-05,2.9886548e-05 +0.2,1.44062798e-06,1.37238871e-05,2.32031543e-05,2.9976375e-05,3.49850972e-05,3.87934431e-05 +0.25,1.51339311e-06,1.58640641e-05,2.75984142e-05,3.60732842e-05,4.23869381e-05,4.72161098e-05 +0.3,1.57398124e-06,1.75778465e-05,3.15106613e-05,4.16800483e-05,4.93093966e-05,5.51779678e-05 +0.35,1.62850042e-06,1.89066912e-05,3.49710733e-05,4.68254625e-05,5.57777249e-05,6.27008481e-05 +0.4,1.67954465e-06,1.99038903e-05,3.80055631e-05,5.1535257e-05,6.18151125e-05,6.98050819e-05 +0.45,1.72842228e-06,2.06426046e-05,4.06339946e-05,5.58319e-05,6.74427175e-05,7.65095639e-05 +0.5,1.77587873e-06,2.12014099e-05,4.28702151e-05,5.97340983e-05,7.26796093e-05,8.28317845e-05 +0.55,1.82237721e-06,2.1642574e-05,4.47264474e-05,6.32558909e-05,7.75425798e-05,8.87878199e-05 +0.6,1.86822461e-06,2.20069087e-05,4.62257015e-05,6.64053963e-05,8.20457579e-05,9.43922632e-05 +0.65,1.91363432e-06,2.23194529e-05,4.74142846e-05,6.91840043e-05,8.61999379e-05,9.96580688e-05 +0.7,1.95876051e-06,2.25956399e-05,4.83568809e-05,7.15885247e-05,9.00115486e-05,0.000104596268 +0.75,2.00371796e-06,2.28452948e-05,4.91178383e-05,7.36200066e-05,9.34813539e-05,0.000109215497 +0.8,2.04859432e-06,2.30749214e-05,4.97484587e-05,7.52976946e-05,9.66035673e-05,0.000113521265 +0.85,2.0934579e-06,2.32889901e-05,5.02853103e-05,7.66655974e-05,9.93673135e-05,0.000117514918 +0.9,2.13836285e-06,2.34906799e-05,5.07534419e-05,7.77828289e-05,0.000101763357,0.000121192432 +0.95,2.18335277e-06,2.36823187e-05,5.11699862e-05,7.87076679e-05,0.000103796107,0.000124543646 +1.0,2.22846319e-06,2.38656557e-05,5.15468482e-05,7.9488099e-05,0.00010549299,0.000127553489 +1.05,2.27372338e-06,2.40420348e-05,5.18924873e-05,8.01601527e-05,0.000106901615,0.000130207452 +1.1,2.3191577e-06,2.42125084e-05,5.22130572e-05,8.07498866e-05,0.000108077159,0.000132501641 +1.15,2.36478658e-06,2.43779148e-05,5.25131378e-05,8.12760102e-05,0.000109070698,0.000134452166 +1.2,2.41062728e-06,2.45389316e-05,5.27962094e-05,8.17520636e-05,0.000109923908,0.000136095888 +1.25,2.45669449e-06,2.46961139e-05,5.30649672e-05,8.21879924e-05,0.000110668687,0.000137481615 +1.3,2.50300078e-06,2.48499215e-05,5.33215347e-05,8.25912293e-05,0.000111328816,0.000138659044 +1.35,2.54955699e-06,2.50007396e-05,5.35676102e-05,8.29674278e-05,0.000111921934,0.000139671729 +1.4,2.59637251e-06,2.51488935e-05,5.38045708e-05,8.33209617e-05,0.000112461204,0.000140554796 +1.45,2.64345558e-06,2.52946608e-05,5.4033547e-05,8.36552685e-05,0.00011295656,0.000141335427 +1.5,2.69081349e-06,2.54382796e-05,5.42554768e-05,8.39730892e-05,0.000113415606,0.000142034314 +1.55,2.73845281e-06,2.55799564e-05,5.44711468e-05,8.42766391e-05,0.000113844245,0.000142667182 +1.6,2.78637955e-06,2.5719871e-05,5.46812222e-05,8.45677299e-05,0.000114247124,0.000143246049 +1.65,2.83459941e-06,2.58581814e-05,5.48862702e-05,8.48478595e-05,0.000114627951,0.000143780191 +1.7,2.88311792e-06,2.59950275e-05,5.50867787e-05,8.51182792e-05,0.000114989723,0.000144276852 +1.75,2.93194068e-06,2.61305343e-05,5.528317e-05,8.53800437e-05,0.000115334888,0.000144741758 +1.8,2.98107354e-06,2.62648146e-05,5.54758125e-05,8.56340492e-05,0.000115665469,0.000145179489 +1.85,3.03052283e-06,2.63979718e-05,5.56650299e-05,8.58810636e-05,0.000115983152,0.00014559375 +1.9,3.08029561e-06,2.65301018e-05,5.58511092e-05,8.61217496e-05,0.000116289356,0.000145987574 +1.95,3.13039987e-06,2.66612952e-05,5.6034307e-05,8.63566832e-05,0.000116585288,0.000146363463 +2.0,3.18084485e-06,2.67916396e-05,5.62148553e-05,8.65863689e-05,0.000116871976,0.000146723509 +2.05,3.2316413e-06,2.69212213e-05,5.63929669e-05,8.68112519e-05,0.00011715031,0.000147069466 +2.1,3.28280177e-06,2.70501274e-05,5.65688399e-05,8.70317288e-05,0.000117421058,0.000147402828 +2.15,3.33434093e-06,2.71784476e-05,5.67426619e-05,8.72481566e-05,0.000117684894,0.000147724866 +2.2,3.38627591e-06,2.73062767e-05,5.69146148e-05,8.74608605e-05,0.000117942412,0.000148036679 +2.25,3.43862669e-06,2.74337157e-05,5.70848782e-05,8.76701415e-05,0.000118194138,0.000148339217 +2.3,3.4914164e-06,2.75608746e-05,5.72536342e-05,8.78762831e-05,0.000118440545,0.00014863331 +2.35,3.5446718e-06,2.76878738e-05,5.74210707e-05,8.80795576e-05,0.000118682063,0.000148919688 +2.4,3.59842363e-06,2.78148467e-05,5.7587386e-05,8.82802325e-05,0.000118919089,0.000149198999 +2.45,3.65270708e-06,2.79419415e-05,5.77527922e-05,8.84785765e-05,0.000119151994,0.000149471826 +2.5,3.70756225e-06,2.80693231e-05,5.79175199e-05,8.86748659e-05,0.000119381136,0.000149738694 +2.55,3.76303459e-06,2.81971756e-05,5.80818216e-05,8.88693898e-05,0.000119606863,0.00015000009 +2.6,3.81917542e-06,2.83257044e-05,5.82459762e-05,8.90624572e-05,0.000119829524,0.000150256468 +2.65,3.87604245e-06,2.84551382e-05,5.84102929e-05,8.9254402e-05,0.000120049479,0.000150508262 +2.7,3.93370027e-06,2.85857312e-05,5.85751155e-05,8.94455898e-05,0.0001202671,0.000150755899 +2.75,3.99222094e-06,2.87177657e-05,5.87408264e-05,8.96364235e-05,0.000120482788,0.000150999802 +2.8,4.0516845e-06,2.88515539e-05,5.89078507e-05,8.98273498e-05,0.000120696975,0.000151240407 +2.85,4.1121796e-06,2.89874402e-05,5.90766605e-05,9.0018865e-05,0.000120910132,0.000151478169 +2.9,4.17380404e-06,2.91258039e-05,5.92477793e-05,9.02115214e-05,0.000121122781,0.000151713572 +2.95,4.23666538e-06,2.92670608e-05,5.94217857e-05,9.04059331e-05,0.000121335499,0.00015194714 +3.0,4.30088155e-06,2.94116661e-05,5.95993182e-05,9.06027828e-05,0.000121548927,0.000152179448 +3.05,4.36658147e-06,2.95601159e-05,5.97810787e-05,9.08028275e-05,0.000121763783,0.000152411129 +3.1,4.43390564e-06,2.97129502e-05,5.99678375e-05,9.10069049e-05,0.00012198086,0.000152642885 +3.15,4.50300679e-06,2.98707544e-05,6.01604364e-05,9.12159393e-05,0.000122201046,0.0001528755 +3.2,4.57405047e-06,3.00341618e-05,6.03597938e-05,9.14309482e-05,0.000122425323,0.000153109844 +3.25,4.64721571e-06,3.02038554e-05,6.05669078e-05,9.1653048e-05,0.00012265478,0.000153346889 +3.3,4.7226956e-06,3.03805702e-05,6.07828606e-05,9.18834602e-05,0.000122890617,0.000153587718 diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Rds/0_W10_L10.0_rds/0_measured_W10_L10.0.ods b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Rds/0_W10_L10.0_rds/0_measured_W10_L10.0.ods new file mode 100644 index 00000000..e64e3747 Binary files /dev/null and b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/nmos_3p3/Rds/0_W10_L10.0_rds/0_measured_W10_L10.0.ods differ diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/0_measured_W10_L10.0.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/0_measured_W10_L10.0.csv new file mode 100644 index 00000000..69951e80 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/0_measured_W10_L10.0.csv @@ -0,0 +1,80 @@ +-vds (V),vgs =-0.8,vgs =-1.3,vgs =-1.8,vgs =-2.3,vgs =-2.8,vgs =-3.3 +0.0,848229.659876871,56660.819270118,29459.593221936797,20736.304707555897,16511.458952513043,14059.991170325546 +0.05,1401830.510280324,61082.13103338749,30568.51320865456,21240.757615342627,16803.729083558224,14253.074744549269 +0.1,7056963.811889571,72354.39762793342,33056.21208865676,22326.76107909701,17420.237089426788,14655.42888379857 +0.15,44992351.300279,88628.12524926661,35981.96583872164,23529.02422783625,18083.37884317009,15080.977307653446 +0.2,162364020.1331407,113973.10234784594,39472.3338412107,24867.332779620723,18798.582586872948,15532.050385971452 +0.25,374391613.6278494,157803.3769922676,43707.05781569608,26366.44079415719,19572.535817740547,16010.502889895766 +0.3,661375661.3756175,244654.30346919785,48949.78241821715,28055.999775552,20412.329046744228,16518.823199035298 +0.35,986193293.8855648,443577.0049680621,55604.054647664925,29976.01918465229,21326.96368018085,17060.770464394176 +0.4,1314060446.7805707,947059.380623165,64313.64478287711,32177.10277366628,22326.91062537678,17639.173075566225 +0.45,1623376623.3767354,2196836.5553602832,76167.26331022922,34724.63365511494,23424.689622862497,18257.503834075804 +0.5,1904761904.7621465,4830917.874396219,93118.53990129438,37705.96885486972,24635.396137169893,18920.7598577159 +0.55,2150537634.408612,9319664.49207852,118934.34823977156,41242.21553181835,25977.399662293792,19633.6363457876 +0.6,2364066193.8535576,15698587.127158364,161420.50040355127,45502.11584838692,27473.28223302838,20401.91778027134 +0.65,2557544757.033464,23584905.660376523,237473.28425552117,50727.94602546544,29149.41992654348,21232.324090194907 +0.7,2724795640.326047,32573289.902279697,383435.5828220869,57290.17473503297,31042.403923759823,22133.197583054814 +0.75,2873563218.390609,42016806.7226882,672494.9562878325,65746.21959237344,33197.224712014126,23112.836869597395 +0.8,3003003003.0041327,51546391.75257231,1225490.1960784153,77000.07700007688,35670.97096382961,24182.627200619067 +0.85,3125000000.0003333,60975609.75609926,2178649.237472733,92609.74254491576,38538.61569292424,25356.255388204256 +0.9,3225806451.611999,69930069.9300864,3623188.405797162,115313.65313653168,41904.12336573916,26647.48048072053 +0.95,3322259136.2126546,78740157.48032084,5555555.555555921,150217.8158329579,45903.14436538903,28077.2686433064 +1.0,3412969283.2769003,86956521.73913199,7874015.748032093,206996.48105982124,50727.94602546549,29669.18854769327 +1.05,3496503496.5037417,94339622.6415062,10526315.789473137,303674.4609778317,56666.85555618523,31449.507815202727 +1.1,3571428571.427893,102040816.32649194,13333333.333331184,471698.1132075526,64131.34098634006,33454.88608611281 +1.15,3636363636.363009,108695652.17391476,16129032.258064386,757575.7575757483,73757.19132615431,35732.15179018071 +1.2,3717472118.959285,116279069.76743896,19230769.23077093,1213592.2330096934,86557.60408551907,38339.14810412916 +1.25,3773584905.659871,123456790.12347022,21739130.434783,1879699.2481203708,104210.08753647323,41351.36252739525 +1.3,3816793893.129688,128205128.20513958,24390243.902435955,2770083.102492983,129550.45990413189,44871.21959974888 +1.35,3875968992.249229,135135135.13511705,27777777.77776912,3846153.846153427,167476.13465081353,49031.625398382064 +1.4,3921568627.450599,140845070.42259586,29411764.70589109,5050505.050505204,226398.00769753224,54024.8514316583 +1.45,3968253968.254057,144927536.23188666,31250000.000014223,6369426.751593516,320102.4327784888,60121.445319545724 +1.5,4032258064.5175858,151515151.51514998,34482758.620674506,7751937.984495421,469263.2566870025,67700.22341073764 +1.55,4065040650.405397,156249999.99992636,37037037.03702557,9174311.92660536,699300.6993006909,77345.50235903733 +1.6,4098360655.7361646,161290322.58059978,40000000.00002066,10526315.789476868,1035196.6873706528,89952.32526760765 +1.65,4149377593.359931,166666666.66677156,41666666.66666348,11764705.882350575,1490312.965722843,106928.99914456894 +1.7,4184100418.410862,172413793.10347325,41666666.66666357,13157894.73683673,2057613.168724073,130514.22605063971 +1.75,4201680672.270689,178571428.5713613,45454545.45455083,14492753.623192225,2732240.437158046,164365.54898093216 +1.8,4237288135.594598,178571428.5713613,47619047.61902008,15625000.000007112,3484320.557491879,214270.40925648183 +1.85,4291845493.561748,185185185.1851565,47619047.61905839,16949152.542364895,4255319.14893665,289100.89621277264 +1.9,4310344827.584264,188679245.28308737,52631578.94739372,18181818.18181189,5076142.131979034,401284.10914927017 +1.95,4329004329.003392,192307692.30770937,52631578.94734692,18867924.52830878,5917159.763314876,564971.7514124456 +2.0,4366812227.075336,199999999.9999,52631578.9473468,19999999.999996778,6711409.395973691,794281.1755361499 +2.05,4405286343.612994,200000000.00006983,58823529.41175301,21276595.74468023,7518796.992480046,1097694.84083421 +2.1,4424778761.061079,204081632.6530725,58823529.41181163,22727272.727275416,8264462.809917754,1472754.05007379 +2.15,4424778761.061079,208333333.3332811,58823529.41181163,23809523.809529245,9009009.009005764,1915708.8122608135 +2.2,4464285714.286986,212765957.446879,62499999.99999536,23809523.809529245,9803921.568625502,2409638.554216701 +2.25,4484304932.735116,217391304.34782895,62499999.99999508,24999999.99998745,10526315.7894806,2923976.608186506 +2.3,4484304932.735136,222222222.22215343,62499999.99999536,27027027.027017288,11235955.056180812,3460207.612456465 +2.35,4504504504.505309,222222222.22215343,66666666.66667113,27027027.027042035,12048192.771077603,4016064.2570291455 +2.4,4504504504.505309,222222222.22236255,66666666.66667113,27777777.77779532,12658227.848095236,4566210.045661982 +2.45,4484304932.735136,232558139.5348779,66666666.66667113,29411764.705876507,13157894.73684846,5128205.128202799 +2.5,4464285714.284329,232558139.53487688,71428571.42858742,30303030.303025976,13888888.8888976,5649717.5141227 +2.55,4464285714.286986,232558139.5348779,71428571.42850131,31249999.99999768,14492753.623185106,6134969.32515778 +2.6,4424778761.061079,238095238.0951484,76923076.92300856,31249999.99999768,15151515.151513057,6666666.666670125 +2.65,4347826086.956599,238095238.09538847,76923076.9231088,32258064.51612884,15873015.873015229,7194244.6043113 +2.7,4273504273.505232,238095238.0951484,76923076.9231088,33333333.333335564,16393442.62295131,7692307.692306871 +2.75,4184100418.4085264,238095238.0951473,76923076.92310846,34482758.620694496,16949152.54237459,8130081.300817547 +2.8,4065040650.4075847,238095238.09538847,76923076.9231088,35714285.71429387,17543859.649126068,8547008.547004664 +2.85,3906250000.000825,232558139.5348779,83333333.33326833,35714285.71429387,18181818.18182313,9009009.009005764 +2.9,3731343283.581178,227272727.2727979,83333333.33326833,37037037.03700233,18518518.518524405,9523809.523807088 +2.95,3546099290.779785,222222222.22215343,76923076.9231088,38461538.46150428,19230769.23075214,9900990.099008128 +3.0,3322259136.212644,212765957.44668636,76923076.92310846,38461538.46155423,19999999.99998318,10309278.35052883 +3.05,3086419753.087209,200000000.00006983,83333333.33338597,38461538.4615544,20000000.00001037,10869565.217399504 +3.1,2857142857.142861,188679245.2830878,83333333.33326833,40000000.00002075,20833333.333346494,11235955.056180812 +3.15,2610966057.440821,175438596.49120852,83333333.33326833,40000000.00002075,21739130.434766985,11494252.873564882 +3.2,2369668246.445191,156249999.99992636,83333333.33338597,39999999.99996654,21739130.434766985,11904761.90475502 +3.25,2136752136.7520025,140845070.42259553,76923076.92310846,41666666.66663398,22222222.222240344,12499999.999993725 +3.3,2024291497.975792,135135135.13527146,71428571.42858742,41666666.6666928,22727272.727292813,12820512.82050694 +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, +,,,,,, diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/0_simulated_W10_L10.0.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/0_simulated_W10_L10.0.csv new file mode 100644 index 00000000..c264eca8 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/0_simulated_W10_L10.0.csv @@ -0,0 +1,68 @@ +,-vds (V),vgs =-0.8,vgs =-1.3,vgs =-1.8,vgs =-2.3,vgs =-2.8,vgs =-3.3 +0,-0.0,,,,,, +1,-0.05,852040.4247444011,56697.13691002142,29469.511948045252,20741.21786864382,16514.54502699289,14062.195527100223 +2,-0.1,1408866.1967256337,61123.87316458915,30579.121219416094,21245.872720994805,16806.88711410066,14255.321431304123 +3,-0.15,2061977.6229706989,66287.81530390415,31774.944188051948,21775.507050484557,17109.670834228884,14453.76852769568 +4,-0.2,2732852.6745590824,72378.40198664817,33067.35840582345,22332.01888335667,17423.465793054093,14657.760064428478 +5,-0.25,3407980.0098470994,79637.66544171513,34468.4333971418,22917.501111980073,17748.883037941985,14867.5318670232 +6,-0.3,4084462.424199627,88340.26287606372,35992.262959185246,23534.26702242947,18086.579515639227,15083.332773993076 +7,-0.35,4761410.158278116,98672.83291806448,37655.352549728326,24184.880559339625,18437.262284426524,15305.42645367606 +8,-0.4,5438477.965802579,110474.77945022171,39477.04170695176,24872.18835300336,18801.693169556864,15534.091764392706 +9,-0.45,6115510.147050133,123210.53434954863,41479.88504873029,25599.359073966738,19180.694830132696,15769.624430274134 +10,-0.5,6792429.144347457,136385.2080400324,43689.7630123078,26369.926377380627,19575.15577448949,16012.338159855566 +11,-0.55,7469193.673966147,149745.08784790136,46135.0953025246,27187.8371384491,19986.037971902337,16262.565807396551 +12,-0.6,8145780.858524166,163186.17570270767,48843.619573035285,28057.504603885787,20414.383402942978,16520.66110222899 +13,-0.65,8822177.770299647,176665.88989845806,51833.76827579922,28983.86191945492,20861.3230105345,16787.000231730333 +14,-0.7,9498377.134421032,190165.38468891173,55098.66301126393,29972.408813431342,21328.08511314832,17061.983563616 +15,-0.75,10174375.018496165,203675.54684175443,58592.643606096906,31029.235650673745,21816.005865957468,17346.037524960513 +16,-0.8,10850169.492735494,217191.60728842692,62243.50811880978,32160.984768067163,22326.53981658876,17639.616850764367 +17,-0.85,11525759.921555841,230710.90078986672,65985.2414769503,33374.667662912274,22861.2713799047,17943.20676989001 +18,-0.9,12201146.44086824,244231.85484658266,69775.31781707545,34677.171733109986,23421.926492698767,18257.325537855635 +19,-0.95,12876329.624198152,257753.50348736419,73590.90402792532,36074.14908439537,24010.383667000708,18582.52717440312 +20,-1.0,13551310.425676014,271275.2284165229,77420.40296111982,37567.89928196474,24628.6824063995,18919.40429879288 +21,-1.05,14226089.936283782,284796.62681016535,81257.84418729441,39154.31745709041,25279.0260373583,19268.591322817843 +22,-1.1,14900669.361096008,298317.4284130786,85100.0213817672,40820.694420649386,25963.771847490214,19630.767639771017 +23,-1.15,15575049.947187511,311837.4488021887,88945.12764700892,42547.61960109046,26685.39607101817,20006.661174345256 +24,-1.2,16249232.944803068,325356.5628664633,92792.0920104733,44315.00278325914,27446.410780027953,20397.05169388497 +25,-1.25,16923219.652990762,338874.68354831537,96640.25514264352,46107.1880062235,28249.189390075437,20802.773919760046 +26,-1.3,17597011.267295927,352391.75180697616,100489.19220958928,47914.0380288265,29095.633798628773,21224.72020108509 +27,-1.35,18270609.035526693,365907.72660919616,104338.62331956948,49729.58158635155,29986.60158658976,21663.841781934752 +28,-1.4,18944014.10560465,379422.58111105545,108188.35629924848,51550.40266240449,30921.08510162442,22121.14743409313 +29,-1.45,19617227.599801127,392936.2995843471,112038.2581753525,53374.53130581722,31895.414785340374,22597.69798746725 +30,-1.5,20290250.628449257,406448.87170714495,115888.23355552147,55200.80065890914,32903.167701580234,23094.592145361086 +31,-1.55,20963084.230473094,419960.2921853954,119738.21240644236,57028.495928939876,33936.3316628258,23612.93808390873 +32,-1.6,21635729.40364157,433470.5616243451,123588.14544053788,58857.16498323281,34987.18515622487,24153.800034255222 +33,-1.65,22308187.09912213,446979.6806856804,127437.9930749731,60686.51141580954,36049.63289861358,24718.102734430224 +34,-1.7,22980458.236149933,460487.6562112276,131287.72741090585,62516.33515063171,37119.47348411243,25306.471793734036 +35,-1.75,23652543.71119153,473994.4913118611,135137.32759478976,64346.498141496646,38194.02315830646,25918.98988903611 +36,-1.8,24324444.303002305,487500.1943907025,138986.77697563276,66176.90195458516,39271.61889911664,26554.88633144024 +37,-1.85,24996160.792373866,501004.77319704846,142836.06268084975,68007.47558757705,40351.23098660629,27212.266270572178 +38,-1.9,25667693.85535241,514508.2345323396,146685.17483587415,69838.16629617152,41432.21258798498,27888.093862611113 +39,-1.95,26339044.07707331,528010.5880257336,150534.10658972702,71668.93485981843,42514.14759095926,28578.597339843487 +40,-2.0,27010211.92909143,541511.8415494547,154382.8515789433,73499.75083216968,43596.76141632206,29279.964047951988 +41,-2.05,27681197.70390487,555012.0032716685,158231.40696449438,75330.59133165593,44679.868069634285,29988.93993266532 +42,-2.1,28352001.438661557,568511.0823885476,162079.76931819317,77161.43793205582,45763.33823486289,30703.07713198381 +43,-2.15,29022622.86724691,582009.0867048443,165927.934920193,78992.2763519878,46847.08026367567,31420.678633433312 +44,-2.2,29693061.20668498,595506.0213887574,169775.90529702447,80823.09534938619,47931.027356211205,32140.61789139928 +45,-2.25,30363315.16245461,609001.8924530807,173623.67605291435,82653.8859415901,49015.130166834366,32862.158432076256 +46,-2.3,31033382.39490708,622496.7022492909,177471.2487510557,84484.64073455677,50099.3513702325,33584.81766484894 +47,-2.35,31703259.56267239,635990.4529118596,181318.6220096441,86315.35340813217,51183.66248856971,34308.274990225975 +48,-2.4,32372941.771020293,649483.1379361057,185165.79706893343,88146.01937553077,52268.04130918403,35032.31369667784 +49,-2.45,33042422.094883416,662974.7452218498,189012.77386128312,89976.634830742,53352.47053786749,35756.783902920535 +50,-2.5,33711691.059115835,676465.2532323864,192859.55101170225,91807.19664642852,54436.936274768006,36481.5800649797 +51,-2.55,34380736.02975396,689954.6304504375,196706.1303905232,93637.70154386097,55521.427296255344,37206.626135927596 +52,-2.6,35049540.08492282,703442.8234151702,200552.5098228691,95468.14794653356,56605.934551373735,37931.86613137743 +53,-2.65,35718081.26586475,716929.7570269052,204398.6890994202,97298.53410505831,57690.45067103017,38657.25830884741 +54,-2.7,36386331.241257645,730415.3232153407,208244.66706039305,99128.85780051262,58774.969506348556,39382.7708688672 +55,-2.75,37054254.01545127,743899.3725425199,212090.4399601773,100959.11860207701,59859.48610352561,40108.379316593586 +56,-2.8,37721804.14098865,757381.703104652,215936.00131980082,102789.31508300234,60943.99611985248,40834.06434815613 +57,-2.85,38388924.95517164,770862.0443944645,219781.3417794352,104619.44632349536,62028.49596504525,41559.81080317563 +58,-2.9,39055546.4924242,784340.0356172055,223626.45239982955,106449.51122991137,63112.98280520516,42285.60631118915 +59,-2.95,39721582.88875861,797815.210900869,227471.3107785222,108279.5093632999,64197.45385411939,43011.440996648635 +60,-3.0,40386930.107147455,811286.9748703698,231315.89250056527,110109.43861521201,65281.907142501725,43737.30673196709 +61,-3.05,41051462.38512781,824754.5653450689,235160.16026049267,111939.297983226,66366.34076927419,44463.19680174505 +62,-3.1,41715029.52440423,838217.0200322836,239004.0648192285,113769.08519985127,67450.75309549131,45189.105510154724 +63,-3.15,42377452.92199964,851673.1502966426,242847.53864999526,115598.79666570207,68535.1426541371,45915.02819993897 +64,-3.2,43038521.84820771,865121.4762618872,246690.49095501224,117428.42781360421,69619.50819726415,46640.96091888151 +65,-3.25,43697989.1490955,878560.1928485578,250532.80812303527,119257.97220004197,70703.8487431215,47366.90031816113 +66,-3.3,44355566.8802337,891987.1103105295,254374.33671891698,121087.4200719828,71788.16315476834,48092.843391562164 diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/diff_table.csv b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/diff_table.csv new file mode 100644 index 00000000..b68d5f39 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/diff_table.csv @@ -0,0 +1,80 @@ +,0,1,2,3,4,5 +0,100.0,,,,, +1,99.999996,1294.909461,85.475612,38.740399,23.432232,15.866543 +2,99.999999,1847.174246,84.908885,36.961743,21.96087,14.680282 +3,100.0,2226.549972,84.225108,35.045737,20.417247,13.452003 +4,100.0,2297.804937,83.364891,32.975091,18.796291,12.1775 +5,100.0,2059.636932,82.207793,30.728427,17.090097,10.857749 +6,100.0,1569.483171,80.471206,28.287223,15.294374,9.490726 +7,100.0,973.412306,77.456183,25.618256,13.400486,8.068169 +8,100.0,474.248888,71.775025,22.68675,11.400044,6.590559 +9,100.0,178.378022,61.763111,19.453773,9.283664,5.056502 +10,100.0,40.603283,46.464075,15.86962,7.040805,3.458613 +11,100.0,19.855552,25.90567,11.863766,4.659579,1.794887 +12,100.0,48.111376,1.093836,7.343623,2.126511,0.0611 +13,100.0,62.593966,25.605994,2.179907,0.567963,1.747341 +14,100.0,70.839982,50.404868,3.825284,3.446882,3.637579 +15,100.0,75.784987,69.713446,10.880589,6.530633,5.610869 +16,100.0,78.950671,82.277165,19.164356,9.839895,7.675293 +17,100.0,81.097754,89.41037,28.749136,13.399412,9.839718 +18,100.0,82.552361,93.259201,39.490844,17.246397,12.104536 +19,100.0,83.647061,95.360437,51.010535,21.412466,14.484618 +20,100.0,84.415993,96.554805,62.598203,25.9424,16.989026 +21,100.0,84.920345,97.294432,73.241792,30.904376,19.620281 +22,100.0,85.397344,97.762619,81.958795,36.348291,22.39169 +23,100.0,85.670954,98.066608,88.259243,42.313937,25.318251 +24,100.0,86.02566,98.308146,92.353932,48.802877,28.411527 +25,100.0,86.292192,98.441176,94.858738,55.755542,31.684985 +26,100.0,86.274331,98.555194,96.37234,63.015154,35.157471 +27,100.0,86.479749,98.682732,97.287196,70.306467,38.842326 +28,100.0,86.54975,98.709963,97.857871,77.230187,42.765071 +29,100.0,86.464113,98.742604,98.240999,83.325796,46.948357 +30,100.0,86.608435,98.821298,98.505042,88.236709,51.398731 +31,100.0,86.583626,98.866107,98.694853,91.844925,56.123717 +32,100.0,86.585848,98.916324,98.825913,94.314398,61.104746 +33,100.0,86.615088,98.927249,98.916777,95.927935,66.286383 +34,100.0,86.671334,98.89483,99.002213,96.961706,71.559059 +35,100.0,86.754576,98.957212,99.067552,97.644918,76.762756 +36,100.0,86.378311,98.97625,99.110485,98.100723,81.671935 +37,100.0,86.502073,98.94789,99.157267,98.401824,86.042509 +38,100.0,86.396122,99.022434,99.193232,98.624188,89.675093 +39,100.0,86.303697,98.99678,99.202169,98.788795,92.474996 +40,100.0,86.494894,98.971128,99.228086,98.904854,94.511168 +41,100.0,86.159401,99.05648,99.256312,98.998103,95.929664 +42,100.0,86.107519,99.033531,99.286849,99.066347,96.892669 +43,100.0,86.069141,99.010585,99.303103,99.123186,97.554582 +44,100.0,86.044261,99.04719,99.286941,99.175604,98.010862 +45,100.0,86.032875,99.025597,99.305505,99.214788,98.323683 +46,100.0,86.034978,99.004005,99.343356,99.248087,98.552129 +47,100.0,85.733533,99.046014,99.329121,99.283583,98.725527 +48,100.0,85.432176,99.025775,99.333403,99.303646,98.85533 +49,100.0,85.791758,99.005538,99.357357,99.316178,98.959627 +50,100.0,85.503973,99.052949,99.363563,99.338988,99.036466 +51,100.0,85.216284,99.034064,99.37054,99.3539,99.095001 +52,100.0,85.279193,99.085524,99.358232,99.36991,99.150911 +53,100.0,84.998406,99.067991,99.366364,99.387019,99.198103 +54,100.0,84.717741,99.05046,99.375266,99.395314,99.235925 +55,100.0,84.437213,99.032931,99.384938,99.404341,99.263728 +56,100.0,84.156842,99.015404,99.395379,99.414101,99.286955 +57,100.0,83.492762,99.074966,99.384612,99.424593,99.311484 +58,100.0,82.81556,99.058792,99.396209,99.425173,99.337314 +59,100.0,82.125288,98.96284,99.408575,99.436947,99.351606 +60,100.0,81.018143,98.945327,99.398579,99.449453,99.366766 +61,100.0,79.474269,99.010295,99.388584,99.440304,99.38943 +62,100.0,77.891034,98.99414,99.40249,99.453908,99.399688 +63,100.0,75.844852,98.977992,99.392881,99.468246,99.403744 +64,100.0,72.455346,98.961854,99.383274,99.459829,99.415196 +65,100.0,68.974428,98.857872,99.398721,99.463339,99.434369 +66,100.0,67.176881,98.751218,99.389502,99.467215,99.440052 +67,,,,,, +68,,,,,, +69,,,,,, +70,,,,,, +71,,,,,, +72,,,,,, +73,,,,,, +74,,,,,, +75,,,,,, +76,,,,,, +77,,,,,, +78,,,,,, diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/get_diff.py b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/get_diff.py new file mode 100644 index 00000000..811fe745 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/get_diff.py @@ -0,0 +1,14 @@ +import pandas as pd + +measured = pd.read_csv('0_measured_W10_L10.0.csv') +simulated = pd.read_csv('0_simulated_W10_L10.0.csv') + +error_1 = round (100 * (abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1]),6) +error_2 = round (100 * (abs(measured.iloc[:, 2]) - abs(simulated.iloc[:, 2]))/abs(measured.iloc[:, 2]),6) +error_3 = round (100 * (abs(measured.iloc[:, 3]) - abs(simulated.iloc[:, 3]))/abs(measured.iloc[:, 3]),6) +error_4 = round (100 * (abs(measured.iloc[:, 4]) - abs(simulated.iloc[:, 4]))/abs(measured.iloc[:, 4]),6) +error_5 = round (100 * (abs(measured.iloc[:, 5]) - abs(simulated.iloc[:, 5]))/abs(measured.iloc[:, 5]),6) +error_6 = round (100 * (abs(measured.iloc[:, 6]) - abs(simulated.iloc[:, 6]))/abs(measured.iloc[:, 6]),6) + +df = pd.DataFrame(data=[error_1,error_2,error_3,error_4,error_5,error_6]).transpose() +df.to_csv("diff_table.csv") \ No newline at end of file diff --git a/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/rds_calc.py b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/rds_calc.py new file mode 100644 index 00000000..dbf119ae --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/0_man_error_debugging/pmos_3p3/Rds_large_signal/rds_calc.py @@ -0,0 +1,14 @@ +import pandas as pd + + +df = pd.read_csv ("../../../pmos_3p3_iv/simulated_Id/0_simulated_W10_L10.0.csv") + +df["vgs =-0.8"] = df["-vds (V)"]/df["vgs =-0.8"] +df["vgs =-1.3"] = df["-vds (V)"]/df["vgs =-1.3"] +df["vgs =-1.8"] = df["-vds (V)"]/df["vgs =-1.8"] +df["vgs =-2.3"] = df["-vds (V)"]/df["vgs =-2.3"] +df["vgs =-2.8"] = df["-vds (V)"]/df["vgs =-2.8"] +df["vgs =-3.3"] = df["-vds (V)"]/df["vgs =-3.3"] + +df.to_csv ("0_simulated_W10_L10.0.csv") + diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_iv.spice new file mode 100644 index 00000000..524d1f94 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_iv.spice @@ -0,0 +1,48 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 3.3 + +.temp {{temp}} +.options tnom={{temp}} + + +xmn1 D_tn G_tn 0 0 nmos_3p3 W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +print -i(Vds) +wrdata nmos_3p3_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_sab_iv.spice new file mode 100644 index 00000000..a22503c8 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_sab_iv.spice @@ -0,0 +1,47 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 3.3 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 nmos_3p3_sab W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +print -i(Vds) +wrdata nmos_3p3_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_iv.spice new file mode 100644 index 00000000..c1842a20 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_iv.spice @@ -0,0 +1,46 @@ +*************************** +** nmos_6p0_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc 6.6 +Vgs G_tn 0 6 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 nmos_6p0 W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 6.6 0.05 Vgs 1 6 1 +print -i(Vds) +wrdata nmos_6p0_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_nat_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_nat_iv.spice new file mode 100644 index 00000000..5a93ceb3 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_nat_iv.spice @@ -0,0 +1,46 @@ +*************************** +** nmos_6p0_nat_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc 6.6 +Vgs G_tn 0 6 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 nmos_6p0_nat W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 6.6 0.05 Vgs 0.25 6 1.15 +print -i(Vds) +wrdata nmos_6p0_nat_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_sab_iv.spice new file mode 100644 index 00000000..7bcdab89 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_sab_iv.spice @@ -0,0 +1,47 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc 6.6 +Vgs G_tn 0 6 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 nmos_6p0_sab W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 6.6 0.05 Vgs 1 6 1 +print -i(Vds) +wrdata nmos_6p0_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_iv.spice new file mode 100644 index 00000000..90099fee --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_iv.spice @@ -0,0 +1,46 @@ +*************************** +** pmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 -3.3 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 pmos_3p3 W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds -0 -3.3 -0.05 Vgs -0.8 -3.3 -0.5 +print -i(Vds) +wrdata pmos_3p3_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_sab_iv.spice new file mode 100644 index 00000000..aaa16ab2 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_sab_iv.spice @@ -0,0 +1,47 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 -3.3 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 pmos_3p3_sab W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 -3.3 -0.05 Vgs -0.8 -3.3 -0.5 +print -i(Vds) +wrdata pmos_3p3_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_iv.spice new file mode 100644 index 00000000..d4d2cca4 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_iv.spice @@ -0,0 +1,47 @@ +*************************** +** pmos_6p0_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc -6.6 +Vgs G_tn 0 -6 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 pmos_6p0 W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 -6.6 -0.05 Vgs -1 -6 -1 +print -i(Vds) +wrdata pmos_6p0_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_sab_iv.spice new file mode 100644 index 00000000..10ef8b19 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_sab_iv.spice @@ -0,0 +1,47 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vds D_tn 0 dc -6.6 +Vgs G_tn 0 -6 + +.temp {{temp}} +.options tnom={{temp}} + +xmn1 D_tn G_tn 0 0 pmos_6p0_sab W = {{width}}u L = {{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +**** begin architecture code + + +.control +set filetype=ascii + +dc Vds 0 -6.6 -0.05 Vgs -1 -6 -1 +print -i(Vds) +wrdata pmos_6p0_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv -i(Vds) +.endc + + + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +**** end architecture code + + +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_iv.spice new file mode 100644 index 00000000..aeaf9539 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=3.3 +vgs G_tn 0 dc=3.3 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +mn D_tn G_tn 0 0 nmos_3p3 W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.05 +let vds_max = 3.3 + +compose vgs_vector start=0.8 stop=3.3 step=0.5 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[vth] @mn[id] @mn[gm] @mn[gmbs] @mn[gds] @mn[cgg] @mn[cgs] @mn[cgd] @mn[cdd] @mn[cdb] @mn[cgb] @mn[csb] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@mn[gds] + print Rds + wrdata nmos_3p3_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_sab_iv.spice new file mode 100644 index 00000000..dfefba20 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_sab_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=3.3 +vgs G_tn 0 dc=3.3 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +xmn1 D_tn G_tn 0 0 nmos_3p3_sab W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.05 +let vds_max = 3.3 + +compose vgs_vector start=0.8 stop=3.3 step=0.5 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save all @m.xmn1.m0[gds] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@m.xmn1.m0[gds] + print Rds + wrdata nmos_3p3_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_iv.spice new file mode 100644 index 00000000..ba3d9a93 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_6p0_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=6.6 +vgs G_tn 0 dc=6 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +mn D_tn G_tn 0 0 nmos_6p0 W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.05 +let vds_max = 6.6 + +compose vgs_vector start=1 stop=6 step=1 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[vth] @mn[id] @mn[gm] @mn[gmbs] @mn[gds] @mn[cgg] @mn[cgs] @mn[cgd] @mn[cdd] @mn[cdb] @mn[cgb] @mn[csb] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@mn[gds] + print Rds + wrdata nmos_6p0_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[gds] + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_nat_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_nat_iv.spice new file mode 100644 index 00000000..2ea4dc84 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_nat_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_6p0_nat_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=6.6 +vgs G_tn 0 dc=6 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +mn D_tn G_tn 0 0 nmos_6p0_nat W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.05 +let vds_max = 6.6 + +compose vgs_vector start=0.25 stop=6 step=1.15 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[vth] @mn[id] @mn[gm] @mn[gmbs] @mn[gds] @mn[cgg] @mn[cgs] @mn[cgd] @mn[cdd] @mn[cdb] @mn[cgb] @mn[csb] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@mn[gds] + print Rds + wrdata nmos_6p0_nat_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_sab_iv.spice new file mode 100644 index 00000000..e7d46fcc --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_sab_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=6.6 +vgs G_tn 0 dc=6 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +xmn1 D_tn G_tn 0 0 nmos_6p0_sab W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.05 +let vds_max = 6.6 + +compose vgs_vector start=1 stop=6 step=1 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save all @m.xmn1.m0[gds] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = @m.xmn1.m0[gds] + print Rds + wrdata nmos_6p0_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_iv.spice new file mode 100644 index 00000000..56e3016a --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_iv.spice @@ -0,0 +1,68 @@ +*************************** +** pmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-3.3 +vgs G_tn 0 dc=-3.3 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +mn D_tn G_tn 0 0 pmos_3p3 W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.05 +let vds_max = -3.3 + +compose vgs_vector start=-0.8 stop=-3.3 step=-0.5 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[vth] @mn[id] @mn[gm] @mn[gmbs] @mn[gds] @mn[cgg] @mn[cgs] @mn[cgd] @mn[cdd] @mn[cdb] @mn[cgb] @mn[csb] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@mn[gds] + print Rds + wrdata pmos_3p3_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_sab_iv.spice new file mode 100644 index 00000000..0d50993f --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_sab_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-3.3 +vgs G_tn 0 dc=-3.3 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +xmn1 D_tn G_tn 0 0 pmos_3p3_sab W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.05 +let vds_max = -3.3 + +compose vgs_vector start=-0.8 stop=-3.3 step=-0.5 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save all @m.xmn1.m0[gds] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@m.xmn1.m0[gds] + print Rds + wrdata pmos_3p3_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_iv.spice new file mode 100644 index 00000000..de3e4911 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_iv.spice @@ -0,0 +1,68 @@ +*************************** +** pmos_6p0_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-6.6 +vgs G_tn 0 dc=-6 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +mn D_tn G_tn 0 0 pmos_6p0 W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.05 +let vds_max = -6.6 + +compose vgs_vector start=-1 stop=-6 step=-1 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[vth] @mn[id] @mn[gm] @mn[gmbs] @mn[gds] @mn[cgg] @mn[cgs] @mn[cgd] @mn[cdd] @mn[cdb] @mn[cgb] @mn[csb] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = 1/@mn[gds] + print Rds + wrdata pmos_6p0_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[gds] + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_sab_iv.spice b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_sab_iv.spice new file mode 100644 index 00000000..780a169a --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_sab_iv.spice @@ -0,0 +1,68 @@ +*************************** +** nmos_3p3_t_id +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-6.6 +vgs G_tn 0 dc=-6 + +.temp {{temp}} +.options tnom={{temp}} + +* circuit +xmn1 D_tn G_tn 0 0 pmos_6p0_sab W = {{width}}u L = {{length}}u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.05 +let vds_max = -6.6 + +compose vgs_vector start=-1 stop=-6 step=-1 + +set appendwrite + +foreach t {{temp}} + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=$t + alter vgs = vgs_vector[vgs_counter] + + save all @m.xmn1.m0[gds] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + let Rds = @m.xmn1.m0[gds] + print Rds + wrdata pmos_6p0_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv Rds + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/ngspice/testing/regression/mos_iv_vgs/models_regression.py b/models/ngspice/testing/regression/mos_iv_vgs/models_regression.py new file mode 100644 index 00000000..76815a22 --- /dev/null +++ b/models/ngspice/testing/regression/mos_iv_vgs/models_regression.py @@ -0,0 +1,294 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vds,vgs): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops*2,2): + width = dimensions["W (um)"].iloc[int(i/2)] + length = dimensions["L (um)"].iloc[int(i/2)] + + # Special case for 1st measured values + if i == 0 : + # measured Id + col_list = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + # measured Rds + col_list = [f"{vds}",f"vgs ={vgs[0]}.{i+1}",f"vgs ={vgs[1]}.{i+1}",f"vgs ={vgs[2]}.{i+1}",f"vgs ={vgs[3]}.{i+1}",f"vgs ={vgs[4]}.{i+1}",f"vgs ={vgs[5]}.{i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Rds/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + else: + # measured Id + col_list = [f"{vds}",f"vgs ={vgs[0]}.{i}",f"vgs ={vgs[1]}.{i}",f"vgs ={vgs[2]}.{i}",f"vgs ={vgs[3]}.{i}",f"vgs ={vgs[4]}.{i}",f"vgs ={vgs[5]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + # measured Rds + col_list = [f"{vds}",f"vgs ={vgs[0]}.{i+1}",f"vgs ={vgs[1]}.{i+1}",f"vgs ={vgs[2]}.{i+1}",f"vgs ={vgs[3]}.{i+1}",f"vgs ={vgs[4]}.{i+1}",f"vgs ={vgs[5]}.{i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Rds/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + +def ext_simulated(device,vds,vgs,vds_sweep,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + AD = float(width) * 0.24 + PD = 2 * (float(width) + 0.24) + AS = AD + PS = PD + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: + temp = 125 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True) + with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist: + netlist.write(tmpl.render(width = width,length = length,i = i , temp = temp , AD = AD , PD = PD , AS = AS , PS = PD )) + netlist_path = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + + # empty array to append in it shaped (vds_sweep, number of trials + 1) + new_array = np.empty((vds_sweep, 1+int(df_simulated.shape[0]/vds_sweep))) + new_array[:, 0] = df_simulated.iloc[:vds_sweep, 0] + times = int(df_simulated.shape[0]/vds_sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vds_sweep:(j+1)*vds_sweep, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + df_simulated.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + +def error_cal(device,vds,vgs,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: temp = 125 + + measured = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv") + simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[1:, 1]) - abs(simulated.iloc[1:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[1:, 2]) - abs(simulated.iloc[1:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[1:, 3]) - abs(simulated.iloc[1:, 3]))/abs(measured.iloc[:, 3])),6) + error_4 = round (100 * abs((abs(measured.iloc[1:, 4]) - abs(simulated.iloc[1:, 4]))/abs(measured.iloc[:, 4])),6) + error_5 = round (100 * abs((abs(measured.iloc[1:, 5]) - abs(simulated.iloc[1:, 5]))/abs(measured.iloc[:, 5])),6) + error_6 = round (100 * abs((abs(measured.iloc[1:, 6]) - abs(simulated.iloc[1:, 6]))/abs(measured.iloc[:, 6])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5,error_6]).transpose() + df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"vgs ={vgs[0]}"].mean() + df_error[f"vgs ={vgs[1]}"].mean() + df_error[f"vgs ={vgs[2]}"].mean() + + df_error[f"vgs ={vgs[3]}"].mean() + df_error[f"vgs ={vgs[4]}"].mean() + df_error[f"vgs ={vgs[5]}"].mean())/6 + # Max error + max_error = df_error[[f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}" ]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vds = df_error[f"{vds}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & Vds (V) = {max_location_vds}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["nmos_3p3_iv" , "pmos_3p3_iv" , "nmos_6p0_iv" , "pmos_6p0_iv" , "nmos_6p0_nat_iv", "nmos_3p3_sab_iv", "pmos_3p3_sab_iv" , "nmos_6p0_sab_iv" , "pmos_6p0_sab_iv"] + nmos_vds = "vds (V)" + pmos_vds = "-vds (V)" + nmos_rds = "Rds" + Id_sim = "Id" + Rds_sim = "Rds" + mos_3p3_vgs_sweep = 67 + mos_6p0_vgs_sweep = 133 + nmos3p3_vgs = [ 0.8 , 1.3 , 1.8 , 2.3 , 2.8 , 3.3] + pmos3p3_vgs = [-0.8 , -1.3 , -1.8 , -2.3 , -2.8 , -3.3] + nmos6p0_vgs = [ 1 , 2 , 3 , 4 , 5 , 6] + pmos6p0_vgs = [-1 , -2 , -3 , -4 , -5 , -6] + nmos6p0_nat_vgs = [ 0.25 , 1.4 , 2.55 , 3.7 , 4.85 , 6] + + for device in devices: + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/measured_{Rds_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/MOS/{device}.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/simulated_{Rds_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Rds_sim}",exist_ok=False) + + # =========== nmos_3p3_iv ============== + ext_measured ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs) + + ext_simulated("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + error_cal ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,Id_sim) + + ext_simulated("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + error_cal ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,Rds_sim) + + # =========== pmos_3p3_iv ============== + ext_measured ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs) + + ext_simulated("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + error_cal ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,Id_sim) + + ext_simulated("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + error_cal ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,Rds_sim) + + # =========== nmos_6p0_iv ============== + ext_measured ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs) + + ext_simulated("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + error_cal ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,Id_sim) + + ext_simulated("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + error_cal ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,Rds_sim) + + # =========== pmos_6p0_iv ============== + ext_measured ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs) + + ext_simulated("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + error_cal ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,Id_sim) + + ext_simulated("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + error_cal ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,Rds_sim) + + # ============ nmos_6p0_nat_iv ============= + ext_measured ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs) + + ext_simulated("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,mos_6p0_vgs_sweep,Id_sim) + error_cal ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,Id_sim) + + ext_simulated("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,mos_6p0_vgs_sweep,Rds_sim) + error_cal ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,Rds_sim) + + # ============ nmos_3p3_sab_iv ============= + ext_measured ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs) + + ext_simulated("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + error_cal ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,Id_sim) + + ext_simulated("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + error_cal ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,Rds_sim) + + # =========== pmos_3p3_sab_iv ============== + ext_measured ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs) + + ext_simulated("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + error_cal ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,Id_sim) + + ext_simulated("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + error_cal ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,Rds_sim) + + # =========== nmos_6p0_sab_iv ============== + ext_measured ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs) + + ext_simulated("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + error_cal ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,Id_sim) + + ext_simulated("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + error_cal ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,Rds_sim) + + # =========== pmos_6p0_sab_iv ============== + ext_measured ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs) + + ext_simulated("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + error_cal ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,Id_sim) + + ext_simulated("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + error_cal ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,Rds_sim) + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/moscap_c/.spiceinit b/models/ngspice/testing/regression/moscap_c/.spiceinit new file mode 100644 index 00000000..7779a4cc --- /dev/null +++ b/models/ngspice/testing/regression/moscap_c/.spiceinit @@ -0,0 +1,2 @@ +* user provided init file +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/moscap_c/device_netlists/.spiceinit b/models/ngspice/testing/regression/moscap_c/device_netlists/.spiceinit new file mode 100644 index 00000000..84222e23 --- /dev/null +++ b/models/ngspice/testing/regression/moscap_c/device_netlists/.spiceinit @@ -0,0 +1,5 @@ + +* user provided init file +set ngbehavior=hs + + diff --git a/models/ngspice/testing/regression/moscap_c/device_netlists/moscap.spice b/models/ngspice/testing/regression/moscap_c/device_netlists/moscap.spice new file mode 100644 index 00000000..6150abb2 --- /dev/null +++ b/models/ngspice/testing/regression/moscap_c/device_netlists/moscap.spice @@ -0,0 +1,38 @@ +*************************** +** cap +*************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +.options noacct + +Ich 0 p dc 10u + +.temp 25 +.options tnom=25 + +xcn p 0 {{device}} c_length={{length}}u c_width={{width}}u + +.ic v(p)=0.0 +.tran 10ns 100us + +* .print tran v(p) cj=par('10.0e-6 * time / v(p)') + +.meas tran CV FIND par('(10.0e-6 * time / v(p))*1.0e15') AT=100us + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" moscap_{{corner}} +.end + diff --git a/models/ngspice/testing/regression/moscap_c/models_regression.py b/models/ngspice/testing/regression/moscap_c/models_regression.py new file mode 100644 index 00000000..dc0c019d --- /dev/null +++ b/models/ngspice/testing/regression/moscap_c/models_regression.py @@ -0,0 +1,191 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vn,d_in, cv_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 50 ; length = 50 + if i == 1+start: width = 1 ; length = 1 + if i == 2+start: width = 50 ; length = 1 + if i == 3+start: width = 1 ; length = 50 + + # measured cv + col_list = [f"{vn}",f"{d_in}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.loc[i:i].to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_w{width}_l{length}.csv", index=False) + +def ext_simulated(device,vn,d_in,cv_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + netlist_tmp = f"./device_netlists/moscap.spice" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 50 ; length = 50 + if i == 1+start: width = 1 ; length = 1 + if i == 2+start: width = 50 ; length = 1 + if i == 3+start: width = 1 ; length = 50 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{cv_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, width = width, length = length , corner = corner )) + netlist_path = f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice.log") + clean_data = str(df_simulated.loc[4]).replace("Compatibility modes selected: hs","").replace("\nName: 4, dtype: object","").split("=") + df_clean_ = {vn: [f"moscap_{corner}"],d_in: [clean_data[1]]} + df_clean = pd.DataFrame(df_clean_) + df_clean.to_csv(f"{dirpath}/simulated_{cv_sim}/{i-start}_simulated_w{width}_l{length}.csv",index= False) + +def error_cal(device,vn,d_in,Id_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + df_final = pd.DataFrame() + for i in range (start,4+start): + if i == 0+start: width = 50 ; length = 50 + if i == 1+start: width = 1 ; length = 1 + if i == 2+start: width = 50 ; length = 1 + if i == 3+start: width = 1 ; length = 50 + + measured = pd.read_csv(f"{dirpath}/measured_{Id_sim}/{i-start}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i-start}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{Id_sim}/{i-start}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{d_in}"].mean()) + # Max error + max_error = df_error[f"{d_in}"].max() + + df_final_ = {'Run no.': f'{i-start}', 'Device name': f'{dirpath}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + + +def main(): + + # 3p3 + corners = ["typical","ff","ss"] + devices = ["nmoscap_3p3" , "pmoscap_3p3" , "nmoscap_3p3_b" , "pmoscap_3p3_b"] + measure = ["cv","corners", "CV (fF)"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + dirpath = f"{device}_{cv_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + + ext_measured (device,cap_vn,cap_in, cv_sim, corner,start) + ext_simulated(device,cap_vn,cap_in,cv_sim, corner,start) + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = start + 32 + + # 6p0 + corners = ["typical","ff","ss"] + devices = ["nmoscap_6p0" , "pmoscap_6p0" , "nmoscap_6p0_b" , "pmoscap_6p0_b"] + measure = ["cv","corners", "CV (fF)"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + dirpath = f"{device}_{cv_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + + ext_measured (device,cap_vn,cap_in, cv_sim, corner,start) + ext_simulated(device,cap_vn,cap_in,cv_sim, corner,start) + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = start + 32 + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/regression/resistor_r/.spiceinit b/models/ngspice/testing/regression/resistor_r/.spiceinit new file mode 100644 index 00000000..7779a4cc --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/.spiceinit @@ -0,0 +1,2 @@ +* user provided init file +set ngbehavior=hs diff --git a/models/ngspice/testing/regression/resistor_r/device_netlists/.spiceinit b/models/ngspice/testing/regression/resistor_r/device_netlists/.spiceinit new file mode 100644 index 00000000..84222e23 --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/device_netlists/.spiceinit @@ -0,0 +1,5 @@ + +* user provided init file +set ngbehavior=hs + + diff --git a/models/ngspice/testing/regression/resistor_r/device_netlists/2term_res_a.spice b/models/ngspice/testing/regression/resistor_r/device_netlists/2term_res_a.spice new file mode 100644 index 00000000..1f39ae3f --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/device_netlists/2term_res_a.spice @@ -0,0 +1,44 @@ +************************** +** res +************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +Vn n 0 DC {{sign}}3.3 + +.temp 25 +.options tnom=25 + +r1 n p 1M +xrn p 0 {{device}} r_width={{width}}u r_length={{length}}u + + +.print dc Rs=par('(1M*V(p)/(V(n)-V(p)))/{{length}}u*{{width}}u') + + +.control +set filetype=ascii +set appendwrite + +DC Vn {{sign}}3.3 {{sign}}3.3 0.1 +wrdata {{device}}_r_{{corner}}/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv Rs + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" res_{{corner}} + +.end diff --git a/models/ngspice/testing/regression/resistor_r/device_netlists/2term_res_b.spice b/models/ngspice/testing/regression/resistor_r/device_netlists/2term_res_b.spice new file mode 100644 index 00000000..21db7ab6 --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/device_netlists/2term_res_b.spice @@ -0,0 +1,44 @@ +************************** +** res +************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +Vn n 0 DC {{sign}}3.3 + +.temp {{temp}} +.options tnom={{temp}} + +r1 n p 1M +xrn p 0 {{device}} r_width={{width}}u r_length={{length}}u + + +.print dc Rs=par('(1M*V(p)/(V(n)-V(p)))/{{length}}u*{{width}}u') + + +.control +set filetype=ascii +set appendwrite + +DC Vn {{sign}}3.3 {{sign}}3.3 0.1 +wrdata {{device}}_r_{{corner}}_temp/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv Rs + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" res_{{corner}} + +.end diff --git a/models/ngspice/testing/regression/resistor_r/device_netlists/3term_res_a.spice b/models/ngspice/testing/regression/resistor_r/device_netlists/3term_res_a.spice new file mode 100644 index 00000000..86535998 --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/device_netlists/3term_res_a.spice @@ -0,0 +1,44 @@ +************************** +** res +************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +Vn n 0 DC {{sign}}3.3 + +.temp 25 +.options tnom=25 + +r1 n p 1M +xrn p 0 0 {{device}} r_width={{width}}u r_length={{length}}u + + +.print dc Rs=par('(1M*V(p)/(V(n)-V(p)))/{{length}}u*{{width}}u') + + +.control +set filetype=ascii +set appendwrite + +DC Vn {{sign}}3.3 {{sign}}3.3 0.1 +wrdata {{device}}_r_{{corner}}/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv Rs + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" res_{{corner}} + +.end diff --git a/models/ngspice/testing/regression/resistor_r/device_netlists/3term_res_b.spice b/models/ngspice/testing/regression/resistor_r/device_netlists/3term_res_b.spice new file mode 100644 index 00000000..120aa9db --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/device_netlists/3term_res_b.spice @@ -0,0 +1,44 @@ +************************** +** res +************************** +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +Vn n 0 DC {{sign}}3.3 + +.temp {{temp}} +.options tnom={{temp}} + +r1 n p 1M +xrn p 0 0 {{device}} r_width={{width}}u r_length={{length}}u + + +.print dc Rs=par('(1M*V(p)/(V(n)-V(p)))/{{length}}u*{{width}}u') + + +.control +set filetype=ascii +set appendwrite + +DC Vn {{sign}}3.3 {{sign}}3.3 0.1 +wrdata {{device}}_r_{{corner}}_temp/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv Rs + +.endc + +** library calling + +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" res_{{corner}} + +.end diff --git a/models/ngspice/testing/regression/resistor_r/models_regression.py b/models/ngspice/testing/regression/resistor_r/models_regression.py new file mode 100644 index 00000000..f166171c --- /dev/null +++ b/models/ngspice/testing/regression/resistor_r/models_regression.py @@ -0,0 +1,323 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured_a(device,vn,d_in, r_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["w (um)" , "l (um)"]) + loops = dimensions["l (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["w (um)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + + # measured r + col_list = [f"{vn}",f"{d_in}_{corner} Rev9 "] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}","value"] + df_measured.loc[i:i].to_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv", index=False) + +def ext_measured_b(device,vn,d_in, r_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}_temp" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["Temperature (C)" , "l (um)"]) + if "rm" in device or "tm" in device: + loops = dimensions["l (um)"].count() + else: + loops = 11 + + # Extracting measured values for each W & L + for i in range (0,loops): + temp = dimensions["Temperature (C)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + if "rm" in device or "tm" in device or "_u" in device: + width = length + else: + width = length/2 + + # measured r + col_list = [f"{vn}",f"{d_in}_{corner} Rev9 "] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}","value"] + df_measured.loc[i:i].to_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv", index=False) + +def ext_simulated_a(device,vn,d_in,r_sim, corner,sign): + + if "rm" in device or "tm" in device: + netlist_tmp = f"./device_netlists/2term_res_a.spice" + else: + netlist_tmp = f"./device_netlists/3term_res_a.spice" + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["w (um)" , "l (um)"]) + loops = dimensions["l (um)"].count() + temp = 25 + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["w (um)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{r_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, width = width, length = length , corner = corner, i = i , sign = sign)) + netlist_path = f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + + # Writing final simulated data + df_simulated.columns = [f"{vn}","value"] + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + +def ext_simulated_b(device,vn,d_in,r_sim, corner,sign): + + if "rm" in device or "tm" in device: + netlist_tmp = f"./device_netlists/2term_res_b.spice" + else: + netlist_tmp = f"./device_netlists/3term_res_b.spice" + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}_temp" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["Temperature (C)" , "l (um)"]) + if "rm" in device or "tm" in device: + loops = dimensions["l (um)"].count() + else: + loops = 11 + + # Extracting measured values for each W & L + for i in range (0,loops): + temp = dimensions["Temperature (C)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + if "rm" in device or "tm" in device or "_u" in device: + width = length + else: + width = length/2 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{r_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, temp = temp , width = width, length = length , corner = corner, i = i , sign = sign)) + netlist_path = f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + + # Writing final simulated data + df_simulated.columns = [f"{vn}","value"] + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + +def error_cal_a(device,vn,d_in,r_sim, corner): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["w (um)" , "l (um)"]) + loops = dimensions["l (um)"].count() + temp = 25 + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["w (um)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + + measured = pd.read_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{r_sim}/{i}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{r_sim}/{i}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"value"].mean()) + # Max error + max_error = df_error[f"value"].max() + + df_final_ = {'Run no.': f'{i}', 'Device name': f'{dirpath}', 'Temperature': temp, 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{r_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{r_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{r_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def error_cal_b(device,vn,d_in,r_sim, corner): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}_temp" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["Temperature (C)" , "l (um)"]) + if "rm" in device or "tm" in device: + loops = dimensions["l (um)"].count() + else: + loops = 11 + + # Extracting measured values for each W & L + for i in range (0,loops): + temp = dimensions["Temperature (C)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + if "rm" in device or "tm" in device or "_u" in device: + width = length + else: + width = length/2 + + measured = pd.read_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{r_sim}/{i}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{r_sim}/{i}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"value"].mean()) + # Max error + max_error = df_error[f"value"].max() + + df_final_ = {'Run no.': f'{i}', 'Device name': f'{dirpath}', 'Temperature': temp, 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{r_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{r_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{r_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + # res W&L var. + corners_a = ["typical","ff","ss"] + + devices_a = ["nplus_u" , "pplus_u" , "nplus_s" , "pplus_s" , "npolyf_u" , "ppolyf_u" , "npolyf_s" , "ppolyf_s" , "ppolyf_u_1k" , "ppolyf_u_2k" , "ppolyf_u_1k_6p0" , + "ppolyf_u_2k_6p0" , "ppolyf_u_3k" , "rm1" , "rm2" , "rm3" , "tm6k" , "tm9k" , "tm11k" , "tm30k" , "nwell"] + + dev_data_a = ["RES01a-wl-nplus_u.nl_out" ,"RES02a-wl-pplus_u.nl_out" ,"RES03a-wl-nplus_s.nl_out" , "RES04a-wl-pplus_s.nl_out" , + "RES06a-wl-npolyf_u.nl_out" ,"RES07a-wl-ppolyf_u.nl_out" ,"RES08a-wl-npolyf_s.nl_out" , "RES09a-wl-ppolyf_s.nl_out" , "RES10a-wl-ppolyf_u_1k.nl_out", + "RES11a-wl-ppolyf_u_2k.nl_out" ,"RES12a-wl-ppolyf_u_1k_6p0.nl_o" ,"RES13a-wl-ppolyf_u_2k_6p0.nl_o" , "RES14a-wl-ppolyf_u_3k.nl_out" , + "RES15a-wl-rm1.nl_out" , "RES16a-wl-rm2.nl_out" , "RES17a-wl-rm3.nl_out" , "RES18a-wl-tm6k.nl_out" , "RES19a-wl-tm9k.nl_out" , + "RES20a-wl-tm11k.nl_out" , "RES21a-wl-tm30k.nl_out" ,"RES05a-wl-nwell.nl_out"] + + sign_a = ["+" , "-" , "+" , "-" , "+" , "+" , "-" , "+" , "-" , "-" , "-" , "-" , "-" , "-" , "+" , "+" , "+" , "+" , "+" , "+", "+", ""] + measure_a = ["r","corners", "res"] + + for corner in corners_a: + for i,device in enumerate(devices_a): + # Folder structure of measured values + r_sim, res_vn, res_in = measure_a[0], measure_a[1], measure_a[2] + dirpath = f"{device}_{r_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{r_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Resistor/{dev_data_a[i]}.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{r_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{r_sim}",exist_ok=False) + + ext_measured_a (device,res_vn,res_in, r_sim, corner) + ext_simulated_a(device,res_vn,res_in,r_sim, corner,sign_a[i]) + error_cal_a (device,res_vn,res_in,r_sim, corner) + + + # res temp_var + corners_b = ["typical","ff","ss"] + devices_b = ["nplus_u" , "nplus_s", "pplus_u" , "pplus_s" , "nwell" , "npolyf_u" , "ppolyf_u" , "npolyf_s" , "ppolyf_s" , "ppolyf_u_1k" , "ppolyf_u_2k" , "ppolyf_u_1k_6p0" , "ppolyf_u_2k_6p0" , "ppolyf_u_3k" , + "rm1" , "rm2", "rm3" , "tm6k" , "tm9k" , "tm11k", "tm30k"] + dev_data_b = ["RES01b-temp-nplus_u.nl_out" , "RES03b-temp-nplus_s.nl_out", "RES02b-temp-pplus_u.nl_out" , "RES04b-temp-pplus_s.nl_out" , "RES05b-temp-nwell.nl_out" , + "RES06b-temp-npolyf_u.nl_out" , "RES07b-temp-ppolyf_u.nl_out" , "RES08b-temp-npolyf_s.nl_out" , "RES09b-temp-ppolyf_s.nl_out" , "RES10b-temp-ppolyf_u_1k.nl_out" , + "RES11b-temp-ppolyf_u_2k.nl_out" , "RES12b-temp-ppolyf_u_1k_6p0.nl" , "RES13b-temp-ppolyf_u_2k_6p0.nl" , "RES14b-temp-ppolyf_u_3k.nl_out" , + "RES15b-temp-rm1.nl_out", "RES16b-temp-rm2.nl_out" , "RES17b-temp-rm3.nl_out" , + "RES18b-temp-tm6k.nl_out", "RES19b-temp-tm9k.nl_out" , "RES20b-temp-tm11k.nl_out", "RES21b-temp-tm30k.nl_out"] + + sign_b = ["+" , "+", "-" , "-" , "+" , "+" , "-" ,"+" , "-" , "-" , "-" , "-" , "-" , "-" , "+" , "+" , "+" , "+" , "+" , "+", "+"] + measure_b = ["r","corners", "res"] + + for corner in corners_b: + for i,device in enumerate(devices_b): + # Folder structure of measured values + r_sim, res_vn, res_in = measure_b[0], measure_b[1], measure_b[2] + dirpath = f"{device}_{r_sim}_{corner}_temp" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{r_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Resistor/{dev_data_b[i]}.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{r_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{r_sim}",exist_ok=False) + + ext_measured_b (device,res_vn,res_in, r_sim, corner) + ext_simulated_b(device,res_vn,res_in,r_sim, corner,sign_b[i]) + error_cal_b (device,res_vn,res_in,r_sim, corner) + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/.spiceinit b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/.spiceinit b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1.spice b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1.spice new file mode 100644 index 00000000..9a491545 --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1.spice @@ -0,0 +1,46 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vin I 0 dc pulse(0 5 100p 1p 1p 100p 200p) +Vdd VDD 0 dc {{volt}} + +* Main circuit +X1 I ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__inv_1 + +* Temperature set +.temp {{temp}} +.options tnom={{temp}} + +* Analyses +.control +tran 1p 200p +meas tran high_in FIND V(ZN) AT=100p +meas tran low_in FIND V(ZN) AT=200p + +wrdata inv/simulated/inv_{{process}}_{{temp}}c_{{volt}}v.csv {high_in} {low_in} + +.endc + +* Libraries calling +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" {{process}} + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__inv_1 I ZN VDD VNW VPW VSS +xM_i_0 ZN I VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_1 ZN I VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1_run.spice b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1_run.spice new file mode 100644 index 00000000..76b31f6f --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1_run.spice @@ -0,0 +1,46 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vin I 0 dc pulse(0 5 100p 1p 1p 100p 200p) +Vdd VDD 0 dc 5 + +* Main circuit +X1 I ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__inv_1 + +* Temperature set +.temp 25 +.options tnom=25 + +* Analyses +.control +tran 1p 200p +meas tran high_in FIND V(ZN) AT=100p +meas tran low_in FIND V(ZN) AT=200p + +wrdata inv/inv_simulated.csv {high_in} {low_in} + +.endc + +* Libraries calling +.include "../../../../design.ngspice" +.lib "../../../../sm141064.ngspice" typical + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__inv_1 I ZN VDD VNW VPW VSS +xM_i_0 ZN I VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_1 ZN I VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1.spice b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1.spice new file mode 100644 index 00000000..56e45238 --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1.spice @@ -0,0 +1,50 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc {{volt}} +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) + +* Main circuit +X1 I1 I2 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__nand2_1 + +* Temperature set +.temp {{temp}} +.options tnom={{temp}} + +* Analyses +.control +tran 1p 800p +meas tran o0 FIND V(ZN) AT=200p +meas tran o1 FIND V(ZN) AT=400p +meas tran o2 FIND V(ZN) AT=600p +meas tran o3 FIND V(ZN) AT=800p + +wrdata nand2/simulated/nand2_{{process}}_{{temp}}c_{{volt}}v.csv {o0} {o1} {o2} {o3} +.endc + +* Libraries calling +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" {{process}} + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__nand2_1 A1 A2 ZN VDD VNW VPW VSS +xM_i_1 net_0 A2 VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_0 ZN A1 net_0 VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_3 ZN A2 VDD VNW pmos_6p0 W=1.13e-06 L=5e-07 +xM_i_2 VDD A1 ZN VNW pmos_6p0 W=1.13e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1_run.spice b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1_run.spice new file mode 100644 index 00000000..ff981f9c --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1_run.spice @@ -0,0 +1,50 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc 5 +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) + +* Main circuit +X1 I1 I2 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__nand2_1 + +* Temperature set +.temp 25 +.options tnom=25 + +* Analyses +.control +tran 1p 800p +meas tran o0 FIND V(ZN) AT=200p +meas tran o1 FIND V(ZN) AT=400p +meas tran o2 FIND V(ZN) AT=600p +meas tran o3 FIND V(ZN) AT=800p + +wrdata nand2/nand2_simulated.csv {o0} {o1} {o2} {o3} +.endc + +* Libraries calling +.include "../../../../design.ngspice" +.lib "../../../../sm141064.ngspice" typical + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__nand2_1 A1 A2 ZN VDD VNW VPW VSS +xM_i_1 net_0 A2 VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_0 ZN A1 net_0 VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_3 ZN A2 VDD VNW pmos_6p0 W=1.13e-06 L=5e-07 +xM_i_2 VDD A1 ZN VNW pmos_6p0 W=1.13e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1.spice b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1.spice new file mode 100644 index 00000000..f269c03a --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1.spice @@ -0,0 +1,59 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc {{volt}} +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) +Vin3 I3 0 dc pulse(0 5 800p 1p 1p 800p 1600p) + +* Main circuit +X1 I1 I2 I3 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__or3_1 + +* Temperature set +.temp {{temp}} +.options tnom={{temp}} + +* Analyses +.control +tran 1p 1600p +meas tran o0 FIND V(ZN) AT=200p +meas tran o1 FIND V(ZN) AT=400p +meas tran o2 FIND V(ZN) AT=600p +meas tran o3 FIND V(ZN) AT=800p +meas tran o4 FIND V(ZN) AT=1000p +meas tran o5 FIND V(ZN) AT=1200p +meas tran o6 FIND V(ZN) AT=1400p +meas tran o7 FIND V(ZN) AT=1600p + +wrdata or3/simulated/or3_{{process}}_{{temp}}c_{{volt}}v.csv {o0} {o1} {o2} {o3} {o4} {o5} {o6} {o7} +.endc + +* Libraries calling +.include "../../../design.ngspice" +.lib "../../../sm141064.ngspice" {{process}} + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__or3_1 A1 A2 A3 Z VDD VNW VPW VSS +M_i_2 VSS A1 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_3 Z_neg A2 VSS VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_4 VSS A3 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_0 Z Z_neg VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +M_i_5 net_0 A1 Z_neg VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_6 net_1 A2 net_0 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_7 VDD A3 net_1 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_1 Z Z_neg VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1_run.spice b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1_run.spice new file mode 100644 index 00000000..24a5c054 --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1_run.spice @@ -0,0 +1,59 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc 5 +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) +Vin3 I3 0 dc pulse(0 5 800p 1p 1p 800p 1600p) + +* Main circuit +X1 I1 I2 I3 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__or3_1 + +* Temperature set +.temp 25 +.options tnom=25 + +* Analyses +.control +tran 1p 1600p +meas tran o0 FIND V(ZN) AT=200p +meas tran o1 FIND V(ZN) AT=400p +meas tran o2 FIND V(ZN) AT=600p +meas tran o3 FIND V(ZN) AT=800p +meas tran o4 FIND V(ZN) AT=1000p +meas tran o5 FIND V(ZN) AT=1200p +meas tran o6 FIND V(ZN) AT=1400p +meas tran o7 FIND V(ZN) AT=1600p + +wrdata or3/or3_simulated.csv {o0} {o1} {o2} {o3} {o4} {o5} {o6} {o7} +.endc + +* Libraries calling +.include "../../../../design.ngspice" +.lib "../../../../sm141064.ngspice" typical + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__or3_1 A1 A2 A3 Z VDD VNW VPW VSS +M_i_2 VSS A1 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_3 Z_neg A2 VSS VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_4 VSS A3 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_0 Z Z_neg VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +M_i_5 net_0 A1 Z_neg VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_6 net_1 A2 net_0 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_7 VDD A3 net_1 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_1 Z Z_neg VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/models_regression.py b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/models_regression.py new file mode 100644 index 00000000..154994b9 --- /dev/null +++ b/models/ngspice/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/models_regression.py @@ -0,0 +1,140 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from cmath import inf +from re import L, T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device, table): + + # Generate CSVs with truth tables + df = pd.DataFrame(data=table) + df.set_index(df.columns[0]) + new_header = df.iloc[0] + df = df[1:] + df.columns = new_header + df.to_csv(f"{device}/{device}_measured.csv", index = False) + +def ext_simulated(device, processes, volts, temps): + + # Get all corners simulated + for process in processes: + for volt in volts: + for temp in temps: + with open(f"device_netlists/gf180mcu_fd_sc_mcu7t5v0__{device}_1.spice") as f: + tmpl = Template(f.read()) + netlist_path = f"{device}/{device}_netlists/{device}_{process}_{temp}c_{volt}v.spice" + with open(netlist_path, "w") as netlist: + netlist.write(tmpl.render(process = process, volt = volt , temp = temp )) + + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + df_simulated = pd.read_csv(f"{device}/simulated/{device}_{process}_{temp}c_{volt}v.csv",header=None, delimiter=r"\s+") + results = [] + for i in df_simulated.columns: + if df_simulated.iloc[0, i] > 2.5: + results.append(1) + else: + results.append(0) + df_measured = pd.read_csv(f"{device}/{device}_measured.csv",header=0) + df = df_measured + df_measured.drop(df_measured.columns[len(df_measured.columns)-1], axis=1, inplace=True) + df_measured['output'] = results[1::2] + df_measured.to_csv(f"{device}/simulated/{device}_{process}_{temp}c_{volt}v.csv",index= False) + +def error_cal(device, processes, volts, temps): + + print (f"\nSimulation results of {device}") + measured = pd.read_csv(f"{device}/{device}_measured.csv") + for process in processes: + for volt in volts: + for temp in temps: + simulated = pd.read_csv(f"{device}/simulated/{device}_{process}_{temp}c_{volt}v.csv") + + res = (measured == simulated).all().all() + print ("{:^5s} in PVT of {:^7s}, {:^3s}V, {:^3s}C functional simulation = {}".format(device, process, volt, temp, res)) + print ("================================================================================================\n") + +def main(): + + devices = ["inv","nand2","or3"] + + # Generate truth tables data + inv_table = [["input","output"], + [0,1], + [1,0]] + + nand2_table = [["input1","input2","output"], + [0,0,1], + [0,1,1], + [1,0,1], + [1,1,0]] + + or3_table = [["input1","input2","input3","output"], + [0,0,0,0], + [0,0,1,1], + [0,1,0,1], + [0,1,1,1], + [1,0,0,1], + [1,0,1,1], + [1,1,0,1], + [1,1,1,1]] + + tables = [inv_table,nand2_table,or3_table] + + processes = ["typical","ff","ss"] + volts = ["5", "4.5", "5.5"] + temps = ["25", "-40", "125"] + + for i, device in enumerate(devices): + # Folder structure of measured values + if os.path.exists(device) and os.path.isdir(device): + shutil.rmtree(device) + os.makedirs(device) + + # Folder structure of simulated values + os.makedirs(f"{device}/{device}_netlists",exist_ok=True) + os.makedirs(f"{device}/simulated",exist_ok=True) + + ext_measured (device, tables[i]) + # =========== Simulate ============== + ext_simulated(device, processes, volts, temps) + + # ============ Results ============== + error_cal (device, processes, volts, temps) + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/ngspice/testing/smoke_test/.spiceinit b/models/ngspice/testing/smoke_test/.spiceinit new file mode 100644 index 00000000..6fc9af84 --- /dev/null +++ b/models/ngspice/testing/smoke_test/.spiceinit @@ -0,0 +1,2 @@ +************ +set ngbehavior=hs diff --git a/models/ngspice/testing/smoke_test/inv_ng.spice b/models/ngspice/testing/smoke_test/inv_ng.spice new file mode 100644 index 00000000..5a3b4c99 --- /dev/null +++ b/models/ngspice/testing/smoke_test/inv_ng.spice @@ -0,0 +1,44 @@ +**.subckt INV_tb +* Copyright 2022 Efabless Corporation +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +Vdd Vdd 0 3.3 +Vin Vin 0 dc pulse(0 3.3 0 1p 1p 100p 200p) +X1 Vdd Vout Vin 0 INV + + +.temp {{temp}} +.options tnom={{temp}} + + +.control +tran 1p 400p +meas tran tphl TRIG v(Vin) VAL={0.5*3.3} RISE=2 TARG v(Vout) VAL={0.5*3.3} FALL=2 +meas tran tplh TRIG v(Vin) VAL={0.5*3.3} FALL=1 TARG v(Vout) VAL={0.5*3.3} RISE=1 +print {(tplh+tphl)/2} +wrdata {{run_path}}/simulation/inv_W{{width}}_L{{length}}_T{{temp}}_{{corner}}.csv {(tplh+tphl)/2} +.endc + + +.include "../../design.ngspice" +.lib "../../sm141064.ngspice" {{corner}} + + +.subckt INV VDD Vout Vin GND +XM1 Vout Vin GND GND nmos_3p3 W={{width}}u L={{length}}u +*ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u +XM2 Vout Vin VDD VDD pmos_3p3 W = {{width_p}}u L = {{length}}u +*ad={{AD_p}}u pd={{PD_p}}u as={{AD_p}}u ps={{PD_p}}u +.ends + +.end \ No newline at end of file diff --git a/models/ngspice/testing/smoke_test/ng_smoke_test.py b/models/ngspice/testing/smoke_test/ng_smoke_test.py new file mode 100644 index 00000000..23128ee7 --- /dev/null +++ b/models/ngspice/testing/smoke_test/ng_smoke_test.py @@ -0,0 +1,120 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Usage: + smoke_test.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +import re +from docopt import docopt +import pandas as pd +import os +from jinja2 import Template +import concurrent.futures +import itertools +import datetime +import warnings +import subprocess + +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + p = subprocess.Popen(f"ngspice -b -a {file_name} > {file_name}.log 2>&1", shell=True, executable='/bin/bash') + p.wait() + +def get_sizes(models_path): + with open(models_path, "r") as f: + device_model = f.read() + dimensions = re.findall(f"\.model nmos_3p3.*\n.*\n\+lmin.*= (.*\S).*\n.*\n\+wmin.*= (.*\S)", device_model) + return dimensions[0:16] + +def get_results(run_path, sizes, temp, corner): + netlist_tmp = f"./inv_ng.spice" + width = float(sizes[1]) * 1000000 + width_p = width * 1.5 + length = float(sizes[0]) * 1000000 + # AD = width * 0.24 + # AD_p = AD * 1.5 + # PD = 2 * (width + 0.24) + # PD_p = width + PD + # AS = AD + # PS = PD + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + + os.makedirs(f"{run_path}/netlists",exist_ok=True) + os.makedirs(f"{run_path}/simulation",exist_ok=True) + netlist_path = f"{run_path}/netlists/inv_W{width}_L{length}_T{temp}_{corner}.spice" + with open(netlist_path, "w") as netlist: + netlist.write(tmpl.render(corner = corner, width = width,length = length, temp = temp , run_path = run_path, width_p = width_p))#, AD = AD , PD = PD , AS = AS , PS = PS, AD_p = AD_p, PD_p = PD_p )) + + call_simulator(netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{run_path}/simulation/inv_W{width}_L{length}_T{temp}_{corner}.csv",header=None, delimiter=r"\s+") + return [f"W{width}_L{length}_T{temp}_{corner}",df_simulated.iloc[-1, -1]] + +def main(): + + models_path = "../../sm141064.ngspice" + temps = ["25","-40","125"] + corners = ["typical","ff","ss","fs","sf"]#,"stat"] + + time = f"{datetime.datetime.now()}".replace(" ", "_") + run_path = f"../run_smoke_{time}" + os.makedirs(run_path,exist_ok=True) + + sizes = get_sizes(models_path) + results = [] + + all_combs = list(itertools.product(sizes, temps, corners)) + + with concurrent.futures.ThreadPoolExecutor(max_workers=workers_count) as executor: + # Start the load operations and mark each future with its URL + future_list = [executor.submit(get_results, run_path, comb[0], comb[1], comb[2]) for comb in all_combs] + for future in concurrent.futures.as_completed(future_list): + try: + results.append(future.result()) + except Exception as exc: + print('Generated an exception: %s' % (exc)) + + + df_results = pd.DataFrame(results) + df_results.columns = ["run","tpd_result"] + df_results.to_csv(f"{run_path}/final_results.csv",index= False) + + print (df_results) + + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='smoke_test: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_cv_npn.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_cv_npn.nl_out.xlsx new file mode 100644 index 00000000..4910b809 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_cv_npn.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_cv_pnp.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_cv_pnp.nl_out.xlsx new file mode 100644 index 00000000..045b1a33 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_cv_pnp.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_fc_npn.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_fc_npn.nl_out.xlsx new file mode 100644 index 00000000..054b06ab Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_fc_npn.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_fc_pnp.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_fc_pnp.nl_out.xlsx new file mode 100644 index 00000000..d9db37a2 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_fc_pnp.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mc_npn.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mc_npn.nl_out.xlsx new file mode 100644 index 00000000..d8d27d02 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mc_npn.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mc_pnp.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mc_pnp.nl_out.xlsx new file mode 100644 index 00000000..2492ba0e Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mc_pnp.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mm_pnp.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mm_pnp.nl_out.xlsx new file mode 100644 index 00000000..6ac61639 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_mm_pnp.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_f.nl_out.xlsx new file mode 100644 index 00000000..2c7d4549 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_r.nl_out.xlsx new file mode 100644 index 00000000..1b769d4c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_beta_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_f.nl_out.xlsx new file mode 100644 index 00000000..f5a1c990 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_r.nl_out.xlsx new file mode 100644 index 00000000..6ac941ab Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_flyback_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_f.nl_out.xlsx new file mode 100644 index 00000000..49897472 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_r.nl_out.xlsx new file mode 100644 index 00000000..26898b21 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_gummel_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_f.nl_out.xlsx new file mode 100644 index 00000000..96b07d97 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_r.nl_out.xlsx new file mode 100644 index 00000000..76d04f4b Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_npn_icvc_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_f.nl_out.xlsx new file mode 100644 index 00000000..a80ee451 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_r.nl_out.xlsx new file mode 100644 index 00000000..335d907c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_beta_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_f.nl_out.xlsx new file mode 100644 index 00000000..364ca478 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_r.nl_out.xlsx new file mode 100644 index 00000000..ac6108ee Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_flyback_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_f.nl_out.xlsx new file mode 100644 index 00000000..af592f16 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_r.nl_out.xlsx new file mode 100644 index 00000000..443c2de9 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_gummel_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_f.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_f.nl_out.xlsx new file mode 100644 index 00000000..8fa1a77b Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_f.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_r.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_r.nl_out.xlsx new file mode 100644 index 00000000..fec8e829 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/BJT/bjt_pnp_icvc_r.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx new file mode 100644 index 00000000..1b616417 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Cap/mimcap_mc.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Cap/mimcap_mc.nl_out.xlsx new file mode 100644 index 00000000..0ef13b4a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Cap/mimcap_mc.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx new file mode 100644 index 00000000..4711b881 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx new file mode 100644 index 00000000..3585f1a9 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwps_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwps_cv.nl_out.xlsx new file mode 100644 index 00000000..5582df37 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwps_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwps_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwps_iv.nl_out.xlsx new file mode 100644 index 00000000..d9d62db3 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwps_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwpw_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwpw_cv.nl_out.xlsx new file mode 100644 index 00000000..ccd29089 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwpw_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwpw_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwpw_iv.nl_out.xlsx new file mode 100644 index 00000000..25d7edfc Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/dnwpw_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_3p3_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..cbf4db35 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_3p3_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_3p3_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..f4527e09 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_3p3_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_6p0_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..7023e41c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_6p0_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_6p0_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..08807f63 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/np_6p0_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..1b2af926 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..0c964d83 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_3p3_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..5789d79c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9321fb63 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/nwp_6p0_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_3p3_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..bed97275 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_3p3_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_3p3_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..c45be6c1 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_3p3_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_6p0_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..2fc2a7c5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_6p0_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_6p0_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9cbce9b0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/pn_6p0_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/sc_diode_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/sc_diode_cv.nl_out.xlsx new file mode 100644 index 00000000..a6767fc7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/sc_diode_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Diode/sc_diode_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Diode/sc_diode_iv.nl_out.xlsx new file mode 100644 index 00000000..8b9344f7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Diode/sc_diode_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/hvfet_spec.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/hvfet_spec.nl_out.xlsx new file mode 100644 index 00000000..efd10396 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/hvfet_spec.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_cv.nl_out.xlsx new file mode 100644 index 00000000..c763f6b0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_iv.nl_out.xlsx new file mode 100644 index 00000000..0d975fee Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_noi.nl_out.xlsx new file mode 100644 index 00000000..674174cc Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_scaling_trend.n.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_scaling_trend.n.xlsx new file mode 100644 index 00000000..bbadf6c0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/nmos_10p0_asym_scaling_trend.n.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_cv.nl_out.xlsx new file mode 100644 index 00000000..dfd13b60 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_iv.nl_out.xlsx new file mode 100644 index 00000000..8e5eb303 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_noi.nl_out.xlsx new file mode 100644 index 00000000..ca38856a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_scaling_trend.n.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_scaling_trend.n.xlsx new file mode 100644 index 00000000..b2f245d1 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/pmos_10p0_asym_scaling_trend.n.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_1sig.nl.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_1sig.nl.xlsx new file mode 100644 index 00000000..d337742c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_1sig.nl.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_2sig.nl.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_2sig.nl.xlsx new file mode 100644 index 00000000..c6d8642d Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_2sig.nl.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_3sig.nl.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_3sig.nl.xlsx new file mode 100644 index 00000000..bc8639c3 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/HV_FET/stat_mc_np_correlation_3sig.nl.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/3p3_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..813635cd Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/3p3_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/3p3_sab_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/3p3_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..fd139e1f Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/3p3_sab_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..a6d80eec Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_nat_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_nat_cv.nl_out.xlsx new file mode 100644 index 00000000..407129c7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_nat_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_sab_cv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..1dbd85c5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/6p0_sab_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..b6b74f90 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_noi.nl_out.xlsx new file mode 100644 index 00000000..dd48b9d6 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..cba86bee Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv_dsab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..5ceb2a6d Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..b4b36f96 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_3p3_sab_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..9842b38a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_iv.nl_out.xlsx new file mode 100644 index 00000000..3a70d17d Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_noi.nl_out.xlsx new file mode 100644 index 00000000..ab51a895 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_nat_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_noi.nl_out.xlsx new file mode 100644 index 00000000..3662177d Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..3aee7048 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv_dsab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..bb8e4f4f Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..865ff150 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/nmos_6p0_sab_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_iv.nl_out.xlsx new file mode 100644 index 00000000..2fa27975 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_noi.nl_out.xlsx new file mode 100644 index 00000000..f7ba8acf Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..d87ad5dc Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv_dsab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..c7cf1cc0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..16c3a3af Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_3p3_sab_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_iv.nl_out.xlsx new file mode 100644 index 00000000..a9254cb1 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_noi.nl_out.xlsx new file mode 100644 index 00000000..aebf3e13 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv.nl_out.xlsx new file mode 100644 index 00000000..a8248735 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv_dsab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv_dsab.nl_out.xlsx new file mode 100644 index 00000000..10eaca32 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_iv_dsab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_noi.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_noi.nl_out.xlsx new file mode 100644 index 00000000..8cb3a2d9 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/pmos_6p0_sab_noi.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..1416ab96 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..89a74f0f Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_3p3_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..e7085f0c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..ad30f919 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_nmos_6p0_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..19118d4a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..48791d7e Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_3p3_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..a85c6c35 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..be21ff61 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/scaling_pmos_6p0_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/spec_all_fets.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/spec_all_fets.nl_out.xlsx new file mode 100644 index 00000000..3ef61df5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/spec_all_fets.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3.nl_out.xlsx new file mode 100644 index 00000000..0f182735 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..a3030a12 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_3p3_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0.nl_out.xlsx new file mode 100644 index 00000000..f191aaa7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..32629490 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_6p0_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_nmos_6p0_nat.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_nmos_6p0_nat.nl_out.xlsx new file mode 100644 index 00000000..a4830f96 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mc_nmos_6p0_nat.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..51142f05 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..4cafde66 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_3p3_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..274347db Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..a139dced Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_nmos_6p0_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3.nl_out.xlsx new file mode 100644 index 00000000..86f46317 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3_sab.nl_out.xlsx new file mode 100644 index 00000000..c4bd3830 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_3p3_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0.nl_out.xlsx new file mode 100644 index 00000000..b9314cc1 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0_sab.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0_sab.nl_out.xlsx new file mode 100644 index 00000000..c081636c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/MOS/stat_mm_pmos_6p0_sab.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01a-wl-nplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01a-wl-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..bb5c8e7a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01a-wl-nplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nom-nplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nom-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..84cfe2f7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nom-nplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..57c0b79f Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01b-temp-nplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01c-mm-nplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01c-mm-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..623e9bae Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01c-mm-nplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01d-mc-nplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01d-mc-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..40744c42 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01d-mc-nplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01e-cvcor-nplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01e-cvcor-nplus_u.nl_out.xlsx new file mode 100644 index 00000000..cb09382a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES01e-cvcor-nplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02a-wl-pplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02a-wl-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..0dbd2782 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02a-wl-pplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-nom-pplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-nom-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..20315b0c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-nom-pplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-pplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..2df4e8f3 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02b-temp-pplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02c-mm-pplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02c-mm-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..5640c401 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02c-mm-pplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02d-mc-pplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02d-mc-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..4ba25498 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02d-mc-pplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02e-cvcor-pplus_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02e-cvcor-pplus_u.nl_out.xlsx new file mode 100644 index 00000000..10b193a0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES02e-cvcor-pplus_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03a-wl-nplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03a-wl-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..260a8cad Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03a-wl-nplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03b-temp-nplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03b-temp-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..e65b1fc5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03b-temp-nplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03d-mc-nplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03d-mc-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..ff7ad366 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03d-mc-nplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03e-cvcor-nplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03e-cvcor-nplus_s.nl_out.xlsx new file mode 100644 index 00000000..76fea8b4 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES03e-cvcor-nplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04a-wl-pplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04a-wl-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..1a49e0c3 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04a-wl-pplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04b-temp-pplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04b-temp-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..0fbb6725 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04b-temp-pplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04d-mc-pplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04d-mc-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..6e0a4b1b Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04d-mc-pplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04e-cvcor-pplus_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04e-cvcor-pplus_s.nl_out.xlsx new file mode 100644 index 00000000..b0438256 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES04e-cvcor-pplus_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05a-wl-nwell.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05a-wl-nwell.nl_out.xlsx new file mode 100644 index 00000000..64089955 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05a-wl-nwell.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05b-temp-nwell.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05b-temp-nwell.nl_out.xlsx new file mode 100644 index 00000000..7cbd7767 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05b-temp-nwell.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05e-cvcor-nwell.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05e-cvcor-nwell.nl_out.xlsx new file mode 100644 index 00000000..12f2d079 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES05e-cvcor-nwell.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06a-wl-npolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06a-wl-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..0d06e5e9 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06a-wl-npolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06b-temp-npolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06b-temp-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..2687b8c5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06b-temp-npolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06c-mm-npolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06c-mm-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..c624220a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06c-mm-npolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06d-mc-npolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06d-mc-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..e06c435f Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06d-mc-npolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06e-cvcor-npolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06e-cvcor-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..d48576b9 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06e-cvcor-npolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06f-noise-npolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06f-noise-npolyf_u.nl_out.xlsx new file mode 100644 index 00000000..fa0909e5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES06f-noise-npolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07a-wl-ppolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07a-wl-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..479a205f Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07a-wl-ppolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07b-temp-ppolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07b-temp-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..6d890fae Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07b-temp-ppolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07c-mm-ppolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07c-mm-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..fba4fbc2 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07c-mm-ppolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07d-mc-ppolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07d-mc-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..31fcb16b Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07d-mc-ppolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07e-cvcor-ppolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07e-cvcor-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..a4188bd5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07e-cvcor-ppolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07f-noise-ppolyf_u.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07f-noise-ppolyf_u.nl_out.xlsx new file mode 100644 index 00000000..a26d9baa Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES07f-noise-ppolyf_u.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08a-wl-npolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08a-wl-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..64025b9d Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08a-wl-npolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08b-temp-npolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08b-temp-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..d9c246d7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08b-temp-npolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08d-mc-npolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08d-mc-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..5bb22314 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08d-mc-npolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08e-cvcor-npolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08e-cvcor-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..77df6d2b Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08e-cvcor-npolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08f-noise-npolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08f-noise-npolyf_s.nl_out.xlsx new file mode 100644 index 00000000..da255dfa Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES08f-noise-npolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09a-wl-ppolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09a-wl-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..68965182 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09a-wl-ppolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09b-temp-ppolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09b-temp-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..04bb357c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09b-temp-ppolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09d-mc-ppolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09d-mc-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..d7d005b9 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09d-mc-ppolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09e-cvcor-ppolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09e-cvcor-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..02146f86 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09e-cvcor-ppolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09f-noise-ppolyf_s.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09f-noise-ppolyf_s.nl_out.xlsx new file mode 100644 index 00000000..2d1275da Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES09f-noise-ppolyf_s.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10a-wl-ppolyf_u_1k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10a-wl-ppolyf_u_1k.nl_out.xlsx new file mode 100644 index 00000000..7c03c8a0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10a-wl-ppolyf_u_1k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10b-temp-ppolyf_u_1k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10b-temp-ppolyf_u_1k.nl_out.xlsx new file mode 100644 index 00000000..de70746e Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10b-temp-ppolyf_u_1k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10d-mc-ppolyf_u_1k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10d-mc-ppolyf_u_1k.nl_out.xlsx new file mode 100644 index 00000000..758a7f4d Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10d-mc-ppolyf_u_1k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10e-cvcor-ppolyf_u_1k.nl_ou.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10e-cvcor-ppolyf_u_1k.nl_ou.xlsx new file mode 100644 index 00000000..76c959ab Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10e-cvcor-ppolyf_u_1k.nl_ou.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10f-noise-ppolyf_u_1k.nl_ou.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10f-noise-ppolyf_u_1k.nl_ou.xlsx new file mode 100644 index 00000000..5ad8dfef Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES10f-noise-ppolyf_u_1k.nl_ou.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11a-wl-ppolyf_u_2k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11a-wl-ppolyf_u_2k.nl_out.xlsx new file mode 100644 index 00000000..71aa86d7 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11a-wl-ppolyf_u_2k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11b-temp-ppolyf_u_2k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11b-temp-ppolyf_u_2k.nl_out.xlsx new file mode 100644 index 00000000..1e91eb03 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11b-temp-ppolyf_u_2k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11d-mc-ppolyf_u_2k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11d-mc-ppolyf_u_2k.nl_out.xlsx new file mode 100644 index 00000000..8347b1ca Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11d-mc-ppolyf_u_2k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11e-cvcor-ppolyf_u_2k.nl_ou.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11e-cvcor-ppolyf_u_2k.nl_ou.xlsx new file mode 100644 index 00000000..4b15b257 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11e-cvcor-ppolyf_u_2k.nl_ou.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11f-noise-ppolyf_u_2k.nl_ou.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11f-noise-ppolyf_u_2k.nl_ou.xlsx new file mode 100644 index 00000000..430db7b3 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES11f-noise-ppolyf_u_2k.nl_ou.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12a-wl-ppolyf_u_1k_6p0.nl_o.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12a-wl-ppolyf_u_1k_6p0.nl_o.xlsx new file mode 100644 index 00000000..bbcecca1 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12a-wl-ppolyf_u_1k_6p0.nl_o.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12b-temp-ppolyf_u_1k_6p0.nl.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12b-temp-ppolyf_u_1k_6p0.nl.xlsx new file mode 100644 index 00000000..6632263a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12b-temp-ppolyf_u_1k_6p0.nl.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12d-mc-ppolyf_u_1k_6p0.nl_o.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12d-mc-ppolyf_u_1k_6p0.nl_o.xlsx new file mode 100644 index 00000000..0c2cd974 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12d-mc-ppolyf_u_1k_6p0.nl_o.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12e-cvcor-ppolyf_u_1k_6p0.n.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12e-cvcor-ppolyf_u_1k_6p0.n.xlsx new file mode 100644 index 00000000..26afc556 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12e-cvcor-ppolyf_u_1k_6p0.n.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12f-noise-ppolyf_u_1k_6p0.n.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12f-noise-ppolyf_u_1k_6p0.n.xlsx new file mode 100644 index 00000000..d587bc97 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES12f-noise-ppolyf_u_1k_6p0.n.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13a-wl-ppolyf_u_2k_6p0.nl_o.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13a-wl-ppolyf_u_2k_6p0.nl_o.xlsx new file mode 100644 index 00000000..75bb7db5 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13a-wl-ppolyf_u_2k_6p0.nl_o.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13b-temp-ppolyf_u_2k_6p0.nl.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13b-temp-ppolyf_u_2k_6p0.nl.xlsx new file mode 100644 index 00000000..f258c605 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13b-temp-ppolyf_u_2k_6p0.nl.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13d-mc-ppolyf_u_2k_6p0.nl_o.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13d-mc-ppolyf_u_2k_6p0.nl_o.xlsx new file mode 100644 index 00000000..f3039060 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13d-mc-ppolyf_u_2k_6p0.nl_o.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13e-cvcor-ppolyf_u_2k_6p0.n.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13e-cvcor-ppolyf_u_2k_6p0.n.xlsx new file mode 100644 index 00000000..7fb23308 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13e-cvcor-ppolyf_u_2k_6p0.n.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13f-noise-ppolyf_u_2k_6p0.n.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13f-noise-ppolyf_u_2k_6p0.n.xlsx new file mode 100644 index 00000000..731c3cea Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES13f-noise-ppolyf_u_2k_6p0.n.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14a-wl-ppolyf_u_3k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14a-wl-ppolyf_u_3k.nl_out.xlsx new file mode 100644 index 00000000..e11f941c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14a-wl-ppolyf_u_3k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14b-temp-ppolyf_u_3k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14b-temp-ppolyf_u_3k.nl_out.xlsx new file mode 100644 index 00000000..40b1ff22 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14b-temp-ppolyf_u_3k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14d-mc-ppolyf_u_3k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14d-mc-ppolyf_u_3k.nl_out.xlsx new file mode 100644 index 00000000..332dbc3a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14d-mc-ppolyf_u_3k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14e-cvcor-ppolyf_u_3k.nl_ou.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14e-cvcor-ppolyf_u_3k.nl_ou.xlsx new file mode 100644 index 00000000..63866694 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14e-cvcor-ppolyf_u_3k.nl_ou.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14f-noise-ppolyf_u_3k.nl_ou.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14f-noise-ppolyf_u_3k.nl_ou.xlsx new file mode 100644 index 00000000..359b06cd Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES14f-noise-ppolyf_u_3k.nl_ou.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES15a-wl-rm1.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES15a-wl-rm1.nl_out.xlsx new file mode 100644 index 00000000..597ed2ab Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES15a-wl-rm1.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES15b-temp-rm1.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES15b-temp-rm1.nl_out.xlsx new file mode 100644 index 00000000..7af7d6b3 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES15b-temp-rm1.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES16a-wl-rm2.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES16a-wl-rm2.nl_out.xlsx new file mode 100644 index 00000000..8e224e27 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES16a-wl-rm2.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES16b-temp-rm2.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES16b-temp-rm2.nl_out.xlsx new file mode 100644 index 00000000..7400b884 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES16b-temp-rm2.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES17a-wl-rm3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES17a-wl-rm3.nl_out.xlsx new file mode 100644 index 00000000..7d5f551e Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES17a-wl-rm3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES17b-temp-rm3.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES17b-temp-rm3.nl_out.xlsx new file mode 100644 index 00000000..18592fa4 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES17b-temp-rm3.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES18a-wl-tm6k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES18a-wl-tm6k.nl_out.xlsx new file mode 100644 index 00000000..214f5609 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES18a-wl-tm6k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES18b-temp-tm6k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES18b-temp-tm6k.nl_out.xlsx new file mode 100644 index 00000000..acbbf897 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES18b-temp-tm6k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES19a-wl-tm9k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES19a-wl-tm9k.nl_out.xlsx new file mode 100644 index 00000000..c7701c81 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES19a-wl-tm9k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES19b-temp-tm9k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES19b-temp-tm9k.nl_out.xlsx new file mode 100644 index 00000000..88ec343e Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES19b-temp-tm9k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES20a-wl-tm11k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES20a-wl-tm11k.nl_out.xlsx new file mode 100644 index 00000000..b4148481 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES20a-wl-tm11k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES20b-temp-tm11k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES20b-temp-tm11k.nl_out.xlsx new file mode 100644 index 00000000..5dc8f38a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES20b-temp-tm11k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES21a-wl-tm30k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES21a-wl-tm30k.nl_out.xlsx new file mode 100644 index 00000000..8639044c Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES21a-wl-tm30k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES21b-temp-tm30k.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES21b-temp-tm30k.nl_out.xlsx new file mode 100644 index 00000000..aab88bd0 Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/RES21b-temp-tm30k.nl_out.xlsx differ diff --git a/models/xyce/testing/180MCU_SPICE_DATA/Resistor/efuse.nl_out.xlsx b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/efuse.nl_out.xlsx new file mode 100644 index 00000000..596dfb6a Binary files /dev/null and b/models/xyce/testing/180MCU_SPICE_DATA/Resistor/efuse.nl_out.xlsx differ diff --git a/models/xyce/testing/Makefile b/models/xyce/testing/Makefile new file mode 100644 index 00000000..7cc3ce2c --- /dev/null +++ b/models/xyce/testing/Makefile @@ -0,0 +1,183 @@ +# Copyright 2022 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +#================================================================= +# ------------------------ models_xyce ------------------------ +#================================================================= + +SHELL := /bin/bash +Testing_DIR ?= $(shell pwd) +run_folder := $(shell date +'run_%Y_%m_%d_%H:%M:%S') + + +.DEFAULT_GOAL := all + +all : test-models_xyce + +test-models_xyce: smoke-test models-MOS models-BJT models-diode models-MOSCAP models-MIMCAP models-RES + +#================================ +#---------- Create Run ---------- +#================================ + +.ONESHELL: +Add_run-dir: + @cd $(Testing_DIR) + @ [ ! -d "$(run_folder)/" ] && cp -rf $(Testing_DIR)/regression $(Testing_DIR)/$(run_folder) + +#================================ +#---------- smoke-test ---------- +#================================ + +.ONESHELL: +smoke-test: + @cd $(Testing_DIR)/smoke_test + @python3 xyce_smoke_test.py + + +#================================ +# ---------- models-MOS---------- +#================================ + +.ONESHELL: +models-MOS: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/mos_iv_vgs + @echo "========== Runing models_xyce-MOS regression ==========" |& tee -a ../run_log.log + @ python3 models_regression.py |& tee -a ../run_log.log +# @cd ../mos_iv_vbs +# @ python3 models_regression.py |& tee -a ../run_log.log + +# .ONESHELL: +# clean-models-MOS: +# @echo "==== Cleaning models-MOS old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/mos_iv_vgs && rm -rf nmos_* pmos_* + +#================================ +# ---------- models-BJT---------- +#================================ + +.ONESHELL: +models-BJT: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/bjt_cj + @echo "========== Runing models_xyce-BJT regression ==========" |& tee -a ../run_log.log + @ python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-BJT: +# @echo "==== Cleaning models-BJT old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/bjt_cj && rm -rf vnpn_* vpnp_* + +#================================ +# --------- models-diode -------- +#================================ + +.ONESHELL: +models-diode: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/diode + @echo "========== Runing models_xyce-diode regression ==========" |& tee -a ../run_log.log + @ python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-diode: +# @echo "==== Cleaning models-diode old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/diode && rm -rf np_* pn_* nwp* dnw* sc_* + +#================================ +# -------- models-MOSCAP -------- +#================================ + +.ONESHELL: +models-MOSCAP: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/moscap_c + @echo "========== Runing models_xyce-MOSCAP regression ==========" |& tee -a ../run_log.log + @ python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-MOSCAP: +# @echo "==== Cleaning models-MOSCAP old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/moscap_c && rm -rf nmoscap_* pmoscap_* + +#================================ +# -------- models-MIMCAP -------- +#================================ + +.ONESHELL: +models-MIMCAP: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/mimcap_c + @echo "========== Runing models_xyce-MIMCAP regression ==========" |& tee -a ../run_log.log + @ python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-MIMCAP: +# @echo "==== Cleaning models-MIMCAP old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/mimcap_c && rm -rf mim* + + +#================================ +# --------- models-RES ---------- +#================================ + +.ONESHELL: +models-RES: Add_run-dir + @cd $(Testing_DIR)/$(run_folder)/resistor_r + @echo "========== Runing models_xyce-RES regression ==========" |& tee -a ../run_log.log + @ python3 models_regression.py |& tee -a ../run_log.log + + +# .ONESHELL: +# clean-models-RES: +# @echo "==== Cleaning models-RES old runs ====" +# @cd $(Testing_DIR)/$(run_folder)/resistor_r && rm -rf nplus* pplus* npoly* ppoly* rm* tm* nwell + + +#=============================== +# --------- Clean ALL ---------- +#=============================== + +# .ONESHELL: +# clean: clean-models-MOS clean-models-BJT clean-models-diode clean-models-MOSCAP clean-models-MIMCAP clean-models-RES +# @echo "==== Cleaning all runs is done ====" + + +#========================== +# --------- HELP ---------- +#========================== + +# Help Target +help: + @echo "\n ==== The following are some of the valid targets for this Makefile ====\n" + @echo "... all (the default if no target is provided)" + @echo "... smoke-test (To run smoke test for an inverter)" + @echo "... test-models_xyce (To run regression for all devices)" + @echo "... models-MOS (To run regression for MOS devices)" + @echo "... models-BJT (To run regression for BJT devices)" + @echo "... models-diode (To run regression for diode devices)" + @echo "... models-MOSCAP (To run regression for MOSCAP devices)" + @echo "... models-MIMCAP (To run regression for MIMCAP devices)" + @echo "... models-RES (To run regression for RES devices)" +# @echo "... clean-models-MOS (To clean old runs for MOS devices)" +# @echo "... clean-models-BJT (To clean old runs for BJT devices)" +# @echo "... clean-models-diode (To clean old runs for diode devices)" +# @echo "... clean-models-MOSCAP (To clean old runs for MOSCAP devices)" +# @echo "... clean-models-MIMCAP (To clean old runs for MIMCAP devices)" +# @echo "... clean-models-RES (To run regression for RES devices)" + +# @echo "... clean (To clean all old runs) " + +.PHONY : help \ No newline at end of file diff --git a/models/xyce/testing/README.md b/models/xyce/testing/README.md new file mode 100644 index 00000000..063cc259 --- /dev/null +++ b/models/xyce/testing/README.md @@ -0,0 +1,51 @@ +# Globalfoundries 180nm MCU models-xyce regression + +Explains how to run GF180nm models-xyce regression. + +## Folder Structure + +```text +📦testing + ┣ 📜Makefile + ┣ 📜README.md + ┣ 📦regression + ┣ 📦smoke_test + ┣ 📦180MCU_SPICE_Models + ``` + +## Prerequisites + +At a minimum: + +- Git 2.35+ +- Python 3.6+ +- Xyce 7.5+ + +### On Ubuntu, you can just + +`apt install -y build-essential python3` + +- Check this [xyce](https://xyce.sandia.gov/documentation-tutorials/building-guide/) for Xyce installation. + +## Regression Usage + +To make a full test for GF180nm models-xyce, you could use the following command in testing directory: + +```bash +make all +``` + +- You could also check allowed targets in the Makefile, using the following command: + + ```bash + make help + ``` + +## **Regression Outputs** + +- The resulting files are in `regression//` with name of `` that contains: + + 1. A final report file of all results. + 2. measured folder that contains measured data used in regression. + 3. simulated folder that contains simulated data used in regression. + 4. netlists folder that contains spice files used in simulation. diff --git a/models/xyce/testing/regression/bjt_beta/device_netlists/npn.spice b/models/xyce/testing/regression/bjt_beta/device_netlists/npn.spice new file mode 100644 index 00000000..ad9e2165 --- /dev/null +++ b/models/xyce/testing/regression/bjt_beta/device_netlists/npn.spice @@ -0,0 +1,26 @@ +***************** +** main netlist +***************** + +Vcp c 0 dc 3 +Vbp b 0 dc 1.2 + +xq1 c b 0 0 {{device}} + + +***************** +** Analysis +***************** + +.DC Vbp 0.2 1.2 0.01 Vcp 1 3 1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=npn/simulated_Ic/{{i}}_simulated_{{device}}.csv Vbp +.print DC FORMAT=CSV file=npn/simulated_Ic/{{i}}_simulated_{{device}}.csv {-I(Vcp)} +.print DC FORMAT=CSV file=npn/simulated_Ib/{{i}}_simulated_{{device}}.csv Vbp +.print DC FORMAT=CSV file=npn/simulated_Ib/{{i}}_simulated_{{device}}.csv {-I(Vbp)} + + +.include "../../../design.xyce" +.lib "../../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_beta/device_netlists/pnp.spice b/models/xyce/testing/regression/bjt_beta/device_netlists/pnp.spice new file mode 100644 index 00000000..f238b9cc --- /dev/null +++ b/models/xyce/testing/regression/bjt_beta/device_netlists/pnp.spice @@ -0,0 +1,26 @@ +***************** +** main netlist +***************** + +Vcp c 0 dc -3 +Vbp b 0 dc -1.2 + +xq1 c b 0 {{device}} + + +***************** +** Analysis +***************** + +.DC Vbp -0.2 -1.2 -0.01 Vcp -1 -3 -1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pnp/simulated_Ic/{{i}}_simulated_{{device}}.csv Vbp +.print DC FORMAT=CSV file=pnp/simulated_Ic/{{i}}_simulated_{{device}}.csv {I(Vcp)} +.print DC FORMAT=CSV file=pnp/simulated_Ib/{{i}}_simulated_{{device}}.csv Vbp +.print DC FORMAT=CSV file=pnp/simulated_Ib/{{i}}_simulated_{{device}}.csv {I(Vbp)} + + +.include "../../../design.xyce" +.lib "../../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_beta/device_netlists/run_npn_beta.spice b/models/xyce/testing/regression/bjt_beta/device_netlists/run_npn_beta.spice new file mode 100644 index 00000000..60e160e6 --- /dev/null +++ b/models/xyce/testing/regression/bjt_beta/device_netlists/run_npn_beta.spice @@ -0,0 +1,25 @@ + +***************** +** main netlist +***************** + +Vcp c 0 dc 3 +Vbp b 0 dc 1.2 + +xq1 c b 0 0 vnpn_10x10 + + +***************** +** Analysis +***************** +.DC Vbp 0.2 1.2 0.01 Vcp 1 3 1 +.STEP TEMP 25 -60 200 +.print DC FORMAT=CSV file=result0.csv Vbp +.print DC FORMAT=CSV file=result0.csv {-I(Vbp)} +.print DC FORMAT=CSV file=result1.csv Vbp +.print DC FORMAT=CSV file=result1.csv {-I(Vcp)} + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_beta/models_regression.py b/models/xyce/testing/regression/bjt_beta/models_regression.py new file mode 100644 index 00000000..9bdc7cd3 --- /dev/null +++ b/models/xyce/testing/regression/bjt_beta/models_regression.py @@ -0,0 +1,243 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from cmath import inf +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device,vb,step,Id_sim,list_devices,vc): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + + # Extracting measured values for each Device + for i in range (loops): + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + # Special case for 1st measured values + if i == 0 : + if device == "pnp": + temp_vb = vb + vb = "-vb " + # measured Id_sim 0 + col_list = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[0]}/{i}_measured_{list_devices[k]}.csv", index = False) + + if device == "pnp": + vb = temp_vb + + # measured Id_sim 1 + col_list = [f"{vb}",f"{vc}{step[0]}.{2*i+1}",f"{vc}{step[1]}.{2*i+1}",f"{vc}{step[2]}.{2*i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[1]}/{i}_measured_{list_devices[k]}.csv", index = False) + else: + # measured Id_sim 0 + col_list = [f"{vb}",f"{vc}{step[0]}.{2*i}",f"{vc}{step[1]}.{2*i}",f"{vc}{step[2]}.{2*i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[0]}/{i}_measured_{list_devices[k]}.csv", index = False) + + # measured Id_sim 1 + col_list = [f"{vb}",f"{vc}{step[0]}.{2*i+1}",f"{vc}{step[1]}.{2*i+1}",f"{vc}{step[2]}.{2*i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vb}",f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim[1]}/{i}_measured_{list_devices[k]}.csv", index = False) + +def ext_simulated(device,vc,step,sweep,Id_sim,list_devices,ib): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + netlist_tmp = f"./device_netlists/{device}.spice" + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_sim",exist_ok=True) + with open(f"{device}/{device}_netlists_sim/{i}_{device}_netlist_{list_devices[k]}.spice", "w") as netlist: + netlist.write(tmpl.render(device = list_devices[k], i = i , temp = temp )) + netlist_path = f"{device}/{device}_netlists_sim/{i}_{device}_netlist_{list_devices[k]}.spice" + + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data 0 + df_simulated = pd.read_csv(f"{device}/simulated_{Id_sim[0]}/{i}_simulated_{list_devices[k]}.csv",header=0) + + # empty array to append in it shaped (sweep, number of trials + 1) + new_array = np.empty((sweep, 1+int(df_simulated.shape[0]/sweep))) + new_array[:, 0] = df_simulated.iloc[:sweep, 0] + times = int(df_simulated.shape[0]/sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*sweep:(j+1)*sweep, 1] + + # Writing final simulated data 0 + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{Id_sim[0]}/{i}_simulated_{list_devices[k]}.csv",index= False) + df_simulated.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}"] + df_simulated.to_csv(f"{device}/simulated_{Id_sim[0]}/{i}_simulated_{list_devices[k]}.csv",index= False) + + + # Writing simulated data 1 + df_simulated = pd.read_csv(f"{device}/simulated_{Id_sim[1]}/{i}_simulated_{list_devices[k]}.csv",header=0) + + # empty array to append in it shaped (sweep, number of trials + 1) + new_array = np.empty((sweep, 1+int(df_simulated.shape[0]/sweep))) + new_array[:, 0] = df_simulated.iloc[:sweep, 0] + times = int(df_simulated.shape[0]/sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*sweep:(j+1)*sweep, 1] + + # Writing final simulated data 1 + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{Id_sim[1]}/{i}_simulated_{list_devices[k]}.csv",index= False) + df_simulated.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}"] + df_simulated.to_csv(f"{device}/simulated_{Id_sim[1]}/{i}_simulated_{list_devices[k]}.csv",index= False) + +def error_cal(device,vb,step,Id_sim,list_devices,vc): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + measured = pd.read_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv") + simulated = pd.read_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[0:, 1]) - abs(simulated.iloc[0:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[0:, 2]) - abs(simulated.iloc[0:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[0:, 3]) - abs(simulated.iloc[0:, 3]))/abs(measured.iloc[:, 3])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3]).transpose() + df_error.replace([np.inf, -np.inf], df_error.max().nlargest(2).iloc[1], inplace=True) + df_error.to_csv(f"{device}/error_{Id_sim}/{i}_{device}_error_{list_devices[k]}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{vc}{step[0]}"].mean() + df_error[f"{vc}{step[1]}"].mean() + df_error[f"{vc}{step[2]}"].mean())/6 + # Max error + max_error = df_error[[f"{vc}{step[0]}",f"{vc}{step[1]}",f"{vc}{step[2]}"]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vc = (df_error == max_error).idxmax(axis=1)[max_index] + if Id_sim == "Ic": + if i == 0 : + if device == "pnp": + temp_vb = vb + vb = "-vb " + else: + if device == "pnp": + vb = temp_vb + max_location_vb = df_error[f"{vb}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'device': f'{list_devices[k]}','Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vc} & Vc (V) = {max_location_vb}'} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["npn","pnp"] + list_devices = [["vnpn_10x10" , "vnpn_5x5" , "vnpn_0p54x16" , "vnpn_0p54x8" , "vnpn_0p54x4", "vnpn_0p54x2"], + ["vpnp_0p42x10" , "vpnp_0p42x5", "vpnp_10x10" , "vpnp_5x5"]] + vb = ["vbp ","-vb (V)"] + vc = ["vcp =","vc =-"] + Id_sim = ["Ic","Ib"] + sweep = 101 + step = [1, 2, 3] + + for i, device in enumerate(devices): + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim[0]}",exist_ok=False) + os.makedirs(f"{device}/measured_{Id_sim[1]}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/bjt_{device}_beta_f.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim[0]}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim[0]}",exist_ok=False) + os.makedirs(f"{device}/simulated_{Id_sim[1]}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim[1]}",exist_ok=False) + + # =========== Simulate ============== + ext_measured (device,vb[i],step,Id_sim,list_devices[i],vc[i]) + + ext_simulated(device,vb[i],step,sweep,Id_sim,list_devices[i],vc[i]) + + # ============ Results ============= + error_cal (device,vb[i],step,Id_sim[0],list_devices[i],vc[i]) + error_cal (device,vb[i],step,Id_sim[1],list_devices[i],vc[i]) + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/bjt_cj/device_netlists/cv.spice b/models/xyce/testing/regression/bjt_cj/device_netlists/cv.spice new file mode 100644 index 00000000..92eed520 --- /dev/null +++ b/models/xyce/testing/regression/bjt_cj/device_netlists/cv.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +.param volt = 0 +V1 in 0 dc {volt} ac 1 +{{Iopen}} + +R1 in out 1G +xq1 {{connection}} {{device}} + +.meas AC freq when Vdb(out)=-3 PRECISION=15 + +***************** +** Analysis +***************** +.ac dec 10 1 10G +.step volt 0 -3.0 -0.1 +.STEP TEMP {{temp}} -60 200 + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" bjt_{{corner}} + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/bjt_cj/device_netlists/run_npn_cv.spice b/models/xyce/testing/regression/bjt_cj/device_netlists/run_npn_cv.spice new file mode 100644 index 00000000..3b6d488e --- /dev/null +++ b/models/xyce/testing/regression/bjt_cj/device_netlists/run_npn_cv.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +.param volt = -3.0 +V1 in 0 dc {volt} ac 1 +*Iopen open 0 0 + +R1 in out 1G +xq1 0 out 0 0 vnpn_10x10 + +.meas AC freq when Vdb(out)=-3 PRECISION=15 + +***************** +** Analysis +***************** +.ac dec 10 1 10G +.STEP volt 0 -3.0 -0.1 +.STEP TEMP 25 -60 200 + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_cj/device_netlists/run_pnp_cv.spice b/models/xyce/testing/regression/bjt_cj/device_netlists/run_pnp_cv.spice new file mode 100644 index 00000000..d64aa7e2 --- /dev/null +++ b/models/xyce/testing/regression/bjt_cj/device_netlists/run_pnp_cv.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +.param volt = 0 +V1 in 0 dc {volt} ac 1 +* Iopen 0 open 0 + +R1 in out 1G +xq1 out 0 0 vpnp_0p42x10 + +.meas AC freq when Vdb(out)=-3 PRECISION=15 + +***************** +** Analysis +***************** +.ac dec 10 1 10G +.STEP volt 0 -3.0 -0.1 +* .STEP TEMP 25 -60 200 + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" bjt_typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/bjt_cj/models_regression.py b/models/xyce/testing/regression/bjt_cj/models_regression.py new file mode 100644 index 00000000..3954d943 --- /dev/null +++ b/models/xyce/testing/regression/bjt_cj/models_regression.py @@ -0,0 +1,257 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device,vn,d_in, cv_sim, corner,start,dirpath): + + # Get dimensions used for each device + if "vnpn" in device: + loops = 3 + else: + loops = 2 + + # Extracting measured values for each W & L + for i in range (start,loops+start): + + # Special case for 1st measured values + if i == 0 : + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_{device}.csv", index = False) + else: + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}.{i}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_{device}.csv", index = False) + +def ext_simulated(device,vn,d_in,cv_sim, corner,temp,dirpath,cap): + + # Get dimensions used for each device + netlist_tmp = f"./device_netlists/cv.spice" + + if "EBJ" in cap: + i = 0 + if "vnpn" in device: + connection = "0 out 0 0" + else: + connection = "0 0 out" + Iopen = "" + elif "CBJ" in cap: + i = 1 + if "vnpn" in device: + connection = "0 out open 0" + Iopen = "Iopen open 0 0" + else: + connection = "out 0 0" + Iopen = "" + else: + i =2 + connection = "0 0 open out" + Iopen = "Iopen open 0 0" + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{cv_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i}_{device}_netlist_{device}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, i = i , Iopen = Iopen , connection = connection , temp = temp, cv_sim = cv_sim , corner = corner )) + netlist_path = f"{dirpath}/{device}_netlists_{cv_sim}/{i}_{device}_netlist_{device}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = [] + # Writing simulated data + for j in range(len([x for x in os.listdir(f"{dirpath}/{device}_netlists_{cv_sim}") if f"{i}_{device}_netlist_{device}.spice.ma" in x])): + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i}_{device}_netlist_{device}.spice.ma{j}") as f: + caps = 1000000/(float(next(f).replace("FREQ = ", ""))*2*np.pi) + df_simulated.append(caps) + + # zero array to append in it shaped (vn_sweeps, number of trials + 1) + new_array = np.zeros((len(df_simulated), 2)) + new_array[:len(df_simulated), 0] = df_simulated + new_array[:len(df_simulated), 1] = df_simulated + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + if "npn_EBJ" in cap: + df_cbj = pd.read_csv(f"{dirpath}/simulated_{cv_sim}/1_simulated_{device}.csv") + diff = df_simulated.iloc[:, 1] - df_cbj.iloc[:, 1] + df_simulated = pd.DataFrame(data=[df_simulated.iloc[:, 0],diff]).transpose() + df_simulated.columns = [f"{vn}",f"{d_in}_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv",index= False) + elif "pnp_CBJ" in cap: + df_ebj = pd.read_csv(f"{dirpath}/simulated_{cv_sim}/0_simulated_{device}.csv") + diff = df_simulated.iloc[:, 1] - (2*df_ebj.iloc[:, 1]) + df_simulated = pd.DataFrame(data=[df_simulated.iloc[:, 0],diff]).transpose() + df_simulated.columns = [f"{vn}",f"{d_in}_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv",index= False) + else: + df_simulated.columns = [f"{vn}",f"{d_in}_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv",index= False) + + +def error_cal(device,vn,d_in,cv_sim, corner,temp,dirpath): + + # Get dimensions used for each device + if "vnpn" in device: + loops = 3 + else: + loops = 2 + df_final = pd.DataFrame() + for i in range (0,loops): + if i == 0 : cap = "EBJ" + elif i == 1 : cap = "CBJ" + else : cap = "CSJ" + + measured = pd.read_csv(f"{dirpath}/measured_{cv_sim}/{i}_measured_{device}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{cv_sim}/{i}_simulated_{device}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{cv_sim}/{i}_{device}_error_{device}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{d_in}_{corner}"].mean()) + # Max error + max_error = df_error[f"{d_in}_{corner}"].max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vds = df_error[f"{vn}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'corner': f'{corner}' , 'Junction': f'{cap}', 'Simulated_Val':f'{cv_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & vn (V) = {max_location_vds}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{cv_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{cv_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + corners = ["typical","ff","ss"] + temps = [ 25 , -40 , 175 ] + measure = ["cv","Vj", "bjt", 31] + cv_sim, bjt_vn, bjt_in = measure[0], measure[1], measure[2] + + #vnpn + npn_devices = ["vnpn_10x10" , "vnpn_5x5" , "vnpn_0p54x16" , "vnpn_0p54x8" , "vnpn_0p54x4" , "vnpn_0p54x2"] + npn_start = 0 + + for corner in corners: + for temp in temps: + for device in npn_devices: + # Folder structure of measured values + dirpath = f"{device}_{cv_sim}_{corner}_T{temp}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/{bjt_in}_{cv_sim}_npn.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + ext_measured (device,bjt_vn,bjt_in, cv_sim, corner,npn_start,dirpath) + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"npn_CBJ") + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"npn_EBJ") + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"npn_CSJ") + + npn_start = npn_start + 3 + npn_start = 0 + + # vpnp + pnp_devices = ["vpnp_0p42x10" , "vpnp_0p42x5" , "vpnp_10x10" , "vpnp_5x5"] + pnp_start = 0 + + for corner in corners: + for temp in temps: + for device in pnp_devices: + # Folder structure of measured values + dirpath = f"{device}_{cv_sim}_{corner}_T{temp}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/{bjt_in}_{cv_sim}_pnp.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + ext_measured (device,bjt_vn,bjt_in, cv_sim, corner,pnp_start,dirpath) + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"pnp_EBJ") + ext_simulated(device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath,"pnp_CBJ") + error_cal (device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath) + + pnp_start = pnp_start + 2 + pnp_start = 0 + + for corner in corners: + for temp in temps: + for device in npn_devices: + # Folder structure of measured values + dirpath = f"{device}_{cv_sim}_{corner}_T{temp}" + error_cal (device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath) + + npn_start = npn_start + 3 + npn_start = 0 + + # vpnp + pnp_devices = ["vpnp_0p42x10" , "vpnp_0p42x5" , "vpnp_10x10" , "vpnp_5x5"] + pnp_start = 0 + + for corner in corners: + for temp in temps: + for device in pnp_devices: + # Folder structure of measured values + dirpath = f"{device}_{cv_sim}_{corner}_T{temp}" + error_cal (device,bjt_vn,bjt_in,cv_sim, corner,temp,dirpath) + + pnp_start = pnp_start + 2 + pnp_start = 0 + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/bjt_iv/device_netlists/npn.spice b/models/xyce/testing/regression/bjt_iv/device_netlists/npn.spice new file mode 100644 index 00000000..7bac45c3 --- /dev/null +++ b/models/xyce/testing/regression/bjt_iv/device_netlists/npn.spice @@ -0,0 +1,26 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** + +Vcp c 0 dc 6 +Ib 0 b 9u + +xq1 c b 0 0 {{device}} + + +***************** +** Analysis +***************** +.DC Vcp 0 6 0.1 Ib 1u 9u 2u +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=npn/simulated_IcVc/{{i}}_simulated_{{device}}.csv {-I(Vcp)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_iv/device_netlists/pnp.spice b/models/xyce/testing/regression/bjt_iv/device_netlists/pnp.spice new file mode 100644 index 00000000..76d695f8 --- /dev/null +++ b/models/xyce/testing/regression/bjt_iv/device_netlists/pnp.spice @@ -0,0 +1,26 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** + +Vcp c 0 dc -6 +Ib 0 b -9u + +xq1 c b 0 {{device}} + + +***************** +** Analysis +***************** +.DC Vcp 0 -3 -0.1 Ib -1u -9u -2u +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pnp/simulated_IcVc/{{i}}_simulated_{{device}}.csv {I(Vcp)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_iv/device_netlists/run_npn_vcic.spice b/models/xyce/testing/regression/bjt_iv/device_netlists/run_npn_vcic.spice new file mode 100644 index 00000000..f76470a5 --- /dev/null +++ b/models/xyce/testing/regression/bjt_iv/device_netlists/run_npn_vcic.spice @@ -0,0 +1,26 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** + +Vcp c 0 dc 6 +Ib 0 b 9u + +xq1 c b 0 0 vnpn_10x10 + + +***************** +** Analysis +***************** +.DC Vcp 0 6 0.1 Ib 1u 9u 2u +.STEP TEMP 25 -60 200 +.print DC FORMAT=CSV file=result.csv {-I(Vcp)} + +.include "../../design.xyce" +.lib "../../sm141064.xyce" bjt_typical + +.end diff --git a/models/xyce/testing/regression/bjt_iv/models_regression.py b/models/xyce/testing/regression/bjt_iv/models_regression.py new file mode 100644 index 00000000..5fe2163a --- /dev/null +++ b/models/xyce/testing/regression/bjt_iv/models_regression.py @@ -0,0 +1,208 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device,vc,step,Id_sim,list_devices,ib): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + + # Extracting measured values for each Device + for i in range (loops): + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + # Special case for 1st measured values + if i == 0 : + if device == "pnp": + temp_vc = vc + vc = "-vc " + # measured Id_sim + col_list = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv", index = False) + else: + if device == "pnp": + vc = temp_vc + # measured Id_sim + col_list = [f"{vc}",f"{ib}{step[0]}.{i}",f"{ib}{step[1]}.{i}",f"{ib}{step[2]}.{i}",f"{ib}{step[3]}.{i}",f"{ib}{step[4]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_measured.to_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv", index = False) + +def ext_simulated(device,vc,step,sweep,Id_sim,list_devices,ib): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + netlist_tmp = f"./device_netlists/{device}.spice" + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{Id_sim}",exist_ok=True) + with open(f"{device}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_{list_devices[k]}.spice", "w") as netlist: + netlist.write(tmpl.render(device = list_devices[k], i = i , temp = temp )) + netlist_path = f"{device}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_{list_devices[k]}.spice" + + # Running Xyce for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv",header=0) + + # empty array to append in it shaped (sweep, number of trials + 1) + new_array = np.empty((sweep, 1+int(df_simulated.shape[0]/sweep))) + new_array[:, 0] = df_simulated.iloc[:sweep, 0] + times = int(df_simulated.shape[0]/sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*sweep:(j+1)*sweep, 0] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv",index= False) + df_simulated.columns = [f"{vc}",f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"] + df_simulated.to_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv",index= False) + +def error_cal(device,vc,step,Id_sim,list_devices,ib): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["corners"]) + loops = dimensions["corners"].count() + temp_range = int(loops/4) + for i in range (loops): + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + elif i in range (2*temp_range,3*temp_range):temp = 125 + else: temp = 175 + + k = i + if i >= len(list_devices): + while k >= len(list_devices): + k = k - len(list_devices) + + measured = pd.read_csv(f"{device}/measured_{Id_sim}/{i}_measured_{list_devices[k]}.csv") + simulated = pd.read_csv(f"{device}/simulated_{Id_sim}/{i}_simulated_{list_devices[k]}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[0:, 1]) - abs(simulated.iloc[0:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[0:, 2]) - abs(simulated.iloc[0:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[0:, 3]) - abs(simulated.iloc[0:, 3]))/abs(measured.iloc[:, 3])),6) + error_4 = round (100 * abs((abs(measured.iloc[0:, 4]) - abs(simulated.iloc[0:, 4]))/abs(measured.iloc[:, 4])),6) + error_5 = round (100 * abs((abs(measured.iloc[0:, 5]) - abs(simulated.iloc[0:, 5]))/abs(measured.iloc[:, 5])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5]).transpose() + df_error.to_csv(f"{device}/error_{Id_sim}/{i}_{device}_error_{list_devices[k]}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{ib}{step[0]}"].mean() + df_error[f"{ib}{step[1]}"].mean() + df_error[f"{ib}{step[2]}"].mean() + + df_error[f"{ib}{step[3]}"].mean() + df_error[f"{ib}{step[4]}"].mean())/6 + # Max error + max_error = df_error[[f"{ib}{step[0]}",f"{ib}{step[1]}",f"{ib}{step[2]}",f"{ib}{step[3]}",f"{ib}{step[4]}"]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_ib = (df_error == max_error).idxmax(axis=1)[max_index] + if i == 0 : + if device == "pnp": + temp_vc = vc + vc = "-vc " + else: + if device == "pnp": + vc = temp_vc + max_location_vc = df_error[f"{vc}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'device': f'{list_devices[k]}','Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_ib} & Vc (V) = {max_location_vc}'} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["npn","pnp"] + list_devices = [["vnpn_10x10" , "vnpn_5x5" , "vnpn_0p54x16" , "vnpn_0p54x8" , "vnpn_0p54x4", "vnpn_0p54x2"], + ["vpnp_0p42x10" , "vpnp_0p42x5", "vpnp_10x10" , "vpnp_5x5"]] + vc = ["vcp ","-vc (A)"] + ib = ["ibp =","ib =-"] + Id_sim = "IcVc" + sweep = [61,31] + step = [ "1.000E-06" , "3.000E-06" , "5.000E-06" , "7.000E-06" , "9.000E-06"] + + for i, device in enumerate(devices): + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/BJT/bjt_{device}_icvc_f.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False) + + # =========== Simulate ============== + ext_measured (device,vc[i],step,Id_sim,list_devices[i],ib[i]) + + ext_simulated(device,vc[i],step,sweep[i],Id_sim,list_devices[i],ib[i]) + + # ============ Results ============= + error_cal (device,vc[i],step,Id_sim,list_devices[i],ib[i]) + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/diode/device_netlists/cv.spice b/models/xyce/testing/regression/diode/device_netlists/cv.spice new file mode 100644 index 00000000..d5797e87 --- /dev/null +++ b/models/xyce/testing/regression/diode/device_netlists/cv.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +.param volt = -3.3 +V1 in 0 dc {volt} ac 1 +R1 in out 1G +dn1 out 0 np_3p3 AREA={10u*10u} + +.meas AC freq when Vdb(out)=-3 +*.meas AC C param = {1/(2*3.141592653589793238*freq*1000000000)} + +***************** +** Analysis +***************** +*.control +.ac dec 10 1 10G +.step volt -12.13 1.13 0.13 + +.include "../../design.xyce" +.lib "../../sm141064.xyce" diode_typical + +.end + + diff --git a/models/xyce/testing/regression/diode/device_netlists/iv.spice b/models/xyce/testing/regression/diode/device_netlists/iv.spice new file mode 100644 index 00000000..2ed78b2d --- /dev/null +++ b/models/xyce/testing/regression/diode/device_netlists/iv.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 dc 1 + + +dn1 n 0 {{device}} AREA={{area}}p +* PJ=40u + + +***************** +** Analysis +***************** +.DC Vn -12.13 1.13 0.13 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file={{device}}_{{Id_sim}}_{{corner}}/simulated_{{Id_sim}}/{{i}}_simulated_A{{area}}_P{{pj}}.csv {abs(I(dn1))} +* .print DC FORMAT=CSV file=result.csv {N(dn1:is)} + + + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" diode_{{corner}} + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/diode/device_netlists/run_np_3p3_iv_independently.spice b/models/xyce/testing/regression/diode/device_netlists/run_np_3p3_iv_independently.spice new file mode 100644 index 00000000..62580c10 --- /dev/null +++ b/models/xyce/testing/regression/diode/device_netlists/run_np_3p3_iv_independently.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 dc 1 + + +dn1 n 0 sc_diode AREA={10u*10u} +* PJ=40u + + +***************** +** Analysis +***************** +.DC Vn -12.13 1.13 0.13 +.STEP TEMP LIST -40 25 125 175 +.print DC FORMAT=CSV file=result.csv {abs(I(dn1))} +* .print DC FORMAT=CSV file=result.csv {N(dn1:is)} + + + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" diode_typical + +.end diff --git a/models/xyce/testing/regression/diode/models_regression.py b/models/xyce/testing/regression/diode/models_regression.py new file mode 100644 index 00000000..983702ee --- /dev/null +++ b/models/xyce/testing/regression/diode/models_regression.py @@ -0,0 +1,187 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device,vn,d_in, Id_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["W (um)"].iloc[i] + length = dimensions["L (um)"].iloc[i] + + # Special case for 1st measured values + if i == 0 : + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{Id_sim}/{i}_measured_A{width}_P{length}.csv", index = False) + else: + # measured Id + col_list = [f"{vn}",f"{d_in}_{corner}.{i}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}",f"{d_in}_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{Id_sim}/{i}_measured_A{width}_P{length}.csv", index = False) + +def ext_simulated(device,vn,d_in,vn_sweeps,Id_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + netlist_tmp = f"./device_netlists/{Id_sim}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + + if i % 4 == 0: temp = -40 + elif i % 4 == 1: temp = 25 + elif i % 4 == 2: temp = 125 + else: + temp = 175 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{Id_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_A{width}_P{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, area = width, pj = length, i = i , temp = temp, Id_sim = Id_sim , corner = corner )) + netlist_path = f"{dirpath}/{device}_netlists_{Id_sim}/{i}_{device}_netlist_A{width}_P{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",header=0) + #df_simulated.to_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",index= False) + + # zero array to append in it shaped (vn_sweeps, number of trials + 1) + new_array = np.zeros((vn_sweeps, 2)) + new_array[:len(df_simulated.index), 0] = df_simulated.iloc[:, 0] + + new_array[:len(df_simulated.index), 1] = df_simulated.iloc[:, 0] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",index= False) + df_simulated.columns = [f"{vn}",f"{d_in}_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv",index= False) + +def error_cal(device,vn,d_in,Id_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i % 4 == 0: temp = -40 + elif i % 4 == 1: temp = 25 + elif i % 4 == 2: temp = 125 + else: + temp = 175 + + measured = pd.read_csv(f"{dirpath}/measured_{Id_sim}/{i}_measured_A{width}_P{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i}_simulated_A{width}_P{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{Id_sim}/{i}_{device}_error_A{width}_P{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"{d_in}_{corner}"].mean())/6 + # Max error + max_error = df_error[f"{d_in}_{corner}"].max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vds = df_error[f"{vn}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{dirpath}', 'Area': f'{width}', 'Perimeter': f'{length}', 'Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & vn (V) = {max_location_vds}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["np_3p3","dnwpw","dnwps","np_6p0", "nwp_3p3","nwp_6p0","pn_3p3","pn_6p0","sc_diode"] + corners = ["typical","ff","ss"] + measures = [["iv","Vn1 (V)", " |In1(A)| diode", 103]]#, + # ["cv","Vj", "diode", 17]] + + for device in devices: + for measure in measures: + for corner in corners: + # Folder structure of measured values + Id_sim, diode_vn, diode_in, no_of_vn_sweeps = measure[0], measure[1], measure[2], measure[3] + dirpath = f"{device}_{Id_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{Id_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Diode/{device}_{Id_sim}.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{Id_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{Id_sim}",exist_ok=False) + + ext_measured (device,diode_vn,diode_in, Id_sim, corner) + + ext_simulated(device,diode_vn,diode_in,no_of_vn_sweeps,Id_sim, corner) + + for device in devices: + for measure in measures: + for corner in corners: + # Folder structure of measured values + Id_sim, diode_vn, diode_in, no_of_vn_sweeps = measure[0], measure[1], measure[2], measure[3] + error_cal (device,diode_vn,diode_in,Id_sim, corner) + + + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/mimcap_c/device_netlists/mimcap.spice b/models/xyce/testing/regression/mimcap_c/device_netlists/mimcap.spice new file mode 100644 index 00000000..491a56f3 --- /dev/null +++ b/models/xyce/testing/regression/mimcap_c/device_netlists/mimcap.spice @@ -0,0 +1,30 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +.param volt = -3.0 +V1 in 0 dc {volt} ac 1 +R1 in out 1G +xcn out 0 {{device}} c_length={{length}}u c_width={{width}}u l={{length}}u w={{width}}u + +.meas AC freq when Vdb(out)=-3 PRECISION=15 + + + + +***************** +** Analysis +***************** + +.ac dec 10 1 10G +.step volt {{voltage}} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" mimcap_{{corner}} + +.end + + diff --git a/models/xyce/testing/regression/mimcap_c/models_regression.py b/models/xyce/testing/regression/mimcap_c/models_regression.py new file mode 100644 index 00000000..625e5acf --- /dev/null +++ b/models/xyce/testing/regression/mimcap_c/models_regression.py @@ -0,0 +1,181 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device,vn,d_in, cv_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 100 ; length = 100 + if i == 1+start: width = 5 ; length = 5 + if i == 2+start: width = 100 ; length = 5 + if i == 3+start: width = 5 ; length = 100 + + if i == 0 : + # measured cv + col_list = [f"Vj",f"mimcap_{corner}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_w{width}_l{length}.csv", index=False) + else: + # measured cv + col_list = [f"Vj",f"mimcap_{corner}.{i}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"Vj",f"mimcap_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_w{width}_l{length}.csv", index=False) + +def ext_simulated(device,vn,d_in,cv_sim, corner,start,voltage): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + netlist_tmp = f"./device_netlists/mimcap.spice" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 100 ; length = 100 + if i == 1+start: width = 5 ; length = 5 + if i == 2+start: width = 100 ; length = 5 + if i == 3+start: width = 5 ; length = 100 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{cv_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, width = width, length = length , corner = corner , voltage = voltage)) + netlist_path = f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = [] + # Writing simulated data + for j in range(len([x for x in os.listdir(f"{dirpath}/{device}_netlists_{cv_sim}") if f"{i-start}_{device}_netlist_w{width}_l{length}.spice.ma" in x])): + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice.ma{j}") as f: + cap = 1000000/(float(next(f).replace("FREQ = ", ""))*2*np.pi) + df_simulated.append(cap) + + # zero array to append in it shaped (vn_sweeps, number of trials + 1) + new_array = np.zeros((len(df_simulated), 2)) + new_array[:len(df_simulated), 0] = df_simulated + new_array[:len(df_simulated), 1] = df_simulated + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.columns = [f"Vj",f"mimcap_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i-start}_simulated_w{width}_l{length}.csv",index= False) + +def error_cal(device,vn,d_in,Id_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + df_final = pd.DataFrame() + for i in range (start,4+start): + if i == 0+start: width = 100 ; length = 100 + if i == 1+start: width = 5 ; length = 5 + if i == 2+start: width = 100 ; length = 5 + if i == 3+start: width = 5 ; length = 100 + + measured = pd.read_csv(f"{dirpath}/measured_{Id_sim}/{i-start}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i-start}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{Id_sim}/{i-start}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"mimcap_{corner}"].mean()) + # Max error + max_error = df_error[f"mimcap_{corner}"].max() + + df_final_ = {'Run no.': f'{i-start}', 'Device name': f'{dirpath}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + + +def main(): + + # 3p3 + corners = ["ss" , "typical","ff"] + devices = ["mim_1p5fF" , "mim_1p0fF" , "mim_2p0fF"] + measure = ["cv","corners", "CV (fF)"] + voltage = ["-3.0 3.0 0.1"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + dirpath = f"{device}_{cv_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Cap/mimcap_fc.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + + ext_measured (device,cap_vn,cap_in, cv_sim, corner,start) + ext_simulated(device,cap_vn,cap_in,cv_sim, corner,start,voltage[0]) + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = 0 + + + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = 0 + + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/mos_cv/device_netlists_Cgc/nmos_3p3_cv.spice b/models/xyce/testing/regression/mos_cv/device_netlists_Cgc/nmos_3p3_cv.spice new file mode 100644 index 00000000..87c6de84 --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/device_netlists_Cgc/nmos_3p3_cv.spice @@ -0,0 +1,62 @@ +*************************** +** nmos_3p3_cv +*************************** + +** library calling + +.include "../../180MCU_SPICE_hspice/design.xyce" +.lib "../../180MCU_SPICE_hspice/sm141064.xyce" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=0 +vgs G_tn 0 dc=3.3 +vbs S_tn 0 dc=0 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn nmos_3p3 W = {{width}}u L = {{length}}u nf={{nf}} ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vgs_min = -3.3 +let vgs_step = 0.1 +let vgs_max = 3.3 + +compose vbs_vector start=0 stop=-3.3 step=-0.825 + +set appendwrite + +foreach t 25 + + let vbs_counter = 0 + while vbs_counter < length(vbs_vector) + option TEMP=25 + alter vbs = vbs_vector[vbs_counter] + + save @mn[vs] @mn[vgs] @mn[id] @mn[cgb] + ******************* + ** simulation part + ******************* + DC vgs $&vgs_min $&vgs_max $&vgs_step + + * ** parameters calculation + + print @mn[cgb] + + wrdata nmos_3p3_cv/simulated_Cgc/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[cgb] + + reset + let vbs_counter = vbs_counter + 1 + end +end +.endc +.end diff --git a/models/xyce/testing/regression/mos_cv/device_netlists_Cgc/pmos_3p3_cv.spice b/models/xyce/testing/regression/mos_cv/device_netlists_Cgc/pmos_3p3_cv.spice new file mode 100644 index 00000000..377a4b14 --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/device_netlists_Cgc/pmos_3p3_cv.spice @@ -0,0 +1,62 @@ +*************************** +** pmos_3p3_cv +*************************** + +** library calling + +.include "../../180MCU_SPICE_hspice/design.xyce" +.lib "../../180MCU_SPICE_hspice/sm141064.xyce" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=0 +vgs G_tn 0 dc=3.3 +vbs S_tn 0 dc=0 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn pmos_3p3 W = {{width}}u L = {{length}}u nf={{nf}} ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vgs_min = -3.3 +let vgs_step = 0.1 +let vgs_max = 3.3 + +compose vbs_vector start=0 stop=3.3 step=0.825 + +set appendwrite + +foreach t 25 + + let vbs_counter = 0 + while vbs_counter < length(vbs_vector) + option TEMP=25 + alter vbs = vbs_vector[vbs_counter] + + save @mn[vs] @mn[vgs] @mn[id] @mn[cgb] + ******************* + ** simulation part + ******************* + DC vgs $&vgs_min $&vgs_max $&vgs_step + + * ** parameters calculation + + print @mn[cgb] + + wrdata pmos_3p3_cv/simulated_Cgc/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[cgb] + + reset + let vbs_counter = vbs_counter + 1 + end +end +.endc +.end diff --git a/models/xyce/testing/regression/mos_cv/device_netlists_Cgd/nmos_3p3_cv.spice b/models/xyce/testing/regression/mos_cv/device_netlists_Cgd/nmos_3p3_cv.spice new file mode 100644 index 00000000..f85c481a --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/device_netlists_Cgd/nmos_3p3_cv.spice @@ -0,0 +1,62 @@ +*************************** +** nmos_3p3_cv +*************************** + +** library calling + +.include "../../180MCU_SPICE_hspice/design.xyce" +.lib "../../180MCU_SPICE_hspice/sm141064.xyce" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=3.3 +vgs G_tn 0 dc=3.3 +vs S_tn 0 dc=0.2 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn nmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.1 +let vds_max = 3.3 + +compose vgs_vector start=0 stop=3.3 step=1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgd] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgd] + + wrdata nmos_3p3_cv/simulated_Cgd/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[cgd] + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/xyce/testing/regression/mos_cv/device_netlists_Cgd/pmos_3p3_cv.spice b/models/xyce/testing/regression/mos_cv/device_netlists_Cgd/pmos_3p3_cv.spice new file mode 100644 index 00000000..4e35ebc4 --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/device_netlists_Cgd/pmos_3p3_cv.spice @@ -0,0 +1,62 @@ +*************************** +** pmos_3p3_cv +*************************** + +** library calling + +.include "../../180MCU_SPICE_hspice/design.xyce" +.lib "../../180MCU_SPICE_hspice/sm141064.xyce" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-3.3 +vgs G_tn 0 dc=-3.3 +vs S_tn 0 dc=0.2 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn pmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.1 +let vds_max = -3.3 + +compose vgs_vector start=0 stop=-3.3 step=-1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgs] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgd] + + wrdata pmos_3p3_cv/simulated_Cgd/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[cgd] + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/xyce/testing/regression/mos_cv/device_netlists_Cgs/nmos_3p3_cv.spice b/models/xyce/testing/regression/mos_cv/device_netlists_Cgs/nmos_3p3_cv.spice new file mode 100644 index 00000000..9358ece3 --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/device_netlists_Cgs/nmos_3p3_cv.spice @@ -0,0 +1,62 @@ +*************************** +** nmos_3p3_cv +*************************** + +** library calling + +.include "../../180MCU_SPICE_hspice/design.xyce" +.lib "../../180MCU_SPICE_hspice/sm141064.xyce" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=3.3 +vgs G_tn 0 dc=3.3 +vs S_tn 0 dc=0.1 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn nmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = 0.1 +let vds_max = 3.3 + +compose vgs_vector start=0 stop=3.3 step=1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgs] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgs] + + wrdata nmos_3p3_cv/simulated_Cgs/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[cgs] + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/xyce/testing/regression/mos_cv/device_netlists_Cgs/pmos_3p3_cv.spice b/models/xyce/testing/regression/mos_cv/device_netlists_Cgs/pmos_3p3_cv.spice new file mode 100644 index 00000000..c01b53eb --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/device_netlists_Cgs/pmos_3p3_cv.spice @@ -0,0 +1,62 @@ +*************************** +** pmos_3p3_cv +*************************** + +** library calling + +.include "../../180MCU_SPICE_hspice/design.xyce" +.lib "../../180MCU_SPICE_hspice/sm141064.xyce" typical + + +** Circuit Description ** +* power supply +vds D_tn 0 dc=-3.3 +vgs G_tn 0 dc=-3.3 +vs S_tn 0 dc=0.1 + +.temp 25 +.options tnom=25 + +*l_diff_min = 0.24 +* ad = int((nf+1)/2) * width/nf * 0.24 = 24u +* pd = (int((nf+1)/2) * width/nf + 0.24)*2 = 200.48u + +* circuit +mn D_tn G_tn S_tn S_tn pmos_3p3 W = 200u L = 0.28u nf=20 ad= 24u pd=200.48u as=24u ps=200.48u + +.control +set filetype=ascii + +let vds_min = 0 +let vds_step = -0.1 +let vds_max = -3.3 + +compose vgs_vector start=0 stop=-3.3 step=-1 + +set appendwrite + +foreach t 25 + + let vgs_counter = 0 + while vgs_counter < length(vgs_vector) + option TEMP=25 + alter vgs = vgs_vector[vgs_counter] + + save @mn[vds] @mn[vgs] @mn[id] @mn[cgs] + ******************* + ** simulation part + ******************* + DC vds $&vds_min $&vds_max $&vds_step + + * ** parameters calculation + + print @mn[cgs] + + wrdata pmos_3p3_cv/simulated_Cgs/{{i}}_simulated_W{{width}}_L{{length}}.csv @mn[cgs] + + reset + let vgs_counter = vgs_counter + 1 + end +end +.endc +.end diff --git a/models/xyce/testing/regression/mos_cv/measured_data/3p3_cv.nl_out.xlsx b/models/xyce/testing/regression/mos_cv/measured_data/3p3_cv.nl_out.xlsx new file mode 100644 index 00000000..813635cd Binary files /dev/null and b/models/xyce/testing/regression/mos_cv/measured_data/3p3_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/regression/mos_cv/measured_data/3p3_sab_cv.nl_out.xlsx b/models/xyce/testing/regression/mos_cv/measured_data/3p3_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..fd139e1f Binary files /dev/null and b/models/xyce/testing/regression/mos_cv/measured_data/3p3_sab_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/regression/mos_cv/measured_data/6p0_cv.nl_out.xlsx b/models/xyce/testing/regression/mos_cv/measured_data/6p0_cv.nl_out.xlsx new file mode 100644 index 00000000..a6d80eec Binary files /dev/null and b/models/xyce/testing/regression/mos_cv/measured_data/6p0_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/regression/mos_cv/measured_data/6p0_nat_cv.nl_out.xlsx b/models/xyce/testing/regression/mos_cv/measured_data/6p0_nat_cv.nl_out.xlsx new file mode 100644 index 00000000..407129c7 Binary files /dev/null and b/models/xyce/testing/regression/mos_cv/measured_data/6p0_nat_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/regression/mos_cv/measured_data/6p0_sab_cv.nl_out.xlsx b/models/xyce/testing/regression/mos_cv/measured_data/6p0_sab_cv.nl_out.xlsx new file mode 100644 index 00000000..1dbd85c5 Binary files /dev/null and b/models/xyce/testing/regression/mos_cv/measured_data/6p0_sab_cv.nl_out.xlsx differ diff --git a/models/xyce/testing/regression/mos_cv/models_regression.py b/models/xyce/testing/regression/mos_cv/models_regression.py new file mode 100644 index 00000000..d31986db --- /dev/null +++ b/models/xyce/testing/regression/mos_cv/models_regression.py @@ -0,0 +1,280 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,sweep_x,sweep_y,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = int(dimensions["L (um)"].count()/2) + + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + # Special case for 1st measured values + if i == 0 : + # measured Cgc + if sim_val == "Cgc": + col_list = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]] + else: + # measured Cgs & Cgd + if sim_val == "Cgs": + col_list = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]] + else: + col_list = [sweep_x,f"{sweep_y[0]}.1",f"{sweep_y[1]}.1",f"{sweep_y[2]}.1",f"{sweep_y[3]}.1"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]] + df_measured.to_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv", index = False) + else: + # measured Cgc + if sim_val == "Cgc": + col_list = [sweep_x,f"{sweep_y[0]}.{i}",f"{sweep_y[1]}.{i}",f"{sweep_y[2]}.{i}",f"{sweep_y[3]}.{i}",f"{sweep_y[4]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,f"{sweep_y[0]}",f"{sweep_y[1]}",f"{sweep_y[2]}",f"{sweep_y[3]}",f"{sweep_y[4]}"] + else: + # measured Cgs & Cgd + cgs_index = 2*i + cgd_index = cgs_index + 1 + if sim_val == "Cgs": + col_list = [sweep_x,f"{sweep_y[0]}.{cgs_index}",f"{sweep_y[1]}.{cgs_index}",f"{sweep_y[2]}.{cgs_index}",f"{sweep_y[3]}.{cgs_index}"] + else: + col_list = [sweep_x,f"{sweep_y[0]}.{cgd_index}",f"{sweep_y[1]}.{cgd_index}",f"{sweep_y[2]}.{cgd_index}",f"{sweep_y[3]}.{cgd_index}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [sweep_x,f"{sweep_y[0]}",f"{sweep_y[1]}",f"{sweep_y[2]}",f"{sweep_y[3]}"] + + df_measured.to_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv", index = False) + +def ext_simulated(device,sweep_x,sweep_y,vds_sweep,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = int(dimensions["L (um)"].count()/2) + + netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i == 0: + nf = 20 + else: + nf = 1 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True) + with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist: + netlist.write(tmpl.render(width = width,length = length,i = i, nf = nf )) + netlist_path = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + + # empty array to append in it shaped (vds_sweep, number of trials + 1) + new_array = np.empty((vds_sweep, 1+int(df_simulated.shape[0]/vds_sweep))) + new_array[:, 0] = df_simulated.iloc[:vds_sweep, 0] + times = int(df_simulated.shape[0]/vds_sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vds_sweep:(j+1)*vds_sweep, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + if sim_val == "Cgc": + df_simulated.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]] + else: + df_simulated.columns = [sweep_x,sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]] + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + +def error_cal(device,sweep_x,sweep_y,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = int(dimensions["L (um)"].count()/2) + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + + measured = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv") + simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv") + + error_1 = round (100 * (abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1]),6) + error_2 = round (100 * (abs(measured.iloc[:, 2]) - abs(simulated.iloc[:, 2]))/abs(measured.iloc[:, 2]),6) + error_3 = round (100 * (abs(measured.iloc[:, 3]) - abs(simulated.iloc[:, 3]))/abs(measured.iloc[:, 3]),6) + error_4 = round (100 * (abs(measured.iloc[:, 4]) - abs(simulated.iloc[:, 4]))/abs(measured.iloc[:, 4]),6) + if sim_val == "Cgc": + error_5 = round (100 * (abs(measured.iloc[:, 5]) - abs(simulated.iloc[:, 5]))/abs(measured.iloc[:, 5]),6) + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5]).transpose() + else: + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4]).transpose() + df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False) + + # Mean error + if sim_val == "Cgc": + mean_error = (df_error[sweep_y[0]].mean() + df_error[sweep_y[1]].mean() + df_error[sweep_y[2]].mean() + + df_error[sweep_y[3]].mean() + df_error[sweep_y[4]].mean())/5 + else: + mean_error = (df_error[sweep_y[0]].mean() + df_error[sweep_y[1]].mean() + df_error[sweep_y[2]].mean() + + df_error[sweep_y[3]].mean())/4 + # Max error + if sim_val == "Cgc": + max_error = df_error[[sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3],sweep_y[4]]].max().max() + else: + max_error = df_error[[sweep_y[0],sweep_y[1],sweep_y[2],sweep_y[3]]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_sweep_y = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_sweep_x = df_error[sweep_x][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'25', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_sweep_y} & {sweep_x}= {max_location_sweep_x}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["nmos_3p3_cv" , "pmos_3p3_cv" ] + measured_data = ["3p3_cv"] + nmos_vds = "Vds (V)" + pmos_vds = "-Vds (V)" + nmos_vgs = "Vgs (V)" + pmos_vgs = "-Vgs (V)" + nmos_rds = "Rds" + cgc_sim = "Cgc" + cgs_sim = "Cgs" + cgd_sim = "Cgd" + Rds_sim = "Rds" + mos_3p3_vbs_sweep = 67 + mos_3p3_vgs_sweep = 34 + + mos_6p0_vgs_sweep = 133 + + nmos3p3_vgs = ["Vgs=0" , "Vgs=1.1" , "Vgs=2.2" , "Vgs=3.3" ] + pmos3p3_vgs = ["Vgs=-0" , "Vgs=-1.1" , "Vgs=-2.2" , "Vgs=-3.3"] + # pmos3p3_vgs = [-0.8 , -1.3 , -1.8 , -2.3 , -2.8 , -3.3] + # nmos6p0_vgs = [ 1 , 2 , 3 , 4 , 5 , 6] + # pmos6p0_vgs = [-1 , -2 , -3 , -4 , -5 , -6] + # nmos6p0_nat_vgs = [ 0.25 , 1.4 , 2.55 , 3.7 , 4.85 , 6] + + nmos3p3_vbs = ["Vbs=0" , "Vbs=-0.825" , "Vbs=-1.65" , "Vbs=-2.475" , "Vbs=-3.3"] + pmos3p3_vbs = ["Vbs=-0" , "Vbs=0.825" , "Vbs=1.65" , "Vbs=2.475" , "Vbs=3.3" ] + # nmos6p0_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + # pmos6p0_vbs = [ 0 , 0.75 , 1.5 , 2.25 , 3] + # nmos6p0_nat_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + + for device in devices: + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{cgc_sim}",exist_ok=False) + os.makedirs(f"{device}/measured_{cgs_sim}",exist_ok=False) + os.makedirs(f"{device}/measured_{cgd_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"./measured_data/{measured_data[0]}.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{cgc_sim}",exist_ok=False) + os.makedirs(f"{device}/simulated_{cgs_sim}",exist_ok=False) + os.makedirs(f"{device}/simulated_{cgd_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{cgc_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{cgs_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{cgd_sim}",exist_ok=False) + + + # =========== nmos_3p3_cv ============== + # Cgc + ext_measured ("nmos_3p3_cv",nmos_vgs,nmos3p3_vbs,cgc_sim) + ext_simulated("nmos_3p3_cv",nmos_vgs,nmos3p3_vbs,mos_3p3_vbs_sweep,cgc_sim) + error_cal ("nmos_3p3_cv",nmos_vgs,nmos3p3_vbs,cgc_sim) + + # Cgs + ext_measured ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgs_sim) + ext_simulated("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,cgs_sim) + error_cal ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgs_sim) + + # Cgd + ext_measured ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgd_sim) + ext_simulated("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,cgd_sim) + error_cal ("nmos_3p3_cv",nmos_vds,nmos3p3_vgs,cgd_sim) + + + # =========== nmos_3p3_cv ============== + # Cgc + ext_measured ("pmos_3p3_cv",pmos_vgs,pmos3p3_vbs,cgc_sim) + ext_simulated("pmos_3p3_cv",pmos_vgs,pmos3p3_vbs,mos_3p3_vbs_sweep,cgc_sim) + error_cal ("pmos_3p3_cv",pmos_vgs,pmos3p3_vbs,cgc_sim) + + # Cgs + ext_measured ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgs_sim) + ext_simulated("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,mos_3p3_vgs_sweep,cgs_sim) + error_cal ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgs_sim) + + # Cgd + ext_measured ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgd_sim) + ext_simulated("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,mos_3p3_vgs_sweep,cgd_sim) + error_cal ("pmos_3p3_cv",pmos_vgs,pmos3p3_vgs,cgd_sim) + + # =========== pmos_3p3_iv ============== + + + # =========== nmos_6p0_iv ============== + + + # =========== pmos_6p0_iv ============== + + + # ============ nmos_3p3_sab_iv ============= # Error in ngspice + + + # ============ nmos_6p0_nat_iv ============= + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_3p3_iv_vbs.spice b/models/xyce/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_3p3_iv_vbs.spice new file mode 100644 index 00000000..0d09520d --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vbs/device_netlists_Id/nmos_3p3_iv_vbs.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 0.05 +Vgs G_tn 0 dc 3.3 +Vbs S_tn 0 dc 0 + +xmn1 D_tn G_tn 0 S_tn nmos_3p3 W=10u L=10u ad=2.4u pd=20.48u as=2.4u ps=20.48u + + +***************** +** Analysis +***************** +.dc Vgs 0 3.3 0.05 Vbs 0 -3.3 -0.825 +.STEP TEMP -40 -60 200 +.print DC FORMAT=CSV file=result.csv {-I(Vds)} + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" typical + +.end diff --git a/models/xyce/testing/regression/mos_iv_vbs/models_regression.py b/models/xyce/testing/regression/mos_iv_vbs/models_regression.py new file mode 100644 index 00000000..3a85b3ea --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vbs/models_regression.py @@ -0,0 +1,224 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"ngspice -b -a {file_name} -o {file_name}.log > {file_name}.log") + +def ext_measured(device,vgs,vbs): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops*2,2): + width = dimensions["W (um)"].iloc[int(i/2)] + length = dimensions["L (um)"].iloc[int(i/2)] + + # Special case for 1st measured values + if i == 0 : + # measured Id + if device in ["pmos_3p3_iv" , "pmos_6p0_iv"]: + col_list = ['-vgs ',f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + else: + col_list = ['vgs ',f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vgs}",f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + else: + # measured Id + col_list = [f"{vgs}",f"vbs ={vbs[0]}.{i}",f"vbs ={vbs[1]}.{i}",f"vbs ={vbs[2]}.{i}",f"vbs ={vbs[3]}.{i}",f"vbs ={vbs[4]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vgs}",f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + + +def ext_simulated(device,vgs,vbs,vbs_sweep,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + AD = float(width) * 0.24 + PD = 2 * (float(width) + 0.24) + AS = AD + PS = PD + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: + temp = 125 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True) + with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist: + netlist.write(tmpl.render(width = width,length = length,i = i , temp = temp , AD = AD , PD = PD , AS = AS , PS = PD )) + netlist_path = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=None, delimiter=r"\s+") + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + + # empty array to append in it shaped (vbs_sweep, number of trials + 1) + new_array = np.empty((vbs_sweep, 1+int(df_simulated.shape[0]/vbs_sweep))) + new_array[:, 0] = df_simulated.iloc[:vbs_sweep, 0] + times = int(df_simulated.shape[0]/vbs_sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vbs_sweep:(j+1)*vbs_sweep, 1] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + df_simulated.columns = [f"{vgs}",f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"] + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + +def error_cal(device,vgs,vbs,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: temp = 125 + + measured = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv") + simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[:, 2]) - abs(simulated.iloc[:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[:, 3]) - abs(simulated.iloc[:, 3]))/abs(measured.iloc[:, 3])),6) + error_4 = round (100 * abs((abs(measured.iloc[:, 4]) - abs(simulated.iloc[:, 4]))/abs(measured.iloc[:, 4])),6) + error_5 = round (100 * abs((abs(measured.iloc[:, 5]) - abs(simulated.iloc[:, 5]))/abs(measured.iloc[:, 5])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5]).transpose() + df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"vbs ={vbs[0]}"].mean() + df_error[f"vbs ={vbs[1]}"].mean() + df_error[f"vbs ={vbs[2]}"].mean() + + df_error[f"vbs ={vbs[3]}"].mean() + df_error[f"vbs ={vbs[4]}"].mean())/6 + # Max error + max_error = df_error[[f"vbs ={vbs[0]}",f"vbs ={vbs[1]}",f"vbs ={vbs[2]}",f"vbs ={vbs[3]}",f"vbs ={vbs[4]}"]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vbs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vgs = df_error[f"{vgs}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & vbs (V) = {max_location_vbs}'} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["nmos_3p3_iv" , "pmos_3p3_iv" , "nmos_6p0_iv" , "pmos_6p0_iv" , "nmos_6p0_nat_iv"] #"nmos_3p3_sab_iv" + nmos_vgs = "vgs (V)" + pmos_vgs = "-vgs (V)" + nmos_rds = "Rds" + Id_sim = "Id" + Rds_sim = "Rds" + mos_3p3_vbs_sweep = 67 + mos_6p0_vbs_sweep = 121 + mos_6p0_nat_vbs_sweep = 131 + nmos3p3_vbs = [0 , -0.825 , -1.65 , -2.48 , -3.3] + pmos3p3_vbs = [0 , 0.825 , 1.65 , 2.48 , 3.3] + nmos6p0_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + pmos6p0_vbs = [ 0 , 0.75 , 1.5 , 2.25 , 3] + nmos6p0_nat_vbs = [ 0 , -0.75 , -1.5 , -2.25 , -3] + + for device in devices: + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False) + # os.makedirs(f"{device}/measured_{Rds_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/MOS/{device}.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False) + # os.makedirs(f"{device}/simulated_{Rds_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False) + # os.makedirs(f"{device}/error_{Rds_sim}",exist_ok=False) + + # =========== nmos_3p3_iv ============== + ext_measured ("nmos_3p3_iv",nmos_vgs,nmos3p3_vbs) + ext_simulated("nmos_3p3_iv",nmos_vgs,nmos3p3_vbs,mos_3p3_vbs_sweep,Id_sim) + error_cal ("nmos_3p3_iv",nmos_vgs,nmos3p3_vbs,Id_sim) + + # =========== pmos_3p3_iv ============== + ext_measured ("pmos_3p3_iv",pmos_vgs,pmos3p3_vbs) + ext_simulated("pmos_3p3_iv",pmos_vgs,pmos3p3_vbs,mos_3p3_vbs_sweep,Id_sim) + error_cal ("pmos_3p3_iv",pmos_vgs,pmos3p3_vbs,Id_sim) + + # =========== nmos_6p0_iv ============== + ext_measured ("nmos_6p0_iv",nmos_vgs,nmos6p0_vbs) + ext_simulated("nmos_6p0_iv",nmos_vgs,nmos6p0_vbs,mos_6p0_vbs_sweep,Id_sim) + error_cal ("nmos_6p0_iv",nmos_vgs,nmos6p0_vbs,Id_sim) + + # =========== pmos_6p0_iv ============== + ext_measured ("pmos_6p0_iv",pmos_vgs,pmos6p0_vbs) + ext_simulated("pmos_6p0_iv",pmos_vgs,pmos6p0_vbs,mos_6p0_vbs_sweep,Id_sim) + error_cal ("pmos_6p0_iv",pmos_vgs,pmos6p0_vbs,Id_sim) + + # ============ nmos_3p3_sab_iv ============= # Error in ngspice + # ext_measured ("nmos_3p3_sab_iv",nmos_vgs,nmos3p3_vbs) + # ext_simulated("nmos_3p3_sab_iv",nmos_vgs,nmos3p3_vbs,mos_3p3_vbs_sweep,Id_sim) + # error_cal ("nmos_3p3_sab_iv",nmos_vgs,nmos3p3_vbs,Rds_sim) + + # ============ nmos_6p0_nat_iv ============= + ext_measured ("nmos_6p0_nat_iv",nmos_vgs,nmos6p0_nat_vbs) + ext_simulated("nmos_6p0_nat_iv",nmos_vgs,nmos6p0_nat_vbs,mos_6p0_nat_vbs_sweep,Id_sim) + error_cal ("nmos_6p0_nat_iv",nmos_vgs,nmos6p0_nat_vbs,Id_sim) + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_iv.spice new file mode 100644 index 00000000..4e307ff0 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_3p3 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_3p3_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_sab_iv.spice new file mode 100644 index 00000000..4a010573 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_3p3_sab_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_3p3_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_3p3_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_iv.spice new file mode 100644 index 00000000..889d85bc --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_6p0 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 6.6 0.05 Vgs 1 6 1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_6p0_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_nat_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_nat_iv.spice new file mode 100644 index 00000000..688a4455 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_nat_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_6p0_nat W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 6.6 0.05 Vgs 0.25 6 1.15 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_6p0_nat_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_sab_iv.spice new file mode 100644 index 00000000..ba9ec408 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/nmos_6p0_sab_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_6p0_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 6.6 0.05 Vgs 1 6 1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_6p0_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_iv.spice new file mode 100644 index 00000000..65ec7776 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_3p3 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 -3.3 -0.05 Vgs -0.8 -3.3 -0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_3p3_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_sab_iv.spice new file mode 100644 index 00000000..8c95a4ee --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_3p3_sab_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_3p3_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 -3.3 -0.05 Vgs -0.8 -3.3 -0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_3p3_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_iv.spice new file mode 100644 index 00000000..4cb584cf --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_6p0 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 -6.6 -0.05 Vgs -1 -6 -1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_6p0_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_sab_iv.spice new file mode 100644 index 00000000..eb914ad5 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/pmos_6p0_sab_iv.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_6p0_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + +***************** +** Analysis +***************** +.DC Vds 0 -6.6 -0.05 Vgs -1 -6 -1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_6p0_sab_iv/simulated_Id/{{i}}_simulated_W{{width}}_L{{length}}.csv {-I(Vds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/run_nmos_3p3_iv_independently.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/run_nmos_3p3_iv_independently.spice new file mode 100644 index 00000000..993faebc --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Id/run_nmos_3p3_iv_independently.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + +* .OPTIONS DEVICE TEMP=-40 + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_3p3_sab W=10u L=10u ad=2.4u pd=20.48u as=2.4u ps=20.48u + +***************** +** Analysis +***************** +.DC Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +.STEP TEMP 25 -60 200 +.print DC FORMAT=CSV file=result.csv {-I(Vds)} + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_iv.spice new file mode 100644 index 00000000..ccc637af --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_3p3 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_3p3_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {1/N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_sab_iv.spice new file mode 100644 index 00000000..009c02c0 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_3p3_sab_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_3p3_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_3p3_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {1/N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_iv.spice new file mode 100644 index 00000000..5b4fad88 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_6p0 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 6.6 0.05 Vgs 1 6 1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_6p0_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_nat_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_nat_iv.spice new file mode 100644 index 00000000..a83c9490 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_nat_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_6p0_nat W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 6.6 0.05 Vgs 0.25 6 1.15 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_6p0_nat_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {1/N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_sab_iv.spice new file mode 100644 index 00000000..de6c2b41 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/nmos_6p0_sab_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_6p0_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 6.6 0.05 Vgs 1 6 1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=nmos_6p0_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_iv.spice new file mode 100644 index 00000000..3104bbe2 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_3p3 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 -3.3 -0.05 Vgs -0.8 -3.3 -0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_3p3_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {1/N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_sab_iv.spice new file mode 100644 index 00000000..15a279a1 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_3p3_sab_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_3p3_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 -3.3 -0.05 Vgs -0.8 -3.3 -0.5 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_3p3_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {1/N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_iv.spice new file mode 100644 index 00000000..08035f6a --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_6p0 W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 -6.6 -0.05 Vgs -1 -6 -1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_6p0_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_sab_iv.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_sab_iv.spice new file mode 100644 index 00000000..d1bea5b4 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/pmos_6p0_sab_iv.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc -3.3 +Vgs G_tn 0 dc -3.3 + + +xmn1 D_tn G_tn 0 0 pmos_6p0_sab W={{width}}u L={{length}}u ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u + + + +***************** +** Analysis +***************** +.DC Vds 0 -6.6 -0.05 Vgs -1 -6 -1 +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file=pmos_6p0_sab_iv/simulated_Rds/{{i}}_simulated_W{{width}}_L{{length}}.csv {N(xmn1:m0:gds)} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/run_nmos_3p3_rds_independently.spice b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/run_nmos_3p3_rds_independently.spice new file mode 100644 index 00000000..4b90836f --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/device_netlists_Rds/run_nmos_3p3_rds_independently.spice @@ -0,0 +1,27 @@ +*Xyce Common Source Circuit +** library calling + + + +***************** +** main netlist +***************** +Vds D_tn 0 dc 3.3 +Vgs G_tn 0 dc 3.3 + + +xmn1 D_tn G_tn 0 0 nmos_3p3 W=10u L=10u ad=2.4u pd=20.48u as=2.4u ps=20.48u + + + +***************** +** Analysis +***************** +.DC Vds 0 3.3 0.05 Vgs 0.8 3.3 0.5 +.STEP TEMP -40 -40 -40 +.print DC FORMAT=CSV file=result.csv {1/N(xmn1:m0:gds)} + +.include "../../design.xyce" +.lib "../../sm141064.xyce" typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/mos_iv_vgs/models_regression.py b/models/xyce/testing/regression/mos_iv_vgs/models_regression.py new file mode 100644 index 00000000..e59763d6 --- /dev/null +++ b/models/xyce/testing/regression/mos_iv_vgs/models_regression.py @@ -0,0 +1,287 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce {file_name} -l {file_name}.log") + +def ext_measured(device,vds,vgs): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops*2,2): + width = dimensions["W (um)"].iloc[int(i/2)] + length = dimensions["L (um)"].iloc[int(i/2)] + + # Special case for 1st measured values + if i == 0 : + # measured Id + col_list = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + # measured Rds + col_list = [f"{vds}",f"vgs ={vgs[0]}.{i+1}",f"vgs ={vgs[1]}.{i+1}",f"vgs ={vgs[2]}.{i+1}",f"vgs ={vgs[3]}.{i+1}",f"vgs ={vgs[4]}.{i+1}",f"vgs ={vgs[5]}.{i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Rds/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + else: + # measured Id + col_list = [f"{vds}",f"vgs ={vgs[0]}.{i}",f"vgs ={vgs[1]}.{i}",f"vgs ={vgs[2]}.{i}",f"vgs ={vgs[3]}.{i}",f"vgs ={vgs[4]}.{i}",f"vgs ={vgs[5]}.{i}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Id/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + # measured Rds + col_list = [f"{vds}",f"vgs ={vgs[0]}.{i+1}",f"vgs ={vgs[1]}.{i+1}",f"vgs ={vgs[2]}.{i+1}",f"vgs ={vgs[3]}.{i+1}",f"vgs ={vgs[4]}.{i+1}",f"vgs ={vgs[5]}.{i+1}"] + df_measured = pd.read_csv(f"{device}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_measured.to_csv(f"{device}/measured_Rds/{int(i/2)}_measured_W{width}_L{length}.csv", index = False) + +def ext_simulated(device,vds,vgs,vds_sweep,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + netlist_tmp = f"./device_netlists_{sim_val}/{device}.spice" + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + AD = float(width) * 0.24 + PD = 2 * (float(width) + 0.24) + AS = AD + PS = PD + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: + temp = 125 + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{device}/{device}_netlists_{sim_val}",exist_ok=True) + with open(f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice", "w") as netlist: + netlist.write(tmpl.render(width = width,length = length,i = i , temp = temp , AD = AD , PD = PD , AS = AS , PS = PD )) + netlist_path = f"{device}/{device}_netlists_{sim_val}/{i}_{device}_netlist_W{width}_L{length}.spice" + if ("sab" not in netlist_path) and ("Rds" not in netlist_path): + netlist_path = "-hspice-ext all " + netlist_path + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",header=0) + + # empty array to append in it shaped (vds_sweep, number of trials + 1) + new_array = np.empty((vds_sweep, 1+int(df_simulated.shape[0]/vds_sweep))) + new_array[:, 0] = df_simulated.iloc[:vds_sweep, 0] + times = int(df_simulated.shape[0]/vds_sweep) + + for j in range(times): + new_array[:, (j+1)] = df_simulated.iloc[j*vds_sweep:(j+1)*vds_sweep, 0] + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + df_simulated.columns = [f"{vds}",f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}"] + df_simulated.to_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv",index= False) + +def error_cal(device,vds,vgs,sim_val): + + # Get dimensions used for each device + dimensions = pd.read_csv(f"{device}/{device}.csv",usecols=["W (um)" , "L (um)"]) + loops = dimensions["L (um)"].count() + temp_range = int(loops/3) + df_final = pd.DataFrame() + for i in range (0,loops): + width = dimensions["W (um)"].iloc[int(i)] + length = dimensions["L (um)"].iloc[int(i)] + if i in range (0,temp_range): temp = 25 + elif i in range (temp_range,2*temp_range): temp = -40 + else: temp = 125 + + measured = pd.read_csv(f"{device}/measured_{sim_val}/{i}_measured_W{width}_L{length}.csv") + simulated = pd.read_csv(f"{device}/simulated_{sim_val}/{i}_simulated_W{width}_L{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[1:, 1]) - abs(simulated.iloc[1:, 1]))/abs(measured.iloc[:, 1])),6) + error_2 = round (100 * abs((abs(measured.iloc[1:, 2]) - abs(simulated.iloc[1:, 2]))/abs(measured.iloc[:, 2])),6) + error_3 = round (100 * abs((abs(measured.iloc[1:, 3]) - abs(simulated.iloc[1:, 3]))/abs(measured.iloc[:, 3])),6) + error_4 = round (100 * abs((abs(measured.iloc[1:, 4]) - abs(simulated.iloc[1:, 4]))/abs(measured.iloc[:, 4])),6) + error_5 = round (100 * abs((abs(measured.iloc[1:, 5]) - abs(simulated.iloc[1:, 5]))/abs(measured.iloc[:, 5])),6) + error_6 = round (100 * abs((abs(measured.iloc[1:, 6]) - abs(simulated.iloc[1:, 6]))/abs(measured.iloc[:, 6])),6) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1,error_2,error_3,error_4,error_5,error_6]).transpose() + df_error.to_csv(f"{device}/error_{sim_val}/{i}_{device}_error_W{width}_L{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"vgs ={vgs[0]}"].mean() + df_error[f"vgs ={vgs[1]}"].mean() + df_error[f"vgs ={vgs[2]}"].mean() + + df_error[f"vgs ={vgs[3]}"].mean() + df_error[f"vgs ={vgs[4]}"].mean() + df_error[f"vgs ={vgs[5]}"].mean())/6 + # Max error + max_error = df_error[[f"vgs ={vgs[0]}",f"vgs ={vgs[1]}",f"vgs ={vgs[2]}",f"vgs ={vgs[3]}",f"vgs ={vgs[4]}",f"vgs ={vgs[5]}" ]].max().max() + # Max error location + max_index = max((df_error == max_error).idxmax()) + max_location_vgs = (df_error == max_error).idxmax(axis=1)[max_index] + max_location_vds = df_error[f"{vds}"][max_index] + + df_final_ = {'Run no.': f'{i}', 'Temp': f'{temp}', 'Device name': f'{device}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{sim_val}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} @ {max_location_vgs} & Vds (V) = {max_location_vds}'} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{device}/Final_report_{sim_val}.csv", index = False) + out_report = pd.read_csv (f"{device}/Final_report_{sim_val}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + devices = ["nmos_3p3_iv" , "pmos_3p3_iv" , "nmos_6p0_iv" , "pmos_6p0_iv" , "nmos_6p0_nat_iv", "nmos_3p3_sab_iv", "pmos_3p3_sab_iv" , "nmos_6p0_sab_iv" , "pmos_6p0_sab_iv"] + nmos_vds = "vds (V)" + pmos_vds = "-vds (V)" + nmos_rds = "Rds" + Id_sim = "Id" + Rds_sim = "Rds" + mos_3p3_vgs_sweep = 67 + mos_6p0_vgs_sweep = 133 + nmos3p3_vgs = [ 0.8 , 1.3 , 1.8 , 2.3 , 2.8 , 3.3] + pmos3p3_vgs = [-0.8 , -1.3 , -1.8 , -2.3 , -2.8 , -3.3] + nmos6p0_vgs = [ 1 , 2 , 3 , 4 , 5 , 6] + pmos6p0_vgs = [-1 , -2 , -3 , -4 , -5 , -6] + nmos6p0_nat_vgs = [ 0.25 , 1.4 , 2.55 , 3.7 , 4.85 , 6] + + for device in devices: + # Folder structure of measured values + dirpath = f"{device}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{device}/measured_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/measured_{Rds_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/MOS/{device}.nl_out.xlsx") + read_file.to_csv (f"{device}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{device}/simulated_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/simulated_{Rds_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Id_sim}",exist_ok=False) + os.makedirs(f"{device}/error_{Rds_sim}",exist_ok=False) + + # =========== nmos_3p3_iv ============== + ext_measured ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs) + + ext_simulated("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + + ext_simulated("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + + # =========== pmos_3p3_iv ============== + ext_measured ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs) + + ext_simulated("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + + ext_simulated("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + + # =========== nmos_6p0_iv ============== + ext_measured ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs) + + ext_simulated("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + + ext_simulated("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + + # =========== pmos_6p0_iv ============== + ext_measured ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs) + + ext_simulated("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + + ext_simulated("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + + # ============ nmos_6p0_nat_iv ============= + ext_measured ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs) + + ext_simulated("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,mos_6p0_vgs_sweep,Id_sim) + + ext_simulated("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,mos_6p0_vgs_sweep,Rds_sim) + + # ============ nmos_3p3_sab_iv ============= + ext_measured ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs) + + ext_simulated("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + + ext_simulated("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + + # =========== pmos_3p3_sab_iv ============== + ext_measured ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs) + + ext_simulated("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Id_sim) + + ext_simulated("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,mos_3p3_vgs_sweep,Rds_sim) + + # =========== nmos_6p0_sab_iv ============== + ext_measured ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs) + + ext_simulated("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + + ext_simulated("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + + # =========== pmos_6p0_sab_iv ============== + ext_measured ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs) + + ext_simulated("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Id_sim) + + ext_simulated("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,mos_6p0_vgs_sweep,Rds_sim) + + + + # ============ Results ============= + error_cal ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,Id_sim) + error_cal ("nmos_3p3_iv",nmos_vds,nmos3p3_vgs,Rds_sim) + error_cal ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,Id_sim) + error_cal ("pmos_3p3_iv",pmos_vds,pmos3p3_vgs,Rds_sim) + error_cal ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,Id_sim) + error_cal ("nmos_6p0_iv",nmos_vds,nmos6p0_vgs,Rds_sim) + error_cal ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,Id_sim) + error_cal ("pmos_6p0_iv",pmos_vds,pmos6p0_vgs,Rds_sim) + error_cal ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,Id_sim) + error_cal ("nmos_6p0_nat_iv",nmos_vds,nmos6p0_nat_vgs,Rds_sim) + error_cal ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,Rds_sim) + error_cal ("nmos_3p3_sab_iv",nmos_vds,nmos3p3_vgs,Id_sim) + error_cal ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,Id_sim) + error_cal ("pmos_3p3_sab_iv",pmos_vds,pmos3p3_vgs,Rds_sim) + error_cal ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,Id_sim) + error_cal ("nmos_6p0_sab_iv",nmos_vds,nmos6p0_vgs,Rds_sim) + error_cal ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,Id_sim) + error_cal ("pmos_6p0_sab_iv",pmos_vds,pmos6p0_vgs,Rds_sim) + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/moscap_c/device_netlists/moscap.spice b/models/xyce/testing/regression/moscap_c/device_netlists/moscap.spice new file mode 100644 index 00000000..132247da --- /dev/null +++ b/models/xyce/testing/regression/moscap_c/device_netlists/moscap.spice @@ -0,0 +1,30 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +.param volt = -3.3 +V1 in 0 dc {volt} ac 1 +R1 in out 1G +xcn out 0 {{device}} c_length={{length}}u c_width={{width}}u l={{length}}u w={{width}}u + +.meas AC freq when Vdb(out)=-3 PRECISION=15 + + + + +***************** +** Analysis +***************** + +.ac dec 10 1 10G +.step volt {{voltage}} + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" moscap_{{corner}} + +.end + + diff --git a/models/xyce/testing/regression/moscap_c/device_netlists/run_nmoscap_3p3_independently.spice b/models/xyce/testing/regression/moscap_c/device_netlists/run_nmoscap_3p3_independently.spice new file mode 100644 index 00000000..97c50cff --- /dev/null +++ b/models/xyce/testing/regression/moscap_c/device_netlists/run_nmoscap_3p3_independently.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Ich 0 p dc 10u + + +xcn p 0 nmoscap_3p3 L=50u W=50u +* PJ=40u + + +***************** +** Analysis +***************** +.ic v(p)=0.0 +.tran 10ns 2000us + +.meas tran CV FIND par('(10.0e-6 * time / v(p))*1.0e15') AT=2000us + + + +.include "../../design.xyce" +.lib "../../sm141064.xyce" moscap_typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/moscap_c/models_regression.py b/models/xyce/testing/regression/moscap_c/models_regression.py new file mode 100644 index 00000000..731da96b --- /dev/null +++ b/models/xyce/testing/regression/moscap_c/models_regression.py @@ -0,0 +1,224 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device,vn,d_in, cv_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 50 ; length = 50 + if i == 1+start: width = 1 ; length = 1 + if i == 2+start: width = 50 ; length = 1 + if i == 3+start: width = 1 ; length = 50 + + if i == 0 : + # measured cv + col_list = [f"Vj",f"moscap_{corner}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_w{width}_l{length}.csv", index=False) + else: + # measured cv + col_list = [f"Vj",f"moscap_{corner}.{i}"] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"Vj",f"moscap_{corner}"] + df_measured.to_csv(f"{dirpath}/measured_{cv_sim}/{i-start}_measured_w{width}_l{length}.csv", index=False) + +def ext_simulated(device,vn,d_in,cv_sim, corner,start,voltage): + + # Get dimensions used for each device + dirpath = f"{device}_{cv_sim}_{corner}" + netlist_tmp = f"./device_netlists/moscap.spice" + + # Extracting measured values for each W & L + for i in range (start,4+start): + if i == 0+start: width = 50 ; length = 50 + if i == 1+start: width = 1 ; length = 1 + if i == 2+start: width = 50 ; length = 1 + if i == 3+start: width = 1 ; length = 50 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{cv_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, width = width, length = length , corner = corner , voltage = voltage)) + netlist_path = f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = [] + # Writing simulated data + for j in range(len([x for x in os.listdir(f"{dirpath}/{device}_netlists_{cv_sim}") if f"{i-start}_{device}_netlist_w{width}_l{length}.spice.ma" in x])): + with open(f"{dirpath}/{device}_netlists_{cv_sim}/{i-start}_{device}_netlist_w{width}_l{length}.spice.ma{j}") as f: + cap = 1000000/(float(next(f).replace("FREQ = ", ""))*2*np.pi) + df_simulated.append(cap) + + # zero array to append in it shaped (vn_sweeps, number of trials + 1) + new_array = np.zeros((len(df_simulated), 2)) + new_array[:len(df_simulated), 0] = df_simulated + new_array[:len(df_simulated), 1] = df_simulated + + # Writing final simulated data + df_simulated = pd.DataFrame(new_array) + df_simulated.columns = [f"Vj",f"moscap_{corner}"] + df_simulated.to_csv(f"{dirpath}/simulated_{cv_sim}/{i-start}_simulated_w{width}_l{length}.csv",index= False) + +def error_cal(device,vn,d_in,Id_sim, corner,start): + + # Get dimensions used for each device + dirpath = f"{device}_{Id_sim}_{corner}" + df_final = pd.DataFrame() + for i in range (start,4+start): + if i == 0+start: width = 50 ; length = 50 + if i == 1+start: width = 1 ; length = 1 + if i == 2+start: width = 50 ; length = 1 + if i == 3+start: width = 1 ; length = 50 + + measured = pd.read_csv(f"{dirpath}/measured_{Id_sim}/{i-start}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{Id_sim}/{i-start}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 1]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{Id_sim}/{i-start}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"moscap_{corner}"].mean()) + # Max error + max_error = df_error[f"moscap_{corner}"].max() + + df_final_ = {'Run no.': f'{i-start}', 'Device name': f'{dirpath}', 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{Id_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{Id_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{Id_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + + +def main(): + + # 3p3 + corners = ["typical","ff","ss"] + devices = ["nmoscap_3p3" , "pmoscap_3p3" , "nmoscap_3p3_b" , "pmoscap_3p3_b"] + measure = ["cv","corners", "CV (fF)"] + voltage = ["-3.3 3.3 0.1","-6.6 6.0 0.1"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + dirpath = f"{device}_{cv_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Cap/moscap_cv_3p3.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + + ext_measured (device,cap_vn,cap_in, cv_sim, corner,start) + ext_simulated(device,cap_vn,cap_in,cv_sim, corner,start,voltage[0]) + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = 0 + + # 6p0 + corners = ["typical","ff","ss"] + devices = ["nmoscap_6p0" , "pmoscap_6p0" , "nmoscap_6p0_b" , "pmoscap_6p0_b"] + measure = ["cv","corners", "CV (fF)"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + dirpath = f"{device}_{cv_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{cv_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Cap/moscap_cv_6p0.nl_out.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{cv_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{cv_sim}",exist_ok=False) + + ext_measured (device,cap_vn,cap_in, cv_sim, corner,start) + ext_simulated(device,cap_vn,cap_in,cv_sim, corner,start,voltage[1]) + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = 0 + + # 3p3 + corners = ["typical","ff","ss"] + devices = ["nmoscap_3p3" , "pmoscap_3p3" , "nmoscap_3p3_b" , "pmoscap_3p3_b"] + measure = ["cv","corners", "CV (fF)"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = 0 + + # 6p0 + corners = ["typical","ff","ss"] + devices = ["nmoscap_6p0" , "pmoscap_6p0" , "nmoscap_6p0_b" , "pmoscap_6p0_b"] + measure = ["cv","corners", "CV (fF)"] + start = 0 + for corner in corners: + for device in devices: + # Folder structure of measured values + cv_sim, cap_vn, cap_in = measure[0], measure[1], measure[2] + error_cal (device,cap_vn,cap_in,cv_sim, corner,start) + start = start + 4 + start = 0 + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/regression/resistor_r/device_netlists/2term_res_a.spice b/models/xyce/testing/regression/resistor_r/device_netlists/2term_res_a.spice new file mode 100644 index 00000000..a5f7272e --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/device_netlists/2term_res_a.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 DC 1 + +xrn n 0 {{device}} L={{width}}u W={{length}}u + + +***************** +** Analysis +***************** +.OP +.STEP TEMP 25 -60 200 +.print DC FORMAT=CSV file={{device}}_r_{{corner}}/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv {(V(n)*{{length}}u)/(-I(Vn)*{{width}}u)} + + + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" res_{{corner}} + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/resistor_r/device_netlists/2term_res_b.spice b/models/xyce/testing/regression/resistor_r/device_netlists/2term_res_b.spice new file mode 100644 index 00000000..82ccc77c --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/device_netlists/2term_res_b.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 DC 1 + +xrn n 0 {{device}} L={{width}}u W={{length}}u + + +***************** +** Analysis +***************** +.OP +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file={{device}}_r_{{corner}}_temp/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv {(V(n)*{{length}}u)/(-I(Vn)*{{width}}u)} + + + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" res_{{corner}} + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/resistor_r/device_netlists/3term_res_a.spice b/models/xyce/testing/regression/resistor_r/device_netlists/3term_res_a.spice new file mode 100644 index 00000000..ad0f4ebd --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/device_netlists/3term_res_a.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 DC 1 + +xrn n 0 0 {{device}} L={{width}}u W={{length}}u + + +***************** +** Analysis +***************** +.OP +.STEP TEMP 25 -60 200 +.print DC FORMAT=CSV file={{device}}_r_{{corner}}/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv {(V(n)*{{length}}u)/(-I(Vn)*{{width}}u)} + + + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" res_{{corner}} + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/resistor_r/device_netlists/3term_res_b.spice b/models/xyce/testing/regression/resistor_r/device_netlists/3term_res_b.spice new file mode 100644 index 00000000..b7af6423 --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/device_netlists/3term_res_b.spice @@ -0,0 +1,25 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 DC 1 + +xrn n 0 0 {{device}} L={{width}}u W={{length}}u + + +***************** +** Analysis +***************** +.OP +.STEP TEMP {{temp}} -60 200 +.print DC FORMAT=CSV file={{device}}_r_{{corner}}_temp/simulated_r/{{i}}_simulated_w{{width}}_l{{length}}.csv {(V(n)*{{length}}u)/(-I(Vn)*{{width}}u)} + + + +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" res_{{corner}} + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/resistor_r/device_netlists/run_2term_res.spice b/models/xyce/testing/regression/resistor_r/device_netlists/run_2term_res.spice new file mode 100644 index 00000000..d7e0b81c --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/device_netlists/run_2term_res.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 dc 1 + +r1 n p 1M +xrn p 0 rm1 L=100u W=100u +* PJ=40u + +* .print dc Rs=par('(1M*V(p)/(V(n)-V(p)))/100u*100u') + +***************** +** Analysis +***************** +.OP + +.print DC FORMAT=CSV file=result.csv {(1M*V(p)/(V(n)-V(p)))/100u*100u} + + + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" res_typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/resistor_r/device_netlists/run_3term_res.spice b/models/xyce/testing/regression/resistor_r/device_netlists/run_3term_res.spice new file mode 100644 index 00000000..c1853ca3 --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/device_netlists/run_3term_res.spice @@ -0,0 +1,28 @@ +*Xyce Common Source Circuit +** library calling + + +***************** +** main netlist +***************** +Vn n 0 dc 1 + +*r1 n p 1MEG +xrn n 0 0 ppolyf_s L=50u W=150u +* PJ=40u + +* .print dc Rs=par('(1M*V(p)/(V(n)-V(p)))/100u*100u') + +***************** +** Analysis +***************** +.OP +* .DC Vn 1 1 0.1 +* .print DC FORMAT=CSV file=result.csv {(1MEG*V(p)/(V(n)-V(p)))/50u*150u} +.print DC FORMAT=CSV file=result.csv {(V(n)*150u)/(-I(Vn)*50u)} + + +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" res_typical + +.end \ No newline at end of file diff --git a/models/xyce/testing/regression/resistor_r/models_regression.py b/models/xyce/testing/regression/resistor_r/models_regression.py new file mode 100644 index 00000000..92d38b49 --- /dev/null +++ b/models/xyce/testing/regression/resistor_r/models_regression.py @@ -0,0 +1,324 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from fileinput import filename +from re import T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured_a(device,vn,d_in, r_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["w (um)" , "l (um)"]) + loops = dimensions["l (um)"].count() + + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["w (um)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + + # measured r + col_list = [f"{vn}",f"{d_in}_{corner} Rev9 "] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}","value"] + df_measured.loc[i:i].to_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv", index=False) + +def ext_measured_b(device,vn,d_in, r_sim, corner): + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}_temp" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["Temperature (C)" , "l (um)"]) + if "rm" in device or "tm" in device: + loops = dimensions["l (um)"].count() + else: + loops = 11 + + # Extracting measured values for each W & L + for i in range (0,loops): + temp = dimensions["Temperature (C)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + if "rm" in device or "tm" in device or "_u" in device: + width = length + else: + width = length/2 + + # measured r + col_list = [f"{vn}",f"{d_in}_{corner} Rev9 "] + df_measured = pd.read_csv(f"{dirpath}/{device}.csv",usecols=col_list) + df_measured.columns = [f"{vn}","value"] + df_measured.loc[i:i].to_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv", index=False) + +def ext_simulated_a(device,vn,d_in,r_sim, corner,sign): + + if "rm" in device or "tm" in device: + netlist_tmp = f"./device_netlists/2term_res_a.spice" + else: + netlist_tmp = f"./device_netlists/3term_res_a.spice" + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["w (um)" , "l (um)"]) + loops = dimensions["l (um)"].count() + temp = 25 + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["w (um)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{r_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, width = width, length = length , corner = corner, i = i , sign = sign)) + netlist_path = f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",header=0) + # df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + + # Writing final simulated data + df_simulated.columns = [f"value"]#,"value"] + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + +def ext_simulated_b(device,vn,d_in,r_sim, corner,sign): + + if "rm" in device or "tm" in device: + netlist_tmp = f"./device_netlists/2term_res_b.spice" + else: + netlist_tmp = f"./device_netlists/3term_res_b.spice" + + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}_temp" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["Temperature (C)" , "l (um)"]) + if "rm" in device or "tm" in device: + loops = dimensions["l (um)"].count() + else: + loops = 11 + + # Extracting measured values for each W & L + for i in range (0,loops): + temp = dimensions["Temperature (C)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + if "rm" in device or "tm" in device or "_u" in device: + width = length + else: + width = length/2 + + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{dirpath}/{device}_netlists_{r_sim}",exist_ok=True) + with open(f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice", "w") as netlist: + netlist.write(tmpl.render(device = device, temp = temp , width = width, length = length , corner = corner, i = i , sign = sign)) + netlist_path = f"{dirpath}/{device}_netlists_{r_sim}/{i}_{device}_netlist_w{width}_l{length}.spice" + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",header=0) + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + + # Writing final simulated data + df_simulated.columns = [f"value"]#,"value"] + df_simulated.to_csv(f"{dirpath}/simulated_r/{i}_simulated_w{width}_l{length}.csv",index= False) + +def error_cal_a(device,vn,d_in,r_sim, corner): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["w (um)" , "l (um)"]) + loops = dimensions["l (um)"].count() + temp = 25 + # Extracting measured values for each W & L + for i in range (0,loops): + width = dimensions["w (um)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + + measured = pd.read_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{r_sim}/{i}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 0]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{r_sim}/{i}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"value"].mean()) + # Max error + max_error = df_error[f"value"].max() + + df_final_ = {'Run no.': f'{i}', 'Device name': f'{dirpath}', 'Temperature': temp, 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{r_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{r_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{r_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def error_cal_b(device,vn,d_in,r_sim, corner): + + df_final = pd.DataFrame() + # Get dimensions used for each device + dirpath = f"{device}_{r_sim}_{corner}_temp" + dimensions = pd.read_csv(f"{dirpath}/{device}.csv",usecols=["Temperature (C)" , "l (um)"]) + if "rm" in device or "tm" in device: + loops = dimensions["l (um)"].count() + else: + loops = 11 + + # Extracting measured values for each W & L + for i in range (0,loops): + temp = dimensions["Temperature (C)"].iloc[i] + length = dimensions["l (um)"].iloc[i] + if "rm" in device or "tm" in device or "_u" in device: + width = length + else: + width = length/2 + + measured = pd.read_csv(f"{dirpath}/measured_{r_sim}/{i}_measured_w{width}_l{length}.csv") + simulated = pd.read_csv(f"{dirpath}/simulated_{r_sim}/{i}_simulated_w{width}_l{length}.csv") + + error_1 = round (100 * abs((abs(measured.iloc[:, 1]) - abs(simulated.iloc[:, 0]))/abs(measured.iloc[:, 1])),8) + + df_error = pd.DataFrame(data=[measured.iloc[:, 0],error_1]).transpose() + df_error.to_csv(f"{dirpath}/error_{r_sim}/{i}_{device}_error_w{width}_l{length}.csv",index= False) + + # Mean error + mean_error = (df_error[f"value"].mean()) + # Max error + max_error = df_error[f"value"].max() + + df_final_ = {'Run no.': f'{i}', 'Device name': f'{dirpath}', 'Temperature': temp, 'Width': f'{width}', 'Length': f'{length}', 'Simulated_Val':f'{r_sim}','Mean error%':f'{"{:.2f}".format(mean_error)}', 'Max error%':f'{"{:.2f}".format(max_error)} '} + df_final = df_final.append(df_final_, ignore_index = True) + # Max mean error + print (df_final) + df_final.to_csv (f"{dirpath}/Final_report_{r_sim}.csv", index = False) + out_report = pd.read_csv (f"{dirpath}/Final_report_{r_sim}.csv") + print ("\n",f"Max. mean error = {out_report['Mean error%'].max()}%") + print ("=====================================================================================================================================================") + +def main(): + + # res W&L var. + corners_a = ["typical","ff","ss"] + + devices_a = ["nplus_u" , "pplus_u" , "nplus_s" , "pplus_s" , "npolyf_u" , "ppolyf_u" , "npolyf_s" , "ppolyf_s" , "ppolyf_u_1k" , "ppolyf_u_2k" , "ppolyf_u_1k_6p0" , + "ppolyf_u_2k_6p0" , "ppolyf_u_3k" , "rm1" , "rm2" , "rm3" , "tm6k" , "tm9k" , "tm11k" , "tm30k" , "nwell"] + + dev_data_a = ["RES01a-wl-nplus_u.nl_out" ,"RES02a-wl-pplus_u.nl_out" ,"RES03a-wl-nplus_s.nl_out" , "RES04a-wl-pplus_s.nl_out" , + "RES06a-wl-npolyf_u.nl_out" ,"RES07a-wl-ppolyf_u.nl_out" ,"RES08a-wl-npolyf_s.nl_out" , "RES09a-wl-ppolyf_s.nl_out" , "RES10a-wl-ppolyf_u_1k.nl_out", + "RES11a-wl-ppolyf_u_2k.nl_out" ,"RES12a-wl-ppolyf_u_1k_6p0.nl_o" ,"RES13a-wl-ppolyf_u_2k_6p0.nl_o" , "RES14a-wl-ppolyf_u_3k.nl_out" , + "RES15a-wl-rm1.nl_out" , "RES16a-wl-rm2.nl_out" , "RES17a-wl-rm3.nl_out" , "RES18a-wl-tm6k.nl_out" , "RES19a-wl-tm9k.nl_out" , + "RES20a-wl-tm11k.nl_out" , "RES21a-wl-tm30k.nl_out" ,"RES05a-wl-nwell.nl_out"] + + sign_a = ["+" , "-" , "+" , "-" , "+" , "+" , "-" , "+" , "-" , "-" , "-" , "-" , "-" , "-" , "+" , "+" , "+" , "+" , "+" , "+", "+", ""] + measure_a = ["r","corners", "res"] + + for corner in corners_a: + for i,device in enumerate(devices_a): + # Folder structure of measured values + r_sim, res_vn, res_in = measure_a[0], measure_a[1], measure_a[2] + dirpath = f"{device}_{r_sim}_{corner}" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{r_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Resistor/{dev_data_a[i]}.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{r_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{r_sim}",exist_ok=False) + + ext_measured_a (device,res_vn,res_in, r_sim, corner) + ext_simulated_a(device,res_vn,res_in,r_sim, corner,sign_a[i]) + error_cal_a (device,res_vn,res_in,r_sim, corner) + + + # res temp_var + corners_b = ["typical","ff","ss"] + devices_b = ["nplus_u" , "nplus_s", "pplus_u" , "pplus_s" , "nwell" , "npolyf_u" , "ppolyf_u" , "npolyf_s" , "ppolyf_s" , "ppolyf_u_1k" , "ppolyf_u_2k" , "ppolyf_u_1k_6p0" , "ppolyf_u_2k_6p0" , "ppolyf_u_3k" , + "rm1" , "rm2", "rm3" , "tm6k" , "tm9k" , "tm11k", "tm30k"] + dev_data_b = ["RES01b-temp-nplus_u.nl_out" , "RES03b-temp-nplus_s.nl_out", "RES02b-temp-pplus_u.nl_out" , "RES04b-temp-pplus_s.nl_out" , "RES05b-temp-nwell.nl_out" , + "RES06b-temp-npolyf_u.nl_out" , "RES07b-temp-ppolyf_u.nl_out" , "RES08b-temp-npolyf_s.nl_out" , "RES09b-temp-ppolyf_s.nl_out" , "RES10b-temp-ppolyf_u_1k.nl_out" , + "RES11b-temp-ppolyf_u_2k.nl_out" , "RES12b-temp-ppolyf_u_1k_6p0.nl" , "RES13b-temp-ppolyf_u_2k_6p0.nl" , "RES14b-temp-ppolyf_u_3k.nl_out" , + "RES15b-temp-rm1.nl_out", "RES16b-temp-rm2.nl_out" , "RES17b-temp-rm3.nl_out" , + "RES18b-temp-tm6k.nl_out", "RES19b-temp-tm9k.nl_out" , "RES20b-temp-tm11k.nl_out", "RES21b-temp-tm30k.nl_out"] + + sign_b = ["+" , "+", "-" , "-" , "+" , "+" , "-" ,"+" , "-" , "-" , "-" , "-" , "-" , "-" , "+" , "+" , "+" , "+" , "+" , "+", "+"] + measure_b = ["r","corners", "res"] + + for corner in corners_b: + for i,device in enumerate(devices_b): + # Folder structure of measured values + r_sim, res_vn, res_in = measure_b[0], measure_b[1], measure_b[2] + dirpath = f"{device}_{r_sim}_{corner}_temp" + if os.path.exists(dirpath) and os.path.isdir(dirpath): + shutil.rmtree(dirpath) + os.makedirs(f"{dirpath}/measured_{r_sim}",exist_ok=False) + + # From xlsx to csv + read_file = pd.read_excel (f"../../180MCU_SPICE_DATA/Resistor/{dev_data_b[i]}.xlsx") + read_file.to_csv (f"{dirpath}/{device}.csv", index = False, header=True) + + # Folder structure of simulated values + os.makedirs(f"{dirpath}/simulated_{r_sim}",exist_ok=False) + os.makedirs(f"{dirpath}/error_{r_sim}",exist_ok=False) + + ext_measured_b (device,res_vn,res_in, r_sim, corner) + ext_simulated_b(device,res_vn,res_in,r_sim, corner,sign_b[i]) + error_cal_b (device,res_vn,res_in,r_sim, corner) + + for corner in corners_a: + for i,device in enumerate(devices_a): + # Folder structure of measured values + r_sim, res_vn, res_in = measure_a[0], measure_a[1], measure_a[2] + error_cal_a (device,res_vn,res_in,r_sim, corner) + + + for corner in corners_b: + for i,device in enumerate(devices_b): + # Folder structure of measured values + r_sim, res_vn, res_in = measure_b[0], measure_b[1], measure_b[2] + error_cal_b (device,res_vn,res_in,r_sim, corner) + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1.spice b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1.spice new file mode 100644 index 00000000..9eb17dfb --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1.spice @@ -0,0 +1,43 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vin I 0 dc pulse(0 5 100p 1p 1p 100p 200p) +Vdd VDD 0 dc {{volt}} + +* Main circuit +X1 I ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__inv_1 + +* Temperature set +.STEP TEMP {{temp}} -60 200 + +* Analyses +.tran 1p 200p +.meas tran high_in FIND V(ZN) AT=100p +.meas tran low_in FIND V(ZN) AT=200p + +.print TRAN FORMAT=CSV file=inv/simulated/inv_{{process}}_{{temp}}c_{{volt}}v.csv high_in low_in + + +* Libraries calling +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" {{process}} + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__inv_1 I ZN VDD VNW VPW VSS +xM_i_0 ZN I VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_1 ZN I VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1_run.spice b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1_run.spice new file mode 100644 index 00000000..c4bd339b --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__inv_1_run.spice @@ -0,0 +1,42 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vin I 0 dc pulse(0 5 100p 1p 1p 100p 200p) +Vdd VDD 0 dc 5 + +* Main circuit +X1 I ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__inv_1 + +* Temperature set +.STEP TEMP 25 -60 200 + +* Analyses +.tran 1p 200p +.meas tran high_in FIND V(ZN) AT=100p +.meas tran low_in FIND V(ZN) AT=200p +.print TRAN FORMAT=CSV file=inv_simulated.csv {high_in} {low_in} + + +* Libraries calling +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" typical + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__inv_1 I ZN VDD VNW VPW VSS +xM_i_0 ZN I VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_1 ZN I VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1.spice b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1.spice new file mode 100644 index 00000000..53ce93de --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1.spice @@ -0,0 +1,47 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc {{volt}} +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) + +* Main circuit +X1 I1 I2 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__nand2_1 + +* Temperature set +.STEP TEMP {{temp}} -60 200 + +* Analyses +.tran 1p 800p +.meas tran o0 FIND V(ZN) AT=200p +.meas tran o1 FIND V(ZN) AT=400p +.meas tran o2 FIND V(ZN) AT=600p +.meas tran o3 FIND V(ZN) AT=800p +.print TRAN FORMAT=CSV file=nand2/simulated/nand2_{{process}}_{{temp}}c_{{volt}}v.csv o0 o1 o2 o3 + + +* Libraries calling +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" {{process}} + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__nand2_1 A1 A2 ZN VDD VNW VPW VSS +xM_i_1 net_0 A2 VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_0 ZN A1 net_0 VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_3 ZN A2 VDD VNW pmos_6p0 W=1.13e-06 L=5e-07 +xM_i_2 VDD A1 ZN VNW pmos_6p0 W=1.13e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1_run.spice b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1_run.spice new file mode 100644 index 00000000..6f7509cd --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__nand2_1_run.spice @@ -0,0 +1,48 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc 5 +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) + +* Main circuit +X1 I1 I2 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__nand2_1 + +* Temperature set +.temp 25 +.options tnom=25 + +* Analyses +.tran 1p 800p +.meas tran o0 FIND V(ZN) AT=200p +.meas tran o1 FIND V(ZN) AT=400p +.meas tran o2 FIND V(ZN) AT=600p +.meas tran o3 FIND V(ZN) AT=800p +.print TRAN FORMAT=CSV file=nand2_simulated.csv o0 o1 o2 o3 + + +* Libraries calling +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" typical + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__nand2_1 A1 A2 ZN VDD VNW VPW VSS +xM_i_1 net_0 A2 VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_0 ZN A1 net_0 VPW nmos_6p0 W=8.2e-07 L=6e-07 +xM_i_3 ZN A2 VDD VNW pmos_6p0 W=1.13e-06 L=5e-07 +xM_i_2 VDD A1 ZN VNW pmos_6p0 W=1.13e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1.spice b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1.spice new file mode 100644 index 00000000..01a75346 --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1.spice @@ -0,0 +1,56 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc {{volt}} +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) +Vin3 I3 0 dc pulse(0 5 800p 1p 1p 800p 1600p) + +* Main circuit +X1 I1 I2 I3 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__or3_1 + +* Temperature set +.STEP TEMP {{temp}} -60 200 + +* Analyses +.tran 1p 1600p +.meas tran o0 FIND V(ZN) AT=200p +.meas tran o1 FIND V(ZN) AT=400p +.meas tran o2 FIND V(ZN) AT=600p +.meas tran o3 FIND V(ZN) AT=800p +.meas tran o4 FIND V(ZN) AT=1000p +.meas tran o5 FIND V(ZN) AT=1200p +.meas tran o6 FIND V(ZN) AT=1400p +.meas tran o7 FIND V(ZN) AT=1600p +.print TRAN FORMAT=CSV file=or3/simulated/or3_{{process}}_{{temp}}c_{{volt}}v.csv o0 o1 o2 o3 o4 o5 o6 o7 + + +* Libraries calling +.include "../../../../../design.xyce" +.lib "../../../../../sm141064.xyce" {{process}} + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__or3_1 A1 A2 A3 Z VDD VNW VPW VSS +M_i_2 VSS A1 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_3 Z_neg A2 VSS VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_4 VSS A3 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_0 Z Z_neg VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +M_i_5 net_0 A1 Z_neg VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_6 net_1 A2 net_0 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_7 VDD A3 net_1 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_1 Z Z_neg VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1_run.spice b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1_run.spice new file mode 100644 index 00000000..bfa90e90 --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/device_netlists/gf180mcu_fd_sc_mcu7t5v0__or3_1_run.spice @@ -0,0 +1,59 @@ +* Copyright 2022 GlobalFoundries PDK Authors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. + +* Sources +Vdd VDD 0 dc 5 +Vin1 I1 0 dc pulse(0 5 200p 1p 1p 200p 400p) +Vin2 I2 0 dc pulse(0 5 400p 1p 1p 400p 800p) +Vin3 I3 0 dc pulse(0 5 800p 1p 1p 800p 1600p) + +* Main circuit +X1 I1 I2 I3 ZN VDD VDD 0 0 gf180mcu_fd_sc_mcu7t5v0__or3_1 + +* Temperature set +.temp 25 +.options tnom=25 + +* Analyses +.control +tran 1p 1600p +meas tran o0 FIND V(ZN) AT=200p +meas tran o1 FIND V(ZN) AT=400p +meas tran o2 FIND V(ZN) AT=600p +meas tran o3 FIND V(ZN) AT=800p +meas tran o4 FIND V(ZN) AT=1000p +meas tran o5 FIND V(ZN) AT=1200p +meas tran o6 FIND V(ZN) AT=1400p +meas tran o7 FIND V(ZN) AT=1600p + +wrdata or3/or3_simulated.csv {o0} {o1} {o2} {o3} {o4} {o5} {o6} {o7} +.endc + +* Libraries calling +.include "../../../../design.xyce" +.lib "../../../../sm141064.xyce" typical + +.SUBCKT gf180mcu_fd_sc_mcu7t5v0__or3_1 A1 A2 A3 Z VDD VNW VPW VSS +M_i_2 VSS A1 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_3 Z_neg A2 VSS VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_4 VSS A3 Z_neg VPW nmos_6p0 W=4e-07 L=6e-07 +M_i_0 Z Z_neg VSS VPW nmos_6p0 W=8.2e-07 L=6e-07 +M_i_5 net_0 A1 Z_neg VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_6 net_1 A2 net_0 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_7 VDD A3 net_1 VNW pmos_6p0 W=5.6e-07 L=5e-07 +M_i_1 Z Z_neg VDD VNW pmos_6p0 W=1.22e-06 L=5e-07 +.ENDS + + +.end diff --git a/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/models_regression.py b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/models_regression.py new file mode 100644 index 00000000..c61d72a4 --- /dev/null +++ b/models/xyce/testing/sc_regression/gf180mcu_fd_sc_mcu7t5v0/models_regression.py @@ -0,0 +1,140 @@ +""" +Usage: + models_regression.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +from cmath import inf +from re import L, T +from docopt import docopt +import pandas as pd +import numpy as np +import os +from jinja2 import Template +import concurrent.futures +import shutil +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def ext_measured(device, table): + + # Generate CSVs with truth tables + df = pd.DataFrame(data=table) + df.set_index(df.columns[0]) + new_header = df.iloc[0] + df = df[1:] + df.columns = new_header + df.to_csv(f"{device}/{device}_measured.csv", index = False) + +def ext_simulated(device, processes, volts, temps): + + # Get all corners simulated + for process in processes: + for volt in volts: + for temp in temps: + with open(f"device_netlists/gf180mcu_fd_sc_mcu7t5v0__{device}_1.spice") as f: + tmpl = Template(f.read()) + netlist_path = f"{device}/{device}_netlists/{device}_{process}_{temp}c_{volt}v.spice" + with open(netlist_path, "w") as netlist: + netlist.write(tmpl.render(process = process, volt = volt , temp = temp )) + + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + df_simulated = pd.read_csv(f"{device}/simulated/{device}_{process}_{temp}c_{volt}v.csv",header=0) + results = [] + for i, col in enumerate(df_simulated.columns): + if df_simulated.iloc[-1].iloc[i] > 2.5: + results.append(1) + else: + results.append(0) + df_measured = pd.read_csv(f"{device}/{device}_measured.csv",header=0) + df = df_measured + df_measured.drop(df_measured.columns[len(df_measured.columns)-1], axis=1, inplace=True) + df_measured['output'] = results[1:] + df_measured.to_csv(f"{device}/simulated/{device}_{process}_{temp}c_{volt}v.csv",index= False) + +def error_cal(device, processes, volts, temps): + + print (f"\n\nSimulation results of {device}") + measured = pd.read_csv(f"{device}/{device}_measured.csv") + for process in processes: + for volt in volts: + for temp in temps: + simulated = pd.read_csv(f"{device}/simulated/{device}_{process}_{temp}c_{volt}v.csv") + + res = (measured == simulated).all().all() + print ("{:^5s} in PVT of {:^7s}, {:^3s}V, {:^3s}C functional simulation = {}".format(device, process, volt, temp, res)) + print ("================================================================================================\n") + +def main(): + + devices = ["inv","nand2","or3"] + + # Generate truth tables data + inv_table = [["input","output"], + [0,1], + [1,0]] + + nand2_table = [["input1","input2","output"], + [0,0,1], + [0,1,1], + [1,0,1], + [1,1,0]] + + or3_table = [["input1","input2","input3","output"], + [0,0,0,0], + [0,0,1,1], + [0,1,0,1], + [0,1,1,1], + [1,0,0,1], + [1,0,1,1], + [1,1,0,1], + [1,1,1,1]] + + tables = [inv_table,nand2_table,or3_table] + + processes = ["typical","ff","ss"] + volts = ["5", "4.5", "5.5"] + temps = ["25", "-40", "125"] + + for i, device in enumerate(devices): + # Folder structure of measured values + if os.path.exists(device) and os.path.isdir(device): + shutil.rmtree(device) + os.makedirs(device) + + # Folder structure of simulated values + os.makedirs(f"{device}/{device}_netlists",exist_ok=True) + os.makedirs(f"{device}/simulated",exist_ok=True) + + ext_measured (device, tables[i]) + # =========== Simulate ============== + ext_simulated(device, processes, volts, temps) + + # ============ Results ============== + error_cal (device, processes, volts, temps) + +# ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='comparator: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main() diff --git a/models/xyce/testing/smoke_test/inv_xyce.spice b/models/xyce/testing/smoke_test/inv_xyce.spice new file mode 100644 index 00000000..ada6d540 --- /dev/null +++ b/models/xyce/testing/smoke_test/inv_xyce.spice @@ -0,0 +1,26 @@ +** INV_tb +Vdd Vdd 0 3.3 +Vin Vin 0 dc pulse(0 3.3 0 50p 50p 150p 300p) +X1 Vdd Vout Vin 0 INV + +.measure tran tphl TRIG v(Vin) VAL={0.5*3.3} RISE=2 TARG v(Vout) VAL={0.5*3.3} FALL=2 +.measure tran tplh TRIG v(Vin) VAL={0.5*3.3} FALL=1 TARG v(Vout) VAL={0.5*3.3} RISE=1 +.measure tran tpd param = {(tplh+tphl)/2} + +.STEP TEMP {{temp}} -60 200 +.tran 5p 800p +.print tran FORMAT=CSV file={{run_path}}/simulation/inv_W{{width}}_L{{length}}_T{{temp}}_{{corner}}.csv {tpd} + + +.include "../../design.xyce" +.lib "../../sm141064.xyce" {{corner}} + + +.subckt INV VDD Vout Vin GND +XM1 Vout Vin GND GND nmos_3p3 W={{width}}u L={{length}}u +*ad={{AD}}u pd={{PD}}u as={{AS}}u ps={{PS}}u +XM2 Vout Vin VDD VDD pmos_3p3 W={{width_p}}u L={{length}}u +*ad={{AD_p}}u pd={{PD_p}}u as={{AD_p}}u ps={{PD_p}}u +.ends + +.end diff --git a/models/xyce/testing/smoke_test/xyce_smoke_test.py b/models/xyce/testing/smoke_test/xyce_smoke_test.py new file mode 100644 index 00000000..129157f1 --- /dev/null +++ b/models/xyce/testing/smoke_test/xyce_smoke_test.py @@ -0,0 +1,102 @@ +""" +Usage: + smoke_test.py [--num_cores=] + + -h, --help Show help text. + -v, --version Show version. + --num_cores= Number of cores to be used by simulator +""" + +import re +from docopt import docopt +import pandas as pd +import os +from jinja2 import Template +import concurrent.futures +import datetime +import warnings +warnings.simplefilter(action='ignore', category=FutureWarning) + +def call_simulator(file_name): + """Call simulation commands to perform simulation. + Args: + file_name (str): Netlist file name. + """ + os.system(f"Xyce -hspice-ext all {file_name} -l {file_name}.log") + +def get_sizes(models_path): + sizes = [] + with open(models_path, "r") as f: + device_model = f.read() + # for j, corner in enumerate(corners): + for i in range(16): + data = device_model.split(f".MODEL nmos_3p3.{i} NMOS") + data = data[1].split("+ LEVEL=14") + dimensions = re.findall("LMAX=([0-9e.-]+)[\w+\s=.{}-]+LMIN=([0-9e.-]+)[\w+\s=.{}-]+WMAX=([0-9e.-]+)[\w+\s=.{}-]+WMIN=([0-9e.-]+)[\w+\s=.{}-]+", data[0]) + sizes.append(dimensions) + return sizes + +def get_results(run_path,sizes,temp,corner): + netlist_tmp = f"./inv_xyce.spice" + width = float(sizes[0][3]) * 1000000 + width_p = width * 1.5 + length = float(sizes[0][1]) * 1000000 + # AD = width * 0.24 + # AD_p = AD * 1.5 + # PD = 2 * (width + 0.24) + # PD_p = width + PD + # AS = AD + # PS = PD + with open(netlist_tmp) as f: + tmpl = Template(f.read()) + os.makedirs(f"{run_path}/netlists",exist_ok=True) + os.makedirs(f"{run_path}/simulation",exist_ok=True) + netlist_path = f"{run_path}/netlists/inv_W{width}_L{length}_T{temp}_{corner}.spice" + with open(netlist_path, "w") as netlist: + netlist.write(tmpl.render(corner = corner, width = width,length = length, temp = temp , run_path = run_path, width_p = width_p))#, AD = AD , PD = PD , AS = AS , PS = PS, AD_p = AD_p, PD_p = PD_p )) + # Running ngspice for each netlist + with concurrent.futures.ProcessPoolExecutor(max_workers=workers_count) as executor: + executor.submit(call_simulator, netlist_path) + + # Writing simulated data + df_simulated = pd.read_csv(f"{run_path}/simulation/inv_W{width}_L{length}_T{temp}_{corner}.csv",header=0) + return [f"W{width}_L{length}_T{temp}_{corner}",df_simulated["{TPD}"].iloc[-1]] + +def main(): + + models_path = "../../sm141064.xyce" + temps = ["25","-40","125"] + corners = ["typical","ff","ss","fs","sf"]#,"stat"] + + time = f"{datetime.datetime.now()}".replace(" ", "_") + run_path = f"../run_smoke_{time}" + os.makedirs(run_path,exist_ok=True) + + sizes = get_sizes(models_path) + results = [] + + for corner in corners: + for temp in temps: + for size in sizes: + results.append(get_results(run_path, size, temp, corner)) + + df_results = pd.DataFrame(results) + df_results.columns = ["run","tpd_result"] + df_results.to_csv(f"{run_path}/final_results.csv",index= False) + + print (df_results) + + + +# # ================================================================ +# -------------------------- MAIN -------------------------------- +# ================================================================ + +if __name__ == "__main__": + + # Args + arguments = docopt(__doc__, version='smoke_test: 0.1') + workers_count = os.cpu_count()*2 if arguments["--num_cores"] == None else int(arguments["--num_cores"]) + + # Calling main function + main()