Fix duplicate paths for timing checks

This commit is contained in:
Matt Guthaus 2019-07-25 13:25:58 -07:00
parent 80df996720
commit 0bb41b8a5d
2 changed files with 34 additions and 12 deletions

View File

@ -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)
return "Nodes: {}\nEdges:{} ".format(list(self.graph), self.graph)

View File

@ -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)