mirror of https://github.com/VLSIDA/OpenRAM.git
Connect graph nodes better by hopping over removed nodes
This commit is contained in:
parent
e501e0ef4f
commit
38110a55e1
|
|
@ -90,7 +90,6 @@ class graph:
|
||||||
# Create the graph
|
# Create the graph
|
||||||
x_values, y_values = self.generate_cartesian_values()
|
x_values, y_values = self.generate_cartesian_values()
|
||||||
self.generate_graph_nodes(x_values, y_values)
|
self.generate_graph_nodes(x_values, y_values)
|
||||||
self.remove_blocked_nodes()
|
|
||||||
self.save_end_nodes()
|
self.save_end_nodes()
|
||||||
debug.info(3, "Number of nodes in the routing graph: {}".format(len(self.nodes)))
|
debug.info(3, "Number of nodes in the routing graph: {}".format(len(self.nodes)))
|
||||||
|
|
||||||
|
|
@ -109,6 +108,7 @@ class graph:
|
||||||
y_offset = vector(0, self.router.offset)
|
y_offset = vector(0, self.router.offset)
|
||||||
for shape in [self.source, self.target]:
|
for shape in [self.source, self.target]:
|
||||||
aspect_ratio = shape.width() / shape.height()
|
aspect_ratio = shape.width() / shape.height()
|
||||||
|
# FIXME: Aspect ratio may not be the best way to determine this
|
||||||
# If the pin is tall or fat, add two points on the ends
|
# If the pin is tall or fat, add two points on the ends
|
||||||
if aspect_ratio <= 0.5: # Tall pin
|
if aspect_ratio <= 0.5: # Tall pin
|
||||||
points = [shape.bc() + y_offset, shape.uc() - y_offset]
|
points = [shape.bc() + y_offset, shape.uc() - y_offset]
|
||||||
|
|
@ -124,7 +124,7 @@ class graph:
|
||||||
offset = drc["grid"]
|
offset = drc["grid"]
|
||||||
for blockage in self.graph_blockages:
|
for blockage in self.graph_blockages:
|
||||||
ll, ur = blockage.rect
|
ll, ur = blockage.rect
|
||||||
# Add minimum offset to the blockage corner nodes to prevent overlaps
|
# Add minimum offset to the blockage corner nodes to prevent overlap
|
||||||
x_values.update([ll.x - offset, ur.x + offset])
|
x_values.update([ll.x - offset, ur.x + offset])
|
||||||
y_values.update([ll.y - offset, ur.y + offset])
|
y_values.update([ll.y - offset, ur.y + offset])
|
||||||
|
|
||||||
|
|
@ -143,44 +143,45 @@ class graph:
|
||||||
orthogonal neighbors.
|
orthogonal neighbors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
y_len = len(y_values)
|
# Generate all nodes
|
||||||
left_offset = -(y_len * 2)
|
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
for x in x_values:
|
for x in x_values:
|
||||||
for y in y_values:
|
for y in y_values:
|
||||||
below_node = graph_node([x, y, 0])
|
for z in [0, 1]:
|
||||||
above_node = graph_node([x, y, 1])
|
self.nodes.append(graph_node([x, y, z]))
|
||||||
|
|
||||||
# Connect these two neighbors
|
# Mark nodes that will be removed
|
||||||
below_node.add_neighbor(above_node)
|
self.mark_blocked_nodes()
|
||||||
|
|
||||||
# Find potential orthogonal neighbor nodes
|
# Connect closest nodes that won't be removed
|
||||||
belows = []
|
def search(index, condition, shift):
|
||||||
aboves = []
|
""" Search and connect neighbor nodes. """
|
||||||
count = len(self.nodes) // 2
|
base_nodes = self.nodes[index:index+2]
|
||||||
if count % y_len: # Down
|
found = [hasattr(base_nodes[0], "remove"),
|
||||||
belows.append(-2)
|
hasattr(base_nodes[1], "remove")]
|
||||||
aboves.append(-1)
|
while condition(index) and not all(found):
|
||||||
if count >= y_len: # Left
|
nodes = self.nodes[index - shift:index - shift + 2]
|
||||||
belows.append(left_offset)
|
for k in range(2):
|
||||||
aboves.append(left_offset + 1)
|
if not found[k] and not hasattr(nodes[k], "remove"):
|
||||||
|
found[k] = True
|
||||||
|
if not self.is_probe_blocked(base_nodes[k].center, nodes[k].center):
|
||||||
|
base_nodes[k].add_neighbor(nodes[k])
|
||||||
|
index -= shift
|
||||||
|
y_len = len(y_values)
|
||||||
|
for i in range(0, len(self.nodes), 2):
|
||||||
|
search(i, lambda count: (count / 2) % y_len, 2) # Down
|
||||||
|
search(i, lambda count: (count / 2) >= y_len, y_len * 2) # Left
|
||||||
|
# FIXME: Avoid vias for inter-layer edges
|
||||||
|
if not hasattr(self.nodes[i], "remove") and \
|
||||||
|
not hasattr(self.nodes[i + 1], "remove"):
|
||||||
|
self.nodes[i].add_neighbor(self.nodes[i + 1])
|
||||||
|
|
||||||
# Add these connections if not blocked by a blockage
|
# Remove marked nodes
|
||||||
for i in belows:
|
self.remove_blocked_nodes()
|
||||||
node = self.nodes[i]
|
|
||||||
if not self.is_probe_blocked(below_node.center, node.center):
|
|
||||||
below_node.add_neighbor(node)
|
|
||||||
for i in aboves:
|
|
||||||
node = self.nodes[i]
|
|
||||||
if not self.is_probe_blocked(above_node.center, node.center):
|
|
||||||
above_node.add_neighbor(node)
|
|
||||||
|
|
||||||
self.nodes.append(below_node)
|
|
||||||
self.nodes.append(above_node)
|
|
||||||
|
|
||||||
|
|
||||||
def remove_blocked_nodes(self):
|
def mark_blocked_nodes(self):
|
||||||
""" Remove the graph nodes that are blocked by a blockage. """
|
""" Mark graph nodes to be removed that are blocked by a blockage. """
|
||||||
|
|
||||||
for i in range(len(self.nodes) - 1, -1, -1):
|
for i in range(len(self.nodes) - 1, -1, -1):
|
||||||
node = self.nodes[i]
|
node = self.nodes[i]
|
||||||
|
|
@ -190,11 +191,20 @@ class graph:
|
||||||
# If the blockage is an inflated routable, remove if outside
|
# If the blockage is an inflated routable, remove if outside
|
||||||
# the routable shape
|
# the routable shape
|
||||||
if self.inside_shape(point, blockage) and (not self.is_routable(blockage) or not self.inside_shape(point, blockage.inflated_from)):
|
if self.inside_shape(point, blockage) and (not self.is_routable(blockage) or not self.inside_shape(point, blockage.inflated_from)):
|
||||||
node.remove_all_neighbors()
|
node.remove = True
|
||||||
self.nodes.remove(node)
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def remove_blocked_nodes(self):
|
||||||
|
""" Remove graph nodes that are marked to be removed. """
|
||||||
|
|
||||||
|
for i in range(len(self.nodes) - 1, -1, -1):
|
||||||
|
node = self.nodes[i]
|
||||||
|
if hasattr(node, "remove"):
|
||||||
|
node.remove_all_neighbors()
|
||||||
|
self.nodes.remove(node)
|
||||||
|
|
||||||
|
|
||||||
def save_end_nodes(self):
|
def save_end_nodes(self):
|
||||||
""" Save graph nodes that are inside source and target pins. """
|
""" Save graph nodes that are inside source and target pins. """
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ class graph_router(router_tech):
|
||||||
|
|
||||||
def find_blockages(self, shape_name=None):
|
def find_blockages(self, shape_name=None):
|
||||||
""" Find all blockages in the routing layers. """
|
""" Find all blockages in the routing layers. """
|
||||||
debug.info(1, "Finding blockages...")
|
debug.info(2, "Finding blockages...")
|
||||||
|
|
||||||
# Keep current blockages here
|
# Keep current blockages here
|
||||||
prev_blockages = self.blockages[:]
|
prev_blockages = self.blockages[:]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue