Refactor and cleanup router grids.

This commit is contained in:
mrg
2021-01-15 13:25:57 -08:00
parent 683f4214b2
commit 69fe050bad
8 changed files with 101 additions and 109 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ class grid:
# The bounds are in grids for this
# This is really lower left bottom layer and upper right top layer in 3D.
self.ll = vector3d(ll.x, ll.y, 0).scale(self.track_factor).round()
self.ur = vector3d(ur.x, ur.y, 1).scale(self.track_factor).round()
self.ur = vector3d(ur.x, ur.y, 0).scale(self.track_factor).round()
# let's leave the map sparse, cells are created on demand to reduce memory
self.map={}
@@ -124,7 +124,7 @@ class grid:
def add_perimeter_target(self, side="all"):
debug.info(3, "Adding perimeter target")
print(self.ll, self.ur)
perimeter_list = []
# Add the left/right columns
if side=="all" or side=="left":
+30 -7
View File
@@ -28,7 +28,7 @@ class router(router_tech):
route on a given layer. This is limited to two layer routes.
It populates blockages on a grid class.
"""
def __init__(self, layers, design, gds_filename=None, route_track_width=1):
def __init__(self, layers, design, gds_filename=None, bbox=None, route_track_width=1):
"""
This will instantiate a copy of the gds file or the module at (0,0) and
route on top of this. The blockages from the gds/module will be
@@ -83,12 +83,35 @@ class router(router_tech):
# A list of path blockages (they might be expanded for wide metal DRC)
self.path_blockages = []
# The boundary will determine the limits to the size
# of the routing grid
self.boundary = self.layout.measureBoundary(self.top_name)
# These must be un-indexed to get rid of the matrix type
self.ll = vector(self.boundary[0][0], self.boundary[0][1])
self.ur = vector(self.boundary[1][0], self.boundary[1][1])
self.init_bbox(bbox)
def init_bbox(self, bbox=None):
"""
Initialize the ll,ur values with the paramter or using the layout boundary.
"""
if not bbox:
# The boundary will determine the limits to the size
# of the routing grid
self.boundary = self.layout.measureBoundary(self.top_name)
# These must be un-indexed to get rid of the matrix type
self.ll = vector(self.boundary[0][0], self.boundary[0][1])
self.ur = vector(self.boundary[1][0], self.boundary[1][1])
else:
self.ll, self.ur = bbox
self.bbox = (self.ll, self.ur)
size = self.ur - self.ll
debug.info(1, "Size: {0} x {1}".format(size.x, size.y))
def get_bbox(self):
return self.bbox
def create_routing_grid(self, router_type, bbox=None):
"""
Create a sprase routing grid with A* expansion functions.
"""
self.init_bbox(bbox)
self.rg = router_type(self.ll, self.ur, self.track_width)
def clear_pins(self):
"""
+10 -13
View File
@@ -17,20 +17,12 @@ class signal_escape_router(router):
A router that routes signals to perimeter and makes pins.
"""
def __init__(self, layers, design, gds_filename=None):
def __init__(self, layers, design, bbox=None, gds_filename=None):
"""
This will route on layers in design. It will get the blockages from
either the gds file name or the design itself (by saving to a gds file).
"""
router.__init__(self, layers, design, gds_filename, 1)
def create_routing_grid(self):
"""
Create a sprase routing grid with A* expansion functions.
"""
size = self.ur - self.ll
debug.info(1,"Size: {0} x {1}".format(size.x, size.y))
self.rg = signal_grid(self.ll, self.ur, self.track_width)
router.__init__(self, layers, design, gds_filename, bbox)
def perimeter_dist(self, pin_name):
"""
@@ -47,7 +39,7 @@ class signal_escape_router(router):
Takes a list of tuples (name, side) and routes them. After routing,
it removes the old pin and places a new one on the perimeter.
"""
self.create_routing_grid()
self.create_routing_grid(signal_grid)
start_time = datetime.now()
self.find_pins_and_blockages(pin_names)
@@ -91,8 +83,9 @@ class signal_escape_router(router):
# Marks the grid cells all along the perimeter as a target
self.add_perimeter_target(side)
#if pin_name == "dout1[1]":
# self.write_debug_gds("preroute.gds", False)
# if pin_name == "dout0[3]":
# self.write_debug_gds("pre_route.gds", False)
# breakpoint()
# Actually run the A* router
if self.run_router(detour_scale=detour_scale):
@@ -100,6 +93,10 @@ class signal_escape_router(router):
self.cell.replace_layout_pin(pin_name, new_pin)
return
# if pin_name == "dout0[3]":
# self.write_debug_gds("pre_route.gds", False)
# breakpoint()
self.write_debug_gds("debug_route.gds", True)
+3 -15
View File
@@ -15,24 +15,12 @@ class signal_router(router):
route on a given layer. This is limited to two layer routes.
"""
def __init__(self, layers, design, gds_filename=None):
def __init__(self, layers, design, gds_filename=None, bbox=None):
"""
This will route on layers in design. It will get the blockages from
either the gds file name or the design itself (by saving to a gds file).
"""
router.__init__(self, layers, design, gds_filename)
def create_routing_grid(self):
"""
Create a sprase routing grid with A* expansion functions.
"""
# We will add a halo around the boundary
# of this many tracks
size = self.ur - self.ll
debug.info(1, "Size: {0} x {1}".format(size.x, size.y))
import signal_grid
self.rg = signal_grid.signal_grid(self.ll, self.ur, self.route_track_width)
router.__init__(self, layers, design, gds_filename, bbox)
def route(self, src, dest, detour_scale=5):
"""
@@ -52,7 +40,7 @@ class signal_router(router):
# Creat a routing grid over the entire area
# FIXME: This could be created only over the routing region,
# but this is simplest for now.
self.create_routing_grid()
self.create_routing_grid(signal_grid)
# Get the pin shapes
self.find_pins_and_blockages([src, dest])
+4 -13
View File
@@ -11,6 +11,7 @@ from vector3d import vector3d
from router import router
from direction import direction
from datetime import datetime
from supply_grid import supply_grid
import grid_utils
@@ -20,7 +21,7 @@ class supply_grid_router(router):
routes a grid to connect the supply on the two layers.
"""
def __init__(self, layers, design, gds_filename=None):
def __init__(self, layers, design, gds_filename=None, bbox=None):
"""
This will route on layers in design. It will get the blockages from
either the gds file name or the design itself (by saving to a gds file).
@@ -30,7 +31,7 @@ class supply_grid_router(router):
# Power rail width in minimum wire widths
self.route_track_width = 2
router.__init__(self, layers, design, gds_filename, self.route_track_width)
router.__init__(self, layers, design, gds_filename, bbox, self.route_track_width)
# The list of supply rails (grid sets) that may be routed
self.supply_rails = {}
@@ -39,16 +40,6 @@ class supply_grid_router(router):
print_time("Init supply router", datetime.now(), start_time, 3)
def create_routing_grid(self):
"""
Create a sprase routing grid with A* expansion functions.
"""
size = self.ur - self.ll
debug.info(1, "Size: {0} x {1}".format(size.x, size.y))
import supply_grid
self.rg = supply_grid.supply_grid(self.ll, self.ur, self.route_track_width)
def route(self, vdd_name="vdd", gnd_name="gnd"):
"""
Add power supply rails and connect all pins to these rails.
@@ -64,7 +55,7 @@ class supply_grid_router(router):
# Creat a routing grid over the entire area
# FIXME: This could be created only over the routing region,
# but this is simplest for now.
self.create_routing_grid()
self.create_routing_grid(supply_grid)
# Get the pin shapes
start_time = datetime.now()
+8 -14
View File
@@ -13,7 +13,7 @@ import grid_utils
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import minimum_spanning_tree
from signal_grid import signal_grid
from vector3d import vector3d
class supply_tree_router(router):
"""
@@ -21,23 +21,17 @@ class supply_tree_router(router):
routes a grid to connect the supply on the two layers.
"""
def __init__(self, layers, design, gds_filename=None):
def __init__(self, layers, design, gds_filename=None, bbox=None):
"""
This will route on layers in design. It will get the blockages from
either the gds file name or the design itself (by saving to a gds file).
"""
# Power rail width in minimum wire widths
self.route_track_width = 2
# This is set to match the signal router so that the grids are aligned
# for prettier routes.
self.route_track_width = 1
router.__init__(self, layers, design, gds_filename, self.route_track_width)
def create_routing_grid(self):
"""
Create a sprase routing grid with A* expansion functions.
"""
size = self.ur - self.ll
debug.info(1,"Size: {0} x {1}".format(size.x,size.y))
self.rg = signal_grid(self.ll, self.ur, self.route_track_width)
router.__init__(self, layers, design, gds_filename, bbox, self.route_track_width)
def route(self, vdd_name="vdd", gnd_name="gnd"):
"""
@@ -54,7 +48,7 @@ class supply_tree_router(router):
# Creat a routing grid over the entire area
# FIXME: This could be created only over the routing region,
# but this is simplest for now.
self.create_routing_grid()
self.create_routing_grid(signal_grid)
# Get the pin shapes
start_time = datetime.now()
@@ -122,7 +116,7 @@ class supply_tree_router(router):
# self.write_debug_gds("post_{0}_{1}.gds".format(src, dest), False)
#self.write_debug_gds("final.gds", True)
#return
#return
def route_signal(self, pin_name, src_idx, dest_idx):