mirror of https://github.com/VLSIDA/OpenRAM.git
Spare columns in full sram layout
This commit is contained in:
parent
a5c211bd90
commit
8bd1052fc2
|
|
@ -20,7 +20,7 @@ class control_logic(design.design):
|
|||
Dynamically generated Control logic for the total SRAM circuit.
|
||||
"""
|
||||
|
||||
def __init__(self, num_rows, words_per_row, word_size, sram=None, port_type="rw", name=""):
|
||||
def __init__(self, num_rows, words_per_row, word_size, spare_columns=None, sram=None, port_type="rw", name=""):
|
||||
""" Constructor """
|
||||
name = "control_logic_" + port_type
|
||||
design.design.__init__(self, name)
|
||||
|
|
@ -35,7 +35,12 @@ class control_logic(design.design):
|
|||
self.word_size = word_size
|
||||
self.port_type = port_type
|
||||
|
||||
self.num_cols = word_size * words_per_row
|
||||
if not spare_columns:
|
||||
self.num_spare_cols = spare_columns
|
||||
else:
|
||||
self.num_spare_cols = 0
|
||||
|
||||
self.num_cols = word_size * words_per_row + self.num_spare_cols
|
||||
self.num_words = num_rows * words_per_row
|
||||
|
||||
self.enable_delay_chain_resizing = False
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class sram_1bank(sram_base):
|
|||
self.wmask_bus_size = self.m2_nonpref_pitch * (max(self.num_wmasks + 1, self.col_addr_size + 1)) + self.wmask_bus_gap
|
||||
else:
|
||||
self.data_bus_gap = self.m3_nonpref_pitch * 2
|
||||
self.data_bus_size = self.m3_nonpref_pitch * (max(self.word_size + 1, self.col_addr_size + 1)) + self.data_bus_gap
|
||||
self.data_bus_size = self.m3_nonpref_pitch * (max(self.word_size + self.num_spare_cols + 1, self.col_addr_size + 1)) + self.data_bus_gap
|
||||
|
||||
self.col_addr_bus_gap = self.m2_nonpref_pitch * 2
|
||||
self.col_addr_bus_size = self.m2_nonpref_pitch * (self.col_addr_size) + self.col_addr_bus_gap
|
||||
|
|
@ -191,7 +191,7 @@ class sram_1bank(sram_base):
|
|||
signal + "{}".format(port))
|
||||
|
||||
if port in self.read_ports:
|
||||
for bit in range(self.word_size):
|
||||
for bit in range(self.word_size + self.num_spare_cols):
|
||||
self.copy_layout_pin(self.bank_inst,
|
||||
"dout{0}_{1}".format(port, bit),
|
||||
"dout{0}[{1}]".format(port, bit))
|
||||
|
|
@ -208,7 +208,7 @@ class sram_1bank(sram_base):
|
|||
"addr{0}[{1}]".format(port, bit + self.col_addr_size))
|
||||
|
||||
if port in self.write_ports:
|
||||
for bit in range(self.word_size):
|
||||
for bit in range(self.word_size + self.num_spare_cols):
|
||||
self.copy_layout_pin(self.data_dff_insts[port],
|
||||
"din_{}".format(bit),
|
||||
"din{0}[{1}]".format(port, bit))
|
||||
|
|
@ -218,6 +218,10 @@ class sram_1bank(sram_base):
|
|||
self.copy_layout_pin(self.wmask_dff_insts[port],
|
||||
"din_{}".format(bit),
|
||||
"wmask{0}[{1}]".format(port, bit))
|
||||
for bit in range(self.num_spare_cols):
|
||||
self.copy_layout_pin(self.bank_inst,
|
||||
"spare_wen{0}_{1}".format(port, bit),
|
||||
"spare_wen{0}[{1}]".format(port, bit))
|
||||
|
||||
def route_layout(self):
|
||||
""" Route a single bank SRAM """
|
||||
|
|
@ -380,7 +384,7 @@ class sram_1bank(sram_base):
|
|||
else:
|
||||
offset = self.data_dff_insts[port].ul() + vector(0, self.data_bus_gap)
|
||||
|
||||
dff_names = ["dout_{}".format(x) for x in range(self.word_size)]
|
||||
dff_names = ["dout_{}".format(x) for x in range(self.word_size + self.num_spare_cols)]
|
||||
dff_pins = [self.data_dff_insts[port].get_pin(x) for x in dff_names]
|
||||
if self.write_size:
|
||||
for x in dff_names:
|
||||
|
|
@ -393,7 +397,7 @@ class sram_1bank(sram_base):
|
|||
to_layer="m4",
|
||||
offset=pin_offset)
|
||||
|
||||
bank_names = ["din{0}_{1}".format(port, x) for x in range(self.word_size)]
|
||||
bank_names = ["din{0}_{1}".format(port, x) for x in range(self.word_size + self.num_spare_cols)]
|
||||
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
|
||||
if self.write_size:
|
||||
for x in bank_names:
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ class sram_base(design, verilog, lef):
|
|||
else:
|
||||
self.num_wmasks = 0
|
||||
|
||||
if not self.num_spare_cols:
|
||||
self.num_spare_cols = 0
|
||||
|
||||
# For logical effort delay calculations.
|
||||
self.all_mods_except_control_done = False
|
||||
|
||||
|
|
@ -44,7 +47,7 @@ class sram_base(design, verilog, lef):
|
|||
""" Add pins for entire SRAM. """
|
||||
|
||||
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")
|
||||
|
||||
for port in self.all_ports:
|
||||
|
|
@ -75,8 +78,10 @@ class sram_base(design, verilog, lef):
|
|||
for port in self.write_ports:
|
||||
for bit in range(self.num_wmasks):
|
||||
self.add_pin("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.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("vdd", "POWER")
|
||||
|
|
@ -274,7 +279,7 @@ class sram_base(design, verilog, lef):
|
|||
else:
|
||||
self.col_addr_dff = None
|
||||
|
||||
self.data_dff = factory.create("dff_array", module_name="data_dff", rows=1, columns=self.word_size)
|
||||
self.data_dff = factory.create("dff_array", module_name="data_dff", rows=1, columns=self.word_size + self.num_spare_cols)
|
||||
self.add_mod(self.data_dff)
|
||||
|
||||
if self.write_size:
|
||||
|
|
@ -303,6 +308,7 @@ class sram_base(design, verilog, lef):
|
|||
self.control_logic_rw = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
spare_columns=self.num_spare_cols,
|
||||
sram=self,
|
||||
port_type="rw")
|
||||
self.add_mod(self.control_logic_rw)
|
||||
|
|
@ -310,6 +316,7 @@ class sram_base(design, verilog, lef):
|
|||
self.control_logic_w = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
spare_columns=self.num_spare_cols,
|
||||
sram=self,
|
||||
port_type="w")
|
||||
self.add_mod(self.control_logic_w)
|
||||
|
|
@ -317,6 +324,7 @@ class sram_base(design, verilog, lef):
|
|||
self.control_logic_r = self.mod_control_logic(num_rows=self.num_rows,
|
||||
words_per_row=self.words_per_row,
|
||||
word_size=self.word_size,
|
||||
spare_columns=self.num_spare_cols,
|
||||
sram=self,
|
||||
port_type="r")
|
||||
self.add_mod(self.control_logic_r)
|
||||
|
|
@ -328,12 +336,12 @@ class sram_base(design, verilog, lef):
|
|||
|
||||
temp = []
|
||||
for 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))
|
||||
for port in self.all_ports:
|
||||
temp.append("rbl_bl{0}".format(port))
|
||||
for 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("bank_din{0}[{1}]".format(port, bit))
|
||||
for port in self.all_ports:
|
||||
for bit in range(self.bank_addr_size):
|
||||
|
|
@ -349,6 +357,8 @@ class sram_base(design, verilog, lef):
|
|||
temp.append("w_en{0}".format(port))
|
||||
for bit in range(self.num_wmasks):
|
||||
temp.append("bank_wmask{}[{}]".format(port, bit))
|
||||
for bit in range(self.num_spare_cols):
|
||||
temp.append("spare_wen{0}[{1}]".format(port, bit))
|
||||
for port in self.all_ports:
|
||||
temp.append("wl_en{0}".format(port))
|
||||
temp.extend(["vdd", "gnd"])
|
||||
|
|
@ -436,7 +446,7 @@ class sram_base(design, verilog, lef):
|
|||
# inputs, outputs/output/bar
|
||||
inputs = []
|
||||
outputs = []
|
||||
for bit in range(self.word_size):
|
||||
for bit in range(self.word_size + self.num_spare_cols):
|
||||
inputs.append("din{}[{}]".format(port, bit))
|
||||
outputs.append("bank_din{}[{}]".format(port, bit))
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
#!/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 sram_1bank_2mux_1rw_1r_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
|
||||
|
||||
OPTS.bitcell = "bitcell_1rw_1r"
|
||||
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
|
||||
OPTS.dummy_bitcell="dummy_bitcell_1rw_1r"
|
||||
OPTS.num_rw_ports = 1
|
||||
OPTS.num_r_ports = 1
|
||||
OPTS.num_w_ports = 0
|
||||
|
||||
c = sram_config(word_size=4,
|
||||
num_words=32,
|
||||
num_spare_cols=3,
|
||||
num_banks=1)
|
||||
|
||||
c.words_per_row=2
|
||||
c.recompute_sizes()
|
||||
debug.info(1, "Layout test for {}rw,{}r,{}w sram "
|
||||
"with {} bit words, {} words, {} words per "
|
||||
"row, {} banks".format(OPTS.num_rw_ports,
|
||||
OPTS.num_r_ports,
|
||||
OPTS.num_w_ports,
|
||||
c.word_size,
|
||||
c.num_words,
|
||||
c.words_per_row,
|
||||
c.num_banks))
|
||||
a = factory.create(module_type="sram", sram_config=c)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
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())
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#!/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
|
||||
|
||||
#@unittest.skip("SKIPPING 20_psram_1bank_2mux_1w_1r_test, odd supply routing error")
|
||||
class psram_1bank_2mux_1w_1r_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
|
||||
|
||||
OPTS.bitcell = "bitcell_1w_1r"
|
||||
OPTS.replica_bitcell="replica_bitcell_1w_1r"
|
||||
OPTS.dummy_bitcell="dummy_bitcell_1w_1r"
|
||||
OPTS.num_rw_ports = 0
|
||||
OPTS.num_w_ports = 1
|
||||
OPTS.num_r_ports = 1
|
||||
|
||||
c = sram_config(word_size=4,
|
||||
num_words=32,
|
||||
num_spare_cols=3,
|
||||
num_banks=1)
|
||||
c.num_words=32
|
||||
c.words_per_row=2
|
||||
c.recompute_sizes()
|
||||
debug.info(1, "Layout test for {}rw,{}r,{}w sram "
|
||||
"with {} bit words, {} words, {} words per "
|
||||
"row, {} banks".format(OPTS.num_rw_ports,
|
||||
OPTS.num_r_ports,
|
||||
OPTS.num_w_ports,
|
||||
c.word_size,
|
||||
c.num_words,
|
||||
c.words_per_row,
|
||||
c.num_banks))
|
||||
a = factory.create(module_type="sram", sram_config=c)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
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())
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#!/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 sram_1bank_nomux_1rw_1r_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
|
||||
|
||||
OPTS.bitcell = "bitcell_1rw_1r"
|
||||
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
|
||||
OPTS.dummy_bitcell = "dummy_bitcell_1rw_1r"
|
||||
OPTS.num_rw_ports = 1
|
||||
OPTS.num_r_ports = 1
|
||||
OPTS.num_w_ports = 0
|
||||
|
||||
c = sram_config(word_size=4,
|
||||
num_words=16,
|
||||
num_spare_cols=4,
|
||||
num_banks=1)
|
||||
|
||||
c.words_per_row=1
|
||||
c.recompute_sizes()
|
||||
debug.info(1, "Layout test for {}rw,{}r,{}w sram "
|
||||
"with {} bit words, {} words, {} words per "
|
||||
"row, {} spare columns, {} banks".format(OPTS.num_rw_ports,
|
||||
OPTS.num_r_ports,
|
||||
OPTS.num_w_ports,
|
||||
c.word_size,
|
||||
c.num_words,
|
||||
c.words_per_row,
|
||||
c.num_spare_cols,
|
||||
c.num_banks))
|
||||
a = factory.create(module_type="sram", sram_config=c)
|
||||
self.local_check(a, final_verification=True)
|
||||
|
||||
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