diff --git a/compiler/modules/dummy_array.py b/compiler/modules/dummy_array.py index 9004994b..37ce0ba4 100644 --- a/compiler/modules/dummy_array.py +++ b/compiler/modules/dummy_array.py @@ -53,13 +53,60 @@ class dummy_array(bitcell_base_array): mod=self.dummy_cell) self.connect_inst(self.get_bitcell_pins(row, col)) + def add_pins(self): + # bitline pins are not added because they are floating + for wl_name in self.get_wordline_names(): + self.add_pin(wl_name, "INPUT") + self.add_pin("vdd", "POWER") + self.add_pin("gnd", "GROUND") + + def add_layout_pins(self): + """ Add the layout pins """ + + # Add the bitline metal, but not as pins since they are going to just be floating + # For some reason, LVS has an issue if we don't add this metal + bitline_names = self.cell.get_all_bitline_names() + for col in range(self.column_size): + for port in self.all_ports: + bl_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port]) + self.add_rect(layer=bl_pin.layer, + offset=bl_pin.ll().scale(1, 0), + width=bl_pin.width(), + height=self.height) + br_pin = self.cell_inst[0, col].get_pin(bitline_names[2 * port + 1]) + self.add_rect(layer=br_pin.layer, + offset=br_pin.ll().scale(1, 0), + width=br_pin.width(), + height=self.height) + + wl_names = self.cell.get_all_wl_names() + for row in range(self.row_size): + for port in self.all_ports: + wl_pin = self.cell_inst[row, 0].get_pin(wl_names[port]) + self.add_layout_pin(text="wl_{0}_{1}".format(port, row), + layer=wl_pin.layer, + offset=wl_pin.ll().scale(0, 1), + width=self.width, + height=wl_pin.height()) + + # Copy a vdd/gnd layout pin from every cell + for row in range(self.row_size): + for col in range(self.column_size): + inst = self.cell_inst[row, col] + for pin_name in ["vdd", "gnd"]: + self.copy_layout_pin(inst, pin_name) + def input_load(self): wl_wire = self.gen_wl_wire() return wl_wire.return_input_cap() def get_wordline_cin(self): - """Get the relative input capacitance from the wordline connections in all the bitcell""" - # A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns + """ + Get the relative input capacitance from the + wordline connections in all the bitcell + """ + # A single wordline is connected to all the bitcells + # in a single row meaning the capacitance depends on the # of columns bitcell_wl_cin = self.cell.get_wl_cin() total_cin = bitcell_wl_cin * self.column_size return total_cin diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 299c7421..75fed678 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -187,21 +187,13 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): self.bitline_names = [] # Replica bitlines by port self.rbl_bitline_names = [] - # Dummy bitlines by left/right - self.dummy_col_bitline_names = [] - for loc in ["left", "right"]: - self.dummy_col_bitline_names.append([]) + for x in range(self.add_left_rbl + self.add_right_rbl): + self.rbl_bitline_names.append([]) for port in self.all_ports: - bitline_names = ["dummy_{0}_{1}".format(x, loc) for x in self.row_cap_left.get_bitline_names(port)] - self.dummy_col_bitline_names[-1].extend(bitline_names) - self.all_dummy_col_bitline_names = [x for sl in self.dummy_col_bitline_names for x in sl] - - for port in range(self.add_left_rbl + self.add_right_rbl): - left_names=["rbl_bl_{0}_{1}".format(x, port) for x in self.all_ports] - right_names=["rbl_br_{0}_{1}".format(x, port) for x in self.all_ports] - bitline_names = [x for t in zip(left_names, right_names) for x in t] - self.rbl_bitline_names.append(bitline_names) + self.rbl_bitline_names[-1].append("rbl_bl_{0}_{1}".format(port, x)) + self.rbl_bitline_names[-1].append("rbl_br_{0}_{1}".format(port, x)) + # Make a flat list too self.all_rbl_bitline_names = [x for sl in self.rbl_bitline_names for x in sl] @@ -211,13 +203,11 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): # Make a flat list too self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl] - self.add_pin_list(self.dummy_col_bitline_names[0], "INOUT") for port in range(self.add_left_rbl): self.add_pin_list(self.rbl_bitline_names[port], "INOUT") self.add_pin_list(self.all_bitline_names, "INOUT") for port in range(self.add_left_rbl, self.add_left_rbl + self.add_right_rbl): self.add_pin_list(self.rbl_bitline_names[port], "INOUT") - self.add_pin_list(self.dummy_col_bitline_names[1], "INOUT") def add_wordline_pins(self): @@ -288,29 +278,25 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): for port in range(self.left_rbl + self.right_rbl): self.dummy_row_replica_insts.append(self.add_inst(name="dummy_row_{}".format(port), mod=self.dummy_row)) - self.connect_inst(self.all_bitline_names + self.rbl_wordline_names[port] + supplies) + self.connect_inst(self.rbl_wordline_names[port] + supplies) # Top/bottom dummy rows or col caps self.dummy_row_insts = [] self.dummy_row_insts.append(self.add_inst(name="dummy_row_bot", mod=self.col_cap)) - self.connect_inst(self.all_bitline_names - + self.dummy_row_wordline_names[0] - + supplies) + self.connect_inst(self.dummy_row_wordline_names[0] + supplies) self.dummy_row_insts.append(self.add_inst(name="dummy_row_top", mod=self.col_cap)) - self.connect_inst(self.all_bitline_names - + self.dummy_row_wordline_names[1] - + supplies) + self.connect_inst(self.dummy_row_wordline_names[1] + supplies) # Left/right Dummy columns self.dummy_col_insts = [] self.dummy_col_insts.append(self.add_inst(name="dummy_col_left", mod=self.row_cap_left)) - self.connect_inst(self.dummy_col_bitline_names[0] + self.replica_array_wordline_names + supplies) + self.connect_inst(self.replica_array_wordline_names + supplies) self.dummy_col_insts.append(self.add_inst(name="dummy_col_right", mod=self.row_cap_right)) - self.connect_inst(self.dummy_col_bitline_names[1] + self.replica_array_wordline_names + supplies) + self.connect_inst(self.replica_array_wordline_names + supplies) def create_layout(self): @@ -480,13 +466,11 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): def get_all_bitline_names(self): """ Return ALL the bitline names (including dummy and rbl) """ temp = [] - temp.extend(self.get_dummy_bitline_names(0)) if self.add_left_rbl > 0: temp.extend(self.get_rbl_bitline_names(0)) temp.extend(self.get_bitline_names()) if self.add_right_rbl > 0: temp.extend(self.get_rbl_bitline_names(self.add_left_rbl)) - temp.extend(self.get_dummy_bitline_names(1)) return temp def get_wordline_names(self, port=None): @@ -518,13 +502,6 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): return self.all_dummy_row_wordline_names else: return self.dummy_row_wordline_names[port] - - def get_dummy_bitline_names(self, port=None): - """ Return the BL for the given dummy port """ - if port == None: - return self.all_dummy_col_bitline_names - else: - return self.dummy_col_bitline_names[port] def analytical_power(self, corner, load): """Power of Bitcell array and bitline in nW.""" diff --git a/compiler/tests/15_global_bitcell_array_1rw_1r_test.py b/compiler/tests/15_global_bitcell_array_1rw_1r_test.py new file mode 100755 index 00000000..d92e3b2b --- /dev/null +++ b/compiler/tests/15_global_bitcell_array_1rw_1r_test.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# See LICENSE for licensing information. +# +# Copyright (c) 2016-2019 Regents of the University of California and The Board +# of Regents for the Oklahoma Agricultural and Mechanical College +# (acting for and on behalf of Oklahoma State University) +# All rights reserved. +# +import unittest +from testutils import * +import sys, os +sys.path.append(os.getenv("OPENRAM_HOME")) +import globals +from sram_factory import factory +import debug + + +# @unittest.skip("SKIPPING 05_global_bitcell_array_test") +class global_bitcell_array_test(openram_test): + + def runTest(self): + config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) + globals.init_openram(config_file) + + debug.info(2, "Testing 2 x 4x4 global bitcell array for 6t_cell without replica") + a = factory.create(module_type="global_bitcell_array", cols=[4, 4], rows=4, ports=[0]) + self.local_check(a) + + # debug.info(2, "Testing 4x4 local bitcell array for 6t_cell with replica column") + # a = factory.create(module_type="local_bitcell_array", cols=4, left_rbl=1, rows=4, ports=[0]) + # self.local_check(a) + + globals.end_openram() + + +# run the test from the command line +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main(testRunner=debugTestRunner())