From c340870ba0ff6c6e86da99ac1e667c27a69ae481 Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 1 Jul 2020 14:44:01 -0700 Subject: [PATCH] Channel route dout wires as well in read write ports --- compiler/base/channel_route.py | 2 +- compiler/base/hierarchy_layout.py | 6 +-- compiler/sram/sram_1bank.py | 64 ++++++++++++++++++++++--------- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/compiler/base/channel_route.py b/compiler/base/channel_route.py index 5e9b9531..cd4bbdc1 100644 --- a/compiler/base/channel_route.py +++ b/compiler/base/channel_route.py @@ -161,7 +161,7 @@ class channel_route(design.design): else: # FIXME: We don't support cyclic VCGs right now. debug.error("Cyclic VCG in channel router.", -1) - + # These are the pins we'll have to connect pin_list = nets[net_name] # print("Routing:", net_name, [x.name for x in pin_list]) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 275b69e9..8995488a 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -1176,9 +1176,9 @@ class layout(): self.add_path(layer, [pin_loc, peri_pin_loc]) - self.add_layout_pin_rect_center(text=name, - layer=layer, - offset=peri_pin_loc) + return self.add_layout_pin_rect_center(text=name, + layer=layer, + offset=peri_pin_loc) def add_power_ring(self, bbox): """ diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index 52cbb2a1..d2c58e49 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -81,6 +81,10 @@ class sram_1bank(sram_base): # Write ports need the data input flops and write mask flops if port in self.write_ports: self.data_bus_size[port] += self.num_wmasks + self.word_size + # This is for the din pins that get routed in the same channel + # when we have dout and din together + if port in self.readwrite_ports: + self.data_bus_size[port] += self.word_size # Convert to length self.data_bus_size[port] *= self.m4_nonpref_pitch # Add the gap in unit length @@ -237,18 +241,45 @@ class sram_1bank(sram_base): "clk", "clk{}".format(port)) - # Data output pins go to BOTTOM/TOP - if port in self.read_ports: + # Data input pins go to BOTTOM/TOP + din_ports = [] + if port in self.write_ports: for bit in range(self.word_size + self.num_spare_cols): if OPTS.perimeter_pins: + p = self.add_perimeter_pin(name="din{0}[{1}]".format(port, bit), + pin=self.data_dff_insts[port].get_pin("din_{0}".format(bit)), + side=bottom_or_top, + bbox=bbox) + din_ports.append(p) + else: + self.copy_layout_pin(self.bank_inst, + "din{0}_{1}".format(port, bit), + "din{0}[{1}]".format(port, bit)) + + # Data output pins go to BOTTOM/TOP + if port in self.readwrite_ports and OPTS.perimeter_pins: + for bit in range(self.word_size + self.num_spare_cols): + # This should be routed next to the din pin + p = din_ports[bit] + self.add_layout_pin_rect_center(text="dout{0}[{1}]".format(port, bit), + layer=p.layer, + offset=p.center() + vector(self.m3_pitch, 0), + width=p.width(), + height=p.height()) + elif port in self.read_ports: + for bit in range(self.word_size + self.num_spare_cols): + if OPTS.perimeter_pins: + # This should have a clear route to the perimeter if there are no din routes self.add_perimeter_pin(name="dout{0}[{1}]".format(port, bit), pin=self.bank_inst.get_pin("dout{0}_{1}".format(port, bit)), side=bottom_or_top, bbox=bbox) else: - self.copy_layout_pin(self.bank_inst, - "dout{0}_{1}".format(port, bit), + self.copy_layout_pin(self.data_dff_insts[port], + "dout_{}".format(bit), "dout{0}[{1}]".format(port, bit)) + + # Lower address bits go to BOTTOM/TOP for bit in range(self.col_addr_size): @@ -274,19 +305,6 @@ class sram_1bank(sram_base): "din_{}".format(bit), "addr{0}[{1}]".format(port, bit + self.col_addr_size)) - # Data input pins go to BOTTOM/TOP - if port in self.write_ports: - for bit in range(self.word_size + self.num_spare_cols): - if OPTS.perimeter_pins: - self.add_perimeter_pin(name="din{0}[{1}]".format(port, bit), - pin=self.data_dff_insts[port].get_pin("din_{}".format(bit)), - side=bottom_or_top, - bbox=bbox) - else: - self.copy_layout_pin(self.data_dff_insts[port], - "din_{}".format(bit), - "din{0}[{1}]".format(port, bit)) - # Write mask pins go to BOTTOM/TOP if port in self.write_ports: if self.write_size: @@ -349,12 +367,22 @@ class sram_1bank(sram_base): route_map.extend(list(zip(bank_pins, dff_pins))) if port in self.write_ports: - # data dff + # synchronized inputs from data dff dff_names = ["dout_{}".format(x) for x in range(self.word_size + self.num_spare_cols)] 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 + self.num_spare_cols)] bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] route_map.extend(list(zip(bank_pins, dff_pins))) + + if port in self.readwrite_ports and OPTS.perimeter_pins: + # outputs from sense amp + # These are the output pins which had their pin placed on the perimeter, so route from the + # sense amp which should not align with write driver input + sram_names = ["dout{0}[{1}]".format(port, x) for x in range(self.word_size + self.num_spare_cols)] + sram_pins = [self.get_pin(x) for x in sram_names] + bank_names = ["dout{0}_{1}".format(port, x) for x in range(self.word_size + self.num_spare_cols)] + bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] + route_map.extend(list(zip(bank_pins, sram_pins))) if self.num_wmasks > 0 and port in self.write_ports: layer_stack = self.m3_stack