From cc91cdf008eedbf8f9a8c3849272a141ad95e1c0 Mon Sep 17 00:00:00 2001 From: mrg Date: Tue, 25 May 2021 13:23:39 -0700 Subject: [PATCH] Add power ring pin --- compiler/router/router.py | 54 +++++++++++++++++++++++++++ compiler/router/supply_tree_router.py | 13 +++++-- compiler/sram/sram_base.py | 11 ++++-- 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/compiler/router/router.py b/compiler/router/router.py index ca077572..0121523a 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -909,6 +909,60 @@ class router(router_tech): pg.pins = set(pg.enclosures) self.cell.pin_map[name].update(pg.pins) self.pin_groups[name].append(pg) + + def add_ring_supply_pin(self, name, width=2): + """ + Adds a ring supply pin + """ + pg = pin_group(name, [], self) + if name == "vdd": + offset = width + else: + offset = 0 + + # LEFT + left_grids = set(self.rg.get_perimeter_list(side="left", + width=width, + margin=self.margin, + offset=offset, + layers=[1])) + + # RIGHT + right_grids = set(self.rg.get_perimeter_list(side="right", + width=width, + margin=self.margin, + offset=offset, + layers=[1])) + # TOP + top_grids = set(self.rg.get_perimeter_list(side="top", + width=width, + margin=self.margin, + offset=offset, + layers=[0])) + # BOTTOM + bottom_grids = set(self.rg.get_perimeter_list(side="bottom", + width=width, + margin=self.margin, + offset=offset, + layers=[0])) + + # The big pin group + pg.grids = left_grids | right_grids | top_grids | bottom_grids + pg.enclosures = pg.compute_enclosures() + pg.pins = set(pg.enclosures) + self.cell.pin_map[name].update(pg.pins) + self.pin_groups[name].append(pg) + + # Must move to the same layer + vertical_layer_grids = set() + for x in top_grids | bottom_grids: + vertical_layer_grids.add(vector3d(x.x, x.y, 1)) + horizontal_layer_grids = left_grids | right_grids + + # Add vias in the overlap points + corner_grids = vertical_layer_grids & horizontal_layer_grids + for g in corner_grids: + self.add_via(g) def add_perimeter_target(self, side="all"): """ diff --git a/compiler/router/supply_tree_router.py b/compiler/router/supply_tree_router.py index 97ba87d5..0b9ec923 100644 --- a/compiler/router/supply_tree_router.py +++ b/compiler/router/supply_tree_router.py @@ -21,7 +21,7 @@ class supply_tree_router(router): routes a grid to connect the supply on the two layers. """ - def __init__(self, layers, design, bbox=None, side_pin=None): + def __init__(self, layers, design, bbox=None, pin_type=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). @@ -33,7 +33,9 @@ class supply_tree_router(router): # The pin escape router already made the bounding box big enough, # so we can use the regular bbox here. - self.side_pin = side_pin + if pin_type: + debug.check(pin_type in ["side", "ring"], "Invalid pin type {}".format(pin_type)) + self.pin_type = pin_type router.__init__(self, layers, design, @@ -65,10 +67,13 @@ class supply_tree_router(router): print_time("Finding pins and blockages", datetime.now(), start_time, 3) # Add side pins if enabled - if self.side_pin: + if self.pin_type == "side": self.add_side_supply_pin(self.vdd_name) self.add_side_supply_pin(self.gnd_name) - + elif self.pin_type == "ring": + self.add_ring_supply_pin(self.vdd_name) + self.add_ring_supply_pin(self.gnd_name) + # Route the supply pins to the supply rails # Route vdd first since we want it to be shorter start_time = datetime.now() diff --git a/compiler/sram/sram_base.py b/compiler/sram/sram_base.py index 0db5a4d6..0cc1bdd5 100644 --- a/compiler/sram/sram_base.py +++ b/compiler/sram/sram_base.py @@ -15,7 +15,7 @@ from design import design from verilog import verilog from lef import lef from sram_factory import factory -from tech import spice +from tech import spice, layer class sram_base(design, verilog, lef): @@ -265,7 +265,7 @@ class sram_base(design, verilog, lef): # # their perimeter. # supply_height = highest_coord.y - lowest_coord.y - # supply_pins[pin_name] = self.add_layout_pin(text=pin_name, + # supply_pins[pin_name] = self.add_layout_pin(text=pin_name, # layer=grid_stack[2], # offset=lowest_coord + vector(pin_index * supply_pitch, 0), # width=pin_width, @@ -276,13 +276,16 @@ class sram_base(design, verilog, lef): return elif OPTS.route_supplies == "grid": from supply_grid_router import supply_grid_router as router + rtr=router(grid_stack, self) else: from supply_tree_router import supply_tree_router as router + rtr=router(grid_stack, + self, + pin_type=OPTS.route_supplies) - rtr=router(grid_stack, self, side_pin=(OPTS.route_supplies == "side")) rtr.route() - if OPTS.route_supplies == "side": + if OPTS.route_supplies in ["side", "ring"]: # Find the lowest leftest pin for vdd and gnd for pin_name in ["vdd", "gnd"]: # Copy the pin shape(s) to rectangles