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 import debug
|
||||||
from openram.base.vector import vector
|
from openram.base.vector import vector
|
||||||
|
from openram.base.vector3d import vector3d
|
||||||
from openram import OPTS
|
from openram import OPTS
|
||||||
from .graph import graph
|
from .graph import graph
|
||||||
from .graph_shape import graph_shape
|
from .graph_shape import graph_shape
|
||||||
|
|
@ -75,9 +76,51 @@ class signal_escape_router(router):
|
||||||
self.replace_layout_pins()
|
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):
|
def add_perimeter_fake_pins(self):
|
||||||
"""
|
"""
|
||||||
Add the fake pins on the perimeter to where the signals will be routed.
|
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
|
ll, ur = self.bbox
|
||||||
|
|
@ -118,17 +161,44 @@ class signal_escape_router(router):
|
||||||
self.fake_pins.append(pin)
|
self.fake_pins.append(pin)
|
||||||
|
|
||||||
|
|
||||||
def get_closest_perimeter_fake_pin(self, pin):
|
def create_fake_pin(self, pin):
|
||||||
""" Return the closest fake pin for the given pin. """
|
""" Create a fake pin on the perimeter orthogonal to the given pin. """
|
||||||
|
|
||||||
min_dist = float("inf")
|
ll, ur = self.bbox
|
||||||
close_fake = None
|
c = pin.center()
|
||||||
for fake in self.fake_pins:
|
|
||||||
dist = pin.distance(fake)
|
# Find the closest edge
|
||||||
if dist < min_dist:
|
ll_diff_x = abs(c.x - ll.x)
|
||||||
min_dist = dist
|
ll_diff_y = abs(c.y - ll.y)
|
||||||
close_fake = fake
|
ur_diff_x = abs(c.x - ur.x)
|
||||||
return close_fake
|
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):
|
def get_route_pairs(self, pin_names):
|
||||||
|
|
@ -137,7 +207,7 @@ class signal_escape_router(router):
|
||||||
to_route = []
|
to_route = []
|
||||||
for name in pin_names:
|
for name in pin_names:
|
||||||
pin = next(iter(self.pins[name]))
|
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)))
|
to_route.append((pin, fake, pin.distance(fake)))
|
||||||
return sorted(to_route, key=lambda x: x[2])
|
return sorted(to_route, key=lambda x: x[2])
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue