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.place_top_level_pins()
|
||||||
self.route_output_buffers()
|
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
|
# Route the pins to the perimeter
|
||||||
if OPTS.perimeter_pins:
|
if OPTS.perimeter_pins:
|
||||||
# We now route the escape routes far enough out so that they will
|
# We now route the escape routes far enough out so that they will
|
||||||
# reach past the power ring or stripes on the sides
|
# 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):
|
def setup_layout_constants(self):
|
||||||
|
|
@ -441,7 +444,7 @@ class rom_bank(design,rom_verilog):
|
||||||
pin_num = msb - self.col_bits
|
pin_num = msb - self.col_bits
|
||||||
self.add_io_pin(self.decode_inst, "A{}".format(pin_num), name)
|
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 pin_name in ["vdd", "gnd"]:
|
||||||
for inst in self.insts:
|
for inst in self.insts:
|
||||||
|
|
@ -454,6 +457,7 @@ class rom_bank(design,rom_verilog):
|
||||||
from openram.router import supply_router as router
|
from openram.router import supply_router as router
|
||||||
rtr = router(layers=self.supply_stack,
|
rtr = router(layers=self.supply_stack,
|
||||||
design=self,
|
design=self,
|
||||||
|
bbox=bbox,
|
||||||
pin_type=OPTS.supply_pin_type)
|
pin_type=OPTS.supply_pin_type)
|
||||||
rtr.route()
|
rtr.route()
|
||||||
|
|
||||||
|
|
@ -479,7 +483,7 @@ class rom_bank(design,rom_verilog):
|
||||||
pin.width(),
|
pin.width(),
|
||||||
pin.height())
|
pin.height())
|
||||||
|
|
||||||
def route_escape_pins(self):
|
def route_escape_pins(self, bbox):
|
||||||
pins_to_route = []
|
pins_to_route = []
|
||||||
|
|
||||||
for bit in range(self.col_bits):
|
for bit in range(self.col_bits):
|
||||||
|
|
@ -495,5 +499,6 @@ class rom_bank(design,rom_verilog):
|
||||||
pins_to_route.append("cs")
|
pins_to_route.append("cs")
|
||||||
from openram.router import signal_escape_router as router
|
from openram.router import signal_escape_router as router
|
||||||
rtr = router(layers=self.m3_stack,
|
rtr = router(layers=self.m3_stack,
|
||||||
|
bbox=bbox,
|
||||||
design=self)
|
design=self)
|
||||||
rtr.route(pins_to_route)
|
rtr.route(pins_to_route)
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
def create_modules(self):
|
def create_modules(self):
|
||||||
debug.error("Must override pure virtual function.", -1)
|
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. """
|
""" Route the supply grid and connect the pins to them. """
|
||||||
|
|
||||||
# Copy the pins to the top level
|
# 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
|
from openram.router import supply_router as router
|
||||||
rtr = router(layers=self.supply_stack,
|
rtr = router(layers=self.supply_stack,
|
||||||
design=self,
|
design=self,
|
||||||
|
bbox=bbox,
|
||||||
pin_type=OPTS.supply_pin_type)
|
pin_type=OPTS.supply_pin_type)
|
||||||
rtr.route()
|
rtr.route()
|
||||||
|
|
||||||
|
|
@ -322,7 +323,7 @@ class sram_1bank(design, verilog, lef):
|
||||||
# Grid is left with many top level pins
|
# Grid is left with many top level pins
|
||||||
pass
|
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.
|
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
|
from openram.router import signal_escape_router as router
|
||||||
rtr = router(layers=self.m3_stack,
|
rtr = router(layers=self.m3_stack,
|
||||||
|
bbox=bbox,
|
||||||
design=self)
|
design=self)
|
||||||
rtr.route(pins_to_route)
|
rtr.route(pins_to_route)
|
||||||
|
|
||||||
|
|
@ -1072,14 +1074,15 @@ class sram_1bank(design, verilog, lef):
|
||||||
# Some technologies have an isolation
|
# Some technologies have an isolation
|
||||||
self.add_dnwell(inflate=2.5)
|
self.add_dnwell(inflate=2.5)
|
||||||
|
|
||||||
|
init_bbox = self.get_bbox()
|
||||||
# Route the supplies together and/or to the ring/stripes.
|
# Route the supplies together and/or to the ring/stripes.
|
||||||
# Route the pins to the perimeter
|
# Route the pins to the perimeter
|
||||||
if OPTS.perimeter_pins:
|
if OPTS.perimeter_pins:
|
||||||
# We now route the escape routes far enough out so that they will
|
# We now route the escape routes far enough out so that they will
|
||||||
# reach past the power ring or stripes on the sides
|
# 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):
|
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.
|
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` contains tech constants for the router
|
||||||
router_tech.__init__(self, layers, route_track_width=1)
|
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
|
# Temporary GDSII file name to find pins and blockages
|
||||||
self.gds_filename = OPTS.openram_temp + "temp.gds"
|
self.gds_filename = OPTS.openram_temp + "temp.gds"
|
||||||
# Calculate the bounding box for routing around the perimeter
|
# 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
|
# Dictionary for vdd and gnd pins
|
||||||
self.pins = {}
|
self.pins = {}
|
||||||
# Set of all the 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.
|
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_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
|
# New pins are the side supply pins
|
||||||
self.new_pins = {}
|
self.new_pins = {}
|
||||||
|
|
@ -53,7 +53,6 @@ class signal_escape_router(router):
|
||||||
self.blockages.append(self.inflate_shape(pin))
|
self.blockages.append(self.inflate_shape(pin))
|
||||||
|
|
||||||
# Route vdd and gnd
|
# Route vdd and gnd
|
||||||
i = 0
|
|
||||||
for source, target, _ in self.get_route_pairs(pin_names):
|
for source, target, _ in self.get_route_pairs(pin_names):
|
||||||
# Change fake pin's name so the graph will treat it as routable
|
# Change fake pin's name so the graph will treat it as routable
|
||||||
target.name = source.name
|
target.name = source.name
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ class supply_router(router):
|
||||||
This is the supply router that uses the Hanan grid graph method.
|
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_tech` contains tech constants for the router
|
||||||
router.__init__(self, layers, design)
|
router.__init__(self, layers, design, bbox)
|
||||||
|
|
||||||
# Side supply pin type
|
# Side supply pin type
|
||||||
# (can be "top", "bottom", "right", "left", and "ring")
|
# (can be "top", "bottom", "right", "left", and "ring")
|
||||||
|
|
@ -52,7 +52,6 @@ class supply_router(router):
|
||||||
self.convert_blockages()
|
self.convert_blockages()
|
||||||
|
|
||||||
# Add side pins
|
# Add side pins
|
||||||
self.calculate_ring_bbox()
|
|
||||||
if self.pin_type in ["top", "bottom", "right", "left"]:
|
if self.pin_type in ["top", "bottom", "right", "left"]:
|
||||||
self.add_side_pin(vdd_name)
|
self.add_side_pin(vdd_name)
|
||||||
self.add_side_pin(gnd_name)
|
self.add_side_pin(gnd_name)
|
||||||
|
|
@ -84,7 +83,7 @@ class supply_router(router):
|
||||||
# larger routing region
|
# larger routing region
|
||||||
if path is None:
|
if path is None:
|
||||||
rll, rur = region
|
rll, rur = region
|
||||||
bll, bur = self.ring_bbox
|
bll, bur = self.bbox
|
||||||
# Stop scaling the region and throw an error
|
# Stop scaling the region and throw an error
|
||||||
if rll.x < bll.x and rll.y < bll.y and \
|
if rll.x < bll.x and rll.y < bll.y and \
|
||||||
rur.x > bur.x and rur.y > bur.y:
|
rur.x > bur.x and rur.y > bur.y:
|
||||||
|
|
@ -103,38 +102,10 @@ class supply_router(router):
|
||||||
break
|
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):
|
def add_side_pin(self, pin_name, side, num_vias=3, num_fake_pins=4):
|
||||||
""" Add supply pin to one side of the layout. """
|
""" Add supply pin to one side of the layout. """
|
||||||
|
|
||||||
ll, ur = self.ring_bbox
|
ll, ur = self.bbox
|
||||||
vertical = side in ["left", "right"]
|
vertical = side in ["left", "right"]
|
||||||
inner = pin_name == self.gnd_name
|
inner = pin_name == self.gnd_name
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue