mirror of https://github.com/VLSIDA/OpenRAM.git
Perform signal escape routing in smaller regions
This commit is contained in:
parent
9df3c2ac59
commit
53cc99f5c1
|
|
@ -5,6 +5,7 @@
|
|||
#
|
||||
from openram import debug
|
||||
from openram.base.vector import vector
|
||||
from openram.base.vector3d import vector3d
|
||||
from openram import OPTS
|
||||
from .graph import graph
|
||||
from .graph_shape import graph_shape
|
||||
|
|
@ -75,9 +76,51 @@ class signal_escape_router(router):
|
|||
self.replace_layout_pins()
|
||||
|
||||
|
||||
def prepare_path(self, path):
|
||||
"""
|
||||
Override the `prepare_path` method from the `router` class to prevent
|
||||
overflows from the SRAM layout area.
|
||||
"""
|
||||
|
||||
ll, ur = self.bbox
|
||||
nodes = super().prepare_path(path)
|
||||
new_nodes = []
|
||||
for i in range(len(nodes)):
|
||||
node = nodes[i]
|
||||
c = node.center
|
||||
|
||||
# Haven't overflown yet
|
||||
if ll.x < c.x and c.x < ur.x and ll.y < c.y and c.y < ur.y:
|
||||
new_nodes.append(node)
|
||||
continue
|
||||
|
||||
# Snap the pin to the perimeter and break the iteration
|
||||
ll_diff_x = abs(c.x - ll.x)
|
||||
ll_diff_y = abs(c.y - ll.y)
|
||||
ur_diff_x = abs(c.x - ur.x)
|
||||
ur_diff_y = abs(c.y - ur.y)
|
||||
min_diff = min(ll_diff_x, ll_diff_y, ur_diff_x, ur_diff_y)
|
||||
|
||||
if min_diff == ll_diff_x:
|
||||
fake_center = vector3d(ll.x + self.half_wire, c.y, c.z)
|
||||
if min_diff == ll_diff_y:
|
||||
fake_center = vector3d(c.x, ll.y + self.half_wire, c.z)
|
||||
if min_diff == ur_diff_x:
|
||||
fake_center = vector3d(ur.x - self.half_wire, c.y, c.z)
|
||||
if min_diff == ur_diff_y:
|
||||
fake_center = vector3d(c.x, ur.y - self.half_wire, c.z)
|
||||
|
||||
node.center = fake_center
|
||||
new_nodes.append(node)
|
||||
break
|
||||
return new_nodes
|
||||
|
||||
|
||||
def add_perimeter_fake_pins(self):
|
||||
"""
|
||||
Add the fake pins on the perimeter to where the signals will be routed.
|
||||
These perimeter fake pins are only used to replace layout pins at the
|
||||
end of routing.
|
||||
"""
|
||||
|
||||
ll, ur = self.bbox
|
||||
|
|
@ -118,17 +161,44 @@ class signal_escape_router(router):
|
|||
self.fake_pins.append(pin)
|
||||
|
||||
|
||||
def get_closest_perimeter_fake_pin(self, pin):
|
||||
""" Return the closest fake pin for the given pin. """
|
||||
def create_fake_pin(self, pin):
|
||||
""" Create a fake pin on the perimeter orthogonal to the given pin. """
|
||||
|
||||
min_dist = float("inf")
|
||||
close_fake = None
|
||||
for fake in self.fake_pins:
|
||||
dist = pin.distance(fake)
|
||||
if dist < min_dist:
|
||||
min_dist = dist
|
||||
close_fake = fake
|
||||
return close_fake
|
||||
ll, ur = self.bbox
|
||||
c = pin.center()
|
||||
|
||||
# Find the closest edge
|
||||
ll_diff_x = abs(c.x - ll.x)
|
||||
ll_diff_y = abs(c.y - ll.y)
|
||||
ur_diff_x = abs(c.x - ur.x)
|
||||
ur_diff_y = abs(c.y - ur.y)
|
||||
min_diff = min(ll_diff_x, ll_diff_y, ur_diff_x, ur_diff_y)
|
||||
|
||||
# Keep the fake pin out of the SRAM layout are so that they won't be
|
||||
# blocked by previous signals if they're on the same orthogonal line
|
||||
if min_diff == ll_diff_x:
|
||||
fake_center = vector(ll.x - self.track_wire * 2, c.y)
|
||||
vertical = True
|
||||
if min_diff == ll_diff_y:
|
||||
fake_center = vector(c.x, ll.y - self.track_wire * 2)
|
||||
vertical = False
|
||||
if min_diff == ur_diff_x:
|
||||
fake_center = vector(ur.x + self.track_wire * 2, c.y)
|
||||
vertical = True
|
||||
if min_diff == ur_diff_y:
|
||||
fake_center = vector(c.x, ur.y + self.track_wire * 2)
|
||||
vertical = False
|
||||
|
||||
# Create the fake pin shape
|
||||
layer = self.get_layer(int(not vertical))
|
||||
half_wire_vector = vector([self.half_wire] * 2)
|
||||
nll = fake_center - half_wire_vector
|
||||
nur = fake_center + half_wire_vector
|
||||
rect = [nll, nur]
|
||||
pin = graph_shape(name="fake",
|
||||
rect=rect,
|
||||
layer_name_pp=layer)
|
||||
return pin
|
||||
|
||||
|
||||
def get_route_pairs(self, pin_names):
|
||||
|
|
@ -137,7 +207,7 @@ class signal_escape_router(router):
|
|||
to_route = []
|
||||
for name in pin_names:
|
||||
pin = next(iter(self.pins[name]))
|
||||
fake = self.get_closest_perimeter_fake_pin(pin)
|
||||
fake = self.create_fake_pin(pin)
|
||||
to_route.append((pin, fake, pin.distance(fake)))
|
||||
return sorted(to_route, key=lambda x: x[2])
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue