# Worst case distance

from definitions import *
from pyopus.design.wcd import WorstCaseDistance
from pyopus.design.wc import WorstCase
# If MPI is imported an application not using MPI will behave correctly
# (i.e. only slot 0 will run the program) even when started with mpirun/mpiexec
from pyopus.parallel.mpi import MPI
from pyopus.parallel.cooperative import cOS


if __name__=='__main__':
	atDesign={
		# After yield targetting (beta=3)
		   'c_out':   6.5735996965011167e-13, 
		  'diff_l':   1.1277590722388212e-06, 
		  'diff_w':   7.4072078256213562e-06, 
		  'load_l':   3.0190507158551772e-06, 
		  'load_w':   7.1447511221840934e-06, 
		  'mirr_l':   3.0463894159204191e-07, 
		 'mirr_ld':   2.6572354878028799e-06, 
		  'mirr_w':   1.7060021214780366e-05, 
		 'mirr_wd':   4.1333975797905747e-06, 
		 'mirr_wo':   2.6823400824029106e-05, 
		   'out_l':   3.2878440134599452e-07, 
		   'out_w':   1.5489295777951712e-05, 
		   'r_out':   3.5673408168082747e+03, 
	}
	
	# Create corner with the Monte Carlo model
	corners={
		'mc': {
			'params': {}, 
			'modules': [ 'mc' ]
		}
	}
		
	# Worst case performances (skip area, phase slope)
	wcList=list(measures.keys())
	wcList.sort()
	wcList.remove('area')
	wcList.remove('ph_slope')
		
	# Prepare parallel environment
	cOS.setVM(MPI(mirrorMap={'*':'.'}))
	
	# 3-sigma worst case
	wc=WorstCaseDistance(
		heads, analyses, measures, corners, statParams, opParams, variables=variables, 
		fixedParams=atDesign, 
		stepTol=0.01,  # Try 0.0001
		sigmaBox=10, 
		debug=2, 
		spawnerLevel=0
	)
		
	wcresults, analysisCount = wc(wcList)
	# wcresults, analysisCount = wc(['vgs_drv'])
	# wcresults, analysisCount = wc(['cmrr', 'vgs_drv'])
	# wcresults, analysisCount = wc(['cmrr'])
	# wcresults, analysisCount = wc(['ugbw'])
	# wcresults, analysisCount = wc(['vgs_drv'])
	
	print(wc.formatResults())
	print(wc.analysisCount)
	
	# Finalize cOS parallel environment
	cOS.finalize()

# Result of yield targeting (WCD)
#       cmrr >     6.00000e+01 wc=    6.23915e+01 wcd=    2.44084e+01 neval= 272 2 OUTSIDE+
#       gain >     6.00000e+01 wc=    6.00034e+01 wcd=    1.17317e+01 neval= 284 2 OK
#       isup <     1.00000e-03 wc=    4.25950e-04 wcd=    1.99039e+01 neval= 316 1 SENS+
#     out_op >    -1.25000e-02 wc=   -1.25180e-02 wcd=    3.39775e+00 neval= 443 1 OK
#     out_op <     1.25000e-02 wc=    1.25005e-02 wcd=    3.33059e+00 neval= 116 1 OK
#   overshdn <     1.50000e-01 wc=    1.51615e-01 wcd=    7.38257e+00 neval= 584 1 OK
#   overshup <     1.50000e-01 wc=    1.50019e-01 wcd=    8.94535e+00 neval= 152 1 OK
#         pm >     5.00000e+01 wc=    6.64726e+01 wcd=    1.02878e+01 neval= 139 1 SENS+
#   psrr_vdd >     6.00000e+01 wc=    6.03129e+01 wcd=    9.35088e+00 neval=2107 2 OK
#   psrr_vss >     6.00000e+01 wc=    6.00398e+01 wcd=    1.96043e+01 neval= 420 4 OK
#     slewdn >     2.00000e+06 wc=    4.58236e+06 wcd=    2.71205e+01 neval= 308 2 OUTSIDE+
#     slewup >     2.00000e+06 wc=    3.15462e+06 wcd=    2.00008e+01 neval= 175 1 OUTSIDE+
#      swing >     1.00000e+00 wc=    9.99271e-01 wcd=    9.98178e+00 neval= 653 2 OK
#     tsetdn <     1.00000e-06 wc=    1.02755e-06 wcd=    1.25730e+01 neval=2448 10 OK
#     tsetup <     1.00000e-06 wc=    3.43833e-07 wcd=    1.91472e+01 neval= 154 1 SENS+
#       ugbw >     1.00000e+07 wc=    1.00066e+07 wcd=    6.24011e+00 neval= 126 1 OK
# vds_drv[0] >     0.00000e+00 wc=   -2.19260e-05 wcd=    1.23377e+01 neval= 208 2 OK
# vds_drv[1] >     0.00000e+00 wc=   -7.64982e-04 wcd=    1.24316e+01 neval= 129 1 OK
# vds_drv[2] >     0.00000e+00 wc=    1.77735e-01 wcd=    1.00000e+01 neval= 130 1 OUTSIDE+
# vds_drv[3] >     0.00000e+00 wc=   -4.67636e-04 wcd=    5.69778e+00 neval= 150 1 OK
# vds_drv[4] >     0.00000e+00 wc=    6.25163e-01 wcd=    2.65622e+01 neval= 358 2 SENS+
# vds_drv[5] >     0.00000e+00 wc=    8.91396e-02 wcd=    1.41421e+01 neval= 123 1 OUTSIDE+
# vds_drv[6] >     0.00000e+00 wc=    1.20306e-01 wcd=    1.00000e+01 neval= 116 1 OUTSIDE+
# vds_drv[7] >     0.00000e+00 wc=    3.47905e-01 wcd=    2.67554e+01 neval= 311 1 SENS+
# vgs_drv[0] >     0.00000e+00 wc=    3.65129e-06 wcd=    7.09486e+00 neval= 462 2 OK
# vgs_drv[1] >     0.00000e+00 wc=   -2.23177e-06 wcd=    8.23480e+00 neval= 224 2 OK
# vgs_drv[2] >     0.00000e+00 wc=    3.86036e-02 wcd=    1.48534e+01 neval= 154 1 OUTSIDE+
# vgs_drv[3] >     0.00000e+00 wc=    1.14988e-01 wcd=    1.81999e+01 neval= 212 1 SENS+
# vgs_drv[4] >     0.00000e+00 wc=    1.42463e-02 wcd=    1.75043e+01 neval= 238 1 OUTSIDE+
# vgs_drv[5] >     0.00000e+00 wc=    1.15476e-01 wcd=    2.23607e+01 neval= 171 1 OUTSIDE+
# vgs_drv[6] >     0.00000e+00 wc=    1.15457e-01 wcd=    2.23607e+01 neval= 202 1 OUTSIDE+
# vgs_drv[7] >     0.00000e+00 wc=    1.07848e-01 wcd=    1.79096e+01 neval= 222 1 OUTSIDE+
