From d5e331d4f360f0ad8ce2c06f2e62e0ae9809698b Mon Sep 17 00:00:00 2001 From: jsowash Date: Fri, 9 Aug 2019 14:27:53 -0700 Subject: [PATCH] Connected en together in write_mask_and_array. --- compiler/globals.py | 8 ++- compiler/modules/write_mask_and_array.py | 49 +++++++++++++++--- .../tests/10_write_mask_and_array_test.py | 4 ++ technology/freepdk45/gds_lib/write_driver.gds | Bin 20480 -> 20480 bytes 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/compiler/globals.py b/compiler/globals.py index 0b262430..aa64c0a3 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -476,10 +476,14 @@ def report_status(): # If a write mask is specified by the user, the mask write size should be the same as # the word size so that an entire word is written at once. if OPTS.write_size is not None: - if (OPTS.write_size < 1 or OPTS.write_size > OPTS.word_size): - debug.error("Write size needs to be between 1 bit and {0} bits.".format(OPTS.word_size)) if (OPTS.word_size % OPTS.write_size != 0): debug.error("Write size needs to be an integer multiple of word size.") + # If write size is more than half of the word size, then it doesn't need a write mask. It would be writing + # the whole word. + if (OPTS.write_size < 1 or OPTS.write_size > OPTS.word_size/2): + debug.error("Write size needs to be between 1 bit and {0} bits/2.".format(OPTS.word_size)) + + if not OPTS.tech_name: debug.error("Tech name must be specified in config file.") diff --git a/compiler/modules/write_mask_and_array.py b/compiler/modules/write_mask_and_array.py index b7435e51..e5052c07 100644 --- a/compiler/modules/write_mask_and_array.py +++ b/compiler/modules/write_mask_and_array.py @@ -51,6 +51,7 @@ class write_mask_and_array(design.design): self.place_and2_array() self.add_layout_pins() + self.route_en() self.add_boundary() self.DRC_LVS() @@ -81,10 +82,28 @@ class write_mask_and_array(design.design): def place_and2_array(self): - # place the write mask AND array below the write driver array - and2_spacing = self.and2.width + # Place the write mask AND array at the start of each write driver enable length. + # This ensures the write mask AND array will be directly under the corresponding write driver enable wire. + + # This is just used for measurements, so don't add the module + self.bitcell = factory.create(module_type="bitcell") + self.driver = factory.create(module_type="write_driver") + if self.bitcell.width > self.driver.width: + self.driver_spacing = self.bitcell.width + else: + self.driver_spacing = self.driver.width + + if (self.words_per_row == 1): + wmask_en_len = (self.write_size * self.driver_spacing) + if self.driver_spacing * self.write_size < self.and2.width: + debug.error("Cannot layout write mask AND array. One pand2 is longer than the corresponding write drivers.") + else: + wmask_en_len = 2 * (self.write_size * self.driver_spacing) + if wmask_en_len < self.and2.width: + debug.error("Cannot layout write mask AND array. One pand2 is longer than the corresponding write drivers.") + for i in range(self.num_wmasks): - base = vector(i * and2_spacing, 0) + base = vector(i * wmask_en_len, 0) self.and2_insts[i].place(base) @@ -98,11 +117,13 @@ class write_mask_and_array(design.design): height=wmask_in_pin.height()) en_pin = self.and2_insts[i].get_pin("B") - self.add_layout_pin(text="en", - layer=en_pin.layer, - offset=en_pin.ll(), - width=en_pin.width(), - height=en_pin.height()) + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=en_pin.center()) + self.add_via_center(layers=("metal2", "via2", "metal3"), + offset=en_pin.center()) + self.add_layout_pin_rect_center(text="en", + layer="metal3", + offset=en_pin.center()) wmask_out_pin = self.and2_insts[i].get_pin("Z") self.add_layout_pin(text="wmask_out_{0}".format(i), @@ -115,6 +136,9 @@ class write_mask_and_array(design.design): pin_list = self.and2_insts[i].get_pins(n) for pin in pin_list: pin_pos = pin.center() + # Add the M1->M2 stack + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=pin_pos) # Add the M2->M3 stack self.add_via_center(layers=("metal2", "via2", "metal3"), offset=pin_pos) @@ -123,6 +147,15 @@ class write_mask_and_array(design.design): offset=pin_pos) + def route_en(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. diff --git a/compiler/tests/10_write_mask_and_array_test.py b/compiler/tests/10_write_mask_and_array_test.py index c79b8fc6..830448eb 100644 --- a/compiler/tests/10_write_mask_and_array_test.py +++ b/compiler/tests/10_write_mask_and_array_test.py @@ -27,6 +27,10 @@ class write_mask_and_array_test(openram_test): a = factory.create(module_type="write_mask_and_array", columns=8, word_size=8, write_size=4) self.local_check(a) + debug.info(2, "Testing write_mask_and_array for columns=8, word_size=8, write_size=4") + a = factory.create(module_type="write_mask_and_array", columns=16, word_size=16, write_size=4) + self.local_check(a) + debug.info(2, "Testing write_mask_and_array for columns=16, word_size=8, write_size=2") a = factory.create(module_type="write_mask_and_array", columns=16, word_size=8, write_size=2) self.local_check(a) diff --git a/technology/freepdk45/gds_lib/write_driver.gds b/technology/freepdk45/gds_lib/write_driver.gds index 742e39d40ba6e581ac7a4effccb6d226bc0b9930..86015e7a7991ff9a3775c8e11fa1fee5ce5113a1 100644 GIT binary patch delta 126 zcmZozz}T>Wae}zJFarkzCj%FQHiIz(4-;ETYFc7xP6-2p2s5jl!jaia9|wQ4REiP5 z;JfA>gA6MZ10Mr7gCtOg27?I$lHQGRPc&5+7#N}$7?{MN^h^c@mTy2lj0THuPScvD F3ILqN7}o#* delta 126 zcmZozz}T>Wae}zJ5Cb;@Cj%FQHG>rc4-;ETYFc7xP6-2p2s5jl!jaia9|wQ4REiP5 z;JfArgA6MZ10PVmBv6M2g9!tY-i>ijG*$lp|G$fYfk_-n&tza=JptsyXt4O^G_6^x E0JEkd&;S4c