mirror of https://github.com/VLSIDA/OpenRAM.git
Use method=gear for ngspice to improve convergence. Split TD for trig and targ in measure statements. Start waiting for clk neg edge trigger at clk pos edge.
This commit is contained in:
parent
92095e52f7
commit
a8e1abdce8
|
|
@ -40,9 +40,9 @@ class delay():
|
|||
|
||||
|
||||
def write_stimulus(self, period, load, slew):
|
||||
"""Creates a stimulus file for simulations to probe a certain bitcell, given an address and data-position of the data-word
|
||||
(probe-address form: '111010000' LSB=0, MSB=1)
|
||||
(probe_data form: number corresponding to the bit position of data-bus, begins with position 0)
|
||||
""" Creates a stimulus file for simulations to probe a bitcell at a given clock period.
|
||||
Address and bit were previously set with set_probe().
|
||||
Input slew (in ns) and output capacitive load (in fF) are required for charaterization.
|
||||
"""
|
||||
self.check_arguments()
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ class delay():
|
|||
# creates and opens stimulus file for writing
|
||||
temp_stim = "{0}/stim.sp".format(OPTS.openram_temp)
|
||||
self.sf = open(temp_stim, "w")
|
||||
self.sf.write("* Stimulus for period of {0}n load={1} slew={2}\n\n".format(period,load,slew))
|
||||
self.sf.write("* Stimulus for period of {0}n load={1}fF slew={2}ns\n\n".format(period,load,slew))
|
||||
|
||||
# include files in stimulus file
|
||||
model_list = tech.spice["fet_models"] + [self.sram_sp_file]
|
||||
|
|
@ -141,7 +141,8 @@ class delay():
|
|||
targ_val=targ_val,
|
||||
trig_dir="FALL",
|
||||
targ_dir="FALL",
|
||||
td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
trig_td=self.cycle_times[self.read0_cycle],
|
||||
targ_td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="DELAY1",
|
||||
|
|
@ -151,27 +152,30 @@ class delay():
|
|||
targ_val=targ_val,
|
||||
trig_dir="FALL",
|
||||
targ_dir="RISE",
|
||||
td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
trig_td=self.cycle_times[self.read1_cycle],
|
||||
targ_td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="SLEW0",
|
||||
trig_name=targ_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=0.9*self.vdd,
|
||||
targ_val=0.1*self.vdd,
|
||||
trig_val=0.8*self.vdd,
|
||||
targ_val=0.2*self.vdd,
|
||||
trig_dir="FALL",
|
||||
targ_dir="FALL",
|
||||
td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
trig_td=self.cycle_times[self.read0_cycle],
|
||||
targ_td=self.cycle_times[self.read0_cycle]+0.5*period)
|
||||
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="SLEW1",
|
||||
trig_name=targ_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=0.1*self.vdd,
|
||||
targ_val=0.9*self.vdd,
|
||||
trig_val=0.2*self.vdd,
|
||||
targ_val=0.8*self.vdd,
|
||||
trig_dir="RISE",
|
||||
targ_dir="RISE",
|
||||
td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
trig_td=self.cycle_times[self.read1_cycle],
|
||||
targ_td=self.cycle_times[self.read1_cycle]+0.5*period)
|
||||
|
||||
# add measure statements for power
|
||||
t_initial = self.cycle_times[self.write0_cycle]
|
||||
|
|
|
|||
|
|
@ -116,10 +116,10 @@ class lib:
|
|||
self.lib.write(" output_threshold_pct_fall : 50.0 ;\n")
|
||||
self.lib.write(" input_threshold_pct_rise : 50.0 ;\n")
|
||||
self.lib.write(" output_threshold_pct_rise : 50.0 ;\n")
|
||||
self.lib.write(" slew_lower_threshold_pct_fall : 10.0 ;\n")
|
||||
self.lib.write(" slew_upper_threshold_pct_fall : 90.0 ;\n")
|
||||
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(" slew_lower_threshold_pct_fall : 20.0 ;\n")
|
||||
self.lib.write(" slew_upper_threshold_pct_fall : 80.0 ;\n")
|
||||
self.lib.write(" slew_lower_threshold_pct_rise : 20.0 ;\n")
|
||||
self.lib.write(" slew_upper_threshold_pct_rise : 80.0 ;\n\n")
|
||||
|
||||
self.lib.write(" default_cell_leakage_power : 0.0 ;\n")
|
||||
self.lib.write(" default_leakage_power_density : 0.0 ;\n")
|
||||
|
|
|
|||
|
|
@ -145,7 +145,8 @@ class setup_hold():
|
|||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=dout_rise_or_fall,
|
||||
td=1.9*self.period)
|
||||
trig_td=1.9*self.period,
|
||||
targ_td=1.9*self.period)
|
||||
|
||||
targ_name = "data"
|
||||
# Start triggers right after initialize value is returned to normal
|
||||
|
|
@ -158,7 +159,8 @@ class setup_hold():
|
|||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=din_rise_or_fall,
|
||||
td=1.2*self.period)
|
||||
trig_td=1.2*self.period,
|
||||
targ_td=1.2*self.period)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -218,17 +218,18 @@ def get_inverse_value(value):
|
|||
debug.error("Invalid value to get an inverse of: {0}".format(value))
|
||||
|
||||
|
||||
def gen_meas_delay(stim_file, meas_name, trig_name, targ_name, trig_val, targ_val, trig_dir, targ_dir, td):
|
||||
def gen_meas_delay(stim_file, meas_name, trig_name, targ_name, trig_val, targ_val, trig_dir, targ_dir, trig_td, targ_td):
|
||||
"""Creates the .meas statement for the measurement of delay"""
|
||||
measure_string=".meas tran {0} TRIG v({1}) VAL={2} {3}=1 TD={7}n TARG v({4}) VAL={5} {6}=1 TD={7}n\n\n"
|
||||
measure_string=".meas tran {0} TRIG v({1}) VAL={2} {3}=1 TD={4}n TARG v({5}) VAL={6} {7}=1 TD={8}n\n\n"
|
||||
stim_file.write(measure_string.format(meas_name,
|
||||
trig_name,
|
||||
trig_val,
|
||||
trig_dir,
|
||||
trig_td,
|
||||
targ_name,
|
||||
targ_val,
|
||||
targ_dir,
|
||||
td))
|
||||
targ_td))
|
||||
|
||||
def gen_meas_power(stim_file, meas_name, t_initial, t_final):
|
||||
"""Creates the .meas statement for the measurement of avg power"""
|
||||
|
|
@ -246,7 +247,13 @@ def gen_meas_power(stim_file, meas_name, t_initial, t_final):
|
|||
def write_control(stim_file, end_time):
|
||||
# UIC is needed for ngspice to converge
|
||||
stim_file.write(".TRAN 5p {0}n UIC\n".format(end_time))
|
||||
stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE\n")
|
||||
if OPTS.spice_name == "ngspice":
|
||||
# ngspice sometimes has convergence problems if not using gear method
|
||||
# which is more accurate, but slower than the default trapezoid method
|
||||
stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE method=gear\n")
|
||||
else:
|
||||
stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE\n")
|
||||
|
||||
# create plots for all signals
|
||||
stim_file.write("* probe is used for hspice/xa, while plot is used in ngspice\n")
|
||||
if OPTS.debug_level>0:
|
||||
|
|
|
|||
|
|
@ -48,7 +48,10 @@ class trim_spice():
|
|||
|
||||
# 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)
|
||||
if self.col_addr_size>1:
|
||||
col_address = int(address[0:self.col_addr_size],2)
|
||||
else:
|
||||
col_address = 0
|
||||
# 1. Keep cells in the bitcell array based on WL and BL
|
||||
wl_name = "wl[{}]".format(wl_address)
|
||||
bl_name = "bl[{}]".format(self.words_per_row*data_bit + col_address)
|
||||
|
|
|
|||
Loading…
Reference in New Issue