diff options
Diffstat (limited to 'src/kicadtoNgspice/Processing.py')
-rw-r--r-- | src/kicadtoNgspice/Processing.py | 380 |
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 + + + |