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.is_library_cell = False # Flag for library cells
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
@ -1169,12 +1175,12 @@ class layout():
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.
"""
pins = inst.get_pins(name)
for pin in pins:
if pin.layer == "m3":
if pin.layer == self.pwr_grid_layer:
self.add_layout_pin(name,
pin.layer,
pin.ll(),
@ -1183,14 +1189,17 @@ class layout():
elif pin.layer == "m1":
self.add_power_pin(name, pin.center())
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"):
"""
Add a single power pin from M3 down to M1 at the given center location.
The starting layer is specified to determine which vias are needed.
Add a single power pin from the lowest power_grid layer down to M1 at
the given center location. The starting layer is specified to determine
which vias are needed.
"""
if vertical:
direction = ("V", "V")
@ -1198,18 +1207,18 @@ class layout():
direction = ("H", "H")
via = self.add_via_stack_center(from_layer=start_layer,
to_layer="m3",
to_layer=self.pwr_grid_layer,
size=size,
offset=loc,
direction=direction)
if start_layer == "m3":
if start_layer == self.pwr_grid_layer:
self.add_layout_pin_rect_center(text=name,
layer="m3",
layer=self.pwr_grid_layer,
offset=loc)
else:
self.add_layout_pin_rect_center(text=name,
layer="m3",
layer=self.pwr_grid_layer,
offset=loc,
width=via.width,
height=via.height)

View File

@ -5,7 +5,7 @@
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from tech import drc, layer
from tech import drc, layer, preferred_directions
from contact import contact
from vector import vector
import debug
@ -26,6 +26,9 @@ class router_tech:
self.rail_track_width = rail_track_width
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_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.vert_track_width = self.vert_layer_minwidth + self.vert_layer_spacing
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))
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:
# Do not route the power supply (leave as must-connect pins)
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()