mirror of https://github.com/VLSIDA/OpenRAM.git
Refactor global and local to be a bitcell_base_array
This commit is contained in:
parent
c1c631abe1
commit
4ec47d8ee1
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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 """
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue