From d02ea06ff2d0ff1588d3304b7f19ce9f7e515c3b Mon Sep 17 00:00:00 2001 From: jsowash Date: Fri, 16 Aug 2019 14:12:41 -0700 Subject: [PATCH] Added method to route between the output of wmask AND array and en of write driver. --- compiler/modules/port_data.py | 78 ++++++----------------- compiler/tests/18_port_data_wmask_test.py | 6 +- 2 files changed, 21 insertions(+), 63 deletions(-) diff --git a/compiler/modules/port_data.py b/compiler/modules/port_data.py index 9325bef5..99e1bcba 100644 --- a/compiler/modules/port_data.py +++ b/compiler/modules/port_data.py @@ -438,7 +438,6 @@ class port_data(design.design): 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) - # self.copy_layout_pin(self.write_mask_and_array_inst,"wmask_out_{0}".format(bit), "wdriver_sel_{0}".format(bit)) def route_write_mask_and_array_to_write_driver(self,port): @@ -448,14 +447,7 @@ class port_data(design.design): inst1 = self.write_mask_and_array_inst inst2 = self.write_driver_array_inst - # get length of a single driver enable - driver = factory.create(module_type="write_driver") - bitcell = factory.create(module_type="bitcell") - if bitcell.width > driver.width: - driver_spacing = bitcell.width - else: - driver_spacing = driver.width - + i = 0 for bit in range(self.num_wmasks): # 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)) @@ -463,68 +455,34 @@ class port_data(design.design): wmask_out_pin = inst1.get_pin("wmask_out_{0}".format(bit)) wdriver_en_pin = inst2.get_pin("en_{0}".format(bit)) - - bitline_pin = inst2.get_pin("data_{}".format(bit)) - half_width = bitline_pin.width() / 2 - - - width = driver.width + # The metal2 wdriver_sel_{} wire must hit the en_{} pin after the closest bitline pin that's right of the + # the wdriver_sel_{} pin in the write driver AND array. spacing = 2*drc("metal2_to_metal2") - middle_of_driver = driver.width/2 - len_no_drc = middle_of_driver + spacing + half_width + if bit == 0: + while (wmask_out_pin.lx() > inst2.get_pin("data_{0}".format(i)).rx()): + i += 1 + length = inst2.get_pin("data_{0}".format(i)).rx() + spacing - if self.words_per_row == 1: - length = 3*width + len_no_drc + (bit*driver.width*self.write_size) else: - length = 3*width + self.words_per_row*driver_spacing + len_no_drc + (bit*self.words_per_row*driver_spacing*driver.width*self.write_size) - # while (wdriver_en_pin.lx() > length): - # length += driver.width + i = i + ( bit*self.write_size ) + length = inst2.get_pin("data_{0}".format(i)).rx() + spacing - offset = vector(length, wdriver_en_pin.cy()) - end_en_pin = vector(length,wmask_out_pin.cy()) + beg_pos = wmask_out_pin.center() + middle_pos = vector(length,wmask_out_pin.cy()) + end_pos = vector(length, wdriver_en_pin.cy()) # Add via for the write driver array's enable input self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=offset) + offset=end_pos) self.add_layout_pin_rect_center(text="wdriver_sel_{0}".format(bit), layer="metal2", - offset=offset) + offset=end_pos) + # Route between write mask AND array and write driver array - self.add_path("metal1",[ wmask_out_pin.center(), end_en_pin]) + self.add_path("metal1",[beg_pos, middle_pos]) self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=end_en_pin) - self.add_path("metal2", [end_en_pin, offset]) - - - - # # get length of a single driver enable - # self.driver = factory.create(module_type="write_driver") - # driver_en = self.driver.get_pin("en") - # len = 2*driver_en.width() + bit*driver_en.width() - # - # - # print(len) - # while (wdriver_en_pin.lx() > len): - # len += 2*driver_en.width() - # print("here") - # len += 2*driver_en.width() - # end_en_pin = vector(len,wmask_out_pin.by()) - # - # offset = vector(len, wdriver_en_pin.cy()) - - - # spacing = drc("metal2_to_metal2") - # center_x = wmask_out_pin.cy() - # center_y = wdriver_en_pin.cx() - # end_en_pin = vector(wdriver_en_pin.rx(),wmask_out_pin.by()) - # - # center_wmask = vector(center_x, center_y) - # - # self.add_path("metal2", [wmask_out_pin.center(), wdriver_en_pin.rc()]) - # - # self.add_path("metal2", [wmask_out_pin.center(), wdriver_en_pin.center()]) - - # # + offset=middle_pos) + self.add_path("metal2", [middle_pos, end_pos]) def route_column_mux_to_precharge_array(self, port): diff --git a/compiler/tests/18_port_data_wmask_test.py b/compiler/tests/18_port_data_wmask_test.py index e89ea77d..29b0e624 100644 --- a/compiler/tests/18_port_data_wmask_test.py +++ b/compiler/tests/18_port_data_wmask_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +1#!/usr/bin/env python3 # See LICENSE for licensing information. # # Copyright (c) 2016-2019 Regents of the University of California @@ -70,7 +70,7 @@ class port_data_test(openram_test): self.local_check(a) a = factory.create("port_data", sram_config=c, port=1) self.local_check(a) - + # c.num_words = 32 c.words_per_row = 2 factory.reset() @@ -91,7 +91,7 @@ class port_data_test(openram_test): a = factory.create("port_data", sram_config=c, port=1) self.local_check(a) - c.word_size = 2 + c.word_size = 8 c.num_words = 128 c.words_per_row = 8 factory.reset()