mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'wlbuffer' into dev
This commit is contained in:
commit
c1c1535210
|
|
@ -161,14 +161,23 @@ class spice():
|
||||||
there is a problem. The check option can be set to false
|
there is a problem. The check option can be set to false
|
||||||
where we dynamically generate groups of connections after a
|
where we dynamically generate groups of connections after a
|
||||||
group of modules are generated."""
|
group of modules are generated."""
|
||||||
if (check and (len(self.insts[-1].mod.pins) != len(args))):
|
num_pins = len(self.insts[-1].mod.pins)
|
||||||
|
num_args = len(args)
|
||||||
|
if (check and num_pins != num_args):
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
modpins_string=pformat(self.insts[-1].mod.pins)
|
if num_pins < num_args:
|
||||||
argpins_string=pformat(args)
|
mod_pins = self.insts[-1].mod.pins + [""] * (num_args - num_pins)
|
||||||
debug.error("Mod connections: {}".format(modpins_string))
|
arg_pins = args
|
||||||
debug.error("Inst connections: {}".format(argpins_string))
|
else:
|
||||||
debug.error("Number of net connections ({0}) does not match last instance ({1})".format(len(self.insts[-1].mod.pins),
|
arg_pins = args + [""] * (num_pins - num_args)
|
||||||
len(args)), 1)
|
mod_pins = self.insts[-1].mod.pins
|
||||||
|
|
||||||
|
modpins_string = "\n".join(["{0} -> {1}".format(arg, mod) for (arg, mod) in zip(arg_pins, mod_pins)])
|
||||||
|
debug.error("Connection mismatch:\nInst ({0}) -> Mod ({1})\n{2}".format(num_args,
|
||||||
|
num_pins,
|
||||||
|
modpins_string),
|
||||||
|
1)
|
||||||
|
|
||||||
self.conns.append(args)
|
self.conns.append(args)
|
||||||
|
|
||||||
if check and (len(self.insts)!=len(self.conns)):
|
if check and (len(self.insts)!=len(self.conns)):
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,20 @@
|
||||||
# (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 bitcell_base_array
|
import design
|
||||||
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(bitcell_base_array.bitcell_base_array):
|
class local_bitcell_array(design.design):
|
||||||
"""
|
"""
|
||||||
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, rows, cols, 0)
|
super().__init__(name=name)
|
||||||
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
|
||||||
|
|
@ -76,50 +76,43 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
|
|
||||||
|
# Inputs to the wordline driver (by port)
|
||||||
self.wordline_names = []
|
self.wordline_names = []
|
||||||
|
# Outputs from the wordline driver (by port)
|
||||||
self.driver_wordline_outputs = []
|
self.driver_wordline_outputs = []
|
||||||
|
# Inputs to the bitcell array (by port)
|
||||||
self.array_wordline_inputs = []
|
self.array_wordline_inputs = []
|
||||||
|
|
||||||
# Port 0
|
for port in self.all_ports:
|
||||||
wordline_inputs = [x for x in self.bitcell_array.get_wordline_names(0) if not x.startswith("dummy")]
|
wordline_inputs = []
|
||||||
if len(self.all_ports) > 1:
|
if port == 0:
|
||||||
# Drop off the RBL for port 1
|
wordline_inputs += [self.bitcell_array.get_rbl_wordline_names(0)[0]]
|
||||||
self.wordline_names.append(wordline_inputs[:-1])
|
wordline_inputs += self.bitcell_array.get_wordline_names(port)
|
||||||
else:
|
if port == 1:
|
||||||
|
wordline_inputs += [self.bitcell_array.get_rbl_wordline_names(1)[1]]
|
||||||
self.wordline_names.append(wordline_inputs)
|
self.wordline_names.append(wordline_inputs)
|
||||||
self.driver_wordline_outputs.append([x + "i" for x in self.wordline_names[-1]])
|
|
||||||
self.array_wordline_inputs.append([x + "i" if not x.startswith("dummy") else "gnd" for x in self.bitcell_array.get_wordline_names(0)])
|
|
||||||
|
|
||||||
# Port 1
|
|
||||||
if len(self.all_ports) > 1:
|
|
||||||
self.wordline_names.append([x for x in self.bitcell_array.get_wordline_names(1) if not x.startswith("dummy")][1:])
|
|
||||||
self.driver_wordline_outputs.append([x + "i" for x in self.wordline_names[-1]])
|
self.driver_wordline_outputs.append([x + "i" for x in self.wordline_names[-1]])
|
||||||
self.array_wordline_inputs.append([x + "i" if not x.startswith("dummy") else "gnd" for x in self.bitcell_array.get_wordline_names(1)])
|
|
||||||
|
|
||||||
self.all_driver_wordline_inputs = [x for x in self.bitcell_array.get_wordline_names() if not x.startswith("dummy")]
|
|
||||||
self.replica_names = self.bitcell_array.get_rbl_wordline_names()
|
|
||||||
|
|
||||||
self.gnd_wl_names = []
|
self.gnd_wl_names = []
|
||||||
|
|
||||||
# Connect unused RBL WL to gnd
|
# Connect unused RBL WL to gnd
|
||||||
array_rbl_names = set([x for x in self.bitcell_array.get_all_wordline_names() if x.startswith("rbl")])
|
array_rbl_names = set([x for x in self.bitcell_array.get_all_wordline_names() if x.startswith("rbl")])
|
||||||
dummy_rbl_names = set([x for x in self.bitcell_array.get_all_wordline_names() if x.startswith("dummy")])
|
dummy_rbl_names = set([x for x in self.bitcell_array.get_all_wordline_names() if x.startswith("dummy")])
|
||||||
rbl_wl_names = set([x for port in self.all_ports for x in self.bitcell_array.get_rbl_wordline_names(port)])
|
rbl_wl_names = set([x for rbl_port_names in self.wordline_names for x in rbl_port_names if x.startswith("rbl")])
|
||||||
self.gnd_wl_names = list((array_rbl_names - rbl_wl_names) | dummy_rbl_names)
|
self.gnd_wl_names = list((array_rbl_names - rbl_wl_names) | dummy_rbl_names)
|
||||||
|
|
||||||
self.all_array_wordline_inputs = [x + "i" if x not in self.gnd_wl_names else "gnd" for x in self.bitcell_array.get_wordline_names()]
|
self.all_array_wordline_inputs = [x + "i" if x not in self.gnd_wl_names else "gnd" for x in self.bitcell_array.get_all_wordline_names()]
|
||||||
|
|
||||||
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()
|
||||||
# Arrays are always:
|
# Arrays are always:
|
||||||
# word lines (bottom to top)
|
|
||||||
# bit lines (left to right)
|
# bit lines (left to right)
|
||||||
|
# word lines (bottom to top)
|
||||||
# vdd
|
# vdd
|
||||||
# gnd
|
# gnd
|
||||||
|
self.add_pin_list([x for x in self.all_array_bitline_names if not x.startswith("dummy")], "INOUT")
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
self.add_pin_list(self.wordline_names[port], "INPUT")
|
self.add_pin_list(self.wordline_names[port], "INPUT")
|
||||||
for port in self.all_ports:
|
|
||||||
self.add_pin_list(self.bitline_names[port], "INOUT")
|
|
||||||
self.add_pin("vdd", "POWER")
|
self.add_pin("vdd", "POWER")
|
||||||
self.add_pin("gnd", "GROUND")
|
self.add_pin("gnd", "GROUND")
|
||||||
|
|
||||||
|
|
@ -135,7 +128,7 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
self.bitcell_array_inst = self.add_inst(name="array",
|
self.bitcell_array_inst = self.add_inst(name="array",
|
||||||
mod=self.bitcell_array)
|
mod=self.bitcell_array)
|
||||||
|
|
||||||
self.connect_inst(self.all_array_wordline_inputs + self.bitline_names + ["vdd", "gnd"])
|
self.connect_inst(self.all_array_bitline_names + self.all_array_wordline_inputs + ["vdd", "gnd"])
|
||||||
|
|
||||||
def place(self):
|
def place(self):
|
||||||
""" Place the bitcelll array to the right of the wl driver. """
|
""" Place the bitcelll array to the right of the wl driver. """
|
||||||
|
|
@ -177,9 +170,9 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
|
|
||||||
def add_layout_pins(self):
|
def add_layout_pins(self):
|
||||||
|
|
||||||
for (x, y) in zip(self.bitline_names, self.bitcell_array.get_inouts()):
|
for x in self.get_inouts():
|
||||||
self.copy_layout_pin(self.bitcell_array_inst, y, x)
|
self.copy_layout_pin(self.bitcell_array_inst, x)
|
||||||
|
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
for (x, y) in zip(self.wordline_names[port], self.wl_array.get_inputs()):
|
for (x, y) in zip(self.wordline_names[port], self.wl_array.get_inputs()):
|
||||||
self.copy_layout_pin(self.wl_insts[port], y, x)
|
self.copy_layout_pin(self.wl_insts[port], y, x)
|
||||||
|
|
@ -196,15 +189,8 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
def route(self):
|
def route(self):
|
||||||
|
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
if port == 0:
|
for (driver_name, net_name) in zip(self.wl_insts[port].mod.get_outputs(), self.driver_wordline_outputs[port]):
|
||||||
array_names = [x for x in self.bitcell_array.get_wordline_names(port) if not x.startswith("dummy")]
|
array_name = net_name[:-1]
|
||||||
if len(self.all_ports) > 1:
|
|
||||||
# Drop off the RBL for port 1
|
|
||||||
array_names = array_names[:-1]
|
|
||||||
else:
|
|
||||||
array_names = [x for x in self.bitcell_array.get_wordline_names(port) if not x.startswith("dummy")][1:]
|
|
||||||
|
|
||||||
for (driver_name, array_name) in zip(self.wl_array.get_outputs(), array_names):
|
|
||||||
out_pin = self.wl_insts[port].get_pin(driver_name)
|
out_pin = self.wl_insts[port].get_pin(driver_name)
|
||||||
in_pin = self.bitcell_array_inst.get_pin(array_name)
|
in_pin = self.bitcell_array_inst.get_pin(array_name)
|
||||||
if port == 0:
|
if port == 0:
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
self.rbl_bitline_names.append(bitline_names)
|
self.rbl_bitline_names.append(bitline_names)
|
||||||
# Make a flat list too
|
# Make a flat list too
|
||||||
self.all_rbl_bitline_names = [x for sl in self.rbl_bitline_names for x in sl]
|
self.all_rbl_bitline_names = [x for sl in self.rbl_bitline_names for x in sl]
|
||||||
|
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
bitline_names = self.bitcell_array.get_bitline_names(port)
|
bitline_names = self.bitcell_array.get_bitline_names(port)
|
||||||
self.bitline_names.append(bitline_names)
|
self.bitline_names.append(bitline_names)
|
||||||
|
|
@ -257,7 +257,7 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
self.add_pin_list(self.dummy_row_wordline_names[0], "INPUT")
|
self.add_pin_list(self.dummy_row_wordline_names[0], "INPUT")
|
||||||
for port in range(self.left_rbl):
|
for port in range(self.left_rbl):
|
||||||
self.add_pin_list(self.rbl_wordline_names[port], "INPUT")
|
self.add_pin_list(self.rbl_wordline_names[port], "INPUT")
|
||||||
self.add_pin_list(self.all_wordline_names)
|
self.add_pin_list(self.all_wordline_names, "INPUT")
|
||||||
for port in range(self.left_rbl, self.left_rbl + self.right_rbl):
|
for port in range(self.left_rbl, self.left_rbl + self.right_rbl):
|
||||||
self.add_pin_list(self.rbl_wordline_names[port], "INPUT")
|
self.add_pin_list(self.rbl_wordline_names[port], "INPUT")
|
||||||
self.add_pin_list(self.dummy_row_wordline_names[1], "INPUT")
|
self.add_pin_list(self.dummy_row_wordline_names[1], "INPUT")
|
||||||
|
|
@ -481,10 +481,11 @@ class replica_bitcell_array(bitcell_base_array.bitcell_base_array):
|
||||||
""" Return ALL the bitline names (including dummy and rbl) """
|
""" Return ALL the bitline names (including dummy and rbl) """
|
||||||
temp = []
|
temp = []
|
||||||
temp.extend(self.get_dummy_bitline_names(0))
|
temp.extend(self.get_dummy_bitline_names(0))
|
||||||
temp.extend(self.get_rbl_bitline_names(0))
|
if self.add_left_rbl > 0:
|
||||||
|
temp.extend(self.get_rbl_bitline_names(0))
|
||||||
temp.extend(self.get_bitline_names())
|
temp.extend(self.get_bitline_names())
|
||||||
if len(self.all_ports) > 1:
|
if self.add_right_rbl > 0:
|
||||||
temp.extend(self.get_rbl_bitline_names(1))
|
temp.extend(self.get_rbl_bitline_names(self.add_left_rbl))
|
||||||
temp.extend(self.get_dummy_bitline_names(1))
|
temp.extend(self.get_dummy_bitline_names(1))
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ from sram_factory import factory
|
||||||
import debug
|
import debug
|
||||||
|
|
||||||
|
|
||||||
@unittest.skip("SKIPPING 05_local_bitcell_array_test")
|
# @unittest.skip("SKIPPING 05_local_bitcell_array_test")
|
||||||
class local_bitcell_array_1rw_1r_test(openram_test):
|
class local_bitcell_array_1rw_1r_test(openram_test):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
|
|
@ -32,9 +32,16 @@ class local_bitcell_array_1rw_1r_test(openram_test):
|
||||||
self.local_check(a)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
|
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
|
||||||
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], add_rbl=[0, 1])
|
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], add_rbl=[1, 0])
|
||||||
self.local_check(a)
|
self.local_check(a)
|
||||||
|
|
||||||
|
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
|
||||||
|
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], add_rbl=[0, 1])
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
debug.info(2, "Testing 4x4 local bitcell array for cell_1rw_1r with replica column")
|
||||||
|
a = factory.create(module_type="local_bitcell_array", cols=4, rows=4, rbl=[1, 1], add_rbl=[1, 1])
|
||||||
|
self.local_check(a)
|
||||||
globals.end_openram()
|
globals.end_openram()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue