mirror of https://github.com/VLSIDA/OpenRAM.git
Use the initial bbox to route supply and signals
This commit is contained in:
parent
08dad81214
commit
87eca6b7db
|
|
@ -111,12 +111,15 @@ class rom_bank(design,rom_verilog):
|
|||
self.place_top_level_pins()
|
||||
self.route_output_buffers()
|
||||
|
||||
self.route_supplies()
|
||||
# FIXME: Somehow ROM layout behaves weird and doesn't add all the pin
|
||||
# shapes before routing supplies
|
||||
init_bbox = self.get_bbox()
|
||||
self.route_supplies(init_bbox)
|
||||
# Route the pins to the perimeter
|
||||
if OPTS.perimeter_pins:
|
||||
# We now route the escape routes far enough out so that they will
|
||||
# reach past the power ring or stripes on the sides
|
||||
self.route_escape_pins()
|
||||
self.route_escape_pins(init_bbox)
|
||||
|
||||
|
||||
def setup_layout_constants(self):
|
||||
|
|
@ -441,7 +444,7 @@ class rom_bank(design,rom_verilog):
|
|||
pin_num = msb - self.col_bits
|
||||
self.add_io_pin(self.decode_inst, "A{}".format(pin_num), name)
|
||||
|
||||
def route_supplies(self):
|
||||
def route_supplies(self, bbox):
|
||||
|
||||
for pin_name in ["vdd", "gnd"]:
|
||||
for inst in self.insts:
|
||||
|
|
@ -454,6 +457,7 @@ class rom_bank(design,rom_verilog):
|
|||
from openram.router import supply_router as router
|
||||
rtr = router(layers=self.supply_stack,
|
||||
design=self,
|
||||
bbox=bbox,
|
||||
pin_type=OPTS.supply_pin_type)
|
||||
rtr.route()
|
||||
|
||||
|
|
@ -479,7 +483,7 @@ class rom_bank(design,rom_verilog):
|
|||
pin.width(),
|
||||
pin.height())
|
||||
|
||||
def route_escape_pins(self):
|
||||
def route_escape_pins(self, bbox):
|
||||
pins_to_route = []
|
||||
|
||||
for bit in range(self.col_bits):
|
||||
|
|
@ -495,5 +499,6 @@ class rom_bank(design,rom_verilog):
|
|||
pins_to_route.append("cs")
|
||||
from openram.router import signal_escape_router as router
|
||||
rtr = router(layers=self.m3_stack,
|
||||
bbox=bbox,
|
||||
design=self)
|
||||
rtr.route(pins_to_route)
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ class sram_1bank(design, verilog, lef):
|
|||
def create_modules(self):
|
||||
debug.error("Must override pure virtual function.", -1)
|
||||
|
||||
def route_supplies(self):
|
||||
def route_supplies(self, bbox=None):
|
||||
""" Route the supply grid and connect the pins to them. """
|
||||
|
||||
# Copy the pins to the top level
|
||||
|
|
@ -259,6 +259,7 @@ class sram_1bank(design, verilog, lef):
|
|||
from openram.router import supply_router as router
|
||||
rtr = router(layers=self.supply_stack,
|
||||
design=self,
|
||||
bbox=bbox,
|
||||
pin_type=OPTS.supply_pin_type)
|
||||
rtr.route()
|
||||
|
||||
|
|
@ -322,7 +323,7 @@ class sram_1bank(design, verilog, lef):
|
|||
# Grid is left with many top level pins
|
||||
pass
|
||||
|
||||
def route_escape_pins(self):
|
||||
def route_escape_pins(self, bbox=None):
|
||||
"""
|
||||
Add the top-level pins for a single bank SRAM with control.
|
||||
"""
|
||||
|
|
@ -367,6 +368,7 @@ class sram_1bank(design, verilog, lef):
|
|||
|
||||
from openram.router import signal_escape_router as router
|
||||
rtr = router(layers=self.m3_stack,
|
||||
bbox=bbox,
|
||||
design=self)
|
||||
rtr.route(pins_to_route)
|
||||
|
||||
|
|
@ -1072,14 +1074,15 @@ class sram_1bank(design, verilog, lef):
|
|||
# Some technologies have an isolation
|
||||
self.add_dnwell(inflate=2.5)
|
||||
|
||||
init_bbox = self.get_bbox()
|
||||
# Route the supplies together and/or to the ring/stripes.
|
||||
# Route the pins to the perimeter
|
||||
if OPTS.perimeter_pins:
|
||||
# We now route the escape routes far enough out so that they will
|
||||
# reach past the power ring or stripes on the sides
|
||||
self.route_escape_pins()
|
||||
self.route_escape_pins(init_bbox)
|
||||
|
||||
self.route_supplies()
|
||||
self.route_supplies(init_bbox)
|
||||
|
||||
|
||||
def route_dffs(self, add_routes=True):
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class router(router_tech):
|
|||
This is the base class for routers that use the Hanan grid graph method.
|
||||
"""
|
||||
|
||||
def __init__(self, layers, design):
|
||||
def __init__(self, layers, design, bbox=None):
|
||||
|
||||
# `router_tech` contains tech constants for the router
|
||||
router_tech.__init__(self, layers, route_track_width=1)
|
||||
|
|
@ -32,7 +32,13 @@ class router(router_tech):
|
|||
# Temporary GDSII file name to find pins and blockages
|
||||
self.gds_filename = OPTS.openram_temp + "temp.gds"
|
||||
# Calculate the bounding box for routing around the perimeter
|
||||
self.bbox = self.design.get_bbox(margin=11 * self.track_width)
|
||||
# FIXME: We wouldn't do this if `rom_bank` wasn't behaving weird
|
||||
if bbox is None:
|
||||
self.bbox = self.design.get_bbox(margin=11 * self.track_width)
|
||||
else:
|
||||
ll, ur = bbox
|
||||
margin = vector([11 * self.track_width] * 2)
|
||||
self.bbox = [ll - margin, ur + margin]
|
||||
# Dictionary for vdd and gnd pins
|
||||
self.pins = {}
|
||||
# Set of all the pins
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ class signal_escape_router(router):
|
|||
This is the signal escape router that uses the Hanan grid graph method.
|
||||
"""
|
||||
|
||||
def __init__(self, layers, design):
|
||||
def __init__(self, layers, design, bbox=None):
|
||||
|
||||
# `router_tech` contains tech constants for the router
|
||||
router.__init__(self, layers, design)
|
||||
router.__init__(self, layers, design, bbox)
|
||||
|
||||
# New pins are the side supply pins
|
||||
self.new_pins = {}
|
||||
|
|
@ -53,7 +53,6 @@ class signal_escape_router(router):
|
|||
self.blockages.append(self.inflate_shape(pin))
|
||||
|
||||
# Route vdd and gnd
|
||||
i = 0
|
||||
for source, target, _ in self.get_route_pairs(pin_names):
|
||||
# Change fake pin's name so the graph will treat it as routable
|
||||
target.name = source.name
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ class supply_router(router):
|
|||
This is the supply router that uses the Hanan grid graph method.
|
||||
"""
|
||||
|
||||
def __init__(self, layers, design, pin_type=None):
|
||||
def __init__(self, layers, design, bbox=None, pin_type=None):
|
||||
|
||||
# `router_tech` contains tech constants for the router
|
||||
router.__init__(self, layers, design)
|
||||
router.__init__(self, layers, design, bbox)
|
||||
|
||||
# Side supply pin type
|
||||
# (can be "top", "bottom", "right", "left", and "ring")
|
||||
|
|
@ -52,7 +52,6 @@ class supply_router(router):
|
|||
self.convert_blockages()
|
||||
|
||||
# Add side pins
|
||||
self.calculate_ring_bbox()
|
||||
if self.pin_type in ["top", "bottom", "right", "left"]:
|
||||
self.add_side_pin(vdd_name)
|
||||
self.add_side_pin(gnd_name)
|
||||
|
|
@ -84,7 +83,7 @@ class supply_router(router):
|
|||
# larger routing region
|
||||
if path is None:
|
||||
rll, rur = region
|
||||
bll, bur = self.ring_bbox
|
||||
bll, bur = self.bbox
|
||||
# Stop scaling the region and throw an error
|
||||
if rll.x < bll.x and rll.y < bll.y and \
|
||||
rur.x > bur.x and rur.y > bur.y:
|
||||
|
|
@ -103,38 +102,10 @@ class supply_router(router):
|
|||
break
|
||||
|
||||
|
||||
def calculate_ring_bbox(self, num_vias=3):
|
||||
""" Calculate the ring-safe bounding box of the layout. """
|
||||
|
||||
ll, ur = self.bbox
|
||||
# Calculate the "wideness" of a side supply pin
|
||||
wideness = self.track_wire * num_vias + self.track_space * (num_vias - 1)
|
||||
# Total wideness is used to find it any pin overlaps in this region. If
|
||||
# so, the bbox is shifted to prevent this overlap.
|
||||
total_wideness = wideness * 4
|
||||
for blockage in self.blockages:
|
||||
bll, bur = blockage.rect
|
||||
if self.get_zindex(blockage.lpp) == 1: # Vertical
|
||||
diff = ll.x + total_wideness - bll.x
|
||||
if diff > 0:
|
||||
ll = vector(ll.x - diff, ll.y)
|
||||
diff = ur.x - total_wideness - bur.x
|
||||
if diff < 0:
|
||||
ur = vector(ur.x - diff, ur.y)
|
||||
else: # Horizontal
|
||||
diff = ll.y + total_wideness - bll.y
|
||||
if diff > 0:
|
||||
ll = vector(ll.x, ll.y - diff)
|
||||
diff = ur.y - total_wideness - bur.y
|
||||
if diff < 0:
|
||||
ur = vector(ur.x, ur.y - diff)
|
||||
self.ring_bbox = [ll, ur]
|
||||
|
||||
|
||||
def add_side_pin(self, pin_name, side, num_vias=3, num_fake_pins=4):
|
||||
""" Add supply pin to one side of the layout. """
|
||||
|
||||
ll, ur = self.ring_bbox
|
||||
ll, ur = self.bbox
|
||||
vertical = side in ["left", "right"]
|
||||
inner = pin_name == self.gnd_name
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue