From b9dbad4750ba26e1471756110668caa47a7ae0c5 Mon Sep 17 00:00:00 2001 From: Bugra Onal Date: Fri, 9 Sep 2022 11:48:13 -0700 Subject: [PATCH] Separate measure statements from stimulus --- compiler/characterizer/delay.py | 22 ++++++++++++++++++---- compiler/characterizer/stimuli.py | 17 +++++++++-------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 80540b94..10781df8 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -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): diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index b9e4b3c7..8c91b49f 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -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 """