From 0bb41b8a5df2d48ecc8836aee43b86b367535611 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Thu, 25 Jul 2019 13:25:58 -0700 Subject: [PATCH] Fix duplicate paths for timing checks --- compiler/base/graph_util.py | 35 ++++++++++++++++++++++--------- compiler/modules/control_logic.py | 11 ++++++++-- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/compiler/base/graph_util.py b/compiler/base/graph_util.py index b6ac4677..7cf8ee6f 100644 --- a/compiler/base/graph_util.py +++ b/compiler/base/graph_util.py @@ -10,8 +10,9 @@ from vector import vector from pin_layout import pin_layout class timing_graph(): - """Implements a directed graph - Nodes are currently just Strings. + """ + Implements a directed graph + Nodes are currently just Strings. """ def __init__(self): @@ -20,30 +21,34 @@ class timing_graph(): def add_edge(self, src_node, dest_node): """Adds edge to graph. Nodes added as well if they do not exist.""" + src_node = src_node.lower() dest_node = dest_node.lower() self.graph[src_node].add(dest_node) def add_node(self, node): """Add node to graph with no edges""" + node = node.lower() if not node in self.graph: self.graph[node] = set() def remove_edges(self, node): + """Helper function to remove edges, useful for removing vdd/gnd""" node = node.lower() self.graph[node] = set() - def get_all_paths(self, src_node, dest_node, rmv_rail_nodes=True): + def get_all_paths(self, src_node, dest_node, remove_rail_nodes=True, reduce_paths=True): """Traverse all paths from source to destination""" + src_node = src_node.lower() dest_node = dest_node.lower() - #Remove vdd and gnd by default - #Will require edits if separate supplies are implemented. - if rmv_rail_nodes: - #Names are also assumed. + # Remove vdd and gnd by default + # Will require edits if separate supplies are implemented. + if remove_rail_nodes: + # Names are also assumed. self.remove_edges('vdd') self.remove_edges('gnd') @@ -57,11 +62,20 @@ 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))) - + + if reduce_paths: + self.reduce_paths() + return self.all_paths + + def reduce_paths(self): + """ Remove any path that is a subset of another path """ + + self.all_paths = [p1 for p1 in self.all_paths if not any(set(p1)<=set(p2) for p2 in self.all_paths if p1 is not p2)] def get_all_paths_util(self, cur_node, dest_node, visited, path): """Recursive function to find all paths in a Depth First Search manner""" + # Mark the current node as visited and store in path visited.add(cur_node) path.append(cur_node) @@ -72,7 +86,7 @@ class timing_graph(): self.all_paths.append(copy.deepcopy(path)) else: # If current vertex is not destination - #Recur for all the vertices adjacent to this vertex + # Recur for all the vertices adjacent to this vertex for node in self.graph[cur_node]: if node not in visited: self.get_all_paths_util(node, dest_node, visited, path) @@ -83,4 +97,5 @@ class timing_graph(): def __str__(self): """ override print function output """ - return "Nodes: {}\nEdges:{} ".format(list(self.graph), self.graph) \ No newline at end of file + + return "Nodes: {}\nEdges:{} ".format(list(self.graph), self.graph) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 7843de93..ca65b57b 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -909,6 +909,7 @@ class control_logic(design.design): def get_wl_sen_delays(self): """Gets a list of the stages and delays in order of their path.""" + if self.sen_stage_efforts == None or self.wl_stage_efforts == None: debug.error("Model delays not calculated for SRAM.", 1) wl_delays = logical_effort.calculate_delays(self.wl_stage_efforts) @@ -917,6 +918,7 @@ class control_logic(design.design): def analytical_delay(self, corner, slew, load): """Gets the analytical delay from clk input to wl_en output""" + stage_effort_list = [] #Calculate the load on clk_buf_bar ext_clk_buf_cout = self.sram.get_clk_bar_cin() @@ -944,8 +946,10 @@ class control_logic(design.design): return stage_effort_list def get_clk_buf_cin(self): - """Get the loads that are connected to the buffered clock. - Includes all the DFFs and some logic.""" + """ + Get the loads that are connected to the buffered clock. + Includes all the DFFs and some logic. + """ #Control logic internal load int_clk_buf_cap = self.inv.get_cin() + self.ctrl_dff_array.get_clk_cin() + self.and2.get_cin() @@ -957,6 +961,7 @@ class control_logic(design.design): def get_gated_clk_bar_cin(self): """Get intermediates net gated_clk_bar's capacitance""" + total_cin = 0 total_cin += self.wl_en_driver.get_cin() if self.port_type == 'rw': @@ -965,4 +970,6 @@ class control_logic(design.design): def graph_exclude_dffs(self): """Exclude dffs from graph as they do not represent critical path""" + self.graph_inst_exclude.add(self.ctrl_dff_inst) + self.graph_inst_exclude.add(self.w_en_gate_inst)