tech: Make power_grid configurable

this is the first step to allow engineers, porting technologies, more room
for routing their handmade cells.

For now, we don't allow the specification of power_grids where the lower layer
prefers to be routed vertically. This is due to the router not
connecting some pins properly in that case.

Signed-off-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
This commit is contained in:
Bastian Koppelmann 2020-01-28 11:53:36 +01:00
parent 90a4a72bba
commit 9749c522d1
3 changed files with 47 additions and 18 deletions

View File

@ -39,6 +39,12 @@ class layout():
self.visited = [] # List of modules we have already visited self.visited = [] # List of modules we have already visited
self.is_library_cell = False # Flag for library cells self.is_library_cell = False # Flag for library cells
self.gds_read() self.gds_read()
try:
from tech import power_grid
self.pwr_grid_layer = power_grid[0]
except ImportError:
self.pwr_grid_layer = "m3"
############################################################ ############################################################
# GDS layout # GDS layout
@ -1169,12 +1175,12 @@ class layout():
def copy_power_pins(self, inst, name): def copy_power_pins(self, inst, name):
""" """
This will copy a power pin if it is on M3. This will copy a power pin if it is on the lowest power_grid layer.
If it is on M1, it will add a power via too. If it is on M1, it will add a power via too.
""" """
pins = inst.get_pins(name) pins = inst.get_pins(name)
for pin in pins: for pin in pins:
if pin.layer == "m3": if pin.layer == self.pwr_grid_layer:
self.add_layout_pin(name, self.add_layout_pin(name,
pin.layer, pin.layer,
pin.ll(), pin.ll(),
@ -1183,14 +1189,17 @@ class layout():
elif pin.layer == "m1": elif pin.layer == "m1":
self.add_power_pin(name, pin.center()) self.add_power_pin(name, pin.center())
else: else:
debug.warning("{0} pins of {1} should be on metal3 or metal1 for supply router.".format(name,inst.name)) debug.warning("{0} pins of {1} should be on {2} or metal1 for "\
"supply router."
.format(name,inst.name,self.pwr_grid_layer))
def add_power_pin(self, name, loc, size=[1, 1], vertical=False, start_layer="m1"): def add_power_pin(self, name, loc, size=[1, 1], vertical=False, start_layer="m1"):
""" """
Add a single power pin from M3 down to M1 at the given center location. Add a single power pin from the lowest power_grid layer down to M1 at
The starting layer is specified to determine which vias are needed. the given center location. The starting layer is specified to determine
which vias are needed.
""" """
if vertical: if vertical:
direction = ("V", "V") direction = ("V", "V")
@ -1198,18 +1207,18 @@ class layout():
direction = ("H", "H") direction = ("H", "H")
via = self.add_via_stack_center(from_layer=start_layer, via = self.add_via_stack_center(from_layer=start_layer,
to_layer="m3", to_layer=self.pwr_grid_layer,
size=size, size=size,
offset=loc, offset=loc,
direction=direction) direction=direction)
if start_layer == "m3": if start_layer == self.pwr_grid_layer:
self.add_layout_pin_rect_center(text=name, self.add_layout_pin_rect_center(text=name,
layer="m3", layer=self.pwr_grid_layer,
offset=loc) offset=loc)
else: else:
self.add_layout_pin_rect_center(text=name, self.add_layout_pin_rect_center(text=name,
layer="m3", layer=self.pwr_grid_layer,
offset=loc, offset=loc,
width=via.width, width=via.width,
height=via.height) height=via.height)

View File

@ -5,7 +5,7 @@
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
from tech import drc, layer from tech import drc, layer, preferred_directions
from contact import contact from contact import contact
from vector import vector from vector import vector
import debug import debug
@ -26,6 +26,9 @@ class router_tech:
self.rail_track_width = rail_track_width self.rail_track_width = rail_track_width
if len(self.layers) == 1: if len(self.layers) == 1:
if preferred_directions[self.layers[0]] != "H":
debug.warning("Using '{}' for horizontal routing, but it " \
"prefers vertical routing".format(self.layers[0]))
self.horiz_layer_name = self.vert_layer_name = self.layers[0] self.horiz_layer_name = self.vert_layer_name = self.layers[0]
self.horiz_lpp = self.vert_lpp = layer[self.layers[0]] self.horiz_lpp = self.vert_lpp = layer[self.layers[0]]
@ -35,7 +38,17 @@ class router_tech:
self.horiz_track_width = self.horiz_layer_minwidth + self.horiz_layer_spacing self.horiz_track_width = self.horiz_layer_minwidth + self.horiz_layer_spacing
self.vert_track_width = self.vert_layer_minwidth + self.vert_layer_spacing self.vert_track_width = self.vert_layer_minwidth + self.vert_layer_spacing
else: else:
(self.horiz_layer_name, self.via_layer_name, self.vert_layer_name) = self.layers (try_horiz_layer, self.via_layer_name, try_vert_layer) = self.layers
# figure out wich of the two layers prefers horizontal/vertical
# routing
if preferred_directions[try_horiz_layer] == "H" and preferred_directions[try_vert_layer] == "V":
self.horiz_layer_name = try_horiz_layer
self.vert_layer_name = try_vert_layer
else:
raise ValueError("Layer '{}' and '{}' are using the wrong " \
"preferred_directions '{}' and '{}'. Only "\
"('H', 'V') are supported")
via_connect = contact(self.layers, (1, 1)) via_connect = contact(self.layers, (1, 1))
max_via_size = max(via_connect.width,via_connect.height) max_via_size = max(via_connect.width,via_connect.height)

View File

@ -148,14 +148,21 @@ class sram_base(design, verilog, lef):
if not OPTS.route_supplies: if not OPTS.route_supplies:
# Do not route the power supply (leave as must-connect pins) # Do not route the power supply (leave as must-connect pins)
return return
elif "m4" in tech.layer:
# Route a M3/M4 grid
from supply_grid_router import supply_grid_router as router
rtr=router(self.m3_stack, self)
elif "m3" in tech.layer:
from supply_tree_router import supply_tree_router as router
rtr=router(("m3",), self)
grid_stack = set()
try:
from tech import power_grid
grid_stack = power_grid
except ImportError:
# if no power_grid is specified by tech we use sensible defaults
if "m4" in tech.layer:
# Route a M3/M4 grid
grid_stack = self.m3_stack
elif "m3" in tech.layer:
grid_stack =("m3",)
from supply_grid_router import supply_grid_router as router
rtr=router(grid_stack, self)
rtr.route() rtr.route()