Refactor global and local to be a bitcell_base_array

This commit is contained in:
mrg 2020-09-01 11:59:01 -07:00
parent c1c631abe1
commit 4ec47d8ee1
5 changed files with 122 additions and 100 deletions

View File

@ -8,7 +8,7 @@
import debug import debug
import design import design
from sram_factory import factory from sram_factory import factory
from math import log, ceil from math import log, ceil, floor
from tech import drc, layer from tech import drc, layer
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
@ -372,11 +372,27 @@ class bank(design.design):
self.num_rbl = len(self.all_ports) self.num_rbl = len(self.all_ports)
self.bitcell_array = factory.create(module_type="replica_bitcell_array", try:
cols=self.num_cols + self.num_spare_cols, local_bitline_size = OPTS.local_bitline_size
rows=self.num_rows, except AttributeError:
rbl=[1, 1 if len(self.all_ports)>1 else 0]) 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) self.add_mod(self.bitcell_array)
if(self.num_banks > 1): if(self.num_banks > 1):
@ -392,7 +408,7 @@ class bank(design.design):
# bit lines (left to right) # bit lines (left to right)
# vdd # vdd
# gnd # gnd
import pdb; pdb.set_trace()
temp = self.bitcell_array.get_all_bitline_names() temp = self.bitcell_array.get_all_bitline_names()
wordline_names = self.bitcell_array.get_all_wordline_names() wordline_names = self.bitcell_array.get_all_wordline_names()

View File

@ -27,12 +27,11 @@ class bitcell_base_array(design.design):
# Bitcell for port names only # Bitcell for port names only
self.cell = factory.create(module_type="bitcell") 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_bitline_names()
self.create_all_wordline_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): def create_all_bitline_names(self):
self.bitline_names = [[] for port in self.all_ports] self.bitline_names = [[] for port in self.all_ports]
for col in range(self.column_size): for col in range(self.column_size):
@ -42,8 +41,8 @@ class bitcell_base_array(design.design):
# Make a flat list too # Make a flat list too
self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl] self.all_bitline_names = [x for sl in zip(*self.bitline_names) for x in sl]
def get_all_wordline_names(self, prefix=""): # def get_all_wordline_names(self, prefix=""):
return [prefix + x for x in self.all_wordline_names] # return [prefix + x for x in self.all_wordline_names]
def create_all_wordline_names(self): def create_all_wordline_names(self):
self.wordline_names = [[] for port in self.all_ports] 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.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] 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): def add_pins(self):
for bl_name in self.get_bitline_names(): for bl_name in self.get_bitline_names():
self.add_pin(bl_name, "INOUT") self.add_pin(bl_name, "INOUT")
@ -84,6 +71,70 @@ class bitcell_base_array(design.design):
return bitcell_pins 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): def add_layout_pins(self):
""" Add the layout pins """ """ Add the layout pins """

View File

@ -5,7 +5,7 @@
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
import design import bitcell_base_array
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
from vector import vector from vector import vector
@ -13,7 +13,7 @@ import debug
from numpy import cumsum 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. Creates a global bitcell array.
Rows is an integer number for all local arrays. 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=""): def __init__(self, rows, cols, name=""):
# The total of all columns will be the number of columns # 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.cols = cols
self.num_cols = sum(cols) self.num_cols = sum(cols)
self.col_offsets = [0] + list(cumsum(self.cols)[:-1]) self.col_offsets = [0] + list(cumsum(self.cols)[:-1])
@ -33,7 +33,6 @@ class global_bitcell_array(design.design):
self.left_rbl = self.rbl[0] self.left_rbl = self.rbl[0]
self.right_rbl = self.rbl[1] self.right_rbl = self.rbl[1]
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
@ -78,6 +77,14 @@ class global_bitcell_array(design.design):
self.add_mod(la) self.add_mod(la)
self.local_mods.append(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): def add_pins(self):
self.add_bitline_pins() self.add_bitline_pins()

View File

@ -5,20 +5,21 @@
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
import design import bitcell_base_array
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
from vector import vector from vector import vector
import debug 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. 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 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. or it can be combined into a larger array with hierarchical WL.
""" """
def __init__(self, rows, cols, rbl, add_rbl=None, name=""): 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)) debug.info(2, "create local array of size {} rows x {} cols words".format(rows, cols))
self.rows = rows self.rows = rows
@ -74,8 +75,15 @@ class local_bitcell_array(design.design):
cols=self.cols) cols=self.cols)
self.add_mod(self.wl_array) 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) # Inputs to the wordline driver (by port)
self.wordline_names = [] self.wordline_names = []
# Outputs from the wordline driver (by port) # 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.bitline_names = self.bitcell_array.bitline_names
self.all_array_bitline_names = self.bitcell_array.get_all_bitline_names() self.all_array_bitline_names = self.bitcell_array.get_all_bitline_names()
# Arrays are always: # Arrays are always:
# bit lines (left to right) # bit lines (left to right)
# word lines (bottom to top) # word lines (bottom to top)

View File

@ -51,6 +51,9 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
# Two dummy cols plus replica if we add the column # Two dummy cols plus replica if we add the column
self.extra_cols = 2 + self.add_left_rbl + self.add_right_rbl 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() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
@ -439,70 +442,6 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
for inst in self.replica_col_insts: for inst in self.replica_col_insts:
self.copy_layout_pin(inst, pin_name) 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): def analytical_power(self, corner, load):
"""Power of Bitcell array and bitline in nW.""" """Power of Bitcell array and bitline in nW."""
# Dynamic Power from Bitline # Dynamic Power from Bitline