From 4df862d8af4a41579fa59547b4037b4e491cee1d Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Thu, 29 Nov 2018 12:12:10 -0800 Subject: [PATCH] Convert channel router to take netlist of pins rather than names. --- compiler/base/hierarchy_layout.py | 31 ++++--- compiler/modules/bank.py | 143 ++++++++++++++++-------------- compiler/sram_1bank.py | 19 ++-- 3 files changed, 100 insertions(+), 93 deletions(-) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 07d4f611..d7ed07d5 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -745,13 +745,14 @@ class layout(lef.lef): self.add_wire(layer_stack, [pin.center(), mid, trunk_mid]) - def create_channel_route(self, netlist, pins, offset, - layer_stack=("metal1", "via1", "metal2"), pitch=None, + def create_channel_route(self, netlist, + offset, + layer_stack=("metal1", "via1", "metal2"), + pitch=None, vertical=False): """ - The net list is a list of the nets. Each net is a list of pin - names to be connected. Pins is a dictionary of the pin names - to the pin structures. Offset is the lower-left of where the + The net list is a list of the nets. Each net is a list of pins + to be connected. Offset is the lower-left of where the routing channel will start. This does NOT try to minimize the number of tracks -- instead, it picks an order to avoid the vertical conflicts between pins. @@ -786,7 +787,10 @@ class layout(lef.lef): def vcg_pin_overlap(pin1, pin2, vertical): """ Check for vertical or horizontal overlap of the two pins """ - + # FIXME: If the pins are not in a row, this may break. + # However, a top pin shouldn't overlap another top pin, for example, so the + # extra comparison *shouldn't* matter. + # Pin 1 must be in the "BOTTOM" set x_overlap = pin1.by() < pin2.by() and abs(pin1.center().x-pin2.center().x)0: + return + + if self.col_addr_size == 1: + + # Connect to sel[0] and sel[1] + decode_names = ["Zb", "Z"] + + # The Address LSB + self.copy_layout_pin(self.column_decoder_inst[port], "A", "addr{}_0".format(port)) + + elif self.col_addr_size > 1: + decode_names = [] + for i in range(self.num_col_addr_lines): + decode_names.append("out_{}".format(i)) + + for i in range(self.col_addr_size): + decoder_name = "in_{}".format(i) + addr_name = "addr{0}_{1}".format(port,i) + self.copy_layout_pin(self.column_decoder_inst[port], decoder_name, addr_name) + if port%2: - self.route_column_address_lines_right(port) + offset = self.column_decoder_inst[port].ll() - vector(self.num_col_addr_lines*self.m2_pitch, 0) else: - self.route_column_address_lines_left(port) - - def route_column_address_lines_left(self, port): - """ Connecting the select lines of column mux to the address bus """ - if not self.col_addr_size>0: - return - - if self.col_addr_size == 1: - - # Connect to sel[0] and sel[1] - decode_names = ["Zb", "Z"] - - # The Address LSB - self.copy_layout_pin(self.column_decoder_inst[port], "A", "addr{}_0".format(port)) - - elif self.col_addr_size > 1: - decode_names = [] - for i in range(self.num_col_addr_lines): - decode_names.append("out_{}".format(i)) - - for i in range(self.col_addr_size): - decoder_name = "in_{}".format(i) - addr_name = "addr{0}_{1}".format(port,i) - self.copy_layout_pin(self.column_decoder_inst[port], decoder_name, addr_name) - - offset = self.column_decoder_inst[port].lr() + vector(self.m2_pitch, 0) + offset = self.column_decoder_inst[port].lr() + vector(self.m2_pitch, 0) + decode_pins = [self.column_decoder_inst[port].get_pin(x) for x in decode_names] + sel_names = ["sel_{}".format(x) for x in range(self.num_col_addr_lines)] + column_mux_pins = [self.column_mux_array_inst[port].get_pin(x) for x in sel_names] + + route_map = list(zip(decode_pins, column_mux_pins)) + self.create_vertical_channel_route(route_map, offset) - route_map = list(zip(decode_names, sel_names)) - decode_pins = {key: self.column_decoder_inst[port].get_pin(key) for key in decode_names } - column_mux_pins = {key: self.column_mux_array_inst[port].get_pin(key) for key in sel_names } - # Combine the dff and bank pins into a single dictionary of pin name to pin. - all_pins = {**decode_pins, **column_mux_pins} - self.create_vertical_channel_route(route_map, all_pins, offset) + # def route_column_address_lines_right(self, port): + # """ Connecting the select lines of column mux to the address bus """ + # if not self.col_addr_size>0: + # return - def route_column_address_lines_right(self, port): - """ Connecting the select lines of column mux to the address bus """ - if not self.col_addr_size>0: - return - - if self.col_addr_size == 1: + # if self.col_addr_size == 1: - # Connect to sel[0] and sel[1] - decode_names = ["Zb", "Z"] + # # Connect to sel[0] and sel[1] + # decode_names = ["Zb", "Z"] - # The Address LSB - self.copy_layout_pin(self.column_decoder_inst[port], "A", "addr{}_0".format(port)) + # # The Address LSB + # self.copy_layout_pin(self.column_decoder_inst[port], "A", "addr{}_0".format(port)) - elif self.col_addr_size > 1: - decode_names = [] - for i in range(self.num_col_addr_lines): - decode_names.append("out_{}".format(i)) + # elif self.col_addr_size > 1: + # decode_names = [] + # for i in range(self.num_col_addr_lines): + # decode_names.append("out_{}".format(i)) - for i in range(self.col_addr_size): - decoder_name = "in_{}".format(i) - addr_name = "addr{0}_{1}".format(port,i) - self.copy_layout_pin(self.column_decoder_inst[port], decoder_name, addr_name) + # for i in range(self.col_addr_size): + # decoder_name = "in_{}".format(i) + # addr_name = "addr{0}_{1}".format(port,i) + # self.copy_layout_pin(self.column_decoder_inst[port], decoder_name, addr_name) - offset = self.column_decoder_inst[port].ll() - vector(self.num_col_addr_lines*self.m2_pitch, 0) + # offset = self.column_decoder_inst[port].ll() - vector(self.num_col_addr_lines*self.m2_pitch, 0) - sel_names = ["sel_{}".format(x) for x in range(self.num_col_addr_lines)] + # sel_names = ["sel_{}".format(x) for x in range(self.num_col_addr_lines)] - route_map = list(zip(decode_names, sel_names)) - decode_pins = {key: self.column_decoder_inst[port].get_pin(key) for key in decode_names } - column_mux_pins = {key: self.column_mux_array_inst[port].get_pin(key) for key in sel_names } - # Combine the dff and bank pins into a single dictionary of pin name to pin. - all_pins = {**decode_pins, **column_mux_pins} - self.create_vertical_channel_route(route_map, all_pins, offset) + # route_map = list(zip(decode_names, sel_names)) + # decode_pins = {key: self.column_decoder_inst[port].get_pin(key) for key in decode_names } + # column_mux_pins = {key: self.column_mux_array_inst[port].get_pin(key) for key in sel_names } + # # Combine the dff and bank pins into a single dictionary of pin name to pin. + # all_pins = {**decode_pins, **column_mux_pins} + # self.create_vertical_channel_route(route_map, all_pins, offset) def add_lvs_correspondence_points(self): diff --git a/compiler/sram_1bank.py b/compiler/sram_1bank.py index f8ed1559..be7f20ff 100644 --- a/compiler/sram_1bank.py +++ b/compiler/sram_1bank.py @@ -278,17 +278,20 @@ class sram_1bank(sram_base): """ Connect the output of the data flops to the write driver """ # This is where the channel will start (y-dimension at least) for port in self.write_ports: - offset = self.data_dff_insts[port].ul() + vector(0, 2*self.m1_pitch) + if port%2: + offset = self.data_dff_insts[port].ll() - vector(0, (self.word_size+2)*self.m1_pitch) + else: + offset = self.data_dff_insts[port].ul() + vector(0, 2*self.m1_pitch) + dff_names = ["dout_{}".format(x) for x in range(self.word_size)] + dff_pins = [self.data_dff_insts[port].get_pin(x) for x in dff_names] + bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)] - - route_map = list(zip(bank_names, dff_names)) - dff_pins = {key: self.data_dff_insts[port].get_pin(key) for key in dff_names } - bank_pins = {key: self.bank_inst.get_pin(key) for key in bank_names } - # Combine the dff and bank pins into a single dictionary of pin name to pin. - all_pins = {**dff_pins, **bank_pins} - self.create_horizontal_channel_route(route_map, all_pins, offset) + bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] + + route_map = list(zip(bank_pins, dff_pins)) + self.create_horizontal_channel_route(route_map, offset)