From 92e0671e15b08f00489a95f3f67cf9713b385a56 Mon Sep 17 00:00:00 2001 From: jsowash Date: Thu, 15 Aug 2019 12:36:17 -0700 Subject: [PATCH] Removed DRC error with AND array in freepdk45 and moved pin on en_{} pin in port data. --- compiler/modules/port_data.py | 73 +++++++++++------------- compiler/modules/write_mask_and_array.py | 19 ++---- 2 files changed, 40 insertions(+), 52 deletions(-) diff --git a/compiler/modules/port_data.py b/compiler/modules/port_data.py index 7ce099bb..1052abab 100644 --- a/compiler/modules/port_data.py +++ b/compiler/modules/port_data.py @@ -124,8 +124,8 @@ class port_data(design.design): if self.port in self.readwrite_ports: # (write_mask_and ->) write_driver -> sense_amp -> (column_mux ->) precharge -> bitcell_array - self.route_write_mask_and(self.port) - self.route_write_mask_and_to_write_driver(self.port) + self.route_write_mask_and_array_in(self.port) + self.route_write_mask_and_array_to_write_driver(self.port) self.route_write_driver_in(self.port) self.route_sense_amp_out(self.port) self.route_write_driver_to_sense_amp(self.port) @@ -138,10 +138,9 @@ class port_data(design.design): self.route_column_mux_to_precharge_array(self.port) else: # (write_mask_and ->) write_driver -> (column_mux ->) precharge -> bitcell_array - self.route_write_mask_and(self.port) - self.route_write_mask_and_to_write_driver(self.port) + self.route_write_mask_and_array_in(self.port) + self.route_write_mask_and_array_to_write_driver(self.port) self.route_write_driver_in(self.port) - self.route_write_mask_and_to_write_driver(self.port) self.route_write_driver_to_column_mux_or_precharge_array(self.port) self.route_column_mux_to_precharge_array(self.port) @@ -432,31 +431,44 @@ class port_data(design.design): self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name) - def route_write_mask_and(self, port): - """ Add pins for the write mask and array output """ - - # for bit in range(self.num_wmasks): - # wmask_out_name = "wmask_out_{}".format(bit) - # wdriver_sel_name = "wdriver_sel_{}".format(bit) - # self.copy_layout_pin(self.write_mask_and_array_inst, wmask_out_name, wdriver_sel_name) + def route_write_mask_and_array_in(self, port): + """ Add pins for the write mask and array input """ for bit in range(self.num_wmasks): wmask_in_name = "wmask_in_{}".format(bit) bank_wmask_name = "bank_wmask_{}".format(bit) self.copy_layout_pin(self.write_mask_and_array_inst, wmask_in_name, bank_wmask_name) + + def route_write_mask_and_array_to_write_driver(self,port): + """ Routing of wdriver_sel_{} between write mask AND array and write driver array. Adds layout pin for write + mask AND array output and via for write driver enable """ + + inst1 = self.write_mask_and_array_inst + inst2 = self.write_driver_array_inst + for bit in range(self.num_wmasks): - wdriver_sel_pin = self.write_mask_and_array_inst.get_pin("wmask_out_{}".format(bit)) - # self.add_layout_pin_rect_center(text="wdriver_sel_{0}".format(bit), - # layer=wdriver_sel_pin.layer, - # offset=wdriver_sel_pin.center(), - # height=wdriver_sel_pin.height(), - # width=wdriver_sel_pin.width()) + # Bring write mask AND array output pin to port data level + self.copy_layout_pin(inst1,"wmask_out_{0}".format(bit), "wdriver_sel_{0}".format(bit)) + + # Add via for the write driver enable input in write driver + wmask_out_pin = inst1.get_pin("wmask_out_{0}".format(bit)) + wdriver_en_pin = inst2.get_pin("en_{0}".format(bit)) + center_x = wmask_out_pin.cx() + center_y = wdriver_en_pin.cy() + end_en_pin = vector(wdriver_en_pin.rx(),wmask_out_pin.ly()g) + center_wmask = vector(center_x, center_y) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=wdriver_sel_pin.center()) + offset=wdriver_en_pin.rc()) self.add_layout_pin_rect_center(text="wdriver_sel_{0}".format(bit), layer="metal2", - offset=wdriver_sel_pin.center()) + offset=wdriver_en_pin.rc()) + + # Route between write mask AND array and write driver array + self.add_path("metal1",[ wmask_out_pin.center(), end_en_pin]) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=end_en_pin) + self.add_path("metal2", [end_en_pin, wdriver_en_pin.rc()]) def route_column_mux_to_precharge_array(self, port): @@ -525,7 +537,7 @@ class port_data(design.design): def route_write_driver_to_sense_amp(self, port): """ Routing of BL and BR between write driver and sense amp """ - + inst1 = self.write_driver_array_inst inst2 = self.sense_amp_array_inst @@ -534,17 +546,6 @@ class port_data(design.design): self.channel_route_bitlines(inst1=inst1, inst2=inst2, num_bits=self.word_size) - def route_write_mask_and_to_write_driver(self,port): - """ Routing of wdriver_sel_{} between write mask AND array and write driver array """ - inst1 = self.write_mask_and_array_inst - inst2 = self.write_driver_array_inst - - for bit in range(self.num_wmasks): - wdriver_sel_out_pin = inst1.get_pin("wmask_out_{}".format(bit)) - wdriver_sel_in_pin = inst2.get_pin("en_{}".format(bit)) - self.add_path("metal2", [wdriver_sel_out_pin.center(), wdriver_sel_in_pin.center()]) - - def route_bitline_pins(self): """ Add the bitline pins for the given port """ @@ -581,14 +582,8 @@ class port_data(design.design): if self.write_driver_array_inst: if self.write_mask_and_array_inst: for bit in range(self.num_wmasks): + # Add write driver's en_{} pins self.copy_layout_pin(self.write_driver_array_inst, "en_{}".format(bit), "wdriver_sel_{}".format(bit)) - - wdriver_en_pin = self.write_driver_array_inst.get_pin("en_{}".format(bit)) - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=wdriver_en_pin.center()) - self.add_layout_pin_rect_center(text="wdriver_sel_{0}".format(bit), - layer="metal2", - offset=wdriver_en_pin.center()) else: self.copy_layout_pin(self.write_driver_array_inst, "en", "w_en") if self.write_mask_and_array_inst: diff --git a/compiler/modules/write_mask_and_array.py b/compiler/modules/write_mask_and_array.py index 878da688..ba78a5a0 100644 --- a/compiler/modules/write_mask_and_array.py +++ b/compiler/modules/write_mask_and_array.py @@ -51,7 +51,6 @@ class write_mask_and_array(design.design): self.place_and2_array() self.add_layout_pins() - # self.route_enable() self.add_boundary() self.DRC_LVS() @@ -121,12 +120,13 @@ class write_mask_and_array(design.design): offset=en_pin.center()) self.add_via_center(layers=("metal2", "via2", "metal3"), offset=en_pin.center()) + if i < self.num_wmasks-1: self.add_layout_pin(text="en", layer="metal3", - offset=en_pin.ll(), - width = self.en_width(i), - height = en_pin.height()) + offset=en_pin.bc(), + width = self.en_width(i), + height = drc('minwidth_metal3')) wmask_out_pin = self.and2_insts[i].get_pin("Z") self.add_layout_pin(text="wmask_out_{0}".format(i), @@ -152,18 +152,11 @@ class write_mask_and_array(design.design): def en_width(self, pin): en_pin = self.and2_insts[pin].get_pin("B") next_en_pin = self.and2_insts[pin+1].get_pin("B") - width = next_en_pin.lr() - en_pin.ll() + width = next_en_pin.center() - en_pin.center() + # Return x coordinates only return width[0] - # def route_enable(self): - # for i in range(self.num_wmasks-1): - # en_pin = self.and2_insts[i].get_pin("B") - # next_en_pin = self.and2_insts[i+1].get_pin("B") - # offset = en_pin.center() - # next_offset = next_en_pin.center() - # self.add_path("metal3", [offset, next_offset]) - def get_cin(self): """Get the relative capacitance of all the input connections in the bank""" # The enable is connected to an and2 for every row.