Spare columns in full sram layout

This commit is contained in:
Aditi Sinha 2020-05-14 10:30:29 +00:00
parent a5c211bd90
commit 8bd1052fc2
6 changed files with 208 additions and 13 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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