mirror of https://github.com/VLSIDA/OpenRAM.git
Add optional lvs_lib netlists for LVS usage (sp_lib is for simulation)
This commit is contained in:
parent
8603d3edd6
commit
f358de78bb
|
|
@ -24,6 +24,14 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
|
||||
self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
|
||||
|
||||
# If we have a separate lvs directory, then all the lvs files
|
||||
# should be in there (all or nothing!)
|
||||
lvs_dir = OPTS.openram_tech + "lvs_lib/"
|
||||
if os.path.exists(lvs_dir):
|
||||
self.lvs_file = lvs_dir + name + ".sp"
|
||||
else:
|
||||
self.lvs_file = self.sp_file
|
||||
|
||||
self.name = name
|
||||
hierarchy_spice.spice.__init__(self, name)
|
||||
hierarchy_layout.layout.__init__(self, name)
|
||||
|
|
@ -56,7 +64,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
|
||||
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name)
|
||||
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
|
||||
self.sp_write(tempspice)
|
||||
self.lvs_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
# Final verification option does not allow nets to be connected by label.
|
||||
num_drc_errors = verify.run_drc(self.name, tempgds, extract=True, final_verification=final_verification)
|
||||
|
|
@ -114,7 +122,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
||||
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name)
|
||||
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
|
||||
self.sp_write(tempspice)
|
||||
self.lvs_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification)
|
||||
debug.check(num_errors == 0,
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class spice():
|
|||
# Keep track of any comments to add the the spice
|
||||
try:
|
||||
self.commments
|
||||
except NameError:
|
||||
except AttributeError:
|
||||
self.comments = []
|
||||
|
||||
self.sp_read()
|
||||
|
|
@ -57,7 +57,7 @@ class spice():
|
|||
|
||||
try:
|
||||
self.commments
|
||||
except NameError:
|
||||
except AttributeError:
|
||||
self.comments = []
|
||||
|
||||
self.comments.append(comment)
|
||||
|
|
@ -210,6 +210,24 @@ class spice():
|
|||
else:
|
||||
self.spice = []
|
||||
|
||||
# We don't define self.lvs and will use self.spice if dynamically created
|
||||
# or they are the same file
|
||||
if self.lvs_file!=self.sp_file and os.path.isfile(self.lvs_file):
|
||||
debug.info(3, "opening {0}".format(self.lvs_file))
|
||||
f = open(self.lvs_file)
|
||||
self.lvs = f.readlines()
|
||||
for i in range(len(self.lvs)):
|
||||
self.lvs[i] = self.lvs[i].rstrip(" \n")
|
||||
f.close()
|
||||
|
||||
# pins and subckt should be the same
|
||||
# find the correct subckt line in the file
|
||||
subckt = re.compile("^.subckt {}".format(self.name), re.IGNORECASE)
|
||||
subckt_line = list(filter(subckt.search, self.lvs))[0]
|
||||
# parses line into ports and remove subckt
|
||||
lvs_pins = subckt_line.split(" ")[2:]
|
||||
debug.check(lvs_pins == self.pins, "LVS and spice file pin mismatch.", -1)
|
||||
|
||||
def check_net_in_spice(self, net_name):
|
||||
"""Checks if a net name exists in the current. Intended to be check nets in hand-made cells."""
|
||||
# Remove spaces and lower case then add spaces.
|
||||
|
|
@ -239,16 +257,18 @@ class spice():
|
|||
return True
|
||||
return False
|
||||
|
||||
def sp_write_file(self, sp, usedMODS):
|
||||
""" Recursive spice subcircuit write;
|
||||
Writes the spice subcircuit from the library or the dynamically generated one"""
|
||||
def sp_write_file(self, sp, usedMODS, lvs_netlist=False):
|
||||
"""
|
||||
Recursive spice subcircuit write;
|
||||
Writes the spice subcircuit from the library or the dynamically generated one
|
||||
"""
|
||||
if not self.spice:
|
||||
# recursively write the modules
|
||||
for i in self.mods:
|
||||
if self.contains(i, usedMODS):
|
||||
continue
|
||||
usedMODS.append(i)
|
||||
i.sp_write_file(sp, usedMODS)
|
||||
i.sp_write_file(sp, usedMODS, lvs_netlist)
|
||||
|
||||
if len(self.insts) == 0:
|
||||
return
|
||||
|
|
@ -296,7 +316,10 @@ class spice():
|
|||
# Including the file path makes the unit test fail for other users.
|
||||
# if os.path.isfile(self.sp_file):
|
||||
# sp.write("\n* {0}\n".format(self.sp_file))
|
||||
sp.write("\n".join(self.spice))
|
||||
if lvs_netlist:
|
||||
sp.write("\n".join(self.lvs))
|
||||
else:
|
||||
sp.write("\n".join(self.spice))
|
||||
|
||||
sp.write("\n")
|
||||
|
||||
|
|
@ -310,6 +333,16 @@ class spice():
|
|||
del usedMODS
|
||||
spfile.close()
|
||||
|
||||
def lvs_write(self, spname):
|
||||
"""Writes the lvs to files"""
|
||||
debug.info(3, "Writing to {0}".format(spname))
|
||||
spfile = open(spname, 'w')
|
||||
spfile.write("*FIRST LINE IS A COMMENT\n")
|
||||
usedMODS = list()
|
||||
self.sp_write_file(spfile, usedMODS, True)
|
||||
del usedMODS
|
||||
spfile.close()
|
||||
|
||||
def analytical_delay(self, corner, slew, load=0.0):
|
||||
"""Inform users undefined delay module while building new modules"""
|
||||
|
||||
|
|
|
|||
|
|
@ -574,11 +574,11 @@ class sram_base(design, verilog, lef):
|
|||
sp.write("* Data bits: {}\n".format(self.word_size))
|
||||
sp.write("* Banks: {}\n".format(self.num_banks))
|
||||
sp.write("* Column mux: {}:1\n".format(self.words_per_row))
|
||||
sp.write("**************************************************\n")
|
||||
sp.write("**************************************************\n")
|
||||
# This causes unit test mismatch
|
||||
# sp.write("* Created: {0}\n".format(datetime.datetime.now()))
|
||||
# sp.write("* User: {0}\n".format(getpass.getuser()))
|
||||
# sp.write(".global {0} {1}\n".format(spice["vdd_name"],
|
||||
# sp.write(".global {0} {1}\n".format(spice["vdd_name"],
|
||||
# spice["gnd_name"]))
|
||||
usedMODS = list()
|
||||
self.sp_write_file(sp, usedMODS)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ class library_lvs_test(openram_test):
|
|||
|
||||
def setup_files():
|
||||
gds_dir = OPTS.openram_tech + "/gds_lib"
|
||||
sp_dir = OPTS.openram_tech + "/sp_lib"
|
||||
sp_dir = OPTS.openram_tech + "/lvs_lib"
|
||||
if not os.path.exists(sp_dir):
|
||||
sp_dir = OPTS.openram_tech + "/sp_lib"
|
||||
files = os.listdir(gds_dir)
|
||||
nametest = re.compile("\.gds$", re.IGNORECASE)
|
||||
gds_files = list(filter(nametest.search, files))
|
||||
|
|
|
|||
Loading…
Reference in New Issue