diff options
-rwxr-xr-x | src/kicadtoNgspice/Convert.py | 11 | ||||
-rwxr-xr-x | src/kicadtoNgspice/DeviceModel.py | 282 |
2 files changed, 157 insertions, 136 deletions
diff --git a/src/kicadtoNgspice/Convert.py b/src/kicadtoNgspice/Convert.py index 31d48f8b..9aec6cce 100755 --- a/src/kicadtoNgspice/Convert.py +++ b/src/kicadtoNgspice/Convert.py @@ -525,7 +525,7 @@ class Convert: # print("Library Path :", libpath) # Copying library from devicemodelLibrary to Project Path # Special case for MOSFET - print(eachline[0:5] ) + print(eachline[0:5]) if eachline[0] == 'm': # For mosfet library name come along with MOSFET # dimension information @@ -552,13 +552,14 @@ class Convert: elif eachline[0:6] == 'scmode': tempStr = completeLibPath.split(':') print(tempStr) - includeLine.append(".lib \"" + tempStr[0] + "\" " + tempStr[1]) + includeLine.append( + ".lib \"" + tempStr[0] + "\" " + tempStr[1]) deviceLine[index] = '' - #words.append(completeLibPath) - #deviceLine[index] = words + # words.append(completeLibPath) + # deviceLine[index] = words elif eachline[0:2] == 'sc' and eachline[0:6] != 'scmode': - temp_str = words[0].replace('sc','xsc') + temp_str = words[0].replace('sc', 'xsc') words[0] = temp_str words.append(completeLibPath) deviceLine[index] = words diff --git a/src/kicadtoNgspice/DeviceModel.py b/src/kicadtoNgspice/DeviceModel.py index dd3c27af..550f9d3c 100755 --- a/src/kicadtoNgspice/DeviceModel.py +++ b/src/kicadtoNgspice/DeviceModel.py @@ -1,9 +1,12 @@ -from PyQt5 import QtWidgets, QtCore +from PyQt5 import QtWidgets, QtCore from PyQt5.QtCore import QThread, Qt -import os, wget, zipfile +import os +import wget +import zipfile from xml.etree import ElementTree as ET from . import TrackWidget -flag=0 +flag = 0 + class DeviceModel(QtWidgets.QWidget): """ @@ -68,7 +71,7 @@ class DeviceModel(QtWidgets.QWidget): # print("Reading Device model details from Schematic") if "sky130" in " ".join(schematicInfo): self.eSim_sky130(schematicInfo) - else: + else: self.eSim_general_libs(schematicInfo) def eSim_sky130(self, schematicInfo): @@ -102,7 +105,7 @@ For more info please see the documentation''') self.grid.addWidget(sky130box) sky130box = QtWidgets.QGroupBox() sky130grid = QtWidgets.QGridLayout() - self.count=self.count+1 + self.count = self.count+1 self.row = self.row + 1 self.devicemodel_dict_beg["scmode1"] = self.count i = self.count @@ -110,9 +113,9 @@ For more info please see the documentation''') self.deviceDetail[self.count] = "scmode1" sky130box.setTitle( "Add parameters of sky130 library ") - # + - #" : " + - #words[6]) + # + + # " : " + + # words[6]) self.parameterLabel[self.count] = QtWidgets.QLabel( "Enter the path ") self.row = self.row + 1 @@ -121,7 +124,7 @@ For more info please see the documentation''') init_path = '../../' if os.name == 'nt': init_path = '' - + for child in self.root: if child.tag == "scmode1": if child[0].text \ @@ -130,16 +133,18 @@ For more info please see the documentation''') .setText(child[0].text) path_name = child[0].text else: - path_name = os.path.abspath(init_path + "library/deviceModelLibrary/sky130_fd_pr/models/sky130.lib.spice") + path_name = os.path.abspath( + init_path + "library/deviceModelLibrary/\ +sky130_fd_pr/models/sky130.lib.spice") self.entry_var[self.count].setText(path_name) - #self.trackLibraryWithoutButton(self.count, path_name) + # self.trackLibraryWithoutButton(self.count, path_name) sky130grid.addWidget(self.entry_var[self.count], self.row, 1) self.addbtn = QtWidgets.QPushButton("Add") self.addbtn.setObjectName("%d" % beg) self.addbtn.clicked.connect(self.trackLibrary) sky130grid.addWidget(self.addbtn, self.row, 2) - #self.count = self.count + 1 + # self.count = self.count + 1 self.adddefaultbtn = QtWidgets.QPushButton("Add Default") self.adddefaultbtn.setObjectName("%d" % beg) self.adddefaultbtn.clicked.connect(self.trackDefaultLib) @@ -155,13 +160,12 @@ For more info please see the documentation''') self.entry_var[self.count].setObjectName("%d" % beg) for child in self.root: if child.tag == "scmode1": - if child[1].text : + if child[1].text: self.entry_var[self.count] \ .setText(child[1].text) else: self.entry_var[self.count].setText("") - sky130grid.addWidget(self.entry_var[self.count], self.row, 1) self.entry_var[self.count].textChanged.connect(self.textChange) self.trackLibraryWithoutButton(beg, path_name) @@ -174,12 +178,10 @@ For more info please see the documentation''') 10px; padding: 0 3px 0 3px; } \ ") self.grid.addWidget(sky130box) - #if self.entry_var[self.count-3].text() == "": + # if self.entry_var[self.count-3].text() == "": # pass - #else: - # self.trackLibraryWithoutButton(self.count-3, path_name) - - + # else: + # self.trackLibraryWithoutButton(self.count-3, path_name) self.row = self.row + 1 self.devicemodel_dict_end["scmode1"] = self.count @@ -190,20 +192,24 @@ For more info please see the documentation''') print(eachline) words = eachline.split() # supporteddesignator = ['sc', 'u', 'x', 'v', 'i', 'a'] - if eachline[0:2] != 'sc' and eachline[0] != 'u' and eachline[0] != 'x' and eachline[0] != '*'\ - and eachline[0] != 'v' and eachline[0] != 'i' and eachline[0] != 'a': - print("Only components with designators 'sc', 'u', 'x', 'v', 'i', 'a'\ + if eachline[0:2] != 'sc' and eachline[0] != 'u' \ + and eachline[0] != 'x' and eachline[0] != '*'\ + and eachline[0] != 'v' and eachline[0] != 'i'\ + and eachline[0] != 'a': + print("Only components with designators 'sc', 'u', 'x', 'v', 'i', 'a'\ can be used with sky130 mode") - print("Please remove other components") - self.msg = QtWidgets.QErrorMessage() - self.msg.setModal(True) - self.msg.setWindowTitle("Invalid components") - self.content = "Only components with designators " + \ - "'sc', 'u' and 'x' can be used with sky130 mode. "+ \ - "Please edit the schematic and generate netlist again" - self.msg.showMessage(self.content) - self.msg.exec_() - return + print("Please remove other components") + self.msg = QtWidgets.QErrorMessage() + self.msg.setModal(True) + self.msg.setWindowTitle("Invalid components") + self.content = "Only components with designators " + \ + "'sc', 'u' and 'x' can be used \ + with sky130 mode. " + \ + "Please edit the schematic and \ + generate netlist again" + self.msg.showMessage(self.content) + self.msg.exec_() + return elif eachline[0:2] == 'sc' and eachline[0:6] != 'scmode': self.devicemodel_dict_beg[words[0]] = self.count @@ -218,8 +224,9 @@ For more info please see the documentation''') # Adding to get sky130 dimension self.parameterLabel[self.count] = QtWidgets.QLabel( - "Enter the parameters of sky130 component " + words[0] ) - sky130grid.addWidget(self.parameterLabel[self.count], self.row, 0) + "Enter the parameters of sky130 component " + words[0]) + sky130grid.addWidget( + self.parameterLabel[self.count], self.row, 0) self.entry_var[self.count] = QtWidgets.QLineEdit() self.entry_var[self.count].setText("") self.entry_var[self.count].setMaximumWidth(1000) @@ -239,13 +246,13 @@ For more info please see the documentation''') # print("DEVICE MODEL MATCHING---", \ # child.tag, words[0]) try: - if child[0].text : + if child[0].text: self.entry_var[self.count] \ .setText(child[0].text) - path_name="" + path_name = "" else: self.entry_var[self.count].setText("") - path_name="" + path_name = "" except BaseException as e: print("Error when set text of Device " + "Sky130 Component :", str(e)) @@ -260,12 +267,8 @@ For more info please see the documentation''') self.row = self.row + 1 self.devicemodel_dict_end[words[0]] = self.count self.count = self.count + 1 - - - self.show() - - + self.show() def eSim_general_libs(self, schematicInfo): for eachline in schematicInfo: @@ -565,7 +568,7 @@ For more info please see the documentation''') path_name = os.path.abspath(init_path + "library/deviceModelLibrary/") global flag print("flag="+str(flag)) - if os.path.exists(path_name+'/sky130_fd_pr') : + if os.path.exists(path_name+'/sky130_fd_pr'): print("Sky130_fd_pr PDK already exists") self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) @@ -575,39 +578,39 @@ For more info please see the documentation''') self.msg.showMessage(self.content) self.msg.exec_() return - elif flag==1 : - #print("Sky130_fd_pr PDK download in progress") + elif flag == 1: + # print("Sky130_fd_pr PDK download in progress") self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Download in Progress") self.content = "PDK download in progress.\n" + \ - "Please see the eSim terminal "+\ + "Please see the eSim terminal " +\ "to track the progress.\nClick on OK." self.msg.showMessage(self.content) self.msg.exec_() return - else: + else: self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("PDK download started") self.content = "PDK download started.\n" + \ - "Please see the eSim terminal "+\ + "Please see the eSim terminal " +\ "to track the progress.\nClick on OK." self.msg.showMessage(self.content) self.msg.exec_() - flag=1 + flag = 1 self.downloadThread = downloadThread(path_name) self.downloadThread.start() - - def trackDefaultLib(self): init_path = '../../' if os.name == 'nt': init_path = '' sending_btn = self.sender() self.widgetObjCount = int(sending_btn.objectName()) - path_name = os.path.abspath(init_path + "library/deviceModelLibrary/sky130_fd_pr/models/sky130.lib.spice") + path_name = os.path.abspath( + init_path + "library/deviceModelLibrary/sky130_fd_pr\ +/models/sky130.lib.spice") self.entry_var[self.widgetObjCount].setText(path_name) self.trackLibraryWithoutButton(self.widgetObjCount, path_name) @@ -615,7 +618,7 @@ For more info please see the documentation''') sending_btn = self.sender() self.widgetObjCount = int(sending_btn.objectName()) self.deviceName = self.deviceDetail[self.widgetObjCount] - #self.widgetObjCount = self.count_beg + # self.widgetObjCount = self.count_beg # if self.deviceName[0] == 'm': # width = str(self.entry_var[self.widgetObjCount + 1].text()) # length = str(self.entry_var[self.widgetObjCount + 2].text()) @@ -627,15 +630,18 @@ For more info please see the documentation''') # if multifactor == "": # multifactor = "1" - # self.obj_trac.deviceModelTrack[self.deviceName] = str(self.entry_var[self.widgetObjCount].text()) + \ + # self.obj_trac.deviceModelTrack[self.deviceName] =\ + # str(self.entry_var[self.widgetObjCount].text()) + \ # ":" + "W=" + width + " L=" + length + " M=" + multifactor if self.deviceName[0:6] == 'scmode': - self.obj_trac.deviceModelTrack[self.deviceName] = self.entry_var[self.widgetObjCount].text() + \ - ":" +str(self.entry_var[self.widgetObjCount + 1].text()) + self.obj_trac.deviceModelTrack[self.deviceName] = \ + self.entry_var[self.widgetObjCount].text() + \ + ":" + str(self.entry_var[self.widgetObjCount + 1].text()) print(self.obj_trac.deviceModelTrack[self.deviceName]) elif self.deviceName[0:2] == 'sc': - self.obj_trac.deviceModelTrack[self.deviceName] = str(self.entry_var[self.widgetObjCount].text()) + self.obj_trac.deviceModelTrack[self.deviceName] = str( + self.entry_var[self.widgetObjCount].text()) print(self.obj_trac.deviceModelTrack[self.deviceName]) else: @@ -684,18 +690,17 @@ For more info please see the documentation''') elif self.deviceName[0:6] == 'scmode': self.obj_trac.deviceModelTrack[self.deviceName] = self.libfile + \ - ":" +str(self.entry_var[self.widgetObjCount + 1].text()) + ":" + str(self.entry_var[self.widgetObjCount + 1].text()) print(self.obj_trac.deviceModelTrack[self.deviceName]) elif self.deviceName[0:2] == 'sc': - self.obj_trac.deviceModelTrack[self.deviceName] = str(self.entry_var[self.widgetObjCount].text()) + self.obj_trac.deviceModelTrack[self.deviceName] = str( + self.entry_var[self.widgetObjCount].text()) print(self.obj_trac.deviceModelTrack[self.deviceName]) else: self.obj_trac.deviceModelTrack[self.deviceName] = self.libfile - - def trackLibraryWithoutButton(self, iter_value, path_value): """ This function is use to keep track of all Device Model widget @@ -726,11 +731,12 @@ For more info please see the documentation''') elif self.deviceName[0:6] == 'scmode': self.obj_trac.deviceModelTrack[self.deviceName] = self.libfile + \ - ":" +str(self.entry_var[self.widgetObjCount + 1].text()) + ":" + str(self.entry_var[self.widgetObjCount + 1].text()) print(self.obj_trac.deviceModelTrack[self.deviceName]) elif self.deviceName[0:2] == 'sc': - self.obj_trac.deviceModelTrack[self.deviceName] = str(self.entry_var[self.widgetObjCount].text()) + self.obj_trac.deviceModelTrack[self.deviceName] = str( + self.entry_var[self.widgetObjCount].text()) print(self.obj_trac.deviceModelTrack[self.deviceName]) else: @@ -738,8 +744,8 @@ For more info please see the documentation''') def GenerateSOCbutton(self): -############################################################################ -################### SPICE to Verilog Converter ############################# + ############################################################# + # ***************** SPICE to Verilog Converter ************** # The development is under progress and may not be accurate @@ -748,84 +754,93 @@ For more info please see the documentation''') # Nagesh Karmali, nags@cse.iitb.ac.in # Firuza Karmali, firuza@cse.iitb.ac.in # Rahul Paknikar, rahulp@iitb.ac.in - # GUIDED BY: + # GUIDED BY: # Kunal Ghosh, VLSI System Design Corp.Pvt.Ltd # Anagha Ghosh, VLSI System Design Corp.Pvt.Ltd # Philipp Gühring -############################################################################ + # *********************************************************** kicadFile = self.clarg1 (projpath, filename) = os.path.split(kicadFile) analysisfile = open(os.path.join(projpath, filename)) - #analysisfile = open(os.path.join(projpath, 'analysis')) + # analysisfile = open(os.path.join(projpath, 'analysis')) content = analysisfile.read() contentlines = content.split("\n") - parsedfile = open(os.path.join(projpath, filename+'.parsed.v'),'w') + parsedfile = open(os.path.join(projpath, filename+'.parsed.v'), 'w') parsedfile.write("") - #print("module "+filename) - i=1 - inputlist=[] - realinputlist=[] - outputlist=[] - realoutputlist=[] - wirelist=[] - realwirelist=[] - uutlist=[] - filelist=[] - parsedcontent=[] + # print("module "+filename) + i = 1 + inputlist = [] + realinputlist = [] + outputlist = [] + realoutputlist = [] + wirelist = [] + realwirelist = [] + uutlist = [] + filelist = [] + parsedcontent = [] for contentlist in contentlines: - if "IPDD" in contentlist or "IPAD" in contentlist : - # if len(contentlist)>1 and ( contentlist[0:1]=='U' or contentlist[0:1]=='X') and not 'plot_' in contentlist : - #print(contentlist) - netnames=contentlist.split() - net = ' '.join(map(str,netnames[1:-1])) - netnames[-1]=netnames[-1].replace("IPAD",'') - netnames[-1]=netnames[-1].replace("IPDD",'') - #net=net.replace(netnames[-1],'') - #net=net.replace('BI_','') - #net=net.replace('BO_','') - net2=[] + if "IPDD" in contentlist or "IPAD" in contentlist: + # if len(contentlist)>1 and ( contentlist[0:1]=='U'\ + # or contentlist[0:1]=='X') and not 'plot_' in contentlist : + # print(contentlist) + netnames = contentlist.split() + net = ' '.join(map(str, netnames[1:-1])) + netnames[-1] = netnames[-1].replace("IPAD", '') + netnames[-1] = netnames[-1].replace("IPDD", '') + # net=net.replace(netnames[-1],'') + # net=net.replace('BI_','') + # net=net.replace('BO_','') + net2 = [] + for j in net.split(): - #print(j) - secondpart=j + # print(j) + secondpart = j if '_' in j: - secondpart=j.split('_')[1] + secondpart = j.split('_')[1] if secondpart in net2: continue - if net.count(secondpart)-1>0: - l="["+str(net.count(secondpart)-1)+":0"+"] "+secondpart + if net.count(secondpart)-1 > 0: + k = "["+str(net.count(secondpart)-1) + \ + ":0"+"] "+secondpart else: - l=secondpart - + k = secondpart + net2.append(secondpart) if '_I_' in str(j): - inputlist.append(l) + inputlist.append(k) if '_IR_' in str(j): - inputlist.append(l) + inputlist.append(k) if '_O_' in str(j): - outputlist.append(l) + outputlist.append(k) if '_OR_' in str(j): - realoutputlist.append(l) - if '_W_' in str(j) and not(l in wirelist): - wirelist.append(l) - if '_WR_' in str(j) and not(l in realwirelist): - realwirelist.append(l) - - netnames[-1]=netnames[-1].replace("IPAD",'') - netnames[-1]=netnames[-1].replace("IPDD",'') - uutlist.append(netnames[-1]+" uut"+str(i)+" ("+', '.join(net2)+');') + realoutputlist.append(k) + if '_W_' in str(j) and not(k in wirelist): + wirelist.append(k) + if '_WR_' in str(j) and not(k in realwirelist): + realwirelist.append(k) + + netnames[-1] = netnames[-1].replace("IPAD", '') + netnames[-1] = netnames[-1].replace("IPDD", '') + uutlist.append(netnames[-1]+" uut" + + str(i)+" ("+', '.join(net2)+');') filelist.append(netnames[-1]) - i=i+1 - #print(inputlist) - #print(outputlist) - #print(wirelist) - parsedcontent.append("\\\\Generated from SPICE to Verilog Converter developed at FOSSEE, IIT Bombay\n") - parsedcontent.append("\\\\The development is under progress and may not be accurate\n") + i = i+1 + # print(inputlist) + # print(outputlist) + # print(wirelist) + parsedcontent.append( + "\\\\Generated from SPICE to Verilog. \ +Converter developed at FOSSEE, IIT Bombay\n") + parsedcontent.append( + "\\\\The development is under progress and may not be accurate\n") for j in filelist: parsedcontent.append('''`include "'''+j+'''.v"''') - parsedcontent.append("module "+filename+"("+', '.join(inputlist+realinputlist+outputlist+realoutputlist)+");") + parsedcontent.append( + "module "+filename+"("+', '.join(inputlist # noqa + + realinputlist + outputlist + realoutputlist)+");") # noqa if inputlist: parsedcontent.append("input "+', '.join(inputlist)+";") if realinputlist: @@ -842,11 +857,14 @@ For more info please see the documentation''') parsedcontent.append(j) parsedcontent.append("endmodule;") - print('\n**************Generated Verilog File:'+filename+'.parsed.v***************\n') + print('\n**************Generated Verilog File:' + + filename+'.parsed.v***************\n') for j in parsedcontent: print(j) parsedfile.write(j+"\n") - print('\n**************************************************************************\n') + print( + '\n*************************************\ +************************************\n') self.msg = QtWidgets.QErrorMessage() self.msg.setModal(True) self.msg.setWindowTitle("Verilog File Generated") @@ -858,11 +876,11 @@ For more info please see the documentation''') class downloadThread(QThread): -# initialising the threads - # initialising the threads + # initialising the threads + # initialising the threads def __init__(self, path_name): QThread.__init__(self) - self.path_name=path_name + self.path_name = path_name def __del__(self): self.wait() @@ -871,10 +889,14 @@ class downloadThread(QThread): def run(self): global flag try: - print("\nSky130_fd_pr Download started at Location: "+self.path_name) + print("\nSky130_fd_pr Download started at Location: " + + self.path_name) # noqa print("\nYou will be notified once downloaded\n") - wget.download("https://static.fossee.in/esim/installation-files/sky130_fd_pr.zip", self.path_name+'/sky130_fd_pr.zip') - print("\nSky130_fd_pr Downloaded Successfully at Location: "+self.path_name) + wget.download("https://static.fossee.in/esim/installation\ + -files/sky130_fd_pr.zip", + self.path_name+'/sky130_fd_pr.zip') + print("\nSky130_fd_pr Downloaded Successfully \ + at Location: "+self.path_name) except Exception as e: print(e) @@ -884,15 +906,13 @@ class downloadThread(QThread): print("\nStarted Extracting................................\n") print("\nYou will be notified once extracted") zp = zipfile.ZipFile(self.path_name+'/sky130_fd_pr.zip') - curr_dir=os.getcwd() + curr_dir = os.getcwd() os.chdir(self.path_name) zp.extractall() os.remove('sky130_fd_pr.zip') - print("\nZip File Extracted Successfully\n") - os.chdir(curr_dir) + print("\nZip File Extracted Successfully\n") + os.chdir(curr_dir) except Exception as e: print(e) print("Extraction process Failed") - flag=0 - - + flag = 0 |