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

View File

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