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 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()

View File

@ -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 """

View File

@ -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()

View File

@ -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)

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
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