Add vdd/gnd pins to the side.

This commit is contained in:
mrg 2021-05-03 15:14:15 -07:00
parent 98fb34c44c
commit a0e263b14a
3 changed files with 77 additions and 24 deletions

View File

@ -11,7 +11,7 @@ process_corners = ["TT"]
supply_voltages = [5.0] supply_voltages = [5.0]
temperatures = [25] temperatures = [25]
route_supplies = True route_supplies = "side"
check_lvsdrc = True check_lvsdrc = True
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports, output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,

View File

@ -1214,7 +1214,7 @@ class router(router_tech):
return self.convert_track_to_pin(v) return self.convert_track_to_pin(v)
return None return None
def get_ll_pin(self, pin_name): def get_ll_pin(self, pin_name):
""" Return the lowest, leftest pin group """ """ Return the lowest, leftest pin group """
@ -1228,6 +1228,23 @@ class router(router_tech):
keep_pin = pin keep_pin = pin
return keep_pin return keep_pin
def get_left_pins(self, pin_name):
""" Return the leftest pin(s) group """
keep_pins = []
for index, pg in enumerate(self.pin_groups[pin_name]):
for pin in pg.enclosures:
if not keep_pins:
keep_pins = [pin]
else:
# Only need to check first since they are all the same left value
if pin.lx() == keep_pins[0].lx():
keep_pins.append(pin)
elif pin.lx() < keep_pins[0].lx():
keep_pins = [pin]
return keep_pins
def check_all_routed(self, pin_name): def check_all_routed(self, pin_name):
""" """

View File

@ -229,6 +229,10 @@ 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 OPTS.route_supplies == "grid":
from supply_grid_router import supply_grid_router as router
else:
from supply_tree_router import supply_tree_router as router
try: try:
from tech import power_grid from tech import power_grid
@ -237,17 +241,15 @@ class sram_base(design, verilog, lef):
# if no power_grid is specified by tech we use sensible defaults # if no power_grid is specified by tech we use sensible defaults
# Route a M3/M4 grid # Route a M3/M4 grid
grid_stack = self.m3_stack grid_stack = self.m3_stack
if OPTS.route_supplies == "grid":
from supply_grid_router import supply_grid_router as router
elif OPTS.route_supplies:
from supply_tree_router import supply_tree_router as router
rtr=router(grid_stack, self) rtr=router(grid_stack, self)
rtr.route() rtr.route()
lowest_coord = self.find_lowest_coords()
highest_coord = self.find_highest_coords()
# Find the lowest leftest pin for vdd and gnd # Find the lowest leftest pin for vdd and gnd
for pin_name in ["vdd", "gnd"]: for (pin_name, pin_index) in [("vdd", 0), ("gnd", 1)]:
# Copy the pin shape(s) to rectangles # Copy the pin shape(s) to rectangles
for pin in self.get_pins(pin_name): for pin in self.get_pins(pin_name):
self.add_rect(pin.layer, self.add_rect(pin.layer,
@ -258,23 +260,57 @@ class sram_base(design, verilog, lef):
# Remove the pin shape(s) # Remove the pin shape(s)
self.remove_layout_pin(pin_name) self.remove_layout_pin(pin_name)
# Get the lowest, leftest pin # Either add two long rails or a simple pin
pin = rtr.get_ll_pin(pin_name) if OPTS.route_supplies == "side":
# Get the leftest pins
pins = rtr.get_left_pins(pin_name)
pin_width = 2 * getattr(self, "{}_width".format(pins[0].layer))
pin_space = 2 * getattr(self, "{}_space".format(pins[0].layer))
supply_pitch = pin_width + pin_space
# Add side power rails on left from bottom to top
# These have a temporary name and will be connected later.
# They are here to reserve space now and ensure other pins go beyond
# their perimeter.
supply_height = highest_coord.y - lowest_coord.y
supply_pin = self.add_layout_pin(text=pin_name,
layer="m4",
offset=lowest_coord + vector(pin_index * supply_pitch, 0),
width=pin_width,
height=supply_height)
# Add it as an IO pin to the perimeter route_width = pins[0].rx() - lowest_coord.x
lowest_coord = self.find_lowest_coords() for pin in pins:
route_width = pin.rx() - lowest_coord.x pin_offset = vector(lowest_coord.x, pin.by())
pin_width = 2 * getattr(self, "{}_width".format(pin.layer)) self.add_rect(pin.layer,
pin_offset = vector(lowest_coord.x, pin.by()) pin_offset,
self.add_layout_pin(pin_name, route_width,
pin.layer, pin.height())
pin_offset, center_offset = vector(supply_pin.cx(),
pin_width, pin.cy())
pin.height()) self.add_via_center(layers=self.m3_stack,
self.add_rect(pin.layer, offset=center_offset)
pin_offset, else:
route_width, # Get the lowest, leftest pin
pin.height()) pin = rtr.get_ll_pins(pin_name)
pin_width = 2 * getattr(self, "{}_width".format(pin.layer))
pin_space = 2 * getattr(self, "{}_space".format(pin.layer))
# Add it as an IO pin to the perimeter
route_width = pin.rx() - lowest_coord.x
pin_offset = vector(lowest_coord.x, pin.by())
self.add_rect(pin.layer,
pin_offset,
route_width,
pin.height())
self.add_layout_pin(pin_name,
pin.layer,
pin_offset,
pin_width,
pin.height())
def route_escape_pins(self): def route_escape_pins(self):
""" """