Skip to content

Commit f358de7

Browse files
committed
Add optional lvs_lib netlists for LVS usage (sp_lib is for simulation)
1 parent 8603d3e commit f358de7

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

compiler/base/hierarchy_design.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ def __init__(self, name):
2424
self.gds_file = OPTS.openram_tech + "gds_lib/" + name + ".gds"
2525
self.sp_file = OPTS.openram_tech + "sp_lib/" + name + ".sp"
2626

27+
# If we have a separate lvs directory, then all the lvs files
28+
# should be in there (all or nothing!)
29+
lvs_dir = OPTS.openram_tech + "lvs_lib/"
30+
if os.path.exists(lvs_dir):
31+
self.lvs_file = lvs_dir + name + ".sp"
32+
else:
33+
self.lvs_file = self.sp_file
34+
2735
self.name = name
2836
hierarchy_spice.spice.__init__(self, name)
2937
hierarchy_layout.layout.__init__(self, name)
@@ -56,7 +64,7 @@ def DRC_LVS(self, final_verification=False, force_check=False):
5664

5765
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name)
5866
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
59-
self.sp_write(tempspice)
67+
self.lvs_write(tempspice)
6068
self.gds_write(tempgds)
6169
# Final verification option does not allow nets to be connected by label.
6270
num_drc_errors = verify.run_drc(self.name, tempgds, extract=True, final_verification=final_verification)
@@ -114,7 +122,7 @@ def LVS(self, final_verification=False):
114122
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
115123
tempspice = "{0}/{1}.sp".format(OPTS.openram_temp, self.name)
116124
tempgds = "{0}/{1}.gds".format(OPTS.openram_temp, self.name)
117-
self.sp_write(tempspice)
125+
self.lvs_write(tempspice)
118126
self.gds_write(tempgds)
119127
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification=final_verification)
120128
debug.check(num_errors == 0,

compiler/base/hierarchy_spice.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def __init__(self, name):
4343
# Keep track of any comments to add the the spice
4444
try:
4545
self.commments
46-
except NameError:
46+
except AttributeError:
4747
self.comments = []
4848

4949
self.sp_read()
@@ -57,7 +57,7 @@ def add_comment(self, comment):
5757

5858
try:
5959
self.commments
60-
except NameError:
60+
except AttributeError:
6161
self.comments = []
6262

6363
self.comments.append(comment)
@@ -210,6 +210,24 @@ def sp_read(self):
210210
else:
211211
self.spice = []
212212

213+
# We don't define self.lvs and will use self.spice if dynamically created
214+
# or they are the same file
215+
if self.lvs_file!=self.sp_file and os.path.isfile(self.lvs_file):
216+
debug.info(3, "opening {0}".format(self.lvs_file))
217+
f = open(self.lvs_file)
218+
self.lvs = f.readlines()
219+
for i in range(len(self.lvs)):
220+
self.lvs[i] = self.lvs[i].rstrip(" \n")
221+
f.close()
222+
223+
# pins and subckt should be the same
224+
# find the correct subckt line in the file
225+
subckt = re.compile("^.subckt {}".format(self.name), re.IGNORECASE)
226+
subckt_line = list(filter(subckt.search, self.lvs))[0]
227+
# parses line into ports and remove subckt
228+
lvs_pins = subckt_line.split(" ")[2:]
229+
debug.check(lvs_pins == self.pins, "LVS and spice file pin mismatch.", -1)
230+
213231
def check_net_in_spice(self, net_name):
214232
"""Checks if a net name exists in the current. Intended to be check nets in hand-made cells."""
215233
# Remove spaces and lower case then add spaces.
@@ -239,16 +257,18 @@ def contains(self, mod, modlist):
239257
return True
240258
return False
241259

242-
def sp_write_file(self, sp, usedMODS):
243-
""" Recursive spice subcircuit write;
244-
Writes the spice subcircuit from the library or the dynamically generated one"""
260+
def sp_write_file(self, sp, usedMODS, lvs_netlist=False):
261+
"""
262+
Recursive spice subcircuit write;
263+
Writes the spice subcircuit from the library or the dynamically generated one
264+
"""
245265
if not self.spice:
246266
# recursively write the modules
247267
for i in self.mods:
248268
if self.contains(i, usedMODS):
249269
continue
250270
usedMODS.append(i)
251-
i.sp_write_file(sp, usedMODS)
271+
i.sp_write_file(sp, usedMODS, lvs_netlist)
252272

253273
if len(self.insts) == 0:
254274
return
@@ -296,7 +316,10 @@ def sp_write_file(self, sp, usedMODS):
296316
# Including the file path makes the unit test fail for other users.
297317
# if os.path.isfile(self.sp_file):
298318
# sp.write("\n* {0}\n".format(self.sp_file))
299-
sp.write("\n".join(self.spice))
319+
if lvs_netlist:
320+
sp.write("\n".join(self.lvs))
321+
else:
322+
sp.write("\n".join(self.spice))
300323

301324
sp.write("\n")
302325

@@ -310,6 +333,16 @@ def sp_write(self, spname):
310333
del usedMODS
311334
spfile.close()
312335

336+
def lvs_write(self, spname):
337+
"""Writes the lvs to files"""
338+
debug.info(3, "Writing to {0}".format(spname))
339+
spfile = open(spname, 'w')
340+
spfile.write("*FIRST LINE IS A COMMENT\n")
341+
usedMODS = list()
342+
self.sp_write_file(spfile, usedMODS, True)
343+
del usedMODS
344+
spfile.close()
345+
313346
def analytical_delay(self, corner, slew, load=0.0):
314347
"""Inform users undefined delay module while building new modules"""
315348

compiler/sram/sram_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,11 @@ def sp_write(self, sp_name):
574574
sp.write("* Data bits: {}\n".format(self.word_size))
575575
sp.write("* Banks: {}\n".format(self.num_banks))
576576
sp.write("* Column mux: {}:1\n".format(self.words_per_row))
577-
sp.write("**************************************************\n")
577+
sp.write("**************************************************\n")
578578
# This causes unit test mismatch
579579
# sp.write("* Created: {0}\n".format(datetime.datetime.now()))
580580
# sp.write("* User: {0}\n".format(getpass.getuser()))
581-
# sp.write(".global {0} {1}\n".format(spice["vdd_name"],
581+
# sp.write(".global {0} {1}\n".format(spice["vdd_name"],
582582
# spice["gnd_name"]))
583583
usedMODS = list()
584584
self.sp_write_file(sp, usedMODS)

compiler/tests/02_library_lvs_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ def runTest(self):
4545

4646
def setup_files():
4747
gds_dir = OPTS.openram_tech + "/gds_lib"
48-
sp_dir = OPTS.openram_tech + "/sp_lib"
48+
sp_dir = OPTS.openram_tech + "/lvs_lib"
49+
if not os.path.exists(sp_dir):
50+
sp_dir = OPTS.openram_tech + "/sp_lib"
4951
files = os.listdir(gds_dir)
5052
nametest = re.compile("\.gds$", re.IGNORECASE)
5153
gds_files = list(filter(nametest.search, files))

0 commit comments

Comments
 (0)