summaryrefslogtreecommitdiff
path: root/src/kicadtoNgspice/Processing.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/kicadtoNgspice/Processing.py')
-rw-r--r--src/kicadtoNgspice/Processing.py380
1 files changed, 380 insertions, 0 deletions
diff --git a/src/kicadtoNgspice/Processing.py b/src/kicadtoNgspice/Processing.py
new file mode 100644
index 00000000..09544f19
--- /dev/null
+++ b/src/kicadtoNgspice/Processing.py
@@ -0,0 +1,380 @@
+import sys
+import os
+from xml.etree import ElementTree as ET
+
+
+
+class PrcocessNetlist:
+ """
+ This class include all the function required for pre-proccessing of netlist
+ before converting to Ngspice Netlist.
+ """
+ modelxmlDIR = '../modelParamXML'
+ def __init__(self):
+ pass
+
+ def readNetlist(self,filename):
+ f = open(filename)
+ data=f.read()
+ f.close()
+ return data.splitlines()
+
+ def readParamInfo(self,kicadNetlis):
+ """Read Parameter information and store it into dictionary"""
+ param={}
+ for eachline in kicadNetlis:
+ print eachline
+ eachline=eachline.strip()
+ if len(eachline)>1:
+ words=eachline.split()
+ option=words[0].lower()
+ if option=='.param':
+ for i in range(1, len(words), 1):
+ paramList=words[i].split('=')
+ param[paramList[0]]=paramList[1]
+ return param
+
+ def preprocessNetlist(self,kicadNetlis,param):
+ """Preprocess netlist (replace parameters)"""
+ netlist=[]
+ for eachline in kicadNetlis:
+ # Remove leading and trailing blanks spaces from line
+ eachline=eachline.strip()
+ # Remove special character $
+ eachline=eachline.replace('$','')
+ # Replace parameter with values
+ for subParam in eachline.split():
+ if '}' in subParam:
+ key=subParam.split()[0]
+ key=key.strip('{')
+ key=key.strip('}')
+ if key in param:
+ eachline=eachline.replace('{'+key+'}',param[key])
+ else:
+ print "Parameter " + key +" does not exists"
+ value=raw_input('Enter parameter value: ')
+ eachline=eachline.replace('{'+key+'}',value)
+ #Convert netlist into lower case letter
+ eachline=eachline.lower()
+ # Construct netlist
+ if len(eachline)>1:
+ if eachline[0]=='+':
+ netlist.append(netlist.pop()+eachline.replace('+',' '))
+ else:
+ netlist.append(eachline)
+ #Copy information line
+ infoline=netlist[0]
+ netlist.remove(netlist[0])
+ return netlist,infoline
+
+ def separateNetlistInfo(self,netlist):
+ optionInfo=[]
+ schematicInfo=[]
+ for eachline in netlist:
+ if eachline[0]=='*':
+ continue
+ elif eachline[0]=='.':
+ optionInfo.append(eachline)
+ else:
+ schematicInfo.append(eachline)
+ return optionInfo,schematicInfo
+
+
+ def insertSpecialSourceParam(self,schematicInfo,sourcelist):
+ #Inser Special source parameter
+ schematicInfo1=[]
+
+ print "Reading schematic info for source details"
+
+ for compline in schematicInfo:
+ words=compline.split()
+ compName=words[0]
+ # Ask for parameters of source
+ if compName[0]=='v' or compName[0]=='i':
+ # Find the index component from circuit
+ index=schematicInfo.index(compline)
+ if words[3]=="pulse":
+ Title="Add parameters for pulse source "+compName
+ v1=' Enter initial value(Volts/Amps): '
+ v2=' Enter pulsed value(Volts/Amps): '
+ td=' Enter delay time (seconds): '
+ tr=' Enter rise time (seconds): '
+ tf=' Enter fall time (seconds): '
+ pw=' Enter pulse width (seconds): '
+ tp=' Enter period (seconds): '
+ sourcelist.append([index,compline,words[3],Title,v1,v2,td,tr,tf,pw,tp])
+
+ elif words[3]=="sine":
+ Title="Add parameters for sine source "+compName
+ vo=' Enter offset value (Volts/Amps): '
+ va=' Enter amplitude (Volts/Amps): '
+ freq=' Enter frequency (Hz): '
+ td=' Enter delay time (seconds): '
+ theta=' Enter damping factor (1/seconds): '
+ sourcelist.append([index,compline,words[3],Title,vo,va,freq,td,theta])
+
+ elif words[3]=="pwl":
+ Title="Add parameters for pwl source "+compName
+ t_v=' Enter in pwl format without bracket i.e t1 v1 t2 v2.... '
+ sourcelist.append([index,compline,words[3],Title,t_v])
+
+ elif words[3]=="ac":
+ Title="Add parameters for ac source "+compName
+ v_a=' Enter amplitude (Volts/Amps): '
+ p_a =' Enter Phase Shift: '
+ sourcelist.append([index,compline,words[3],Title,v_a,p_a])
+
+ elif words[3]=="exp":
+ Title="Add parameters for exponential source "+compName
+ v1=' Enter initial value(Volts/Amps): '
+ v2=' Enter pulsed value(Volts/Amps): '
+ td1=' Enter rise delay time (seconds): '
+ tau1=' Enter rise time constant (seconds): '
+ td2=' Enter fall time (seconds): '
+ tau2=' Enter fall time constant (seconds): '
+ sourcelist.append([index,compline,words[3],Title,v1,v2,td1,tau1,td2,tau2])
+
+ elif words[3]=="dc":
+ Title="Add parameters for DC source "+compName
+ v1=' Enter value(Volts/Amps): '
+ v2=' Enter zero frequency: '
+ sourcelist.append([index,compline,words[3],Title,v1,v2])
+
+ elif compName[0]=='h' or compName[0]=='f':
+ # Find the index component from the circuit
+ index=schematicInfo.index(compline)
+ schematicInfo.remove(compline)
+ schematicInfo.insert(index,"* "+compName)
+ schematicInfo1.append("V"+compName+" "+words[3]+" "+words[4]+" 0")
+ schematicInfo1.append(compName+" "+words[1]+" "+words[2]+" "+"V"+compName+" "+words[5])
+
+ schematicInfo=schematicInfo+schematicInfo1
+ print "Source List : ",sourcelist
+ #print schematicInfo
+ return schematicInfo,sourcelist
+
+
+ def convertICintoBasicBlocks(self,schematicInfo,outputOption,modelList,plotText):
+ print "Reading Schematic info for Model"
+ #Insert details of Ngspice model
+ unknownModelList = []
+ multipleModelList = []
+ plotList = ['plot_v1','plot_v2','plot_i2','plot_log','plot_db','plot_phase']
+ interMediateNodeCount=1
+ k = 1
+ for compline in schematicInfo:
+ words = compline.split()
+ compName = words[0]
+ #print "Compline----------------->",compline
+ #print "compName-------------->",compName
+ # Find the IC from schematic
+ if compName[0]=='u' or compName[0] == 'U':
+ # Find the component from the circuit
+ index=schematicInfo.index(compline)
+ compType=words[len(words)-1];
+ schematicInfo.remove(compline)
+ paramDict = {}
+ #e.g compLine : u1 1 2 gain
+ #compType : gain
+ #compName : u1
+ #print "Compline",compline
+ #print "CompType",compType
+ #print "Words",words
+ #print "compName",compName
+ #Looking if model file is present
+ if compType != "port" and compType != "ic" and compType not in plotList and compType != 'transfo':
+ xmlfile = compType+".xml" #XML Model File
+ count = 0 #Check if model of same name is present
+ modelPath = []
+ all_dir = [x[0] for x in os.walk(PrcocessNetlist.modelxmlDIR)]
+ for each_dir in all_dir:
+ all_file = os.listdir(each_dir)
+ if xmlfile in all_file:
+ count += 1
+ modelPath.append(os.path.join(each_dir,xmlfile))
+
+ if count > 1:
+ multipleModelList.append(modelPath)
+ elif count == 0:
+ unknownModelList.append(compType)
+ elif count == 1:
+ try:
+ print "Start Parsing Previous Values XML for ngspice model :",modelPath
+ tree = ET.parse(modelPath[0])
+
+ root = tree.getroot()
+ #Getting number of nodes for model and title
+ for child in tree.iter():
+ if child.tag == 'node_number':
+ num_of_nodes = int(child.text)
+ elif child.tag == 'title':
+ title = child.text+" "+compName
+ elif child.tag == 'name':
+ modelname = child.text
+ elif child.tag == 'type':
+ #Checking for Analog and Digital
+ type = child.text
+ elif child.tag == 'split':
+ splitDetail = child.text
+
+
+ for param in tree.findall('param'):
+ for item in param:
+ #print "Tags ",item.tag
+ #print "Value",item.text
+ if 'vector'in item.attrib:
+ #print "Tag having vector attribute",item.tag,item.attrib['vector']
+ temp_count = 1
+ temp_list = []
+ for i in range(0,int(item.attrib['vector'])):
+ temp_list.append(item.text+" "+str(temp_count))
+ temp_count += 1
+ if 'default' in item.attrib:
+ paramDict[item.tag+":"+item.attrib['default']] = temp_list
+ else:
+ paramDict[item.tag] = item.text
+
+ else:
+ if 'default' in item.attrib:
+ paramDict[item.tag+":"+item.attrib['default']] = item.text
+ else:
+ paramDict[item.tag] = item.text
+
+
+ #print "Number of Nodes : ",num_of_nodes
+ #print "Title : ",title
+ #print "Parameters",paramDict
+ #Creating line for adding model line in schematic
+ if splitDetail == 'None':
+ modelLine = "a"+str(k)+" "
+ for i in range(1,num_of_nodes+1):
+ modelLine += words[i]+" "
+ modelLine += compName
+
+ else:
+ print "Split Details :",splitDetail
+ modelLine = "a"+str(k)+" "
+ vectorDetail = splitDetail.split(':')
+ #print "Vector Details",vectorDetail
+ pos = 1 #Node position
+ for item in vectorDetail:
+ try:
+ if item.split("-")[1] == 'V':
+ #print "Vector"
+ if compType == "aswitch":
+ modelLine += "("
+ for i in range(0,int(item.split("-")[0])):
+ modelLine += words[pos]+" "
+ pos += 1
+ modelLine += ") "
+ else:
+ modelLine += "["
+ for i in range(0,int(item.split("-")[0])):
+ modelLine += words[pos]+" "
+ pos += 1
+ modelLine += "] "
+ elif item.split("-")[1] == 'NV':
+ #print "Non Vector"
+ for i in range(0,int(item.split("-")[0])):
+ modelLine += words[pos]+" "
+ pos += 1
+
+ except:
+ print "There is error while processing Vector Details"
+ sys.exit(2)
+ modelLine += compName
+
+ #print "Final Model Line :",modelLine
+ try:
+ schematicInfo.append(modelLine)
+ k=k+1
+ except Exception as e:
+ print "Error while appending ModelLine ",modelLine
+ print "Exception Message : ",str(e)
+ #Insert comment at remove line
+ schematicInfo.insert(index,"* "+compline)
+ comment = "* Schematic Name: "+compType+", NgSpice Name: "+modelname
+ #Here instead of adding compType(use for XML), added modelName(Unique Model Name)
+ modelList.append([index,compline,modelname,compName,comment,title,type,paramDict])
+ except Exception as e:
+ print "Unable to parse the model, Please check your your XML file"
+ print "Exception Message : ",str(e)
+ sys.exit(2)
+ elif compType == "ic":
+ schematicInfo.insert(index,"* "+compline)
+ modelname = "ic"
+ comment = "* "+compline
+ title = "Initial Condition for "+compName
+ type = "NA" #Its is not model
+ text = "Enter initial voltage at node for "+compline
+ paramDict[title] = text
+ modelList.append([index,compline,modelname,compName,comment,title,type,paramDict])
+
+ elif compType in plotList:
+ schematicInfo.insert(index,"* "+compline)
+ if compType == 'plot_v1':
+ words = compline.split()
+ plotText.append("plot v("+words[1]+")")
+ elif compType == 'plot_v2':
+ words = compline.split()
+ plotText.append("plot v("+words[1]+","+words[2]+")")
+ elif compType == 'plot_i2':
+ words = compline.split()
+ #Adding zero voltage source to netlist
+ schematicInfo.append("v_"+words[0]+" "+words[1]+" "+words[2]+" "+"0")
+ plotText.append("plot i(v_"+words[0]+")")
+ elif compType == 'plot_log':
+ words = compline.split()
+ plotText.append("plot log("+words[1]+")")
+ elif compType == 'plot_db':
+ words = compline.split()
+ plotText.append("plot db("+words[1]+")")
+ elif compType == 'plot_phase':
+ words = compline.split()
+ plotText.append("plot phase("+words[1]+")")
+
+ elif compType == 'transfo':
+ schematicInfo.insert(index,"* "+compline)
+
+ #For Primary Couple
+ modelLine = "a"+str(k)+" ("+words[1]+" "+words[2]+") (interNode_"+str(interMediateNodeCount)+" "+words[3]+") "
+ modelLine += compName+"_primary"
+ schematicInfo.append(modelLine)
+ k=k+1
+ #For iron core
+ modelLine = "a"+str(k)+" ("+words[4]+" "+words[2]+") (interNode_"+str(interMediateNodeCount+1)+" "+words[3]+") "
+ modelLine += compName+"_secondary"
+ schematicInfo.append(modelLine)
+ k=k+1
+ #For Secondary Couple
+ modelLine = "a"+str(k)+" (interNode_"+str(interMediateNodeCount)+" interNode_"+str(interMediateNodeCount+1)+") "
+ modelLine += compName+"_iron_core"
+ schematicInfo.append(modelLine)
+ k=k+1
+ interMediateNodeCount += 2
+
+ modelname = "transfo"
+ comment = "* "+compline
+ title = "Transformer details for model "+compName
+ type = "NA" #It is model but do not load from xml and lib file
+ paramDict['h1_array'] = "Enter the H1 array "
+ paramDict['primary_turns'] = "Enter the primary number of turns (default=310) "
+ paramDict['area'] = "Enter iron core area (default=1)"
+ paramDict['secondar_turns'] = "Enter the secondary number of turns (default=620)"
+ paramDict['length'] = "Enter iron core length (default=0.01)"
+ paramDict['b1_array'] = "Enter the B1 array "
+
+
+ modelList.append([index,compline,modelname,compName,comment,title,type,paramDict])
+
+ else:
+ schematicInfo.insert(index,"* "+compline)
+
+ print "UnknownModelList Used in the Schematic",unknownModelList
+ print "Multiple Model XML file with same name ",multipleModelList
+ print "Model List Details : ",modelList
+
+ return schematicInfo,outputOption,modelList,unknownModelList,multipleModelList,plotText
+
+
+