From 4f3340e973ee87a8c84d913cff0a816713aab5f3 Mon Sep 17 00:00:00 2001 From: Hunter Nichols Date: Tue, 25 Jun 2019 16:37:35 -0700 Subject: [PATCH] Cleaned up graph additions to characterizer. --- compiler/base/graph_util.py | 17 +-------------- compiler/base/hierarchy_design.py | 19 +---------------- compiler/characterizer/delay.py | 35 +++++++++++++------------------ compiler/pgates/pand2.py | 2 +- 4 files changed, 18 insertions(+), 55 deletions(-) diff --git a/compiler/base/graph_util.py b/compiler/base/graph_util.py index af4d0888..b6ac4677 100644 --- a/compiler/base/graph_util.py +++ b/compiler/base/graph_util.py @@ -56,7 +56,7 @@ 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(1, "Paths found={}".format(len(self.all_paths))) + debug.info(2, "Paths found={}".format(len(self.all_paths))) return self.all_paths @@ -69,7 +69,6 @@ class timing_graph(): # If current vertex is same as destination, then print # current path[] if cur_node == dest_node: - debug.info(1,"{}".format(path)) self.all_paths.append(copy.deepcopy(path)) else: # If current vertex is not destination @@ -82,20 +81,6 @@ class timing_graph(): path.pop() visited.remove(cur_node) - def get_path_preconvergence_point(self, path1, path2): - """Assuming the inputs paths have the same starting point and end point, the - paths should split and converge at some point before/at the last stage. Finds the - point before convergence.""" - debug.check(path1[0] == path2[0], "Paths must start from the same point.") - debug.check(path1[-1] == path2[-1], "Paths must end from the same point.") - #Paths must end at the same point, so the paths are traversed backwards to find - #point of convergence. There could be multiple points, only finds first. - for point1,point2 in zip(reversed(path1), reversed(path2)): - if point1 != point2: - return (point1,point2) - debug.info(1,"Pre-convergence point not found, paths are equals.") - return path1[0],path2[0] - def __str__(self): """ override print function output """ return "Nodes: {}\nEdges:{} ".format(list(self.graph), self.graph) \ No newline at end of file diff --git a/compiler/base/hierarchy_design.py b/compiler/base/hierarchy_design.py index a75e5a3c..a8a191af 100644 --- a/compiler/base/hierarchy_design.py +++ b/compiler/base/hierarchy_design.py @@ -147,7 +147,6 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): """Given a list of nets, will compare the internal alias of a mod to determine if the nets have a connection to this mod's net (but not inst). """ - #path_nets = ['xsram_0.xbank0.bl0_7'] if exclusion_set == None: exclusion_set = set() try: @@ -155,31 +154,17 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): except AttributeError: self.name_dict = {} self.build_names(self.name_dict, inst_name, port_nets) - #debug.info(1,"names={}".format(list(self.name_dict))) aliases = [] for net in path_nets: net = net.lower() int_net = self.name_dict[net]['int_net'] int_mod = self.name_dict[net]['mod'] - # debug.info(1,"int_net={}".format(int_net)) - # debug.info(1,"int_mod={}".format(int_mod.name)) - # debug.info(1,"alias_net={}".format(alias)) - # debug.info(1,"alias_mod={}".format(alias_mod.name)) - # debug.info(1,"mod id={}".format(id(alias_mod))) if int_mod.is_net_alias(int_net, alias, alias_mod, exclusion_set): aliases.append(net) - # debug.info(1,"Alias found\n") - # else: - # debug.info(1,"Alias not found\n") - debug.info(1,"Aliases Found={}".format(aliases)) return aliases def is_net_alias(self, known_net, net_alias, mod, exclusion_set): - """Checks if the alias_net in mod is the same as the input net.""" - # debug.info(1,"self name={}".format(self.name)) - # debug.info(1,"self mod id={}".format(id(self))) - # debug.info(1,"self pins={}".format(self.pins)) - # debug.info(1,"known_net={}".format(known_net)) + """Checks if the alias_net in input mod is the same as the input net for this mod (self).""" if self in exclusion_set: return False #Check ports of this mod @@ -193,8 +178,6 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout): if self.is_net_alias_name_check(known_net, inst_conn, net_alias, mod): return True elif inst_conn.lower() == known_net.lower() and subinst.mod not in mod_set: - # debug.info(1,"found matching conn={}".format(inst_conn)) - # debug.info(1,"Setting known pin={}".format(mod_pin)) if subinst.mod.is_net_alias(mod_pin, net_alias, mod, exclusion_set): return True mod_set.add(subinst.mod) diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index a927ef69..6c5be96c 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -216,17 +216,19 @@ 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,"{}".format(self.graph)) + + def set_internal_spice_names(self): + """Sets important names for characterization such as Sense amp enable and internal bit nets.""" port = 0 self.graph.get_all_paths('{}{}'.format(tech.spice["clk"], port), \ '{}{}_{}'.format(self.dout_name, port, self.probe_data)) self.sen_name = self.get_sen_name(self.graph.all_paths) - debug.info(1,"s_en name = {}".format(self.sen_name)) + debug.info(2,"s_en name = {}".format(self.sen_name)) self.bl_name,self.br_name = self.get_bl_name(self.graph.all_paths) - debug.info(1,"bl name={}, br name={}".format(self.bl_name,self.br_name)) - + debug.info(2,"bl name={}, br name={}".format(self.bl_name,self.br_name)) + def get_sen_name(self, paths): """Gets the signal name associated with the sense amp enable from input paths. Only expects a single path to contain the sen signal name.""" @@ -245,13 +247,7 @@ class delay(simulation): cell_mod = self.get_primary_cell_mod(cell_mods) elif len(cell_mods)==0: debug.error("No bitcells found. Cannot determine bitline names.", 1) - #Any sense amp instantiated should be identical, any change to that - #will require some identification to determine the mod desired. - # debug.check(self.are_mod_pins_equal(cell_mods), "Only expected one type of bitcell. Cannot perform bitline checks") - # debug.info(1,"num pbitcells={}".format(len(cell_mods))) - # debug.info(1,"cell ids={}".format([id(i) for i in cell_mods])) - - #cell_mods = cell_mods[1:] + cell_bl = cell_mod.get_bl_name() cell_br = cell_mod.get_br_name() @@ -705,9 +701,8 @@ class delay(simulation): def check_sen_measure(self, port): """Checks that the sen occurred within a half-period""" - self.sen_meas sen_val = self.sen_meas.retrieve_measure(port=port) - debug.info(1,"S_EN delay={} ns".format(sen_val)) + debug.info(2,"S_EN delay={} ns".format(sen_val)) if self.sen_meas.meta_add_delay: max_delay = self.period/2 else: @@ -729,7 +724,7 @@ class delay(simulation): elif self.br_name == meas.targ_name_no_port: br_vals[meas.meta_str] = val - debug.info(1,"{}={}".format(meas.name,val)) + debug.info(2,"{}={}".format(meas.name,val)) bl_check = False for meas in self.debug_volt_meas: @@ -762,24 +757,23 @@ class delay(simulation): for polarity, meas_list in self.bit_meas.items(): for meas in meas_list: val = meas.retrieve_measure() - debug.info(1,"{}={}".format(meas.name, val)) + debug.info(2,"{}={}".format(meas.name, val)) if type(val) != float: continue meas_cycle = meas.meta_str + #Loose error conditions. Assume it's not metastable but account for noise during reads. if (meas_cycle == sram_op.READ_ZERO and polarity == bit_polarity.NONINVERTING) or\ (meas_cycle == sram_op.READ_ONE and polarity == bit_polarity.INVERTING): - success = val < self.vdd_voltage*.1 + success = val < self.vdd_voltage/2 elif (meas_cycle == sram_op.READ_ZERO and polarity == bit_polarity.INVERTING) or\ (meas_cycle == sram_op.READ_ONE and polarity == bit_polarity.NONINVERTING): - success = val > self.vdd_voltage*.9 + success = val > self.vdd_voltage/2 if not success: debug.info(1,("Wrong value detected on probe bit during read cycle. " "Check writes and control logic for bugs.\n measure={}, op={}, " - "bit_storage={}").format(meas.name, meas_cycle.name, polarity.name)) + "bit_storage={}, V(bit)={}").format(meas.name, meas_cycle.name, polarity.name,val)) return success - - def check_bitline_meas(self, v_discharged_bl, v_charged_bl): """Checks the value of the discharging bitline. Confirms s_en timing errors. Returns true if the bitlines are at there expected value.""" @@ -991,6 +985,7 @@ class delay(simulation): """Sets values which are dependent on the data address/bit being tested.""" self.set_probe(probe_address, probe_data) self.create_graph() + self.set_internal_spice_names() self.create_measurement_names() self.create_measurement_objects() diff --git a/compiler/pgates/pand2.py b/compiler/pgates/pand2.py index add59565..f7c26032 100644 --- a/compiler/pgates/pand2.py +++ b/compiler/pgates/pand2.py @@ -18,7 +18,7 @@ class pand2(pgate.pgate): This is a simple buffer used for driving loads. """ def __init__(self, name, size=1, height=None): - debug.info(1, "reating pnand2 {}".format(name)) + debug.info(1, "Creating pnand2 {}".format(name)) self.add_comment("size: {}".format(size)) self.size = size