mirror of https://github.com/VLSIDA/OpenRAM.git
Fix bug in trim netlist. Add info comments to spice netlist and trimmed netlist. Increase verbosity for simulations.
This commit is contained in:
parent
7127895270
commit
84b42b0170
|
|
@ -125,11 +125,14 @@ class delay():
|
||||||
# meas statement for delay and power measurements
|
# meas statement for delay and power measurements
|
||||||
self.sf.write("* Measure statements for delay and power\n")
|
self.sf.write("* Measure statements for delay and power\n")
|
||||||
|
|
||||||
|
for comment in self.cycle_comments:
|
||||||
|
self.sf.write("* {}\n".format(comment))
|
||||||
|
|
||||||
trig_name = "clk"
|
trig_name = "clk"
|
||||||
targ_name = "{0}".format("d[{0}]".format(self.probe_data))
|
targ_name = "{0}".format("d[{0}]".format(self.probe_data))
|
||||||
trig_val = targ_val = 0.5 * self.vdd
|
trig_val = targ_val = 0.5 * self.vdd
|
||||||
# add measure statments for delay0
|
# add measure statments for delay0
|
||||||
# delay the target to measure after the negetive edge
|
# delay the target to measure after the negative edge
|
||||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||||
meas_name="DELAY0",
|
meas_name="DELAY0",
|
||||||
trig_name=trig_name,
|
trig_name=trig_name,
|
||||||
|
|
@ -238,12 +241,14 @@ class delay():
|
||||||
|
|
||||||
# if it failed or the read was longer than a period
|
# if it failed or the read was longer than a period
|
||||||
if type(delay0)!=float or type(delay1)!=float or type(slew1)!=float or type(slew0)!=float:
|
if type(delay0)!=float or type(delay1)!=float or type(slew1)!=float or type(slew0)!=float:
|
||||||
|
debug.info(2,"Failed simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,load,slew,delay0,delay1,slew0,slew1))
|
||||||
return (False,0,0,0,0)
|
return (False,0,0,0,0)
|
||||||
delay0 *= 1e9
|
delay0 *= 1e9
|
||||||
delay1 *= 1e9
|
delay1 *= 1e9
|
||||||
slew0 *= 1e9
|
slew0 *= 1e9
|
||||||
slew1 *= 1e9
|
slew1 *= 1e9
|
||||||
if delay0>period or delay1>period or slew0>period or slew1>period:
|
if delay0>period or delay1>period or slew0>period or slew1>period:
|
||||||
|
debug.info(2,"UNsuccessful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,load,slew,delay0,delay1,slew0,slew1))
|
||||||
return (False,0,0,0,0)
|
return (False,0,0,0,0)
|
||||||
else:
|
else:
|
||||||
debug.info(2,"Successful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,load,slew,delay0,delay1,slew0,slew1))
|
debug.info(2,"Successful simulation: period {0} load {1} slew {2}, delay0={3}n delay1={4}ns slew0={5}n slew1={6}n".format(period,load,slew,delay0,delay1,slew0,slew1))
|
||||||
|
|
@ -394,46 +399,56 @@ class delay():
|
||||||
of the cycles to do a timing evaluation. The last time is the end of the simulation
|
of the cycles to do a timing evaluation. The last time is the end of the simulation
|
||||||
and does not need a rising edge."""
|
and does not need a rising edge."""
|
||||||
|
|
||||||
|
self.cycle_comments = []
|
||||||
# idle cycle, no operation
|
# idle cycle, no operation
|
||||||
t_current = period
|
t_current = period
|
||||||
self.cycle_times = []
|
self.cycle_times = []
|
||||||
|
|
||||||
# cycle0: W data 1 address 1111 to initialize cell to a value
|
# cycle0: W data 1 address 1111 to initialize cell to a value
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
|
self.cycle_comments.append("Cycle0 {}ns: W data 1 address 111 to initialize cell".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle1: W data 0 address 1111 (to ensure a write of value works)
|
# cycle1: W data 0 address 1111 (to ensure a write of value works)
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
self.write0_cycle=1
|
self.write0_cycle=1
|
||||||
|
self.cycle_comments.append("Cycle1 {}ns: W data 0 address 111 (to ensure a write of value works)".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle2: W data 1 address 0000 (to clear the data bus cap)
|
# cycle2: W data 1 address 0000 (to clear the data bus cap)
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
|
self.cycle_comments.append("Cycle2 {}ns: W data 1 address 0000 (to clear bus caps)".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle3: R data 0 address 1111 to check W0 works
|
# cycle3: R data 0 address 1111 to check W0 works
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
self.read0_cycle=3
|
self.read0_cycle=3
|
||||||
|
self.cycle_comments.append("Cycle3 {}ns: R data 0 address 1111 to check W0 worked".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle4: W data 1 address 1111 (to ensure a write of value works)
|
# cycle4: W data 1 address 1111 (to ensure a write of value works)
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
self.write1_cycle=4
|
self.write1_cycle=4
|
||||||
|
self.cycle_comments.append("Cycle4 {}ns: W data 1 address 1111 (to ensure a write of value worked)".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle5: W data 0 address 0000 (to clear the data bus cap)
|
# cycle5: W data 0 address 0000 (to clear the data bus cap)
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
|
self.cycle_comments.append("Cycle5 {}ns: W data 0 address 0000 (to clear bus caps)".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle6: R data 1 address 1111 to check W1 works
|
# cycle6: R data 1 address 1111 to check W1 works
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
self.read1_cycle=6
|
self.read1_cycle=6
|
||||||
|
self.cycle_comments.append("Cycle6 {}ns: R data 1 address 1111 to check W1 worked".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
# cycle7: wait a clock period to end the simulation
|
# cycle7: wait a clock period to end the simulation
|
||||||
self.cycle_times.append(t_current)
|
self.cycle_times.append(t_current)
|
||||||
|
self.cycle_comments.append("Cycle7 {}ns: Idle period to end simulation".format(t_current))
|
||||||
t_current += period
|
t_current += period
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def analytical_model(self,sram, slews, loads):
|
def analytical_model(self,sram, slews, loads):
|
||||||
""" Just return the analytical model results for the SRAM.
|
""" Just return the analytical model results for the SRAM.
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ def run_sim():
|
||||||
xa_cfg.write("set_sim_level -level 7\n")
|
xa_cfg.write("set_sim_level -level 7\n")
|
||||||
xa_cfg.write("set_powernet_level 7 -node vdd\n")
|
xa_cfg.write("set_powernet_level 7 -node vdd\n")
|
||||||
xa_cfg.close()
|
xa_cfg.close()
|
||||||
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 20".format(OPTS.spice_exe,
|
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 2".format(OPTS.spice_exe,
|
||||||
temp_stim,
|
temp_stim,
|
||||||
OPTS.openram_temp)
|
OPTS.openram_temp)
|
||||||
valid_retcode=0
|
valid_retcode=0
|
||||||
|
|
|
||||||
|
|
@ -45,23 +45,30 @@ class trim_spice():
|
||||||
|
|
||||||
# Always start fresh if we do multiple reductions
|
# Always start fresh if we do multiple reductions
|
||||||
self.sp_buffer = self.spice
|
self.sp_buffer = self.spice
|
||||||
|
|
||||||
# Find the row and column indices for the removals
|
|
||||||
# Convert address froms tring to int
|
|
||||||
address = int(address,2)
|
|
||||||
array_row = address >> self.col_addr_size
|
|
||||||
# Which word in the array (0 if only one word)
|
|
||||||
if self.col_addr_size>0:
|
|
||||||
lower_mask = int(self.col_addr_size-1)
|
|
||||||
lower_address = address & lower_mask
|
|
||||||
else:
|
|
||||||
lower_address=0
|
|
||||||
# Which bit in the array
|
|
||||||
array_bit = lower_address*self.word_size + data_bit
|
|
||||||
|
|
||||||
|
# Split up the address and convert to an int
|
||||||
|
wl_address = int(address[self.col_addr_size:],2)
|
||||||
|
col_address = int(address[0:self.col_addr_size],2)
|
||||||
# 1. Keep cells in the bitcell array based on WL and BL
|
# 1. Keep cells in the bitcell array based on WL and BL
|
||||||
wl_name = "wl[{}]".format(array_row)
|
wl_name = "wl[{}]".format(wl_address)
|
||||||
bl_name = "bl[{}]".format(array_bit)
|
bl_name = "bl[{}]".format(self.words_per_row*data_bit + col_address)
|
||||||
|
|
||||||
|
# Prepend info about the trimming
|
||||||
|
addr_msg = "Keeping {} address".format(address)
|
||||||
|
self.sp_buffer.insert(0, "* "+addr_msg)
|
||||||
|
debug.info(1,addr_msg)
|
||||||
|
data_msg = "Keeping {} data bit".format(data_bit)
|
||||||
|
self.sp_buffer.insert(0, "* "+data_msg)
|
||||||
|
debug.info(1,data_msg)
|
||||||
|
bl_msg = "Keeping {} (trimming other BLs)".format(bl_name)
|
||||||
|
wl_msg = "Keeping {} (trimming other WLs)".format(wl_name)
|
||||||
|
self.sp_buffer.insert(0, "* "+bl_msg)
|
||||||
|
debug.info(1,bl_msg)
|
||||||
|
self.sp_buffer.insert(0, "* "+wl_msg)
|
||||||
|
debug.info(1,wl_msg)
|
||||||
|
self.sp_buffer.insert(0, "* It should NOT be used for LVS!!")
|
||||||
|
self.sp_buffer.insert(0, "* WARNING: This is a TRIMMED NETLIST.")
|
||||||
|
|
||||||
self.remove_insts("bitcell_array",[wl_name,bl_name])
|
self.remove_insts("bitcell_array",[wl_name,bl_name])
|
||||||
|
|
||||||
# 2. Keep sense amps basd on BL
|
# 2. Keep sense amps basd on BL
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
word_size = 2
|
word_size = 2
|
||||||
num_words = 16
|
num_words = 128
|
||||||
num_banks = 1
|
num_banks = 1
|
||||||
|
|
||||||
tech_name = "freepdk45"
|
tech_name = "freepdk45"
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import re
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
# Current version of OpenRAM.
|
# Current version of OpenRAM.
|
||||||
VERSION = "1.01"
|
VERSION = "Beta"
|
||||||
|
|
||||||
USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
|
USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -989,7 +989,13 @@ class sram(design.design):
|
||||||
############################################################
|
############################################################
|
||||||
sp = open(sp_name, 'w')
|
sp = open(sp_name, 'w')
|
||||||
|
|
||||||
|
sp.write("**************************************************\n")
|
||||||
sp.write("* OpenRAM generated memory.\n")
|
sp.write("* OpenRAM generated memory.\n")
|
||||||
|
sp.write("* Words: {}\n".format(self.num_words))
|
||||||
|
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")
|
||||||
# This causes unit test mismatch
|
# This causes unit test mismatch
|
||||||
# sp.write("* Created: {0}\n".format(datetime.datetime.now()))
|
# sp.write("* Created: {0}\n".format(datetime.datetime.now()))
|
||||||
# sp.write("* User: {0}\n".format(getpass.getuser()))
|
# sp.write("* User: {0}\n".format(getpass.getuser()))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue