# Monte Carlo verification of yiled

from definitions import *
from pyopus.design.mc import MonteCarlo
from pyopus.design.wc import WorstCase
from pyopus.design.wcd import WorstCaseDistance
from pyopus.evaluator.aggregate import formatParameters
# 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
import sys

# Script arguments 
#   noop computes worst case without operating parameters (assumed initial values)

if __name__=='__main__':
	# Result of yield targeting
	atDesign={
          'dif_l':   7.3260453848463576e-07, 
          'dif_w':   1.3863821509845126e-06, 
           'nl_l':   3.1386361319062818e-06, 
           'nl_w':   2.0147251746630238e-05, 
           'nm_l':   1.8646549831707370e-06, 
           'nm_w':   5.5888605078242105e-06, 
           'pm_l':   1.4522611304179238e-06, 
          'pm_w0':   9.4099048410979254e-05, 
          'pm_w1':   7.3694915424909627e-06, 
          'pm_w2':   1.3390757744322914e-05, 
          'pm_w3':   2.5584875980104416e-06, 
	}
	
	# Set up a corner
	corners={
		'mc': {
			'params': {}, 
			'modules': [ 'wcd' ]
		},
	}
	
	# Worst case performances (skip area, transistor op conditions, and auxiliary measures)
	wcList=list(measures.keys())
	wcList.sort()
	wcList.remove('area')
	wcList.remove('vgs_drv')
	wcList.remove('vds_drv')
	wcList.remove('gain_com')
	wcList.remove('gain_vdd')
	wcList.remove('gain_vss')
	
	# Prepare parallel environment
	cOS.setVM(MPI(mirrorMap={'*':'.'}))
	
	if len(sys.argv)>1 and sys.argv[1]=="noop":
		# No operating parameters
		corners['mc']['params'].update({
			name: v['init'] for name, v in opParams.items()
		})
		opParams = {}
	
	# Verify yield with Monte-Carlo 
	mc=MonteCarlo(
		heads, analyses, measures, corners, 
		statParams, opParams, atDesign, 
		variables=variables, debug=2, 
		wcOptions={ 'debug': 0 }, 
		nSamples=10000, 
		spawnerLevel=2
	)
	results, anCount = mc(wcList)
	print(mc.formatResults())
	print(anCount)
	
	# Verify yield with worst case distances
	# wcd=WorstCaseDistance(
	# 	heads, analyses, measures, statParams, opParams, variables=variables, 
	# 	fixedParams=atDesign, 
	# 	debug=1, 
	# 	spawnerLevel=1
	# )
	# res, anCount = wcd(wcList)
	# print wcd.formatResults()
	# print anCount
	
	# Verify yield with worst case analysis
	#wc=WorstCase(
	#	heads, analyses, measures, statParams, opParams, variables=variables, 
	#	fixedParams=atDesign, beta=3.0, 
	#	debug=1, 
	#	spawnerLevel=1
	#)
	#res, anCount = wc(wcList)
	#print wc.formatResults()
	#print anCount
	
	# Finalize cOS parallel environment
	cOS.finalize()
	