From 33f1b924a4bef749b7e4fa79aa115f103a8e32ad Mon Sep 17 00:00:00 2001 From: Eren Dogan Date: Mon, 22 May 2023 18:16:49 -0700 Subject: [PATCH] Avoid blockages when connecting Hanan points --- compiler/router/navigation_graph.py | 21 +++++++-------------- compiler/router/navigation_node.py | 13 +++++++++---- compiler/router/navigation_router.py | 20 +++++++++++--------- compiler/router/navigation_utils.py | 23 +++++++++++++++++++++++ 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/compiler/router/navigation_graph.py b/compiler/router/navigation_graph.py index b9864067..9985f1dd 100644 --- a/compiler/router/navigation_graph.py +++ b/compiler/router/navigation_graph.py @@ -78,13 +78,19 @@ class navigation_graph: min_neighbor = None for j in range(i + 1, len(self.nodes)): neighbor = self.nodes[j] + # Skip if not on the same layer if node.center.z != neighbor.center.z: continue + # Calculate the distance vector and distance value distance_vector = neighbor.center - node.center distance = node.center.distance(neighbor.center) + # Skip if not connected rectilinearly if (distance_vector.x or (distance_vector.y * d.y <= 0)) and \ (distance_vector.y or (distance_vector.x * d.x <= 0)): continue + # Skip if this connection is blocked by a blockage + if is_probe_blocked(node.center, neighbor.center, self.graph_blockages): + continue if distance < min_dist: min_dist = distance min_neighbor = neighbor @@ -156,7 +162,7 @@ class navigation_graph: # Update neighbor scores for node in current.neighbors: - tentative_score = self.get_edge_cost(current, node) + g_scores[current.id] + tentative_score = current.get_edge_cost(node) + g_scores[current.id] if node.id not in g_scores or tentative_score < g_scores[node.id]: came_from[node.id] = current g_scores[node.id] = tentative_score @@ -165,16 +171,3 @@ class navigation_graph: # Return None if not connected return None - - - def get_edge_cost(self, source, target): - """ """ - - if target in source.neighbors: - is_vertical = source.center.x == target.center.x - layer_dist = source.center.distance(target.center) - if is_vertical != bool(source.center.z): - layer_dist *= 2 - via_dist = abs(source.center.z - target.center.z) * 2 - return layer_dist + via_dist - return float("inf") diff --git a/compiler/router/navigation_node.py b/compiler/router/navigation_node.py index 87a5935d..e8acdd9b 100644 --- a/compiler/router/navigation_node.py +++ b/compiler/router/navigation_node.py @@ -40,9 +40,14 @@ class navigation_node: node.neighbors.remove(self) - def get_edge_cost(self, node): - """ Return the cost of going to node. """ + def get_edge_cost(self, other): + """ Get the cost of going from this node to the other node. """ - if node in self.neighbors: - return self.center.distance(node.center) + abs(self.center.z - node.center.z) + if other in self.neighbors: + is_vertical = self.center.x == other.center.x + layer_dist = self.center.distance(other.center) + if is_vertical != bool(self.center.z): + layer_dist *= 2 + via_dist = abs(self.center.z - other.center.z) * 2 + return layer_dist + via_dist return float("inf") diff --git a/compiler/router/navigation_router.py b/compiler/router/navigation_router.py index 8827ba3c..a6228d43 100644 --- a/compiler/router/navigation_router.py +++ b/compiler/router/navigation_router.py @@ -35,7 +35,8 @@ class navigation_router(router_tech): def route(self, vdd_name="vdd", gnd_name="gnd"): """ Route the given pins in the given order. """ - debug.info(1, "Running router for {}...".format(pins)) + #debug.info(1, "Running router for {}...".format(pins)) + self.write_debug_gds(gds_name="before.gds") # Prepare gdsMill to find pins and blockages self.design.gds_write(self.gds_filename) @@ -63,7 +64,7 @@ class navigation_router(router_tech): # Create the path shapes on layout self.add_path(path) - self.write_debug_gds(source=vdd_0, target=vdd_1) + self.write_debug_gds(gds_name="after.gds", source=vdd_0, target=vdd_1) def find_pins(self, pin_name): @@ -142,13 +143,14 @@ class navigation_router(router_tech): """ """ # Display the inflated blockage - for blockage in self.nav.graph_blockages: - self.add_object_info(blockage, "blockage") - for node in self.nav.nodes: - offset = (node.center.x, node.center.y) - self.design.add_label(text="O", - layer="text", - offset=offset) + if "nav" in self.__dict__: + for blockage in self.nav.graph_blockages: + self.add_object_info(blockage, "blockage") + for node in self.nav.nodes: + offset = (node.center.x, node.center.y) + self.design.add_label(text="O", + layer="text", + offset=offset) if source: self.add_object_info(source, "source") if target: diff --git a/compiler/router/navigation_utils.py b/compiler/router/navigation_utils.py index cf4e93c3..9ce2cba5 100644 --- a/compiler/router/navigation_utils.py +++ b/compiler/router/navigation_utils.py @@ -7,6 +7,29 @@ Utility functions for navigation router. """ +def is_probe_blocked(p1, p2, blockages): + """ + Return if a probe sent from p1 to p2 encounters a blockage. + The probe must be sent vertically or horizontally. + This method assumes that blockages are rectangular. + """ + + # Check if any blockage blocks this probe + for blockage in blockages: + ll, ur = blockage.rect + right_x = ur[0] + upper_y = ur[1] + left_x = ll[0] + lower_y = ll[1] + # Check if blocked vertically + if is_between(left_x, right_x, p1.x) and (is_between(p1.y, p2.y, upper_y) or is_between(p1.y, p2.y, lower_y)): + return True + # Check if blocked horizontally + if is_between(upper_y, lower_y, p1.y) and (is_between(p1.x, p2.x, left_x) or is_between(p1.x, p2.x, right_x)): + return True + return False + + def is_in_region(point, region): """"""