# Test SpiceOpus simulator interface

from pyopus.simulator import simulatorClass

if __name__=='__main__':
	# Job list for simulator
	jobList=[
		{	# First job - op analysis
			'name': 'dcop', 
			'definitions': [
				{ 'file': 'cmos180n.lib', 'section': 'tm' }, 
				{ 'file': 'opamp.cir' }
			], 
			'params': {
				'vdd': 1.8, 
				'temperature': 25
			}, 
			'options': {
				'timeint method': 'trap'
			}, 
			'saves': [
			], 
			'command': 'op()'
		},
		{	# Second job - op analysis with different temperature
			'name': 'dcop100', 
			'definitions': [
				{ 'file': 'cmos180n.lib', 'section': 'tm' }, 
				{ 'file': 'opamp.cir' }
			], 
			'params': {
				'vdd': 1.6, 
				'temperature': 100
			}, 
			'options': {
				'timeint method': 'trap'
			}, 
			'saves': [
			], 
			'command': 'op()'
		},
		{	# Third job - op analysis with different supply voltage
			'name': 'dcopv33', 
			'definitions': [
				{ 'file': 'cmos180n.lib', 'section': 'tm' }, 
				{ 'file': 'opamp.cir' }
			], 
			'params': {
				'vdd': 2.0, 
				'temperature': 25
			}, 
			'options': {
				'timeint method': 'trap'
			}, 
			'saves': [
			], 
			'command': 'op()'
		},
		{	# Fourth job - op analysis with different library
			'name': 'dcopff', 
			'definitions': [
				{ 'file': 'cmos180n.lib', 'section': 'ws' }, 
				{ 'file': 'opamp.cir' }
			], 
			'params': {
				'vdd': 2.0, 
				'temperature': 25
			}, 
			'options': {
				'timeint method': 'trap'
			}, 
			'saves': [
			], 
			'command': 'op()'
		}, 
		{	# Fifth job - op analysis with different library
			'name': 'dcopff100', 
			'definitions': [
				{ 'file': 'cmos180n.lib', 'section': 'ws' }, 
				{ 'file': 'opamp.cir' }
			], 
			'params': {
				'vdd': 2.0, 
				'temperature': 100
			}, 
			'options': {
				'timeint method': 'trap'
			}, 
			'saves': [
				"all()", 
				"i('vdd')", 
				"p('X1:XMN4:M0', 'VGS')"
			], 
			'command': 'op()'
		},
		# {	# Sixth job - noise analysis
		# 	'name': 'noise', 
		# 	'definitions': [
		# 		{ 'file': 'cmos180n.lib', 'section': 'tm' }, 
		# 		{ 'file': 'opamp.cir' }
		# 	], 
		# 	'params': {
		# 		'vdd': 2.0, 
		# 		'temperature': 100
		# 	}, 
		# 	'options': {
		# 		# Xyce complains about this option if noise analysis is run
		# 		# 'timeint method': 'trap'
		# 	}, 
		# 	'saves': [
		# 		'save_ns("x1:xmn2:m0", "id")', 
		# 		'save_ns("x1:xmn3:m0")'
		# 	], 
		# 	'command': 'noise(1, 1e6, "dec", 10, "vin", "out")'
		# }
	]

	# Input parameters
	inParams={
		'mirr_w': 7.46e-005, 
		'mirr_l': 5.63e-007
	}

	# Create simulator
	sim=simulatorClass("Xyce")(debug=10)

	# Set job list and optimize it
	sim.setJobList(jobList)

	# Print optimized job groups 
	ngroups=sim.jobGroupCount()
	print("\nJob Groups:")
	for i in range(ngroups):
		group=sim.jobGroup(i)
		gstr=''
		for j in group:
			gstr+=" %d (%s), " % (j, jobList[j]['name'])
		print("  %d: %s" % (i, gstr))

	print("")
	# Set input parameters
	sim.setInputParameters(inParams)
	
	# Go through all job groups, write file, run it and collect results
	for i in range(ngroups):
		# Run jobs in job group. 
		(jobIndices, status)=sim.runJobGroup(i)
		
		print("")
		for j in jobIndices:
			# Job name
			jobName=jobList[j]['name']
			# Load results
			res=sim.readResults(j, status)
			# Print results
			if res is not None:
				if i<5:
					print("Job %d (%s): Vout=%e" % (j, jobName, res.v("out")))
				else:
					print("Job %d (%s): Inoise=%s" % (j, jobName, str(res.ns("input"))))
					print("Job %d (%s): Onoise_mn2_id=%s" % (j, jobName, str(res.ns("output", "x1:xmn2:m0", "id"))))
					print("Job %d (%s): Onoise_mn3   =%s" % (j, jobName, str(res.ns("output", "x1:xmn3:m0"))))
			else:
				print("Job %d (%s): no results" % (j, jobName))
		print("")

	sim.cleanup()
	