diff --git a/compiler/modules/rom_bank.py b/compiler/modules/rom_bank.py index aa790d6f..7cf30dc3 100644 --- a/compiler/modules/rom_bank.py +++ b/compiler/modules/rom_bank.py @@ -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) diff --git a/compiler/modules/sram_1bank.py b/compiler/modules/sram_1bank.py index 95ea9b87..843d13d8 100644 --- a/compiler/modules/sram_1bank.py +++ b/compiler/modules/sram_1bank.py @@ -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): diff --git a/compiler/router/router.py b/compiler/router/router.py index 917c49d9..39c5cdb1 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -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 diff --git a/compiler/router/signal_escape_router.py b/compiler/router/signal_escape_router.py index d5b7c929..945b4b40 100644 --- a/compiler/router/signal_escape_router.py +++ b/compiler/router/signal_escape_router.py @@ -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 diff --git a/compiler/router/supply_router.py b/compiler/router/supply_router.py index d33b9ad6..7105afd0 100644 --- a/compiler/router/supply_router.py +++ b/compiler/router/supply_router.py @@ -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