diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 839c9a4b..e033e387 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -1190,19 +1190,19 @@ class layout(): ll_offset = vector(0, 0) ur_offset = vector(0, 0) - if side in ["ring", "top"]: + if side in ["ring", "top", "all"]: ur_offset += vector(0, big_margin) else: ur_offset += vector(0, little_margin) - if side in ["ring", "bottom"]: + if side in ["ring", "bottom", "all"]: ll_offset += vector(0, big_margin) else: ll_offset += vector(0, little_margin) - if side in ["ring", "left"]: + if side in ["ring", "left", "all"]: ll_offset += vector(big_margin, 0) else: ll_offset += vector(little_margin, 0) - if side in ["ring", "right"]: + if side in ["ring", "right", "all"]: ur_offset += vector(big_margin, 0) else: ur_offset += vector(little_margin, 0) diff --git a/compiler/options.py b/compiler/options.py index 214eecf7..65620c8c 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -99,6 +99,7 @@ class options(optparse.Values): netlist_only = False # Whether we should do the final power routing route_supplies = "tree" + supply_pin_type = "ring" # This determines whether LVS and DRC is checked at all. check_lvsdrc = False # This determines whether LVS and DRC is checked for every submodule. diff --git a/compiler/router/supply_grid_router.py b/compiler/router/supply_grid_router.py index f24498ab..06831299 100644 --- a/compiler/router/supply_grid_router.py +++ b/compiler/router/supply_grid_router.py @@ -21,7 +21,7 @@ class supply_grid_router(router): routes a grid to connect the supply on the two layers. """ - def __init__(self, layers, design, margin=0, bbox=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). diff --git a/compiler/router/supply_tree_router.py b/compiler/router/supply_tree_router.py index e95cdee1..8ed0c596 100644 --- a/compiler/router/supply_tree_router.py +++ b/compiler/router/supply_tree_router.py @@ -34,7 +34,7 @@ class supply_tree_router(router): # The pin escape router already made the bounding box big enough, # so we can use the regular bbox here. if pin_type: - debug.check(pin_type in ["left", "right", "top", "bottom", "tree", "ring"], + debug.check(pin_type in ["left", "right", "top", "bottom", "single", "ring"], "Invalid pin type {}".format(pin_type)) self.pin_type = pin_type router.__init__(self, @@ -75,6 +75,7 @@ class supply_tree_router(router): self.add_ring_supply_pin(self.vdd_name) self.add_ring_supply_pin(self.gnd_name) + self.write_debug_gds("foo.gds", False) # 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_1bank.py b/compiler/sram/sram_1bank.py index 3bfe3648..9c3802be 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -9,6 +9,7 @@ from vector import vector from sram_base import sram_base from contact import m2_via from channel_route import channel_route +from router_tech import router_tech from globals import OPTS @@ -334,11 +335,21 @@ class sram_1bank(sram_base): # Route the pins to the perimeter pre_bbox = None if OPTS.perimeter_pins: + rt = router_tech(self.supply_stack, 1) + + if OPTS.supply_pin_type in ["ring", "left", "right", "top", "bottom"]: + big_margin = 12 * rt.track_width + little_margin = 2 * rt.track_width + else: + big_margin = 6 * rt.track_width + little_margin = 0 + pre_bbox = self.get_bbox(side="ring", - big_margin=self.m3_pitch) - bbox = self.get_bbox(side=OPTS.route_supplies, - big_margin=14 * self.m3_pitch, - little_margin=4 * self.m3_pitch) + big_margin=rt.track_width) + + bbox = self.get_bbox(side=OPTS.supply_pin_type, + big_margin=big_margin, + little_margin=little_margin) self.route_escape_pins(bbox) # Route the supplies first since the MST is not blockage aware diff --git a/compiler/sram/sram_base.py b/compiler/sram/sram_base.py index 5163ef27..98a8b456 100644 --- a/compiler/sram/sram_base.py +++ b/compiler/sram/sram_base.py @@ -41,6 +41,14 @@ class sram_base(design, verilog, lef): if not self.num_spare_cols: self.num_spare_cols = 0 + try: + from tech import power_grid + self.supply_stack = power_grid + except ImportError: + # if no power_grid is specified by tech we use sensible defaults + # Route a M3/M4 grid + self.supply_stack = self.m3_stack + def add_pins(self): """ Add pins for entire SRAM. """ @@ -239,32 +247,21 @@ class sram_base(design, verilog, lef): for inst in self.insts: self.copy_power_pins(inst, pin_name, self.ext_supply[pin_name]) - try: - from tech import power_grid - grid_stack = power_grid - except ImportError: - # if no power_grid is specified by tech we use sensible defaults - # Route a M3/M4 grid - grid_stack = self.m3_stack - if not OPTS.route_supplies: # Do not route the power supply (leave as must-connect pins) return elif OPTS.route_supplies == "grid": from supply_grid_router import supply_grid_router as router - rtr=router(layers=grid_stack, - design=self, - bbox=bbox) else: from supply_tree_router import supply_tree_router as router - rtr=router(layers=grid_stack, - design=self, - bbox=bbox, - pin_type=OPTS.route_supplies) + rtr=router(layers=self.supply_stack, + design=self, + bbox=bbox, + pin_type=OPTS.supply_pin_type) rtr.route() - if OPTS.route_supplies in ["left", "right", "top", "bottom", "ring"]: + if OPTS.supply_pin_type in ["left", "right", "top", "bottom", "ring"]: # Find the lowest leftest pin for vdd and gnd for pin_name in ["vdd", "gnd"]: # Copy the pin shape(s) to rectangles @@ -286,7 +283,7 @@ class sram_base(design, verilog, lef): pin.width(), pin.height()) - elif OPTS.route_supplies or OPTS.route_supplies == "single": + elif OPTS.route_supplies and OPTS.supply_pin_type == "single": # Update these as we may have routed outside the region (perimeter pins) lowest_coord = self.find_lowest_coords()