mirror of https://github.com/VLSIDA/OpenRAM.git
Spare columns working at bank level
This commit is contained in:
parent
49918b0716
commit
e30938fb66
|
|
@ -31,6 +31,9 @@ class bank(design.design):
|
||||||
else:
|
else:
|
||||||
self.num_wmasks = 0
|
self.num_wmasks = 0
|
||||||
|
|
||||||
|
if not self.num_spare_cols:
|
||||||
|
self.num_spare_cols = 0
|
||||||
|
|
||||||
if name == "":
|
if name == "":
|
||||||
name = "bank_{0}_{1}".format(self.word_size, self.num_words)
|
name = "bank_{0}_{1}".format(self.word_size, self.num_words)
|
||||||
design.design.__init__(self, name)
|
design.design.__init__(self, name)
|
||||||
|
|
@ -77,12 +80,12 @@ class bank(design.design):
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
""" Adding pins for Bank module"""
|
""" Adding pins for Bank module"""
|
||||||
for port in self.read_ports:
|
for port in self.read_ports:
|
||||||
for bit in range(self.word_size):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
self.add_pin("dout{0}_{1}".format(port, bit), "OUTPUT")
|
self.add_pin("dout{0}_{1}".format(port, bit), "OUTPUT")
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
self.add_pin(self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port]), "OUTPUT")
|
self.add_pin(self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port]), "OUTPUT")
|
||||||
for port in self.write_ports:
|
for port in self.write_ports:
|
||||||
for bit in range(self.word_size):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
self.add_pin("din{0}_{1}".format(port,bit), "INPUT")
|
self.add_pin("din{0}_{1}".format(port,bit), "INPUT")
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
for bit in range(self.addr_size):
|
for bit in range(self.addr_size):
|
||||||
|
|
@ -101,6 +104,8 @@ class bank(design.design):
|
||||||
self.add_pin("w_en{0}".format(port), "INPUT")
|
self.add_pin("w_en{0}".format(port), "INPUT")
|
||||||
for bit in range(self.num_wmasks):
|
for bit in range(self.num_wmasks):
|
||||||
self.add_pin("bank_wmask{0}_{1}".format(port, bit), "INPUT")
|
self.add_pin("bank_wmask{0}_{1}".format(port, bit), "INPUT")
|
||||||
|
for bit in range(self.num_spare_cols):
|
||||||
|
self.add_pin("spare_wen{0}_{1}".format(port, bit), "INPUT")
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
self.add_pin("wl_en{0}".format(port), "INPUT")
|
self.add_pin("wl_en{0}".format(port), "INPUT")
|
||||||
self.add_pin("vdd", "POWER")
|
self.add_pin("vdd", "POWER")
|
||||||
|
|
@ -359,7 +364,7 @@ class bank(design.design):
|
||||||
self.add_mod(self.port_data[port])
|
self.add_mod(self.port_data[port])
|
||||||
|
|
||||||
self.port_address = factory.create(module_type="port_address",
|
self.port_address = factory.create(module_type="port_address",
|
||||||
cols=self.num_cols,
|
cols=self.num_cols + self.num_spare_cols,
|
||||||
rows=self.num_rows)
|
rows=self.num_rows)
|
||||||
self.add_mod(self.port_address)
|
self.add_mod(self.port_address)
|
||||||
|
|
||||||
|
|
@ -367,7 +372,7 @@ 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",
|
self.bitcell_array = factory.create(module_type="replica_bitcell_array",
|
||||||
cols=self.num_cols,
|
cols=self.num_cols + self.num_spare_cols,
|
||||||
rows=self.num_rows,
|
rows=self.num_rows,
|
||||||
left_rbl=1,
|
left_rbl=1,
|
||||||
right_rbl=1 if len(self.all_ports)>1 else 0,
|
right_rbl=1 if len(self.all_ports)>1 else 0,
|
||||||
|
|
@ -385,7 +390,7 @@ class bank(design.design):
|
||||||
mod=self.bitcell_array)
|
mod=self.bitcell_array)
|
||||||
|
|
||||||
temp = []
|
temp = []
|
||||||
for col in range(self.num_cols):
|
for col in range(self.num_cols + self.num_spare_cols):
|
||||||
for bitline in self.bitline_names:
|
for bitline in self.bitline_names:
|
||||||
temp.append("{0}_{1}".format(bitline, col))
|
temp.append("{0}_{1}".format(bitline, col))
|
||||||
for rbl in range(self.num_rbl):
|
for rbl in range(self.num_rbl):
|
||||||
|
|
@ -419,14 +424,14 @@ class bank(design.design):
|
||||||
rbl_br_name=self.bitcell_array.get_rbl_br_name(self.port_rbl_map[port])
|
rbl_br_name=self.bitcell_array.get_rbl_br_name(self.port_rbl_map[port])
|
||||||
temp.append(rbl_bl_name)
|
temp.append(rbl_bl_name)
|
||||||
temp.append(rbl_br_name)
|
temp.append(rbl_br_name)
|
||||||
for col in range(self.num_cols):
|
for col in range(self.num_cols + self.num_spare_cols):
|
||||||
temp.append("{0}_{1}".format(self.bl_names[port], col))
|
temp.append("{0}_{1}".format(self.bl_names[port], col))
|
||||||
temp.append("{0}_{1}".format(self.br_names[port], col))
|
temp.append("{0}_{1}".format(self.br_names[port], col))
|
||||||
if port in self.read_ports:
|
if port in self.read_ports:
|
||||||
for bit in range(self.word_size):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
temp.append("dout{0}_{1}".format(port, bit))
|
temp.append("dout{0}_{1}".format(port, bit))
|
||||||
if port in self.write_ports:
|
if port in self.write_ports:
|
||||||
for bit in range(self.word_size):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
temp.append("din{0}_{1}".format(port, bit))
|
temp.append("din{0}_{1}".format(port, bit))
|
||||||
# Will be empty if no col addr lines
|
# Will be empty if no col addr lines
|
||||||
sel_names = ["sel{0}_{1}".format(port, x) for x in range(self.num_col_addr_lines)]
|
sel_names = ["sel{0}_{1}".format(port, x) for x in range(self.num_col_addr_lines)]
|
||||||
|
|
@ -438,6 +443,8 @@ class bank(design.design):
|
||||||
temp.append("w_en{0}".format(port))
|
temp.append("w_en{0}".format(port))
|
||||||
for bit in range(self.num_wmasks):
|
for bit in range(self.num_wmasks):
|
||||||
temp.append("bank_wmask{0}_{1}".format(port, bit))
|
temp.append("bank_wmask{0}_{1}".format(port, bit))
|
||||||
|
for bit in range(self.num_spare_cols):
|
||||||
|
temp.append("spare_wen{0}_{1}".format(port, bit))
|
||||||
temp.extend(["vdd", "gnd"])
|
temp.extend(["vdd", "gnd"])
|
||||||
|
|
||||||
self.connect_inst(temp)
|
self.connect_inst(temp)
|
||||||
|
|
@ -676,7 +683,7 @@ class bank(design.design):
|
||||||
|
|
||||||
self.connect_bitlines(inst1=inst1,
|
self.connect_bitlines(inst1=inst1,
|
||||||
inst2=inst2,
|
inst2=inst2,
|
||||||
num_bits=self.num_cols,
|
num_bits=self.num_cols + self.num_spare_cols,
|
||||||
inst1_bl_name=inst1_bl_name,
|
inst1_bl_name=inst1_bl_name,
|
||||||
inst1_br_name=inst1_br_name,
|
inst1_br_name=inst1_br_name,
|
||||||
inst2_bl_name=inst2_bl_name,
|
inst2_bl_name=inst2_bl_name,
|
||||||
|
|
@ -691,7 +698,7 @@ class bank(design.design):
|
||||||
def route_port_data_out(self, port):
|
def route_port_data_out(self, port):
|
||||||
""" Add pins for the port data out """
|
""" Add pins for the port data out """
|
||||||
|
|
||||||
for bit in range(self.word_size):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
data_pin = self.port_data_inst[port].get_pin("dout_{0}".format(bit))
|
data_pin = self.port_data_inst[port].get_pin("dout_{0}".format(bit))
|
||||||
self.add_layout_pin_rect_center(text="dout{0}_{1}".format(port, bit),
|
self.add_layout_pin_rect_center(text="dout{0}_{1}".format(port, bit),
|
||||||
layer=data_pin.layer,
|
layer=data_pin.layer,
|
||||||
|
|
@ -712,7 +719,7 @@ class bank(design.design):
|
||||||
def route_port_data_in(self, port):
|
def route_port_data_in(self, port):
|
||||||
""" Connecting port data in """
|
""" Connecting port data in """
|
||||||
|
|
||||||
for row in range(self.word_size):
|
for row in range(self.word_size + self.num_spare_cols):
|
||||||
data_name = "din_{}".format(row)
|
data_name = "din_{}".format(row)
|
||||||
din_name = "din{0}_{1}".format(port, row)
|
din_name = "din{0}_{1}".format(port, row)
|
||||||
self.copy_layout_pin(self.port_data_inst[port], data_name, din_name)
|
self.copy_layout_pin(self.port_data_inst[port], data_name, din_name)
|
||||||
|
|
@ -723,6 +730,11 @@ class bank(design.design):
|
||||||
bank_wmask_name = "bank_wmask{0}_{1}".format(port, row)
|
bank_wmask_name = "bank_wmask{0}_{1}".format(port, row)
|
||||||
self.copy_layout_pin(self.port_data_inst[port], wmask_name, bank_wmask_name)
|
self.copy_layout_pin(self.port_data_inst[port], wmask_name, bank_wmask_name)
|
||||||
|
|
||||||
|
for col in range(self.num_spare_cols):
|
||||||
|
sparecol_name = "spare_wen{}".format(col)
|
||||||
|
bank_sparecol_name = "spare_wen{0}_{1}".format(port, col)
|
||||||
|
self.copy_layout_pin(self.port_data_inst[port], sparecol_name, bank_sparecol_name)
|
||||||
|
|
||||||
def channel_route_bitlines(self, inst1, inst2, num_bits,
|
def channel_route_bitlines(self, inst1, inst2, num_bits,
|
||||||
inst1_bl_name="bl_{}", inst1_br_name="br_{}",
|
inst1_bl_name="bl_{}", inst1_br_name="br_{}",
|
||||||
inst2_bl_name="bl_{}", inst2_br_name="br_{}"):
|
inst2_bl_name="bl_{}", inst2_br_name="br_{}"):
|
||||||
|
|
|
||||||
|
|
@ -110,18 +110,12 @@ class port_data(design.design):
|
||||||
|
|
||||||
self.add_pin("rbl_bl", "INOUT")
|
self.add_pin("rbl_bl", "INOUT")
|
||||||
self.add_pin("rbl_br", "INOUT")
|
self.add_pin("rbl_br", "INOUT")
|
||||||
for bit in range(self.num_cols):
|
for bit in range(self.num_cols + self.num_spare_cols):
|
||||||
bl_name = self.get_bl_name(self.port)
|
bl_name = self.get_bl_name(self.port)
|
||||||
br_name = self.get_br_name(self.port)
|
br_name = self.get_br_name(self.port)
|
||||||
self.add_pin("{0}_{1}".format(bl_name, bit), "INOUT")
|
self.add_pin("{0}_{1}".format(bl_name, bit), "INOUT")
|
||||||
self.add_pin("{0}_{1}".format(br_name, bit), "INOUT")
|
self.add_pin("{0}_{1}".format(br_name, bit), "INOUT")
|
||||||
|
|
||||||
for bit in range(self.num_spare_cols):
|
|
||||||
bl_name = self.get_bl_name(self.port)
|
|
||||||
br_name = self.get_br_name(self.port)
|
|
||||||
self.add_pin("spare{0}_{1}".format(bl_name, bit), "INOUT")
|
|
||||||
self.add_pin("spare{0}_{1}".format(br_name, bit), "INOUT")
|
|
||||||
|
|
||||||
if self.port in self.read_ports:
|
if self.port in self.read_ports:
|
||||||
for bit in range(self.word_size + self.num_spare_cols):
|
for bit in range(self.word_size + self.num_spare_cols):
|
||||||
self.add_pin("dout_{}".format(bit), "OUTPUT")
|
self.add_pin("dout_{}".format(bit), "OUTPUT")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
import unittest
|
||||||
|
from testutils import *
|
||||||
|
import sys,os
|
||||||
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
|
import globals
|
||||||
|
from globals import OPTS
|
||||||
|
from sram_factory import factory
|
||||||
|
import debug
|
||||||
|
|
||||||
|
class single_bank_test(openram_test):
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||||
|
globals.init_openram(config_file)
|
||||||
|
from sram_config import sram_config
|
||||||
|
|
||||||
|
c = sram_config(word_size=4,
|
||||||
|
num_words=16,
|
||||||
|
num_spare_cols=3)
|
||||||
|
|
||||||
|
c.words_per_row=1
|
||||||
|
factory.reset()
|
||||||
|
c.recompute_sizes()
|
||||||
|
debug.info(1, "No column mux")
|
||||||
|
a = factory.create("bank", sram_config=c)
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
c.num_words=32
|
||||||
|
c.words_per_row=2
|
||||||
|
factory.reset()
|
||||||
|
c.recompute_sizes()
|
||||||
|
debug.info(1, "Two way column mux")
|
||||||
|
a = factory.create("bank", sram_config=c)
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
c.num_words=64
|
||||||
|
c.words_per_row=4
|
||||||
|
factory.reset()
|
||||||
|
c.recompute_sizes()
|
||||||
|
debug.info(1, "Four way column mux")
|
||||||
|
a = factory.create("bank", sram_config=c)
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
c.word_size=2
|
||||||
|
c.num_words=128
|
||||||
|
c.words_per_row=8
|
||||||
|
factory.reset()
|
||||||
|
c.recompute_sizes()
|
||||||
|
debug.info(1, "Eight way column mux")
|
||||||
|
a = factory.create("bank", sram_config=c)
|
||||||
|
self.local_check(a)
|
||||||
|
|
||||||
|
globals.end_openram()
|
||||||
|
|
||||||
|
# run the test from the command line
|
||||||
|
if __name__ == "__main__":
|
||||||
|
(OPTS, args) = globals.parse_args()
|
||||||
|
del sys.argv[1:]
|
||||||
|
header(__file__, OPTS.tech_name)
|
||||||
|
unittest.main(testRunner=debugTestRunner())
|
||||||
Loading…
Reference in New Issue