Separate measure statements from stimulus

This commit is contained in:
Bugra Onal 2022-09-09 11:48:13 -07:00
parent fcfb9391f6
commit b9dbad4750
2 changed files with 27 additions and 12 deletions

View File

@ -388,12 +388,17 @@ class delay(simulation):
temp_stim = "{0}/{1}".format(OPTS.openram_temp, self.delay_stim_sp)
self.sf = open(temp_stim, "w")
# creates and opens measure file for writing
self.delay_meas_sp = "delay_meas.sp"
temp_meas = "{0}/{1}".format(OPTS.openram_temp, self.delay_meas_sp)
self.mf = open(temp_meas, "w")
if OPTS.spice_name == "spectre":
self.sf.write("simulator lang=spice\n")
self.sf.write("* Delay stimulus for period of {0}n load={1}fF slew={2}ns\n\n".format(self.period,
self.load,
self.slew))
self.stim = stimuli(self.sf, self.corner)
self.stim = stimuli(self.sf, self.mf, self.corner)
# include files in stimulus file
self.stim.write_include(self.trim_sp_file)
@ -418,6 +423,7 @@ class delay(simulation):
t_rise=self.slew,
t_fall=self.slew)
self.stim.write_include(temp_meas)
# self.load_all_measure_nets()
self.write_delay_measures()
# self.write_simulation_saves()
@ -426,6 +432,7 @@ class delay(simulation):
self.stim.write_control(self.cycle_times[-1] + self.period)
self.sf.close()
self.mf.close()
def write_power_stimulus(self, trim):
""" Creates a stimulus file to measure leakage power only.
@ -440,6 +447,11 @@ class delay(simulation):
self.sf.write("* Power stimulus for period of {0}n\n\n".format(self.period))
self.stim = stimuli(self.sf, self.corner)
# creates and opens measure file for writing
self.power_meas_sp = "power_meas.sp"
temp_meas = "{0}/{1}".format(opts.openram_temp, self.power_meas_sp)
self.mf = open(temp_meas, "w")
# include UNTRIMMED files in stimulus file
if trim:
self.stim.write_include(self.trim_sp_file)
@ -470,12 +482,14 @@ class delay(simulation):
for port in self.all_ports:
self.stim.gen_constant(sig_name="CLK{0}".format(port), v_val=0)
self.stim.write_include(temp_meas)
self.write_power_measures()
# run until the end of the cycle time
self.stim.write_control(2 * self.period)
self.sf.close()
self.mf.close()
def get_measure_variants(self, port, measure_obj, measure_type=None):
"""
@ -587,15 +601,15 @@ class delay(simulation):
# Output some comments to aid where cycles start and
# what is happening
for comment in self.cycle_comments:
self.sf.write("* {0}\n".format(comment))
self.mf.write("* {0}\n".format(comment))
self.sf.write("\n")
for read_port in self.targ_read_ports:
self.sf.write("* Read ports {0}\n".format(read_port))
self.mf.write("* Read ports {0}\n".format(read_port))
self.write_delay_measures_read_port(read_port)
for write_port in self.targ_write_ports:
self.sf.write("* Write ports {0}\n".format(write_port))
self.mf.write("* Write ports {0}\n".format(write_port))
self.write_delay_measures_write_port(write_port)
def load_pex_net(self, net: str):

View File

@ -22,7 +22,7 @@ from globals import OPTS
class stimuli():
""" Class for providing stimuli functions """
def __init__(self, stim_file, corner):
def __init__(self, stim_file, meas_file, corner):
self.vdd_name = "vdd"
self.gnd_name = "gnd"
self.pmos_name = tech.spice["pmos"]
@ -31,6 +31,7 @@ class stimuli():
self.tx_length = tech.drc["minlength_channel"]
self.sf = stim_file
self.mf = meas_file
(self.process, self.voltage, self.temperature) = corner
found = False
@ -136,7 +137,7 @@ class stimuli():
offset,
t_rise,
t_fall,
0.5*period-0.5*t_rise-0.5*t_fall,
0.5 * period - 0.5 * t_rise - 0.5 * t_fall,
period))
def gen_pwl(self, sig_name, clk_times, data_values, period, slew, setup):
@ -181,7 +182,7 @@ class stimuli():
def gen_meas_delay(self, 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={4}n TARG v({5}) VAL={6} {7}=1 TD={8}n\n\n"
self.sf.write(measure_string.format(meas_name.lower(),
self.mf.write(measure_string.format(meas_name.lower(),
trig_name,
trig_val,
trig_dir,
@ -194,7 +195,7 @@ class stimuli():
def gen_meas_find_voltage(self, meas_name, trig_name, targ_name, trig_val, trig_dir, trig_td):
""" Creates the .meas statement for the measurement of delay """
measure_string=".meas tran {0} FIND v({1}) WHEN v({2})={3}v {4}=1 TD={5}n \n\n"
self.sf.write(measure_string.format(meas_name.lower(),
self.mf.write(measure_string.format(meas_name.lower(),
targ_name,
trig_name,
trig_val,
@ -204,7 +205,7 @@ class stimuli():
def gen_meas_find_voltage_at_time(self, meas_name, targ_name, time_at):
""" Creates the .meas statement for voltage at time"""
measure_string=".meas tran {0} FIND v({1}) AT={2}n \n\n"
self.sf.write(measure_string.format(meas_name.lower(),
self.mf.write(measure_string.format(meas_name.lower(),
targ_name,
time_at))
@ -215,15 +216,15 @@ class stimuli():
power_exp = "power"
else:
power_exp = "par('(-1*v(" + str(self.vdd_name) + ")*I(v" + str(self.vdd_name) + "))')"
self.sf.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name.lower(),
self.mf.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name.lower(),
power_exp,
t_initial,
t_final))
def gen_meas_value(self, meas_name, dout, t_initial, t_final):
measure_string=".meas tran {0} FIND v({1}) AT={2}n\n\n".format(meas_name.lower(), dout, (t_initial + t_final) / 2)
#measure_string=".meas tran {0} AVG v({1}) FROM={2}n TO={3}n\n\n".format(meas_name.lower(), dout, t_initial, t_final)
self.sf.write(measure_string)
# measure_string=".meas tran {0} AVG v({1}) FROM={2}n TO={3}n\n\n".format(meas_name.lower(), dout, t_initial, t_final)
self.mf.write(measure_string)
def write_control(self, end_time, runlvl=4):
""" Write the control cards to run and end the simulation """