From c89e156bfe32296e519bf9c59ba992a695a8d909 Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 23 Dec 2020 10:49:47 -0800 Subject: [PATCH] Separate add pins and route pins so pins can block supply router. --- compiler/router/router.py | 2 +- compiler/router/router_tech.py | 16 +++--- compiler/router/signal_escape_router.py | 2 + compiler/router/supply_grid_router.py | 2 +- compiler/router/supply_tree_router.py | 4 +- compiler/sram/sram_1bank.py | 75 ++++++++++++++++++------- 6 files changed, 69 insertions(+), 32 deletions(-) diff --git a/compiler/router/router.py b/compiler/router/router.py index 7428b75c..1825925b 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -1132,7 +1132,7 @@ class router(router_tech): show_all_grids = True if show_all_grids: - #self.rg.add_all_grids() + # self.rg.add_all_grids() for g in self.rg.map: self.annotate_grid(g) diff --git a/compiler/router/router_tech.py b/compiler/router/router_tech.py index b34e4233..e77405fa 100644 --- a/compiler/router/router_tech.py +++ b/compiler/router/router_tech.py @@ -28,8 +28,8 @@ class router_tech: self.horiz_layer_name = self.vert_layer_name = 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.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0) + (self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_layer_width_space(1) + (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.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.vert_lpp = layer[self.vert_layer_name] - (self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_supply_layer_width_space(1) - (self.horiz_layer_minwidth, self.horiz_layer_spacing) = self.get_supply_layer_width_space(0) + (self.vert_layer_minwidth, self.vert_layer_spacing) = self.get_layer_width_space(1) + (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 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. 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) - 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 - 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_factor = vector([1/self.track_width] * 2) @@ -109,7 +109,7 @@ class router_tech: else: 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 of the given number of min wire widths. diff --git a/compiler/router/signal_escape_router.py b/compiler/router/signal_escape_router.py index f76cb9f0..83232054 100644 --- a/compiler/router/signal_escape_router.py +++ b/compiler/router/signal_escape_router.py @@ -58,6 +58,8 @@ class signal_escape_router(router): print_time("Maze routing pins",datetime.now(), start_time, 3) + # self.write_debug_gds("final_escape_router.gds",False) + return True def route_signal(self, pin_name, side): diff --git a/compiler/router/supply_grid_router.py b/compiler/router/supply_grid_router.py index db892986..53758d9b 100644 --- a/compiler/router/supply_grid_router.py +++ b/compiler/router/supply_grid_router.py @@ -28,7 +28,7 @@ class supply_grid_router(router): start_time = datetime.now() # 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) diff --git a/compiler/router/supply_tree_router.py b/compiler/router/supply_tree_router.py index 367d3ea5..b4149211 100644 --- a/compiler/router/supply_tree_router.py +++ b/compiler/router/supply_tree_router.py @@ -27,7 +27,7 @@ class supply_tree_router(router): either the gds file name or the design itself (by saving to a gds file). """ # 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) @@ -74,7 +74,7 @@ class supply_tree_router(router): self.route_pins(gnd_name) 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?? if not self.check_all_routed(vdd_name): diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index d2dd62b8..2617d7f1 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -10,6 +10,7 @@ from sram_base import sram_base from contact import m2_via from channel_route import channel_route from signal_escape_router import signal_escape_router as router +from globals import OPTS 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 # but we'll remove them so that they have the right y # 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.remove_layout_pins() @@ -245,12 +246,13 @@ class sram_1bank(sram_base): self.data_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. """ + # List of pin to new pin name - all_pins = [] + pins_to_route = [] for port in self.all_ports: # Depending on the port, use the bottom/top or left/right sides # Port 0 is left/bottom @@ -258,6 +260,46 @@ class sram_1bank(sram_base): bottom_or_top = "bottom" if port==0 else "top" 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 # None so that we will start from the pin layer # Otherwise, set it as the pin layer so that no vias are added. @@ -276,10 +318,6 @@ class sram_1bank(sram_base): signal, signal + "{}".format(port), 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: for bit in range(self.word_size + self.num_spare_cols): @@ -287,7 +325,6 @@ class sram_1bank(sram_base): "din_{}".format(bit), "din{0}[{1}]".format(port, bit), 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: 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), start_layer=pin_layer) - all_pins.append(("dout{0}[{1}]".format(port, bit), bottom_or_top)) for bit in range(self.col_addr_size): 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), start_layer=pin_layer) - all_pins.append(("addr{0}[{1}]".format(port, bit), bottom_or_top)) - for bit in range(self.row_addr_size): self.add_io_pin(self.row_addr_dff_insts[port], "din_{}".format(bit), "addr{0}[{1}]".format(port, bit + self.col_addr_size), 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 self.write_size: @@ -319,7 +352,6 @@ class sram_1bank(sram_base): "din_{}".format(bit), "wmask{0}[{1}]".format(port, bit), start_layer=pin_layer) - all_pins.append(("wmask{0}[{1}]".format(port, bit), bottom_or_top)) if port in self.write_ports: for bit in range(self.num_spare_cols): @@ -327,12 +359,7 @@ class sram_1bank(sram_base): "din_{}".format(bit), "spare_wen{0}[{1}]".format(port, bit), 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): """ Route a single bank SRAM """ @@ -344,9 +371,17 @@ class sram_1bank(sram_base): 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.add_layout_pins() + # Route the pins to the perimeter + if OPTS.perimeter_pins: + self.route_escape_pins() def route_dffs(self, add_routes=True):