diff --git a/compiler/modules/bank.py b/compiler/modules/bank.py index ba6e4a4e..a0b6c9b5 100644 --- a/compiler/modules/bank.py +++ b/compiler/modules/bank.py @@ -8,7 +8,7 @@ import debug import design from sram_factory import factory -from math import log, ceil +from math import log, ceil, floor from tech import drc, layer from vector import vector from globals import OPTS @@ -371,14 +371,30 @@ class bank(design.design): self.add_mod(self.port_address) self.num_rbl = len(self.all_ports) - - self.bitcell_array = factory.create(module_type="replica_bitcell_array", - cols=self.num_cols + self.num_spare_cols, - rows=self.num_rows, - rbl=[1, 1 if len(self.all_ports)>1 else 0]) + try: + local_bitline_size = OPTS.local_bitline_size + except AttributeError: + local_bitline_size = 0 + + if local_bitline_size > 0: + # Find the even multiple that satisfies the fanout with equal sized local arrays + total_cols = self.num_cols + self.num_spare_cols + num_lb = floor(total_cols / local_bitline_size) + final_size = total_cols - num_lb * local_bitline_size + cols = [local_bitline_size] * (num_lb - 1) + # Add the odd bits to the last local array + cols.append(local_bitline_size + final_size) + self.bitcell_array = factory.create(module_type="global_bitcell_array", + cols=cols, + rows=self.num_rows) + else: + self.bitcell_array = factory.create(module_type="replica_bitcell_array", + cols=self.num_cols + self.num_spare_cols, + rows=self.num_rows, + rbl=[1, 1 if len(self.all_ports)>1 else 0]) self.add_mod(self.bitcell_array) - + if(self.num_banks > 1): self.bank_select = factory.create(module_type="bank_select") self.add_mod(self.bank_select) @@ -392,7 +408,7 @@ class bank(design.design): # bit lines (left to right) # vdd # gnd - + import pdb; pdb.set_trace() temp = self.bitcell_array.get_all_bitline_names() wordline_names = self.bitcell_array.get_all_wordline_names() diff --git a/compiler/modules/bitcell_base_array.py b/compiler/modules/bitcell_base_array.py index 18e3adec..00ea49b0 100644 --- a/compiler/modules/bitcell_base_array.py +++ b/compiler/modules/bitcell_base_array.py @@ -26,13 +26,12 @@ class bitcell_base_array(design.design): # Bitcell for port names only self.cell = factory.create(module_type="bitcell") - + + # This will create a default set of bitline/wordline names + # They may get over-riden in the super module self.create_all_bitline_names() self.create_all_wordline_names() - - def get_all_bitline_names(self, prefix=""): - return [prefix + x for x in self.all_bitline_names] - + def create_all_bitline_names(self): self.bitline_names = [[] for port in self.all_ports] for col in range(self.column_size): @@ -42,8 +41,8 @@ class bitcell_base_array(design.design): # Make a flat list too self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl] - def get_all_wordline_names(self, prefix=""): - return [prefix + x for x in self.all_wordline_names] + # def get_all_wordline_names(self, prefix=""): + # return [prefix + x for x in self.all_wordline_names] def create_all_wordline_names(self): self.wordline_names = [[] for port in self.all_ports] @@ -52,18 +51,6 @@ class bitcell_base_array(design.design): self.wordline_names[port].append("wl_{0}_{1}".format(port, row)) self.all_wordline_names = [x for sl in zip(*self.wordline_names) for x in sl] - def get_bitline_names(self, port=None): - if port == None: - return self.all_bitline_names - else: - return self.bitline_names[port] - - def get_wordline_names(self, port=None): - if port == None: - return self.all_wordline_names - else: - return self.wordline_names[port] - def add_pins(self): for bl_name in self.get_bitline_names(): self.add_pin(bl_name, "INOUT") @@ -84,6 +71,70 @@ class bitcell_base_array(design.design): return bitcell_pins + def get_rbl_wordline_names(self, port=None): + """ + Return the ACTIVE WL for the given RBL port. + Inactive will be set to gnd. + """ + if port == None: + return self.all_rbl_wordline_names + else: + return self.rbl_wordline_names[port] + + def get_rbl_bitline_names(self, port=None): + """ Return the BL for the given RBL port """ + if port == None: + return self.all_rbl_bitline_names + else: + return self.rbl_bitline_names[port] + + def get_bitline_names(self, port=None): + """ Return the regular bitlines for the given port or all""" + if port == None: + return self.all_bitline_names + else: + return self.bitline_names[port] + + def get_all_bitline_names(self): + """ Return ALL the bitline names (including dummy and rbl) """ + temp = [] + 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)) + return temp + + def get_wordline_names(self, port=None): + """ Return the regular wordline names """ + if port == None: + return self.all_wordline_names + else: + return self.wordline_names[port] + + def get_all_wordline_names(self, port=None): + """ Return all the wordline names """ + temp = [] + temp.extend(self.get_dummy_wordline_names(0)) + temp.extend(self.get_rbl_wordline_names(0)) + if port == None: + temp.extend(self.all_wordline_names) + else: + temp.extend(self.wordline_names[port]) + if len(self.all_ports) > 1: + temp.extend(self.get_rbl_wordline_names(1)) + temp.extend(self.get_dummy_wordline_names(1)) + return temp + + def get_dummy_wordline_names(self, port=None): + """ + Return the ACTIVE WL for the given dummy port. + """ + if port == None: + return self.all_dummy_row_wordline_names + else: + return self.dummy_row_wordline_names[port] + def add_layout_pins(self): """ Add the layout pins """ diff --git a/compiler/modules/global_bitcell_array.py b/compiler/modules/global_bitcell_array.py index d0b051ff..d5e5678b 100644 --- a/compiler/modules/global_bitcell_array.py +++ b/compiler/modules/global_bitcell_array.py @@ -5,7 +5,7 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -import design +import bitcell_base_array from globals import OPTS from sram_factory import factory from vector import vector @@ -13,7 +13,7 @@ import debug from numpy import cumsum -class global_bitcell_array(design.design): +class global_bitcell_array(bitcell_base_array.bitcell_base_array): """ Creates a global bitcell array. Rows is an integer number for all local arrays. @@ -22,7 +22,7 @@ class global_bitcell_array(design.design): """ def __init__(self, rows, cols, name=""): # The total of all columns will be the number of columns - super().__init__(name=name) + super().__init__(name=name, rows=rows, cols=cols, column_offset=0) self.cols = cols self.num_cols = sum(cols) self.col_offsets = [0] + list(cumsum(self.cols)[:-1]) @@ -32,7 +32,6 @@ class global_bitcell_array(design.design): self.rbl = [1, 1 if len(self.all_ports)>1 else 0] self.left_rbl = self.rbl[0] self.right_rbl = self.rbl[1] - self.create_netlist() if not OPTS.netlist_only: @@ -77,7 +76,15 @@ class global_bitcell_array(design.design): self.add_mod(la) self.local_mods.append(la) - + + # We make these on our own and don't use the base names + def create_all_wordline_names(self): + pass + + # We make these on our own and don't use the base names + def create_all_bitline_names(self): + pass + def add_pins(self): self.add_bitline_pins() diff --git a/compiler/modules/local_bitcell_array.py b/compiler/modules/local_bitcell_array.py index f82b5cd1..b08fc2e5 100644 --- a/compiler/modules/local_bitcell_array.py +++ b/compiler/modules/local_bitcell_array.py @@ -5,20 +5,21 @@ # (acting for and on behalf of Oklahoma State University) # All rights reserved. # -import design +import bitcell_base_array from globals import OPTS from sram_factory import factory from vector import vector import debug -class local_bitcell_array(design.design): + +class local_bitcell_array(bitcell_base_array.bitcell_base_array): """ A local bitcell array is a bitcell array with a wordline driver. This can either be a single aray on its own if there is no hierarchical WL or it can be combined into a larger array with hierarchical WL. """ def __init__(self, rows, cols, rbl, add_rbl=None, name=""): - super().__init__(name=name) + super().__init__(name=name, rows=rows, cols=cols, column_offset=0) debug.info(2, "create local array of size {} rows x {} cols words".format(rows, cols)) self.rows = rows @@ -74,8 +75,15 @@ class local_bitcell_array(design.design): cols=self.cols) self.add_mod(self.wl_array) - def add_pins(self): + # We make these on our own and don't use the base names + def create_all_wordline_names(self): + pass + # We make these on our own and don't use the base names + def create_all_bitline_names(self): + pass + + def add_pins(self): # Inputs to the wordline driver (by port) self.wordline_names = [] # Outputs from the wordline driver (by port) @@ -105,6 +113,7 @@ class local_bitcell_array(design.design): self.bitline_names = self.bitcell_array.bitline_names self.all_array_bitline_names = self.bitcell_array.get_all_bitline_names() + # Arrays are always: # bit lines (left to right) # word lines (bottom to top) diff --git a/compiler/modules/replica_bitcell_array.py b/compiler/modules/replica_bitcell_array.py index 75fed678..0bb95044 100644 --- a/compiler/modules/replica_bitcell_array.py +++ b/compiler/modules/replica_bitcell_array.py @@ -51,6 +51,9 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): # Two dummy cols plus replica if we add the column self.extra_cols = 2 + self.add_left_rbl + self.add_right_rbl + self.create_all_bitline_names() + self.create_all_wordline_names() + self.create_netlist() if not OPTS.netlist_only: self.create_layout() @@ -439,70 +442,6 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array): for inst in self.replica_col_insts: self.copy_layout_pin(inst, pin_name) - def get_rbl_wordline_names(self, port=None): - """ - Return the ACTIVE WL for the given RBL port. - Inactive will be set to gnd. - """ - if port == None: - return self.all_rbl_wordline_names - else: - return self.rbl_wordline_names[port] - - def get_rbl_bitline_names(self, port=None): - """ Return the BL for the given RBL port """ - if port == None: - return self.all_rbl_bitline_names - else: - return self.rbl_bitline_names[port] - - def get_bitline_names(self, port=None): - """ Return the regular bitlines for the given port or all""" - if port == None: - return self.all_bitline_names - else: - return self.bitline_names[port] - - def get_all_bitline_names(self): - """ Return ALL the bitline names (including dummy and rbl) """ - temp = [] - 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)) - return temp - - def get_wordline_names(self, port=None): - """ Return the regular wordline names """ - if port == None: - return self.all_wordline_names - else: - return self.wordline_names[port] - - def get_all_wordline_names(self, port=None): - """ Return all the wordline names """ - temp = [] - temp.extend(self.get_dummy_wordline_names(0)) - temp.extend(self.get_rbl_wordline_names(0)) - if port == None: - temp.extend(self.all_wordline_names) - else: - temp.extend(self.wordline_names[port]) - if len(self.all_ports) > 1: - temp.extend(self.get_rbl_wordline_names(1)) - temp.extend(self.get_dummy_wordline_names(1)) - return temp - - def get_dummy_wordline_names(self, port=None): - """ - Return the ACTIVE WL for the given dummy port. - """ - if port == None: - return self.all_dummy_row_wordline_names - else: - return self.dummy_row_wordline_names[port] - def analytical_power(self, corner, load): """Power of Bitcell array and bitline in nW.""" # Dynamic Power from Bitline