From c289637dabca66c3ad8660a9a976bc19920e512c Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Mon, 29 Jun 2020 23:18:31 -0700 Subject: [PATCH 1/4] Allowed sen's from multiple ports to be characterized --- compiler/base/graph_util.py | 2 ++ compiler/characterizer/delay.py | 38 +++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/compiler/base/graph_util.py b/compiler/base/graph_util.py index 5d1ee692..7ad6249c 100644 --- a/compiler/base/graph_util.py +++ b/compiler/base/graph_util.py @@ -65,6 +65,8 @@ class timing_graph(): # Call the recursive helper function to print all paths self.get_all_paths_util(src_node, dest_node, visited, path) debug.info(2, "Paths found={}".format(len(self.all_paths))) + for path in self.all_paths: + debug.info(2, "Paths ={}".format(path)) if reduce_paths: self.reduce_paths() diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index b5214198..202a0751 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -69,6 +69,8 @@ class delay(simulation): self.read_meas_lists = self.create_read_port_measurement_objects() self.write_meas_lists = self.create_write_port_measurement_objects() + debug.info(1,self.write_meas_lists) + debug.info(1,self.read_meas_lists) self.check_meas_names(self.read_meas_lists+self.write_meas_lists) def check_meas_names(self, measures_lists): @@ -124,6 +126,7 @@ class delay(simulation): # Other measurements associated with the read port not included in the liberty file read_measures.append(self.create_bitline_measurement_objects()) read_measures.append(self.create_debug_measurement_objects()) + debug.info(1,"debug "+str(read_measures[-1])) read_measures.append(self.create_read_bit_measures()) return read_measures @@ -138,17 +141,17 @@ class delay(simulation): self.bitline_volt_meas = [] self.bitline_volt_meas.append(voltage_at_measure("v_bl_READ_ZERO", - self.bl_name)) + self.bl_name+"{}")) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ZERO self.bitline_volt_meas.append(voltage_at_measure("v_br_READ_ZERO", - self.br_name)) + self.br_name+"{}")) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ZERO self.bitline_volt_meas.append(voltage_at_measure("v_bl_READ_ONE", - self.bl_name)) + self.bl_name+"{}")) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ONE self.bitline_volt_meas.append(voltage_at_measure("v_br_READ_ONE", - self.br_name)) + self.br_name+"{}")) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ONE return self.bitline_volt_meas @@ -182,11 +185,12 @@ class delay(simulation): meas.targ_name_no_port)) self.dout_volt_meas[-1].meta_str = meas.meta_str - self.sen_meas = delay_measure("delay_sen", self.clk_frmt, self.sen_name, "FALL", "RISE", measure_scale=1e9) + self.sen_meas = delay_measure("delay_sen", self.clk_frmt, self.sen_name+"{}", "FALL", "RISE", measure_scale=1e9) self.sen_meas.meta_str = sram_op.READ_ZERO self.sen_meas.meta_add_delay = True + self.dout_volt_meas.append(self.sen_meas) - return self.dout_volt_meas+[self.sen_meas] + return self.dout_volt_meas def create_read_bit_measures(self): """ Adds bit measurements for read0 and read1 cycles """ @@ -265,6 +269,7 @@ class delay(simulation): self.graph = graph_util.timing_graph() self.sram_spc_name = "X{}".format(self.sram.name) self.sram.build_graph(self.graph,self.sram_spc_name,self.pins) + debug.info(1,self.graph.all_paths) def set_internal_spice_names(self): """Sets important names for characterization such as Sense amp enable and internal bit nets.""" @@ -273,13 +278,27 @@ class delay(simulation): self.graph.get_all_paths('{}{}'.format("clk", port), '{}{}_{}'.format(self.dout_name, port, self.probe_data)) - self.sen_name = self.get_sen_name(self.graph.all_paths) + sen_with_port = self.get_sen_name(self.graph.all_paths) + if sen_with_port.endswith(str(port)): + self.sen_name = sen_with_port[:-len(str(port))] + else: + self.sen_name = sen_with_port + debug.info(2,"s_en name = {}".format(self.sen_name)) - self.bl_name,self.br_name = self.get_bl_name(self.graph.all_paths, port) + bl_name_port, br_name_port = self.get_bl_name(self.graph.all_paths, port) + if bl_name_port.endswith(str(port)): + self.bl_name = bl_name_port[:-len(str(port))] + else: + self.bl_name = bl_name_port + + if br_name_port.endswith(str(port)): + self.br_name = br_name_port[:-len(str(port))] + else: + self.br_name = br_name_port debug.info(2,"bl name={}, br name={}".format(self.bl_name,self.br_name)) - def get_sen_name(self, paths): + def get_sen_name(self, paths, assumed_port=None): """ Gets the signal name associated with the sense amp enable from input paths. Only expects a single path to contain the sen signal name. @@ -291,6 +310,7 @@ class delay(simulation): debug.check(len(sa_mods) == 1, "Only expected one type of Sense Amp. Cannot perform s_en checks.") enable_name = sa_mods[0].get_enable_name() sen_name = self.get_alias_in_path(paths, enable_name, sa_mods[0]) + return sen_name def get_bl_name(self, paths, port): From 0464e2df5dd0b9bfcff55ac7286a796c656f1f54 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Tue, 30 Jun 2020 01:37:52 -0700 Subject: [PATCH 2/4] Allowed bitline checks for multiple ports. --- compiler/base/graph_util.py | 2 -- compiler/characterizer/delay.py | 49 +++++++++++++++++---------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/compiler/base/graph_util.py b/compiler/base/graph_util.py index 7ad6249c..5d1ee692 100644 --- a/compiler/base/graph_util.py +++ b/compiler/base/graph_util.py @@ -65,8 +65,6 @@ class timing_graph(): # Call the recursive helper function to print all paths self.get_all_paths_util(src_node, dest_node, visited, path) debug.info(2, "Paths found={}".format(len(self.all_paths))) - for path in self.all_paths: - debug.info(2, "Paths ={}".format(path)) if reduce_paths: self.reduce_paths() diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 202a0751..b647e6e9 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -69,8 +69,6 @@ class delay(simulation): self.read_meas_lists = self.create_read_port_measurement_objects() self.write_meas_lists = self.create_write_port_measurement_objects() - debug.info(1,self.write_meas_lists) - debug.info(1,self.read_meas_lists) self.check_meas_names(self.read_meas_lists+self.write_meas_lists) def check_meas_names(self, measures_lists): @@ -126,7 +124,6 @@ class delay(simulation): # Other measurements associated with the read port not included in the liberty file read_measures.append(self.create_bitline_measurement_objects()) read_measures.append(self.create_debug_measurement_objects()) - debug.info(1,"debug "+str(read_measures[-1])) read_measures.append(self.create_read_bit_measures()) return read_measures @@ -141,17 +138,17 @@ class delay(simulation): self.bitline_volt_meas = [] self.bitline_volt_meas.append(voltage_at_measure("v_bl_READ_ZERO", - self.bl_name+"{}")) + self.bl_name)) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ZERO self.bitline_volt_meas.append(voltage_at_measure("v_br_READ_ZERO", - self.br_name+"{}")) + self.br_name)) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ZERO self.bitline_volt_meas.append(voltage_at_measure("v_bl_READ_ONE", - self.bl_name+"{}")) + self.bl_name)) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ONE self.bitline_volt_meas.append(voltage_at_measure("v_br_READ_ONE", - self.br_name+"{}")) + self.br_name)) self.bitline_volt_meas[-1].meta_str = sram_op.READ_ONE return self.bitline_volt_meas @@ -236,9 +233,10 @@ class delay(simulation): qbar_name = cell_name+'.'+str(storage_names[1]) # Bit measures, measurements times to be defined later. The measurement names must be unique - # but they is enforced externally - q_meas = voltage_at_measure("v_q_{}".format(meas_tag), q_name, has_port=False) - qbar_meas = voltage_at_measure("v_qbar_{}".format(meas_tag), qbar_name, has_port=False) + # but they is enforced externally. {} added to names to differentiate between ports allow the + # measurements are independent of the ports + q_meas = voltage_at_measure("v_q_{}{}".format(meas_tag, "{}"), q_name) + qbar_meas = voltage_at_measure("v_qbar_{}{}".format(meas_tag, "{}"), qbar_name) return {bit_polarity.NONINVERTING:q_meas, bit_polarity.INVERTING:qbar_meas} @@ -269,7 +267,6 @@ class delay(simulation): self.graph = graph_util.timing_graph() self.sram_spc_name = "X{}".format(self.sram.name) self.sram.build_graph(self.graph,self.sram_spc_name,self.pins) - debug.info(1,self.graph.all_paths) def set_internal_spice_names(self): """Sets important names for characterization such as Sense amp enable and internal bit nets.""" @@ -283,19 +280,24 @@ class delay(simulation): self.sen_name = sen_with_port[:-len(str(port))] else: self.sen_name = sen_with_port + debug.warning("Error occurred while determining SEN name. Can cause faults in simulation.") debug.info(2,"s_en name = {}".format(self.sen_name)) bl_name_port, br_name_port = self.get_bl_name(self.graph.all_paths, port) - if bl_name_port.endswith(str(port)): - self.bl_name = bl_name_port[:-len(str(port))] + port_pos = -1-len(str(self.probe_data))-len(str(port)) + if bl_name_port.endswith(str(port)+"_"+str(self.probe_data)): + self.bl_name = bl_name_port[:port_pos] +"{}"+ bl_name_port[port_pos+len(str(port)):] else: self.bl_name = bl_name_port + debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") - if br_name_port.endswith(str(port)): - self.br_name = br_name_port[:-len(str(port))] + if br_name_port.endswith(str(port)+"_"+str(self.probe_data)): + port_pos = -1-len(str(self.probe_data))-len(str(port)) + self.br_name = br_name_port[:port_pos] +"{}"+ br_name_port[port_pos+len(str(port)):] else: self.br_name = br_name_port + debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") debug.info(2,"bl name={}, br name={}".format(self.bl_name,self.br_name)) def get_sen_name(self, paths, assumed_port=None): @@ -763,13 +765,10 @@ class delay(simulation): # Loop through all targeted ports and collect delays and powers. result = [{} for i in self.all_ports] - - # First, check that the memory has the right values at the right times - if not self.check_bit_measures(self.read_bit_meas) or \ - not self.check_bit_measures(self.write_bit_meas): - return(False,{}) - for port in self.targ_write_ports: + if not self.check_bit_measures(self.write_bit_meas, port): + return(False,{}) + debug.info(2, "Checking write values for port {}".format(port)) write_port_dict = {} for measure in self.write_lib_meas: @@ -781,6 +780,10 @@ class delay(simulation): for port in self.targ_read_ports: + # First, check that the memory has the right values at the right times + if not self.check_bit_measures(self.read_bit_meas, port): + return(False,{}) + debug.info(2, "Checking read delay values for port {}".format(port)) # Check sen timing, then bitlines, then general measurements. if not self.check_sen_measure(port): @@ -857,7 +860,7 @@ class delay(simulation): return dout_success - def check_bit_measures(self, bit_measures): + def check_bit_measures(self, bit_measures, port): """ Checks the measurements which represent the internal storage voltages at the end of the read cycle. @@ -865,7 +868,7 @@ class delay(simulation): success = False for polarity, meas_list in bit_measures.items(): for meas in meas_list: - val = meas.retrieve_measure() + val = meas.retrieve_measure(port=port) debug.info(2,"{}={}".format(meas.name, val)) if type(val) != float: continue From 119bd94689dfac8ed7be26f917b4f4d077be055d Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Thu, 2 Jul 2020 15:43:23 -0700 Subject: [PATCH 3/4] Fixed warnings with single port characterization. Cleaned up some signal names. --- compiler/characterizer/delay.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index b647e6e9..20188625 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -235,8 +235,9 @@ class delay(simulation): # Bit measures, measurements times to be defined later. The measurement names must be unique # but they is enforced externally. {} added to names to differentiate between ports allow the # measurements are independent of the ports - q_meas = voltage_at_measure("v_q_{}{}".format(meas_tag, "{}"), q_name) - qbar_meas = voltage_at_measure("v_qbar_{}{}".format(meas_tag, "{}"), qbar_name) + q_meas = voltage_at_measure("v_q_{}".format(meas_tag), q_name) + qbar_meas = voltage_at_measure("v_qbar_{}".format(meas_tag), qbar_name) + debug.info(1,"meas name:{}".format(q_meas.name)) return {bit_polarity.NONINVERTING:q_meas, bit_polarity.INVERTING:qbar_meas} @@ -286,15 +287,19 @@ class delay(simulation): bl_name_port, br_name_port = self.get_bl_name(self.graph.all_paths, port) port_pos = -1-len(str(self.probe_data))-len(str(port)) + if bl_name_port.endswith(str(port)+"_"+str(self.probe_data)): self.bl_name = bl_name_port[:port_pos] +"{}"+ bl_name_port[port_pos+len(str(port)):] + elif not bl_name_port[port_pos].isdigit(): # single port SRAM case, bl will not be numbered eg bl_0 + self.bl_name = bl_name_port else: self.bl_name = bl_name_port debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") if br_name_port.endswith(str(port)+"_"+str(self.probe_data)): - port_pos = -1-len(str(self.probe_data))-len(str(port)) self.br_name = br_name_port[:port_pos] +"{}"+ br_name_port[port_pos+len(str(port)):] + elif not br_name_port[port_pos].isdigit(): # single port SRAM case, bl will not be numbered eg bl_0 + self.br_name = br_name_port else: self.br_name = br_name_port debug.warning("Error occurred while determining bitline names. Can cause faults in simulation.") From fb34338fdfc52c3ab0daeb6a5a559cee00372432 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Thu, 2 Jul 2020 18:00:02 -0700 Subject: [PATCH 4/4] Removed debug statements --- compiler/characterizer/delay.py | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 20188625..b7faaec3 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -237,7 +237,6 @@ class delay(simulation): # measurements are independent of the ports q_meas = voltage_at_measure("v_q_{}".format(meas_tag), q_name) qbar_meas = voltage_at_measure("v_qbar_{}".format(meas_tag), qbar_name) - debug.info(1,"meas name:{}".format(q_meas.name)) return {bit_polarity.NONINVERTING:q_meas, bit_polarity.INVERTING:qbar_meas}