mirror of https://github.com/VLSIDA/OpenRAM.git
calibre pex modifications to run hierarchical pex
This commit is contained in:
parent
d14a68847e
commit
fde8794282
|
|
@ -185,10 +185,10 @@ class delay(simulation):
|
|||
meas.targ_name_no_port))
|
||||
self.dout_volt_meas[-1].meta_str = meas.meta_str
|
||||
|
||||
if not OPTS.use_pex:
|
||||
self.sen_meas = delay_measure("delay_sen", self.clk_frmt, self.sen_name + "{}", "FALL", "RISE", measure_scale=1e9)
|
||||
else:
|
||||
if OPTS.use_pex and OPTS.pex_exe[0] != 'calibre':
|
||||
self.sen_meas = delay_measure("delay_sen", self.clk_frmt, self.sen_name, "FALL", "RISE", measure_scale=1e9)
|
||||
else:
|
||||
self.sen_meas = delay_measure("delay_sen", self.clk_frmt, self.sen_name + "{}", "FALL", "RISE", measure_scale=1e9)
|
||||
|
||||
self.sen_meas.meta_str = sram_op.READ_ZERO
|
||||
self.sen_meas.meta_add_delay = True
|
||||
|
|
@ -235,13 +235,15 @@ class delay(simulation):
|
|||
storage_names = cell_inst.mod.get_storage_net_names()
|
||||
debug.check(len(storage_names) == 2, ("Only inverting/non-inverting storage nodes"
|
||||
"supported for characterization. Storage nets={}").format(storage_names))
|
||||
if not OPTS.use_pex:
|
||||
q_name = cell_name + '.' + str(storage_names[0])
|
||||
qbar_name = cell_name + '.' + str(storage_names[1])
|
||||
else:
|
||||
|
||||
#todo: bob vanhoof's modification: hierarchical pex
|
||||
if OPTS.use_pex and OPTS.pex_exe[0] != 'calibre':
|
||||
bank_num = self.sram.get_bank_num(self.sram.name, bit_row, bit_col)
|
||||
q_name = "bitcell_Q_b{0}_r{1}_c{2}".format(bank_num, bit_row, bit_col)
|
||||
qbar_name = "bitcell_Q_bar_b{0}_r{1}_c{2}".format(bank_num, bit_row, bit_col)
|
||||
else:
|
||||
q_name = cell_name + '.' + str(storage_names[0])
|
||||
qbar_name = cell_name + '.' + str(storage_names[1])
|
||||
|
||||
# Bit measures, measurements times to be defined later. The measurement names must be unique
|
||||
# but they is enforced externally. {} added to names to differentiate between ports allow the
|
||||
|
|
|
|||
|
|
@ -426,7 +426,8 @@ class simulation():
|
|||
"""
|
||||
|
||||
port = self.read_ports[0]
|
||||
if not OPTS.use_pex:
|
||||
#todo: modified by bob vanhoof to take into account calibre pex
|
||||
if not OPTS.use_pex or (OPTS.use_pex and OPTS.pex_exe[0] == 'calibre'):
|
||||
self.graph.get_all_paths('{}{}'.format("clk", port),
|
||||
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
||||
|
||||
|
|
@ -482,7 +483,8 @@ class simulation():
|
|||
debug.check(len(sa_mods) == 1, "Only expected one type of Sense Amp. Cannot perform s_en checks.")
|
||||
enable_name = sa_mods[0].get_enable_name()
|
||||
sen_name = self.get_alias_in_path(paths, enable_name, sa_mods[0])
|
||||
if OPTS.use_pex:
|
||||
# todo: modified by bob vanhoof
|
||||
if OPTS.use_pex and (OPTS.pex_exe[0] != 'calibre'):
|
||||
sen_name = sen_name.split('.')[-1]
|
||||
return sen_name
|
||||
|
||||
|
|
@ -540,7 +542,8 @@ class simulation():
|
|||
exclude_set = self.get_bl_name_search_exclusions()
|
||||
for int_net in [cell_bl, cell_br]:
|
||||
bl_names.append(self.get_alias_in_path(paths, int_net, cell_mod, exclude_set))
|
||||
if OPTS.use_pex:
|
||||
#todo modified by bob vanhoof
|
||||
if OPTS.use_pex and OPTS.pex_exe[0] != 'calibre':
|
||||
for i in range(len(bl_names)):
|
||||
bl_names[i] = bl_names[i].split('.')[-1]
|
||||
return bl_names[0], bl_names[1]
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class stimuli():
|
|||
def inst_model(self, pins, model_name):
|
||||
""" Function to instantiate a generic model with a set of pins """
|
||||
|
||||
if OPTS.use_pex:
|
||||
if OPTS.use_pex and OPTS.pex_exe[0] != 'calibre':
|
||||
self.inst_pex_model(pins, model_name)
|
||||
else:
|
||||
self.sf.write("X{0} ".format(model_name))
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ class sram():
|
|||
if OPTS.use_pex:
|
||||
start_time = datetime.datetime.now()
|
||||
# Output the extracted design if requested
|
||||
#todo: bob vanhoof: re-generate the layout so that it now does include the pex labels
|
||||
pexname = OPTS.output_path + self.s.name + ".pex.sp"
|
||||
spname = OPTS.output_path + self.s.name + ".sp"
|
||||
verify.run_pex(self.s.name, gdsname, spname, output=pexname)
|
||||
|
|
|
|||
|
|
@ -201,7 +201,9 @@ class sram_base(design, verilog, lef):
|
|||
highest_coord = self.find_highest_coords()
|
||||
self.width = highest_coord[0]
|
||||
self.height = highest_coord[1]
|
||||
if OPTS.use_pex:
|
||||
#todo: bob vanhoof: this now does not automatically propagate the pex labels when the lvs tool is calibre
|
||||
if OPTS.use_pex and not OPTS.lvs_exe[0] == "calibre":
|
||||
debug.info(2,"adding global pex labels")
|
||||
self.add_global_pex_labels()
|
||||
self.add_boundary(ll=vector(0, 0),
|
||||
ur=vector(self.width, self.height))
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ def write_lvs_script(cell_name, gds_name, sp_name, final_verification=False, out
|
|||
run_file = output_path + "run_lvs.sh"
|
||||
f = open(run_file, "w")
|
||||
f.write("#!/bin/sh\n")
|
||||
#PDK_DIR=os.environ.get("PDK_DIR")
|
||||
#f.write("export PDK_DIR={}\n".format(PDK_DIR))
|
||||
cmd = "{0} -gui -lvs lvs_runset -batch".format(OPTS.lvs_exe[1])
|
||||
|
||||
f.write(cmd)
|
||||
|
|
@ -154,38 +156,80 @@ def write_pex_script(cell_name, extract, output, final_verification=False, outpu
|
|||
|
||||
from tech import drc
|
||||
pex_rules = drc["xrc_rules"]
|
||||
pex_runset = {
|
||||
'pexRulesFile': pex_rules,
|
||||
'pexRunDir': output_path,
|
||||
'pexLayoutPaths': cell_name + ".gds",
|
||||
'pexLayoutPrimary': cell_name,
|
||||
'pexSourcePath': cell_name + ".sp",
|
||||
'pexSourcePrimary': cell_name,
|
||||
'pexReportFile': cell_name + ".pex.report",
|
||||
'pexPexNetlistFile': output,
|
||||
'pexPexReportFile': cell_name + ".pex.report",
|
||||
'pexMaskDBFile': cell_name + ".maskdb",
|
||||
'cmnFDIDEFLayoutPath': cell_name + ".def",
|
||||
}
|
||||
|
||||
# write the runset file
|
||||
f = open(output_path + "pex_runset", "w")
|
||||
for k in sorted(iter(pex_runset.keys())):
|
||||
f.write("*{0}: {1}\n".format(k, pex_runset[k]))
|
||||
# write the rules file
|
||||
f = open(OPTS.openram_temp + "pex_rules", "w")
|
||||
f.write('// Rules file, created by OpenRAM, (c) Bob Vanhoof\n')
|
||||
f.write('\n')
|
||||
f.write('LAYOUT PATH "' + OPTS.openram_temp + cell_name + '.gds"\n')
|
||||
f.write('LAYOUT PRIMARY ' + cell_name + '\n')
|
||||
f.write('LAYOUT SYSTEM GDSII\n')
|
||||
f.write('\n')
|
||||
f.write('SOURCE PATH "' + OPTS.openram_temp + cell_name + '.sp"\n')
|
||||
f.write('SOURCE PRIMARY ' + cell_name +'\n')
|
||||
f.write('SOURCE SYSTEM SPICE\n')
|
||||
f.write('SOURCE CASE YES\n')
|
||||
f.write('\n')
|
||||
f.write('MASK SVDB DIRECTORY "svdb" QUERY XRC\n')
|
||||
f.write('\n')
|
||||
f.write('LVS REPORT "' + OPTS.openram_temp + cell_name + '.pex.report"\n')
|
||||
f.write('LVS REPORT OPTION NONE\n')
|
||||
f.write('LVS FILTER UNUSED OPTION NONE SOURCE\n')
|
||||
f.write('LVS FILTER UNUSED OPTION NONE LAYOUT\n')
|
||||
f.write('LVS POWER NAME vdd\n')
|
||||
f.write('LVS GROUND NAME gnd\n')
|
||||
f.write('LVS RECOGNIZE GATES ALL\n')
|
||||
f.write('LVS CELL SUPPLY YES\n')
|
||||
f.write('LVS PUSH DEVICES SEPARATE PROPERTIES YES\n')
|
||||
f.write('\n')
|
||||
f.write('PEX NETLIST "' + output + '" HSPICE 1 SOURCENAMES GROUND gnd\n')
|
||||
f.write('PEX REDUCE ANALOG NO\n')
|
||||
f.write('PEX NETLIST UPPERCASE KEYWORDS NO\n')
|
||||
f.write('PEX NETLIST VIRTUAL CONNECT YES\n')
|
||||
f.write('PEX NETLIST NOXREF NET NAMES YES\n')
|
||||
f.write('PEX NETLIST MUTUAL RESISTANCE YES\n')
|
||||
f.write('PEX NETLIST EXPORT PORTS YES\n')
|
||||
f.write('PEX PROBE FILE "probe_file"\n')
|
||||
f.write('\n')
|
||||
f.write('VIRTUAL CONNECT COLON NO\n')
|
||||
f.write('VIRTUAL CONNECT REPORT NO\n')
|
||||
f.write('VIRTUAL CONNECT NAME vdd gnd\n')
|
||||
f.write('\n')
|
||||
f.write('DRC ICSTATION YES\n')
|
||||
f.write('\n')
|
||||
f.write('INCLUDE "'+ pex_rules +'"\n')
|
||||
f.close()
|
||||
|
||||
# write probe file
|
||||
#TODO: get from cell name
|
||||
f = open(OPTS.openram_temp + "probe_file", "w")
|
||||
f.write('CELL cell_1rw\n')
|
||||
f.write(' Q 0.100 0.510 11\n')
|
||||
f.write(' Q_bar 0.520 0.510 11\n')
|
||||
f.close()
|
||||
|
||||
# Create an auxiliary script to run calibre with the runset
|
||||
run_file = output_path + "run_pex.sh"
|
||||
f = open(run_file, "w")
|
||||
f.write("#!/bin/sh\n")
|
||||
cmd = "{0} -gui -pex pex_runset -batch".format(OPTS.pex_exe[1])
|
||||
|
||||
cmd = "{0} -lvs -hier -genhcells -spice svdb/{1}.sp -turbo -hyper cmp {2}".format(OPTS.pex_exe[1],
|
||||
cell_name,
|
||||
'pex_rules')
|
||||
f.write(cmd)
|
||||
f.write("\n")
|
||||
cmd = "sed '/dummy/d' svdb/{0}.hcells | sed '/replica_column/d' | sed '/replica_cell/d' > hcell_file".format(cell_name)
|
||||
f.write(cmd)
|
||||
f.write("\n")
|
||||
cmd = "{0} -xrc -pdb -turbo -xcell hcell_file -full -rc {1}".format(OPTS.pex_exe[1], 'pex_rules')
|
||||
f.write(cmd)
|
||||
f.write("\n")
|
||||
cmd = "{0} -xrc -fmt -full {1}".format(OPTS.pex_exe[1],'pex_rules')
|
||||
f.write(cmd)
|
||||
f.write("\n")
|
||||
f.close()
|
||||
os.system("chmod u+x {}".format(run_file))
|
||||
|
||||
return pex_runset
|
||||
return None
|
||||
|
||||
|
||||
def run_drc(cell_name, gds_name, sp_name, extract=False, final_verification=False):
|
||||
|
|
@ -194,6 +238,9 @@ def run_drc(cell_name, gds_name, sp_name, extract=False, final_verification=Fals
|
|||
|
||||
global num_drc_runs
|
||||
num_drc_runs += 1
|
||||
# Copy file to local dir if it isn't already
|
||||
#if not os.path.isfile(OPTS.openram_temp + os.path.basename(gds_name)):
|
||||
# hutil.copy(gds_name, OPTS.openram_temp)
|
||||
|
||||
drc_runset = write_drc_script(cell_name, gds_name, extract, final_verification, OPTS.openram_temp)
|
||||
|
||||
|
|
@ -237,6 +284,12 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
|||
|
||||
lvs_runset = write_lvs_script(cell_name, gds_name, sp_name, final_verification, OPTS.openram_temp)
|
||||
|
||||
# Copy file to local dir if it isn't already
|
||||
#if not os.path.isfile(OPTS.openram_temp + os.path.basename(gds_name)):
|
||||
# shutil.copy(gds_name, OPTS.openram_temp)
|
||||
#if not os.path.isfile(OPTS.openram_temp + os.path.basename(sp_name)):
|
||||
# shutil.copy(sp_name, OPTS.openram_temp)
|
||||
|
||||
(outfile, errfile, resultsfile) = run_script(cell_name, "lvs")
|
||||
|
||||
# check the result for these lines in the summary:
|
||||
|
|
@ -318,6 +371,12 @@ def run_pex(cell_name, gds_name, sp_name, output=None, final_verification=False)
|
|||
|
||||
write_pex_script(cell_name, True, output, final_verification, OPTS.openram_temp)
|
||||
|
||||
# Copy file to local dir if it isn't already
|
||||
#if not os.path.isfile(OPTS.openram_temp + os.path.basename(gds_name)):
|
||||
# shutil.copy(gds_name, OPTS.openram_temp)
|
||||
#if not os.path.isfile(OPTS.openram_temp + os.path.basename(sp_name)):
|
||||
# shutil.copy(sp_name, OPTS.openram_temp)
|
||||
|
||||
(outfile, errfile, resultsfile) = run_script(cell_name, "pex")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue