From b1e4c83373797e771a7ce55bc199042593bfc887 Mon Sep 17 00:00:00 2001 From: Bugra Onal Date: Fri, 9 Sep 2022 12:51:53 -0700 Subject: [PATCH] Move measure functions from stimuli to measure --- compiler/characterizer/delay.py | 2 + compiler/characterizer/functional.py | 1 + compiler/characterizer/measurements.py | 55 ++++++++++++++++++++------ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 10781df8..dc52e8b4 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -698,6 +698,8 @@ class delay(simulation): self.sf.write("\n* Measure statements for idle leakage power\n") # add measure statements for power + # TODO: Convert to measure statement insted of using stimuli + # measure = power_measure('leakage_power', t_initial = self.period t_final = 2 * self.period self.stim.gen_meas_power(meas_name="leakage_power", diff --git a/compiler/characterizer/functional.py b/compiler/characterizer/functional.py index b6a57fb3..c0a0a980 100644 --- a/compiler/characterizer/functional.py +++ b/compiler/characterizer/functional.py @@ -484,6 +484,7 @@ class functional(simulation): measure_name, voltage_value, eo_period)) + # TODO: Convert to measurement statement instead of stimuli self.stim.gen_meas_value(meas_name=measure_name, dout=signal_name, t_initial=t_initial, diff --git a/compiler/characterizer/measurements.py b/compiler/characterizer/measurements.py index d4811d63..c29ed920 100644 --- a/compiler/characterizer/measurements.py +++ b/compiler/characterizer/measurements.py @@ -27,16 +27,17 @@ class spice_measurement(ABC): def get_measure_function(self): return None + @abstractmethod + def measure_function(self): + return None + @abstractmethod def get_measure_values(self): return None def write_measure(self, stim_obj, input_tuple): - measure_func = self.get_measure_function() - if measure_func is None: - debug.error("Did not set measure function", 1) measure_vals = self.get_measure_values(*input_tuple) - measure_func(stim_obj, *measure_vals) + self.measure_func(stim_obj, *measure_vals) def retrieve_measure(self, port=None): self.port_error_check(port) @@ -72,8 +73,18 @@ class delay_measure(spice_measurement): spice_measurement.__init__(self, measure_name, measure_scale, has_port) self.set_meas_constants(trig_name, targ_name, trig_dir_str, targ_dir_str, trig_vdd, targ_vdd) - def get_measure_function(self): - return stimuli.gen_meas_delay + def measure_function(self, stim_obj, 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" + stim_obj.mf.write(measure_string.format(meas_name.lower(), + trig_name, + trig_val, + trig_dir, + trig_td, + targ_name, + targ_val, + targ_dir, + targ_td)) def set_meas_constants(self, trig_name, targ_name, trig_dir_str, targ_dir_str, trig_vdd, targ_vdd): """Set the constants for this measurement: signal names, directions, and trigger scales""" @@ -136,8 +147,17 @@ class power_measure(spice_measurement): spice_measurement.__init__(self, measure_name, measure_scale, has_port) self.set_meas_constants(power_type) - def get_measure_function(self): - return stimuli.gen_meas_power + def measure_function(self, stim_obj, meas_name, t_initial, t_final): + """ Creates the .meas statement for the measurement of avg power """ + # power mea cmd is different in different spice: + if OPTS.spice_name == "hspice": + power_exp = "power" + else: + power_exp = "par('(-1*v(" + str(self.vdd_name) + ")*I(v" + str(self.vdd_name) + "))')" + stim_obj.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 set_meas_constants(self, power_type): """Sets values useful for power simulations. This value is only meta related to the lib file (rise/fall)""" @@ -161,8 +181,15 @@ class voltage_when_measure(spice_measurement): spice_measurement.__init__(self, measure_name, measure_scale, has_port) self.set_meas_constants(trig_name, targ_name, trig_dir_str, trig_vdd) - def get_measure_function(self): - return stimuli.gen_meas_find_voltage + def gen_meas_find_voltage(self, stim_obj, 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" + stim_obj.mf.write(measure_string.format(meas_name.lower(), + targ_name, + trig_name, + trig_val, + trig_dir, + trig_td)) def set_meas_constants(self, trig_name, targ_name, trig_dir_str, trig_vdd): """Sets values useful for power simulations. This value is only meta related to the lib file (rise/fall)""" @@ -195,8 +222,12 @@ class voltage_at_measure(spice_measurement): spice_measurement.__init__(self, measure_name, measure_scale, has_port) self.set_meas_constants(targ_name) - def get_measure_function(self): - return stimuli.gen_meas_find_voltage_at_time + def gen_meas_find_voltage_at_time(self, stim_obj, 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" + stim_obj.mf.write(measure_string.format(meas_name.lower(), + targ_name, + time_at)) def set_meas_constants(self, targ_name): """Sets values useful for power simulations. This value is only meta related to the lib file (rise/fall)"""