Merge branch 'dev' of github.com:VLSIDA/PrivateRAM into dev

This commit is contained in:
mrg 2021-03-01 14:06:51 -08:00
commit f31125645e
12 changed files with 103 additions and 41 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@
**/model_data
outputs
technology/freepdk45/ncsu_basekit
.idea

View File

@ -359,7 +359,9 @@ class instance(geometry):
for offset in range(len(normalized_br_offsets)):
for port in range(len(br_names)):
cell_br_meta.append([br_names[offset], row, col, port])
if normalized_storage_nets == []:
debug.error("normalized storage nets should not be empty! Check if the GDS labels Q and Q_bar are correctly set on M1 of the cell",1)
Q_x = normalized_storage_nets[0][0]
Q_y = normalized_storage_nets[0][1]

View File

@ -170,10 +170,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
@ -220,13 +220,14 @@ 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:
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

View File

@ -236,10 +236,9 @@ class lib:
self.lib.write(" slew_lower_threshold_pct_rise : 10.0 ;\n")
self.lib.write(" slew_upper_threshold_pct_rise : 90.0 ;\n\n")
self.lib.write(" nom_voltage : {};\n".format(tech.spice["nom_supply_voltage"]))
self.lib.write(" nom_temperature : {};\n".format(tech.spice["nom_temperature"]))
self.lib.write(" nom_process : {};\n".format(1.0))
self.lib.write(" nom_voltage : {};\n".format(self.voltage))
self.lib.write(" nom_temperature : {};\n".format(self.temperature))
self.lib.write(" nom_process : 1.0;\n")
self.lib.write(" default_cell_leakage_power : 0.0 ;\n")
self.lib.write(" default_leakage_power_density : 0.0 ;\n")
self.lib.write(" default_input_pin_cap : 1.0 ;\n")
@ -250,7 +249,7 @@ class lib:
self.lib.write(" default_max_fanout : 4.0 ;\n")
self.lib.write(" default_connection_class : universal ;\n\n")
self.lib.write(" voltage_map ( VDD, {} );\n".format(tech.spice["nom_supply_voltage"]))
self.lib.write(" voltage_map ( VDD, {} );\n".format(self.voltage))
self.lib.write(" voltage_map ( GND, 0 );\n\n")
def create_list(self,values):

View File

@ -467,7 +467,7 @@ class simulation():
"""
port = self.read_ports[0]
if not OPTS.use_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))
@ -523,7 +523,7 @@ 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:
if OPTS.use_pex and (OPTS.pex_exe[0] != 'calibre'):
sen_name = sen_name.split('.')[-1]
return sen_name
@ -581,7 +581,7 @@ 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:
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]

View File

@ -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))

View File

@ -22,7 +22,7 @@ import getpass
import subprocess
VERSION = "1.1.9"
VERSION = "1.1.13"
NAME = "OpenRAM v{}".format(VERSION)
USAGE = "openram.py [options] <config file>\nUse -h for help.\n"

View File

@ -201,7 +201,8 @@ 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:
if OPTS.use_pex and 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))

View File

@ -46,7 +46,15 @@ class openram_back_end_test(openram_test):
if OPTS.spice_name:
options += " -s {}".format(OPTS.spice_name)
exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
if OPTS.tech_name:
options += " -t {}".format(OPTS.tech_name)
# Always perform code coverage
if OPTS.coverage == 0:
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
exe_name = "{0}/openram.py ".format(OPENRAM_HOME)
else:
exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
config_name = "{0}/tests/configs/config_back_end.py".format(OPENRAM_HOME)
cmd = "{0} -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name,
out_file,

View File

@ -46,7 +46,15 @@ class openram_front_end_test(openram_test):
if OPTS.spice_name:
options += " -s {}".format(OPTS.spice_name)
exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
if OPTS.tech_name:
options += " -t {}".format(OPTS.tech_name)
# Always perform code coverage
if OPTS.coverage == 0:
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
exe_name = "{0}/openram.py ".format(OPENRAM_HOME)
else:
exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
config_name = "{0}/tests/configs/config_front_end.py".format(OPENRAM_HOME)
cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name,
out_file,

View File

@ -154,38 +154,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):