mirror of https://github.com/VLSIDA/OpenRAM.git
Connected wmask in the spice netlist.
This commit is contained in:
parent
082decba18
commit
45cb159d7f
|
|
@ -290,6 +290,18 @@ class functional(simulation):
|
||||||
for port in self.readwrite_ports:
|
for port in self.readwrite_ports:
|
||||||
self.stim.gen_pwl("WEB{}".format(port), self.cycle_times , self.web_values[port], self.period, self.slew, 0.05)
|
self.stim.gen_pwl("WEB{}".format(port), self.cycle_times , self.web_values[port], self.period, self.slew, 0.05)
|
||||||
|
|
||||||
|
# Generate wmask bits
|
||||||
|
for port in self.write_ports:
|
||||||
|
self.sf.write("\n* Generation of wmask signals\n")
|
||||||
|
if (self.write_size != self.word_size):
|
||||||
|
num_wmask = int(self.word_size / self.write_size)
|
||||||
|
for bit in range(num_wmask):
|
||||||
|
sig_name = "WMASK{0}_{1} ".format(port, bit)
|
||||||
|
self.stim.gen_pwl(sig_name, self.cycle_times, self.data_values[port][bit], self.period,
|
||||||
|
self.slew, 0.05)
|
||||||
|
# self.stim.gen_pwl(sig_name, self.cycle_times, self.wmask_values[port][bit], self.period,
|
||||||
|
# self.slew, 0.05)
|
||||||
|
|
||||||
# Generate CLK signals
|
# Generate CLK signals
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
self.stim.gen_pulse(sig_name="{0}{1}".format(tech.spice["clk"], port),
|
self.stim.gen_pulse(sig_name="{0}{1}".format(tech.spice["clk"], port),
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ class simulation():
|
||||||
# Three dimensional list to handle each addr and data bits for wach port over the number of checks
|
# Three dimensional list to handle each addr and data bits for wach port over the number of checks
|
||||||
self.addr_values = [[[] for bit in range(self.addr_size)] for port in self.all_ports]
|
self.addr_values = [[[] for bit in range(self.addr_size)] for port in self.all_ports]
|
||||||
self.data_values = [[[] for bit in range(self.word_size)] for port in self.write_ports]
|
self.data_values = [[[] for bit in range(self.word_size)] for port in self.write_ports]
|
||||||
|
self.wmask_values = [[[] for bit in range(self.num_wmask)] for port in self.write_ports]
|
||||||
|
|
||||||
# For generating comments in SPICE stimulus
|
# For generating comments in SPICE stimulus
|
||||||
self.cycle_comments = []
|
self.cycle_comments = []
|
||||||
|
|
@ -130,6 +131,20 @@ class simulation():
|
||||||
else:
|
else:
|
||||||
debug.error("Non-binary address string",1)
|
debug.error("Non-binary address string",1)
|
||||||
bit -= 1
|
bit -= 1
|
||||||
|
|
||||||
|
def add_wmask(self, wmask, port):
|
||||||
|
""" Add the array of address values """
|
||||||
|
debug.check(len(wmask) == self.num_wmask, "Invalid wmask size.")
|
||||||
|
|
||||||
|
bit = self.addr_size - 1
|
||||||
|
for c in wmask:
|
||||||
|
if c == "0":
|
||||||
|
self.wmask_values[port][bit].append(0)
|
||||||
|
elif c == "1":
|
||||||
|
self.wmask_values[port][bit].append(1)
|
||||||
|
else:
|
||||||
|
debug.error("Non-binary address string", 1)
|
||||||
|
bit -= 1
|
||||||
|
|
||||||
def add_write(self, comment, address, data, port):
|
def add_write(self, comment, address, data, port):
|
||||||
""" Add the control values for a write cycle. """
|
""" Add the control values for a write cycle. """
|
||||||
|
|
@ -281,13 +296,14 @@ class simulation():
|
||||||
for port in range(total_ports):
|
for port in range(total_ports):
|
||||||
if (port in read_index) and (port in write_index):
|
if (port in read_index) and (port in write_index):
|
||||||
pin_names.append("WEB{0}".format(port))
|
pin_names.append("WEB{0}".format(port))
|
||||||
|
|
||||||
|
for port in range(total_ports):
|
||||||
|
pin_names.append("{0}{1}".format(tech.spice["clk"], port))
|
||||||
|
|
||||||
if (self.write_size != self.word_size):
|
if (self.write_size != self.word_size):
|
||||||
num_wmask = int(self.word_size/self.write_size)
|
num_wmask = int(self.word_size/self.write_size)
|
||||||
for bit in range(num_wmask):
|
for bit in range(num_wmask):
|
||||||
pin_names.append("WMASK{0}_{1}".format(port,bit))
|
pin_names.append("WMASK{0}_{1}".format(port,bit))
|
||||||
|
|
||||||
for port in range(total_ports):
|
|
||||||
pin_names.append("{0}{1}".format(tech.spice["clk"], port))
|
|
||||||
|
|
||||||
for read_output in read_index:
|
for read_output in read_index:
|
||||||
for i in range(dbits):
|
for i in range(dbits):
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ class bank(design.design):
|
||||||
|
|
||||||
self.sram_config = sram_config
|
self.sram_config = sram_config
|
||||||
sram_config.set_local_config(self)
|
sram_config.set_local_config(self)
|
||||||
|
if (self.word_size != self.write_size):
|
||||||
|
self.num_wmask = int(self.word_size/self.write_size)
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -98,6 +100,11 @@ class bank(design.design):
|
||||||
self.add_pin("p_en_bar{0}".format(port), "INPUT")
|
self.add_pin("p_en_bar{0}".format(port), "INPUT")
|
||||||
for port in self.write_ports:
|
for port in self.write_ports:
|
||||||
self.add_pin("w_en{0}".format(port), "INPUT")
|
self.add_pin("w_en{0}".format(port), "INPUT")
|
||||||
|
if (self.word_size != self.write_size):
|
||||||
|
for bit in range(self.num_wmask):
|
||||||
|
self.add_pin("bank_wmask{0}_{1}".format(port,bit),"INPUT")
|
||||||
|
# for bit in range(self.num_wmask):
|
||||||
|
# self.add_pin("wdriver_sel{0}_{1}".format(port, bit),"INOUT")
|
||||||
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")
|
||||||
|
|
@ -406,6 +413,11 @@ class bank(design.design):
|
||||||
temp.append("p_en_bar{0}".format(port))
|
temp.append("p_en_bar{0}".format(port))
|
||||||
if port in self.write_ports:
|
if port in self.write_ports:
|
||||||
temp.append("w_en{0}".format(port))
|
temp.append("w_en{0}".format(port))
|
||||||
|
if (self.word_size != self.write_size):
|
||||||
|
for bit in range(self.num_wmask):
|
||||||
|
temp.append("bank_wmask{0}_{1}".format(port, bit))
|
||||||
|
# for bit in range(self.num_wmask):
|
||||||
|
# temp.append("wdriver_sel_{0}_{1}".format(port, bit))
|
||||||
temp.extend(["vdd","gnd"])
|
temp.extend(["vdd","gnd"])
|
||||||
|
|
||||||
self.connect_inst(temp)
|
self.connect_inst(temp)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ class port_data(design.design):
|
||||||
|
|
||||||
sram_config.set_local_config(self)
|
sram_config.set_local_config(self)
|
||||||
self.port = port
|
self.port = port
|
||||||
self.num_wmask = int(self.word_size/self.write_size)
|
if (self.word_size != self.write_size):
|
||||||
|
self.num_wmask = int(self.word_size/self.write_size)
|
||||||
|
|
||||||
if name == "":
|
if name == "":
|
||||||
name = "port_data_{0}".format(self.port)
|
name = "port_data_{0}".format(self.port)
|
||||||
|
|
@ -96,6 +97,11 @@ class port_data(design.design):
|
||||||
self.add_pin("p_en_bar", "INPUT")
|
self.add_pin("p_en_bar", "INPUT")
|
||||||
if self.port in self.write_ports:
|
if self.port in self.write_ports:
|
||||||
self.add_pin("w_en", "INPUT")
|
self.add_pin("w_en", "INPUT")
|
||||||
|
if (self.word_size != self.write_size):
|
||||||
|
for bit in range(self.num_wmask):
|
||||||
|
self.add_pin("bank_wmask_{}".format(bit),"INPUT")
|
||||||
|
# for bit in range(self.num_wmask):
|
||||||
|
# self.add_pin("wdriver_sel_{}".format(bit), "INOUT")
|
||||||
self.add_pin("vdd","POWER")
|
self.add_pin("vdd","POWER")
|
||||||
self.add_pin("gnd","GROUND")
|
self.add_pin("gnd","GROUND")
|
||||||
|
|
||||||
|
|
@ -168,7 +174,8 @@ class port_data(design.design):
|
||||||
if self.port in self.write_ports:
|
if self.port in self.write_ports:
|
||||||
self.write_driver_array = factory.create(module_type="write_driver_array",
|
self.write_driver_array = factory.create(module_type="write_driver_array",
|
||||||
columns=self.num_cols,
|
columns=self.num_cols,
|
||||||
word_size=self.word_size)
|
word_size=self.word_size,
|
||||||
|
write_size=self.write_size)
|
||||||
self.add_mod(self.write_driver_array)
|
self.add_mod(self.write_driver_array)
|
||||||
if (self.word_size != self.write_size):
|
if (self.word_size != self.write_size):
|
||||||
self.write_mask_and_array = factory.create(module_type="write_mask_and_array",
|
self.write_mask_and_array = factory.create(module_type="write_mask_and_array",
|
||||||
|
|
@ -282,9 +289,8 @@ class port_data(design.design):
|
||||||
mod=self.write_driver_array)
|
mod=self.write_driver_array)
|
||||||
|
|
||||||
temp = []
|
temp = []
|
||||||
m
|
for bit in range(self.word_size):
|
||||||
for bit in range(self.word_size):
|
temp.append("din_{}".format(bit))
|
||||||
temp.append("din_{}".format(bit))
|
|
||||||
|
|
||||||
for bit in range(self.word_size):
|
for bit in range(self.word_size):
|
||||||
if (self.words_per_row == 1):
|
if (self.words_per_row == 1):
|
||||||
|
|
@ -293,7 +299,16 @@ class port_data(design.design):
|
||||||
else:
|
else:
|
||||||
temp.append(self.bl_names[self.port]+"_out_{0}".format(bit))
|
temp.append(self.bl_names[self.port]+"_out_{0}".format(bit))
|
||||||
temp.append(self.br_names[self.port]+"_out_{0}".format(bit))
|
temp.append(self.br_names[self.port]+"_out_{0}".format(bit))
|
||||||
temp.extend(["w_en", "vdd", "gnd"])
|
|
||||||
|
if (self.write_size != self.word_size):
|
||||||
|
i = 0
|
||||||
|
for bit in range(0,self.word_size,self.write_size):
|
||||||
|
for x in range(self.write_size):
|
||||||
|
temp.append("wdriver_sel_{}".format(i))
|
||||||
|
i+=1
|
||||||
|
else:
|
||||||
|
temp.append("w_en")
|
||||||
|
temp.extend(["vdd", "gnd"])
|
||||||
self.connect_inst(temp)
|
self.connect_inst(temp)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -304,8 +319,11 @@ class port_data(design.design):
|
||||||
|
|
||||||
temp = []
|
temp = []
|
||||||
for bit in range(self.num_wmask):
|
for bit in range(self.num_wmask):
|
||||||
temp.append("write_mask_{}".format(bit))
|
temp.append("bank_wmask_{}".format(bit))
|
||||||
temp.extend(["w_en", "vdd", "gnd"])
|
temp.extend(["w_en"])
|
||||||
|
for bit in range(self.num_wmask):
|
||||||
|
temp.append("wdriver_sel_{}".format(bit))
|
||||||
|
temp.extend(["vdd", "gnd"])
|
||||||
self.connect_inst(temp)
|
self.connect_inst(temp)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class write_driver_array(design.design):
|
||||||
Dynamically generated write driver array of all bitlines.
|
Dynamically generated write driver array of all bitlines.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, columns, word_size):
|
def __init__(self, name, columns, word_size,write_size):
|
||||||
design.design.__init__(self, name)
|
design.design.__init__(self, name)
|
||||||
debug.info(1, "Creating {0}".format(self.name))
|
debug.info(1, "Creating {0}".format(self.name))
|
||||||
self.add_comment("columns: {0}".format(columns))
|
self.add_comment("columns: {0}".format(columns))
|
||||||
|
|
@ -27,6 +27,7 @@ class write_driver_array(design.design):
|
||||||
|
|
||||||
self.columns = columns
|
self.columns = columns
|
||||||
self.word_size = word_size
|
self.word_size = word_size
|
||||||
|
self.write_size = write_size
|
||||||
self.words_per_row = int(columns / word_size)
|
self.words_per_row = int(columns / word_size)
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
|
|
@ -59,7 +60,11 @@ class write_driver_array(design.design):
|
||||||
for i in range(self.word_size):
|
for i in range(self.word_size):
|
||||||
self.add_pin("bl_{0}".format(i))
|
self.add_pin("bl_{0}".format(i))
|
||||||
self.add_pin("br_{0}".format(i))
|
self.add_pin("br_{0}".format(i))
|
||||||
self.add_pin("en")
|
if self.word_size != self.write_size:
|
||||||
|
for i in range(self.word_size):
|
||||||
|
self.add_pin("en_{}".format(i))
|
||||||
|
else:
|
||||||
|
self.add_pin("en")
|
||||||
self.add_pin("vdd")
|
self.add_pin("vdd")
|
||||||
self.add_pin("gnd")
|
self.add_pin("gnd")
|
||||||
|
|
||||||
|
|
@ -79,10 +84,16 @@ class write_driver_array(design.design):
|
||||||
self.driver_insts[index]=self.add_inst(name=name,
|
self.driver_insts[index]=self.add_inst(name=name,
|
||||||
mod=self.driver)
|
mod=self.driver)
|
||||||
|
|
||||||
self.connect_inst(["data_{0}".format(index),
|
if self.word_size != self.write_size:
|
||||||
"bl_{0}".format(index),
|
self.connect_inst(["data_{0}".format(index),
|
||||||
"br_{0}".format(index),
|
"bl_{0}".format(index),
|
||||||
"en", "vdd", "gnd"])
|
"br_{0}".format(index),
|
||||||
|
"en_{0}".format(index), "vdd", "gnd"])
|
||||||
|
else:
|
||||||
|
self.connect_inst(["data_{0}".format(index),
|
||||||
|
"bl_{0}".format(index),
|
||||||
|
"br_{0}".format(index),
|
||||||
|
"en", "vdd", "gnd"])
|
||||||
|
|
||||||
|
|
||||||
def place_write_array(self):
|
def place_write_array(self):
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,12 @@ class write_mask_and_array(design.design):
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
for bit in range(self.num_wmask):
|
for bit in range(self.num_wmask):
|
||||||
self.add_pin("wdriver_sel_{}".format(bit))
|
self.add_pin("wmask_in_{}".format(bit),"INPUT")
|
||||||
self.add_pin("en")
|
self.add_pin("en", "INPUT")
|
||||||
self.add_pin("vdd")
|
for bit in range(self.num_wmask):
|
||||||
self.add_pin("gnd")
|
self.add_pin("wmask_out_{}".format(bit),"OUTPUT")
|
||||||
|
self.add_pin("vdd","POWER")
|
||||||
|
self.add_pin("gnd","GROUND")
|
||||||
|
|
||||||
def add_modules(self):
|
def add_modules(self):
|
||||||
self.wmask = factory.create(module_type="dff_buf")
|
self.wmask = factory.create(module_type="dff_buf")
|
||||||
|
|
@ -94,9 +96,9 @@ class write_mask_and_array(design.design):
|
||||||
name = "and2_{}".format(bit)
|
name = "and2_{}".format(bit)
|
||||||
self.and2_insts[bit] = self.add_inst(name=name,
|
self.and2_insts[bit] = self.add_inst(name=name,
|
||||||
mod=self.and2)
|
mod=self.and2)
|
||||||
self.connect_inst(["bank_wmask_{}".format(bit),
|
self.connect_inst(["wmask_in_{}".format(bit),
|
||||||
"en",
|
"en",
|
||||||
"wdriver_sel_{}".format(bit),
|
"wmask_out_{}".format(bit),
|
||||||
"vdd", "gnd"])
|
"vdd", "gnd"])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -357,6 +357,11 @@ class sram_base(design, verilog, lef):
|
||||||
temp.append("p_en_bar{0}".format(port))
|
temp.append("p_en_bar{0}".format(port))
|
||||||
for port in self.write_ports:
|
for port in self.write_ports:
|
||||||
temp.append("w_en{0}".format(port))
|
temp.append("w_en{0}".format(port))
|
||||||
|
if (self.word_size != self.write_size):
|
||||||
|
for bit in range(self.num_masks):
|
||||||
|
temp.append("bank_wmask{}[{}]".format(port, bit))
|
||||||
|
# for bit in range(self.num_masks):
|
||||||
|
# temp.append("wdriver_sel{}[{}]".format(port, bit))
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
temp.append("wl_en{0}".format(port))
|
temp.append("wl_en{0}".format(port))
|
||||||
temp.extend(["vdd", "gnd"])
|
temp.extend(["vdd", "gnd"])
|
||||||
|
|
@ -499,8 +504,6 @@ class sram_base(design, verilog, lef):
|
||||||
if port in self.readwrite_ports:
|
if port in self.readwrite_ports:
|
||||||
temp.append("web{}".format(port))
|
temp.append("web{}".format(port))
|
||||||
temp.append("clk{}".format(port))
|
temp.append("clk{}".format(port))
|
||||||
# if port in self.write_ports:
|
|
||||||
# temp.append("wmask{}".format(port))
|
|
||||||
|
|
||||||
# for port in self.all_ports:
|
# for port in self.all_ports:
|
||||||
# self.add_pin("csb{}".format(port), "INPUT")
|
# self.add_pin("csb{}".format(port), "INPUT")
|
||||||
|
|
@ -508,11 +511,6 @@ class sram_base(design, verilog, lef):
|
||||||
# self.add_pin("web{}".format(port), "INPUT")
|
# self.add_pin("web{}".format(port), "INPUT")
|
||||||
# for port in self.all_ports:
|
# for port in self.all_ports:
|
||||||
# self.add_pin("clk{}".format(port), "INPUT")
|
# self.add_pin("clk{}".format(port), "INPUT")
|
||||||
# # add the optional write mask pins
|
|
||||||
# if self.word_size != self.write_size:
|
|
||||||
# for port in self.write_ports:
|
|
||||||
# print("write_ports", port)
|
|
||||||
# self.add_pin("wmask{0}".format(port), "INPUT")
|
|
||||||
|
|
||||||
# Outputs
|
# Outputs
|
||||||
if port in self.read_ports:
|
if port in self.read_ports:
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ from globals import OPTS
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
import debug
|
import debug
|
||||||
|
|
||||||
@unittest.skip("SKIPPING sram_wmask_func_test")
|
#@unittest.skip("SKIPPING sram_wmask_func_test")
|
||||||
class sram_wmask_func_test(openram_test):
|
class sram_wmask_func_test(openram_test):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
|
|
@ -34,6 +34,8 @@ class sram_wmask_func_test(openram_test):
|
||||||
num_words=16,
|
num_words=16,
|
||||||
write_size=4,
|
write_size=4,
|
||||||
num_banks=1)
|
num_banks=1)
|
||||||
|
c.words_per_row=1
|
||||||
|
c.recompute_sizes_once()
|
||||||
debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} bit writes, {} banks".format(c.word_size,
|
debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} bit writes, {} banks".format(c.word_size,
|
||||||
c.num_words,
|
c.num_words,
|
||||||
c.words_per_row,
|
c.words_per_row,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue