From 23368c0fcfa9fad84dd4a9c2d2f6aca0366e93b5 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Tue, 25 May 2021 14:49:28 -0700 Subject: [PATCH] Updated tests and elmore model with load_slew lists. Changed naming on characterization output to not clash with testing. --- compiler/characterizer/delay.py | 4 +- compiler/characterizer/elmore.py | 51 +++++++++---------- compiler/characterizer/lib.py | 4 +- compiler/tests/21_hspice_delay_test.py | 6 ++- compiler/tests/21_model_delay_test.py | 11 +++- .../tests/21_ngspice_delay_extra_rows_test.py | 6 ++- .../tests/21_ngspice_delay_global_test.py | 6 ++- compiler/tests/21_ngspice_delay_test.py | 6 ++- 8 files changed, 58 insertions(+), 36 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index ff87759d..3b2f56db 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -1157,8 +1157,8 @@ class delay(simulation): debug.warning("Path delay lists not correctly generated for characterizations of more than 1 load,slew") # Get and save the path delays bl_names, bl_delays, sen_names, sen_delays = self.get_delay_lists(self.path_delays) - char_sram_data["bl_path_delays"] = bl_delays - char_sram_data["sen_path_delays"] = sen_delays + char_sram_data["bl_path_measures"] = bl_delays + char_sram_data["sen_path_measures"] = sen_delays char_sram_data["bl_path_names"] = bl_names char_sram_data["sen_path_names"] = sen_names # FIXME: low-to-high delays are altered to be independent of the period. This makes the lib results less accurate. diff --git a/compiler/characterizer/elmore.py b/compiler/characterizer/elmore.py index b9f99f02..549b3367 100644 --- a/compiler/characterizer/elmore.py +++ b/compiler/characterizer/elmore.py @@ -30,7 +30,7 @@ class elmore(simulation): self.create_signal_names() self.add_graph_exclusions() - def get_lib_values(self, slews, loads): + def get_lib_values(self, load_slews): """ Return the analytical model results for the SRAM. """ @@ -53,33 +53,32 @@ class elmore(simulation): # Set delay/power for slews and loads port_data = self.get_empty_measure_data_dict() - power = self.analytical_power(slews, loads) + power = self.analytical_power(load_slews) debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)') max_delay = 0.0 - for slew in slews: - for load in loads: - # Calculate delay based on slew and load - path_delays = self.graph.get_timing(bl_path, self.corner, slew, load) + for load,slew in load_slews: + # Calculate delay based on slew and load + path_delays = self.graph.get_timing(bl_path, self.corner, slew, load) - total_delay = self.sum_delays(path_delays) - max_delay = max(max_delay, total_delay.delay) - debug.info(1, - '{}, {}, {}, {}'.format(slew, - load, - total_delay.delay / 1e3, - total_delay.slew / 1e3)) + total_delay = self.sum_delays(path_delays) + max_delay = max(max_delay, total_delay.delay) + debug.info(1, + '{}, {}, {}, {}'.format(slew, + load, + total_delay.delay / 1e3, + total_delay.slew / 1e3)) - # Delay is only calculated on a single port and replicated for now. - for port in self.all_ports: - for mname in self.delay_meas_names + self.power_meas_names: - if "power" in mname: - port_data[port][mname].append(power.dynamic) - elif "delay" in mname and port in self.read_ports: - port_data[port][mname].append(total_delay.delay / 1e3) - elif "slew" in mname and port in self.read_ports: - port_data[port][mname].append(total_delay.slew / 1e3) - else: - debug.error("Measurement name not recognized: {}".format(mname), 1) + # Delay is only calculated on a single port and replicated for now. + for port in self.all_ports: + for mname in self.delay_meas_names + self.power_meas_names: + if "power" in mname: + port_data[port][mname].append(power.dynamic) + elif "delay" in mname and port in self.read_ports: + port_data[port][mname].append(total_delay.delay / 1e3) + elif "slew" in mname and port in self.read_ports: + port_data[port][mname].append(total_delay.slew / 1e3) + else: + debug.error("Measurement name not recognized: {}".format(mname), 1) # Margin for error in period. Calculated by averaging required margin for a small and large # memory. FIXME: margin is quite large, should be looked into. @@ -92,11 +91,11 @@ class elmore(simulation): return (sram_data, port_data) - def analytical_power(self, slews, loads): + def analytical_power(self, load_slews): """Get the dynamic and leakage power from the SRAM""" # slews unused, only last load is used - load = loads[-1] + load = load_slews[-1][0] power = self.sram.analytical_power(self.corner, load) # convert from nW to mW power.dynamic /= 1e6 diff --git a/compiler/characterizer/lib.py b/compiler/characterizer/lib.py index 5ecc0bf4..b936f746 100644 --- a/compiler/characterizer/lib.py +++ b/compiler/characterizer/lib.py @@ -647,9 +647,9 @@ class lib: # Add to the OPTS to be written out as part of the extended OPTS file # FIXME: should be written to datasheet, current version is simplifies current use of this if not self.use_model: - OPTS.sen_path_delays = self.char_sram_results["sen_path_delays"] + OPTS.sen_path_delays = self.char_sram_results["sen_path_measures"] OPTS.sen_path_names = self.char_sram_results["sen_path_names"] - OPTS.bl_path_delays = self.char_sram_results["bl_path_delays"] + OPTS.bl_path_delays = self.char_sram_results["bl_path_measures"] OPTS.bl_path_names = self.char_sram_results["bl_path_names"] diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 6a5e8f52..584e705f 100755 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -50,7 +50,11 @@ class timing_sram_test(openram_test): import tech loads = [tech.spice["dff_in_cap"]*4] slews = [tech.spice["rise_time"]*2] - data, port_data = d.analyze(probe_address, probe_data, slews, loads) + load_slews = [] + for slew in slews: + for load in loads: + load_slews.append((load, slew)) + data, port_data = d.analyze(probe_address, probe_data, load_slews) #Combine info about port into all data data.update(port_data[0]) diff --git a/compiler/tests/21_model_delay_test.py b/compiler/tests/21_model_delay_test.py index e5c4b96d..28c3def1 100755 --- a/compiler/tests/21_model_delay_test.py +++ b/compiler/tests/21_model_delay_test.py @@ -55,13 +55,17 @@ class model_delay_test(openram_test): import tech loads = [tech.spice["dff_in_cap"]*4] slews = [tech.spice["rise_time"]*2] + load_slews = [] + for slew in slews: + for load in loads: + load_slews.append((load, slew)) # Run a spice characterization - spice_data, port_data = d.analyze(probe_address, probe_data, slews, loads) + spice_data, port_data = d.analyze(probe_address, probe_data, load_slews) spice_data.update(port_data[0]) # Run analytical characterization - model_data, port_data = m.get_lib_values(slews, loads) + model_data, port_data = m.get_lib_values(load_slews) model_data.update(port_data[0]) # Only compare the delays @@ -79,6 +83,9 @@ class model_delay_test(openram_test): else: self.assertTrue(False) # other techs fail + print('spice_delays', spice_delays) + print('model_delays', model_delays) + # Check if no too many or too few results self.assertTrue(len(spice_delays.keys())==len(model_delays.keys())) diff --git a/compiler/tests/21_ngspice_delay_extra_rows_test.py b/compiler/tests/21_ngspice_delay_extra_rows_test.py index 6d1b5567..f5bcc658 100755 --- a/compiler/tests/21_ngspice_delay_extra_rows_test.py +++ b/compiler/tests/21_ngspice_delay_extra_rows_test.py @@ -51,7 +51,11 @@ class timing_sram_test(openram_test): import tech loads = [tech.spice["dff_in_cap"]*4] slews = [tech.spice["rise_time"]*2] - data, port_data = d.analyze(probe_address, probe_data, slews, loads) + load_slews = [] + for slew in slews: + for load in loads: + load_slews.append((load, slew)) + data, port_data = d.analyze(probe_address, probe_data, load_slews) #Combine info about port into all data data.update(port_data[0]) diff --git a/compiler/tests/21_ngspice_delay_global_test.py b/compiler/tests/21_ngspice_delay_global_test.py index 47def503..78b764f4 100755 --- a/compiler/tests/21_ngspice_delay_global_test.py +++ b/compiler/tests/21_ngspice_delay_global_test.py @@ -58,7 +58,11 @@ class timing_sram_test(openram_test): import tech loads = [tech.spice["dff_in_cap"]*4] slews = [tech.spice["rise_time"]*2] - data, port_data = d.analyze(probe_address, probe_data, slews, loads) + load_slews = [] + for slew in slews: + for load in loads: + load_slews.append((load, slew)) + data, port_data = d.analyze(probe_address, probe_data, load_slews) #Combine info about port into all data data.update(port_data[0]) diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 9a0d224c..15fdaca3 100755 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -50,7 +50,11 @@ class timing_sram_test(openram_test): import tech loads = [tech.spice["dff_in_cap"]*4] slews = [tech.spice["rise_time"]*2] - data, port_data = d.analyze(probe_address, probe_data, slews, loads) + load_slews = [] + for slew in slews: + for load in loads: + load_slews.append((load, slew)) + data, port_data = d.analyze(probe_address, probe_data, load_slews) #Combine info about port into all data data.update(port_data[0])