Separate add pins and route pins so pins can block supply router.

This commit is contained in:
mrg 2020-12-23 10:49:47 -08:00
parent 96c75d7c4b
commit c89e156bfe
6 changed files with 69 additions and 32 deletions

View File

@ -1132,7 +1132,7 @@ class router(router_tech):
show_all_grids = True show_all_grids = True
if show_all_grids: if show_all_grids:
#self.rg.add_all_grids() # self.rg.add_all_grids()
for g in self.rg.map: for g in self.rg.map:
self.annotate_grid(g) self.annotate_grid(g)

View File

@ -28,8 +28,8 @@ class router_tech:
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]]
(self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_supply_layer_width_space(1) (self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_layer_width_space(1)
(self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0) (self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_layer_width_space(0)
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
@ -60,8 +60,8 @@ class router_tech:
self.horiz_lpp = layer[self.horiz_layer_name] self.horiz_lpp = layer[self.horiz_layer_name]
self.vert_lpp = layer[self.vert_layer_name] self.vert_lpp = layer[self.vert_layer_name]
(self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_supply_layer_width_space(1) (self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_layer_width_space(1)
(self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0) (self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_layer_width_space(0)
# For supplies, we will make the wire wider than the vias # For supplies, we will make the wire wider than the vias
self.vert_layer_minwidth = max(self.vert_layer_minwidth, max_via_size) self.vert_layer_minwidth = max(self.vert_layer_minwidth, max_via_size)
@ -72,11 +72,11 @@ class router_tech:
# We'll keep horizontal and vertical tracks the same for simplicity. # We'll keep horizontal and vertical tracks the same for simplicity.
self.track_width = max(self.horiz_track_width, self.vert_track_width) self.track_width = max(self.horiz_track_width, self.vert_track_width)
debug.info(1, "Track width: {:.3f}".format(self.track_width)) debug.info(1, "Minimum track width: {:.3f}".format(self.track_width))
self.track_space = max(self.horiz_layer_spacing, self.vert_layer_spacing) self.track_space = max(self.horiz_layer_spacing, self.vert_layer_spacing)
debug.info(1, "Track space: {:.3f}".format(self.track_space)) debug.info(1, "Minimum track space: {:.3f}".format(self.track_space))
self.track_wire = self.track_width - self.track_space self.track_wire = self.track_width - self.track_space
debug.info(1, "Track wire width: {:.3f}".format(self.track_wire)) debug.info(1, "Minimum track wire width: {:.3f}".format(self.track_wire))
self.track_widths = vector([self.track_width] * 2) self.track_widths = vector([self.track_width] * 2)
self.track_factor = vector([1/self.track_width] * 2) self.track_factor = vector([1/self.track_width] * 2)
@ -109,7 +109,7 @@ class router_tech:
else: else:
debug.error("Invalid zindex {}".format(zindex), -1) debug.error("Invalid zindex {}".format(zindex), -1)
def get_supply_layer_width_space(self, zindex): def get_layer_width_space(self, zindex):
""" """
These are the width and spacing of a supply layer given a supply rail These are the width and spacing of a supply layer given a supply rail
of the given number of min wire widths. of the given number of min wire widths.

View File

@ -58,6 +58,8 @@ class signal_escape_router(router):
print_time("Maze routing pins",datetime.now(), start_time, 3) print_time("Maze routing pins",datetime.now(), start_time, 3)
# self.write_debug_gds("final_escape_router.gds",False)
return True return True
def route_signal(self, pin_name, side): def route_signal(self, pin_name, side):

View File

@ -28,7 +28,7 @@ class supply_grid_router(router):
start_time = datetime.now() start_time = datetime.now()
# Power rail width in minimum wire widths # Power rail width in minimum wire widths
self.route_track_width = 3 self.route_track_width = 2
router.__init__(self, layers, design, gds_filename, self.route_track_width) router.__init__(self, layers, design, gds_filename, self.route_track_width)

View File

@ -27,7 +27,7 @@ class supply_tree_router(router):
either the gds file name or the design itself (by saving to a gds file). either the gds file name or the design itself (by saving to a gds file).
""" """
# Power rail width in minimum wire widths # Power rail width in minimum wire widths
self.route_track_width = 3 self.route_track_width = 2
router.__init__(self, layers, design, gds_filename, self.route_track_width) router.__init__(self, layers, design, gds_filename, self.route_track_width)
@ -74,7 +74,7 @@ class supply_tree_router(router):
self.route_pins(gnd_name) self.route_pins(gnd_name)
print_time("Maze routing supplies",datetime.now(), start_time, 3) print_time("Maze routing supplies",datetime.now(), start_time, 3)
#self.write_debug_gds("final.gds",False) # self.write_debug_gds("final_tree_router.gds",False)
# Did we route everything?? # Did we route everything??
if not self.check_all_routed(vdd_name): if not self.check_all_routed(vdd_name):

View File

@ -10,6 +10,7 @@ from sram_base import sram_base
from contact import m2_via from contact import m2_via
from channel_route import channel_route from channel_route import channel_route
from signal_escape_router import signal_escape_router as router from signal_escape_router import signal_escape_router as router
from globals import OPTS
class sram_1bank(sram_base): class sram_1bank(sram_base):
@ -106,7 +107,7 @@ class sram_1bank(sram_base):
# We need to temporarily add some pins for the x offsets # We need to temporarily add some pins for the x offsets
# but we'll remove them so that they have the right y # but we'll remove them so that they have the right y
# offsets after the DFF placement. # offsets after the DFF placement.
self.add_layout_pins(escape_route=False, add_vias=False) self.add_layout_pins(add_vias=False)
self.route_dffs(add_routes=False) self.route_dffs(add_routes=False)
self.remove_layout_pins() self.remove_layout_pins()
@ -245,12 +246,13 @@ class sram_1bank(sram_base):
self.data_pos[port] = vector(x_offset, y_offset) self.data_pos[port] = vector(x_offset, y_offset)
self.spare_wen_pos[port] = vector(x_offset, y_offset) self.spare_wen_pos[port] = vector(x_offset, y_offset)
def add_layout_pins(self, escape_route=True, add_vias=True): def route_escape_pins(self):
""" """
Add the top-level pins for a single bank SRAM with control. Add the top-level pins for a single bank SRAM with control.
""" """
# List of pin to new pin name # List of pin to new pin name
all_pins = [] pins_to_route = []
for port in self.all_ports: for port in self.all_ports:
# Depending on the port, use the bottom/top or left/right sides # Depending on the port, use the bottom/top or left/right sides
# Port 0 is left/bottom # Port 0 is left/bottom
@ -258,6 +260,46 @@ class sram_1bank(sram_base):
bottom_or_top = "bottom" if port==0 else "top" bottom_or_top = "bottom" if port==0 else "top"
left_or_right = "left" if port==0 else "right" left_or_right = "left" if port==0 else "right"
# Connect the control pins as inputs
for signal in self.control_logic_inputs[port]:
if signal.startswith("rbl"):
continue
if signal=="clk":
pins_to_route.append(("{0}{1}".format(signal, port), bottom_or_top))
else:
pins_to_route.append(("{0}{1}".format(signal, port), left_or_right))
if port in self.write_ports:
for bit in range(self.word_size + self.num_spare_cols):
pins_to_route.append(("din{0}[{1}]".format(port, bit), bottom_or_top))
if port in self.readwrite_ports or port in self.read_ports:
for bit in range(self.word_size + self.num_spare_cols):
pins_to_route.append(("dout{0}[{1}]".format(port, bit), bottom_or_top))
for bit in range(self.col_addr_size):
pins_to_route.append(("addr{0}[{1}]".format(port, bit), bottom_or_top))
for bit in range(self.row_addr_size):
pins_to_route.append(("addr{0}[{1}]".format(port, bit + self.col_addr_size), left_or_right))
if port in self.write_ports:
if self.write_size:
for bit in range(self.num_wmasks):
pins_to_route.append(("wmask{0}[{1}]".format(port, bit), bottom_or_top))
if port in self.write_ports:
for bit in range(self.num_spare_cols):
pins_to_route.append(("spare_wen{0}[{1}]".format(port, bit), bottom_or_top))
rtr=router(self.m3_stack, self)
rtr.escape_route(pins_to_route)
def add_layout_pins(self, add_vias=True):
"""
Add the top-level pins for a single bank SRAM with control.
"""
for port in self.all_ports:
# Hack: If we are escape routing, set the pin layer to # Hack: If we are escape routing, set the pin layer to
# None so that we will start from the pin layer # None so that we will start from the pin layer
# Otherwise, set it as the pin layer so that no vias are added. # Otherwise, set it as the pin layer so that no vias are added.
@ -276,10 +318,6 @@ class sram_1bank(sram_base):
signal, signal,
signal + "{}".format(port), signal + "{}".format(port),
start_layer=pin_layer) start_layer=pin_layer)
if signal=="clk":
all_pins.append(("{0}{1}".format(signal, port), bottom_or_top))
else:
all_pins.append(("{0}{1}".format(signal, port), left_or_right))
if port in self.write_ports: if port in self.write_ports:
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
@ -287,7 +325,6 @@ class sram_1bank(sram_base):
"din_{}".format(bit), "din_{}".format(bit),
"din{0}[{1}]".format(port, bit), "din{0}[{1}]".format(port, bit),
start_layer=pin_layer) start_layer=pin_layer)
all_pins.append(("din{0}[{1}]".format(port, bit), bottom_or_top))
if port in self.readwrite_ports or port in self.read_ports: if port in self.readwrite_ports or port in self.read_ports:
for bit in range(self.word_size + self.num_spare_cols): for bit in range(self.word_size + self.num_spare_cols):
@ -295,7 +332,6 @@ class sram_1bank(sram_base):
"dout{0}_{1}".format(port, bit), "dout{0}_{1}".format(port, bit),
"dout{0}[{1}]".format(port, bit), "dout{0}[{1}]".format(port, bit),
start_layer=pin_layer) start_layer=pin_layer)
all_pins.append(("dout{0}[{1}]".format(port, bit), bottom_or_top))
for bit in range(self.col_addr_size): for bit in range(self.col_addr_size):
self.add_io_pin(self.col_addr_dff_insts[port], self.add_io_pin(self.col_addr_dff_insts[port],
@ -303,14 +339,11 @@ class sram_1bank(sram_base):
"addr{0}[{1}]".format(port, bit), "addr{0}[{1}]".format(port, bit),
start_layer=pin_layer) start_layer=pin_layer)
all_pins.append(("addr{0}[{1}]".format(port, bit), bottom_or_top))
for bit in range(self.row_addr_size): for bit in range(self.row_addr_size):
self.add_io_pin(self.row_addr_dff_insts[port], self.add_io_pin(self.row_addr_dff_insts[port],
"din_{}".format(bit), "din_{}".format(bit),
"addr{0}[{1}]".format(port, bit + self.col_addr_size), "addr{0}[{1}]".format(port, bit + self.col_addr_size),
start_layer=pin_layer) start_layer=pin_layer)
all_pins.append(("addr{0}[{1}]".format(port, bit + self.col_addr_size), left_or_right))
if port in self.write_ports: if port in self.write_ports:
if self.write_size: if self.write_size:
@ -319,7 +352,6 @@ class sram_1bank(sram_base):
"din_{}".format(bit), "din_{}".format(bit),
"wmask{0}[{1}]".format(port, bit), "wmask{0}[{1}]".format(port, bit),
start_layer=pin_layer) start_layer=pin_layer)
all_pins.append(("wmask{0}[{1}]".format(port, bit), bottom_or_top))
if port in self.write_ports: if port in self.write_ports:
for bit in range(self.num_spare_cols): for bit in range(self.num_spare_cols):
@ -327,11 +359,6 @@ class sram_1bank(sram_base):
"din_{}".format(bit), "din_{}".format(bit),
"spare_wen{0}[{1}]".format(port, bit), "spare_wen{0}[{1}]".format(port, bit),
start_layer=pin_layer) start_layer=pin_layer)
all_pins.append(("spare_wen{0}[{1}]".format(port, bit), bottom_or_top))
if escape_route:
rtr=router(self.m3_stack, self)
rtr.escape_route(all_pins)
def route_layout(self): def route_layout(self):
""" Route a single bank SRAM """ """ Route a single bank SRAM """
@ -344,9 +371,17 @@ class sram_1bank(sram_base):
self.route_dffs() self.route_dffs()
# We add the vias to M3 before routing supplies because
# they might create some blockages
self.add_layout_pins()
# Route the supplies first since the MST is not blockage aware
# and signals can route to anywhere on sides (it is flexible)
self.route_supplies() self.route_supplies()
self.add_layout_pins() # Route the pins to the perimeter
if OPTS.perimeter_pins:
self.route_escape_pins()
def route_dffs(self, add_routes=True): def route_dffs(self, add_routes=True):