mirror of https://github.com/VLSIDA/OpenRAM.git
Merge lekez2005 changes WITHOUT control logic change.
This commit is contained in:
commit
9e7c04a43a
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
export OPENRAM_HOME="`pwd`/compiler"
|
||||
export OPENRAM_TECH="`pwd`/technology:/software/PDKs/skywater-tech"
|
||||
export OPENRAM_TMP="`pwd`/scn4me_subm"
|
||||
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 20 -t scn4m_subm
|
||||
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 48 -t scn4m_subm
|
||||
- name: Archive
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
export OPENRAM_HOME="`pwd`/compiler"
|
||||
export OPENRAM_TECH="`pwd`/technology:/software/PDKs/skywater-tech"
|
||||
export OPENRAM_TMP="`pwd`/freepdk45"
|
||||
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 20 -t freepdk45
|
||||
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 48 -t freepdk45
|
||||
- name: Archive
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@
|
|||
**/model_data
|
||||
outputs
|
||||
technology/freepdk45/ncsu_basekit
|
||||
.idea
|
||||
|
|
|
|||
|
|
@ -4,13 +4,9 @@
|
|||
[](./LICENSE)
|
||||
|
||||
Master:
|
||||
[](https://github.com/VLSIDA/OpenRAM/commits/master)
|
||||

|
||||
[](https://github.com/VLSIDA/OpenRAM/archive/master.zip)
|
||||
|
||||
Dev:
|
||||
[](https://github.com/VLSIDA/OpenRAM/commits/dev)
|
||||

|
||||
[](https://github.com/VLSIDA/OpenRAM/archive/dev.zip)
|
||||
|
||||
An open-source static random access memory (SRAM) compiler.
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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,13 @@ 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 or OPTS.calibre_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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ class simulation():
|
|||
"""
|
||||
|
||||
port = self.read_ports[0]
|
||||
if not OPTS.use_pex or OPTS.calibre_pex: # pex names handled post extraction
|
||||
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 and not OPTS.calibre_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 and not OPTS.calibre_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]
|
||||
|
|
|
|||
|
|
@ -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 and not OPTS.calibre_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))
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ word_size = 32
|
|||
num_words = 256
|
||||
write_size = 8
|
||||
|
||||
local_array_size = 16
|
||||
#local_array_size = 16
|
||||
|
||||
num_rw_ports = 1
|
||||
num_r_ports = 1
|
||||
|
|
@ -11,9 +11,9 @@ num_w_ports = 0
|
|||
tech_name = "sky130"
|
||||
nominal_corner_only = True
|
||||
|
||||
route_supplies = False
|
||||
#route_supplies = False
|
||||
check_lvsdrc = True
|
||||
perimeter_pins = False
|
||||
#perimeter_pins = False
|
||||
#netlist_only = True
|
||||
#analytical_delay = False
|
||||
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
|
||||
|
|
@ -636,7 +636,7 @@ class control_logic(design.design):
|
|||
self.w_en_gate_inst = self.add_inst(name="w_en_and",
|
||||
mod=self.wen_and)
|
||||
# Only drive the writes in the second half of the clock cycle during a write operation.
|
||||
self.connect_inst([input_name, "rbl_bl_delay", "gated_clk_bar", "w_en", "vdd", "gnd"])
|
||||
self.connect_inst([input_name, "rbl_bl_delay_bar", "gated_clk_bar", "w_en", "vdd", "gnd"])
|
||||
|
||||
def place_wen_row(self, row):
|
||||
x_offset = self.control_x_offset
|
||||
|
|
@ -652,7 +652,7 @@ class control_logic(design.design):
|
|||
# No we for write-only reports, so use cs
|
||||
input_name = "cs"
|
||||
|
||||
wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay", "gated_clk_bar"])
|
||||
wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"])
|
||||
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.input_bus)
|
||||
|
||||
self.connect_output(self.w_en_gate_inst, "Z", "w_en")
|
||||
|
|
|
|||
|
|
@ -196,12 +196,13 @@ class sram_base(design, verilog, lef):
|
|||
|
||||
self.add_lvs_correspondence_points()
|
||||
|
||||
#self.offset_all_coordinates()
|
||||
# self.offset_all_coordinates()
|
||||
|
||||
highest_coord = self.find_highest_coords()
|
||||
self.width = highest_coord[0]
|
||||
self.height = highest_coord[1]
|
||||
if OPTS.use_pex and not OPTS.calibre_pex:
|
||||
if OPTS.use_pex and OPTS.pex_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))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ def write_pex_script(cell_name, extract, output, final_verification=False, outpu
|
|||
if not output_path:
|
||||
output_path = OPTS.openram_temp
|
||||
|
||||
if output == None:
|
||||
if not output:
|
||||
output = cell_name + ".pex.sp"
|
||||
|
||||
# check if lvs report has been done
|
||||
|
|
@ -186,12 +186,73 @@ def write_pex_script(cell_name, extract, output, final_verification=False, outpu
|
|||
f.write("*{0}: {1}\n".format(k, pex_runset[k]))
|
||||
f.close()
|
||||
|
||||
# write the rules file
|
||||
f = open(output_path + "pex_rules", "w")
|
||||
f.write('// Rules file, created by OpenRAM, (c) Bob Vanhoof\n')
|
||||
f.write('\n')
|
||||
f.write('LAYOUT PATH "' + output_path + cell_name + '.gds"\n')
|
||||
f.write('LAYOUT PRIMARY ' + cell_name + '\n')
|
||||
f.write('LAYOUT SYSTEM GDSII\n')
|
||||
f.write('\n')
|
||||
f.write('SOURCE PATH "' + output_path + 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 "' + output_path + 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(output_path + "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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue