mirror of https://github.com/VLSIDA/OpenRAM.git
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:
parent
90a4a72bba
commit
9749c522d1
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue