SRAM layout and functional tests with spare cols

This commit is contained in:
Aditi Sinha
2020-06-03 12:31:30 +00:00
parent c7d86b21ae
commit eb0c595dbe
12 changed files with 373 additions and 77 deletions
+40 -14
View File
@@ -26,6 +26,10 @@ class simulation():
self.addr_size = self.sram.addr_size
self.write_size = self.sram.write_size
self.num_spare_rows = self.sram.num_spare_rows
if not self.sram.num_spare_cols:
self.num_spare_cols = 0
else:
self.num_spare_cols = self.sram.num_spare_cols
self.sp_file = spfile
self.all_ports = self.sram.all_ports
@@ -38,7 +42,6 @@ class simulation():
else:
self.num_wmasks = 0
def set_corner(self,corner):
""" Set the corner values """
self.corner = corner
@@ -61,10 +64,10 @@ class simulation():
self.pins = self.gen_pin_names(port_signal_names=(self.addr_name,self.din_name,self.dout_name),
port_info=(len(self.all_ports),self.write_ports,self.read_ports),
abits=self.addr_size,
dbits=self.word_size)
dbits=self.word_size + self.num_spare_cols)
debug.check(len(self.sram.pins) == len(self.pins),
"Number of pins generated for characterization \
do match pins of SRAM\nsram.pins = {0}\npin_names = {1}".format(self.sram.pins,
do not match pins of SRAM\nsram.pins = {0}\npin_names = {1}".format(self.sram.pins,
self.pins))
#This is TODO once multiport control has been finalized.
#self.control_name = "CSB"
@@ -82,11 +85,13 @@ class simulation():
self.addr_value = {port:[] for port in self.all_ports}
self.data_value = {port:[] for port in self.write_ports}
self.wmask_value = {port:[] for port in self.write_ports}
self.spare_wen_value = {port:[] for port in self.write_ports}
# Three dimensional list to handle each addr and data bits for each port over the number of checks
self.addr_values = {port:[[] for bit in range(self.addr_size)] for port in self.all_ports}
self.data_values = {port:[[] for bit in range(self.word_size)] for port in self.write_ports}
self.data_values = {port:[[] for bit in range(self.word_size + self.num_spare_cols)] for port in self.write_ports}
self.wmask_values = {port:[[] for bit in range(self.num_wmasks)] for port in self.write_ports}
self.spare_wen_values = {port:[[] for bit in range(self.num_spare_cols)] for port in self.write_ports}
# For generating comments in SPICE stimulus
self.cycle_comments = []
@@ -113,10 +118,10 @@ class simulation():
def add_data(self, data, port):
""" Add the array of data values """
debug.check(len(data)==self.word_size, "Invalid data word size.")
debug.check(len(data)==(self.word_size + self.num_spare_cols), "Invalid data word size.")
self.data_value[port].append(data)
bit = self.word_size - 1
bit = self.word_size + self.num_spare_cols - 1
for c in data:
if c=="0":
self.data_values[port][bit].append(0)
@@ -137,10 +142,7 @@ class simulation():
if c=="0":
self.addr_values[port][bit].append(0)
elif c=="1":
if((self.num_spare_rows != 0) and (bit == (self.addr_size - 1))):
self.addr_values[port][bit].append(0)
else:
self.addr_values[port][bit].append(1)
self.addr_values[port][bit].append(1)
else:
debug.error("Non-binary address string",1)
bit -= 1
@@ -161,7 +163,21 @@ class simulation():
debug.error("Non-binary wmask string", 1)
bit -= 1
def add_spare_wen(self, spare_wen, port):
""" Add the array of spare write enable values (for spare cols) """
debug.check(len(spare_wen) == self.num_spare_cols, "Invalid spare enable size.")
self.spare_wen_value[port].append(spare_wen)
bit = self.num_spare_cols - 1
for c in spare_wen:
if c == "0":
self.spare_wen_values[port][bit].append(0)
elif c == "1":
self.spare_wen_values[port][bit].append(1)
else:
debug.error("Non-binary spare enable signal string", 1)
bit -= 1
def add_write(self, comment, address, data, wmask, port):
""" Add the control values for a write cycle. """
debug.check(port in self.write_ports,
@@ -178,6 +194,7 @@ class simulation():
self.add_data(data,port)
self.add_address(address,port)
self.add_wmask(wmask,port)
self.add_spare_wen("1" * self.num_spare_cols, port)
#Add noops to all other ports.
for unselected_port in self.all_ports:
@@ -197,6 +214,7 @@ class simulation():
self.t_current += self.period
self.add_control_one_port(port, "read")
self.add_address(address, port)
self.add_spare_wen("0" * self.num_spare_cols, port)
# If the port is also a readwrite then add
# the same value as previous cycle
@@ -204,7 +222,7 @@ class simulation():
try:
self.add_data(self.data_value[port][-1], port)
except:
self.add_data("0"*self.word_size, port)
self.add_data("0"*(self.word_size + self.num_spare_cols), port)
try:
self.add_wmask(self.wmask_value[port][-1], port)
except:
@@ -239,6 +257,7 @@ class simulation():
self.add_data(data, port)
self.add_address(address, port)
self.add_wmask(wmask, port)
self.add_spare_wen("1" * self.num_spare_cols, port)
def add_read_one_port(self, comment, address, port):
""" Add the control values for a read cycle. Does not increment the period. """
@@ -250,13 +269,14 @@ class simulation():
self.add_control_one_port(port, "read")
self.add_address(address, port)
self.add_spare_wen("0" * self.num_spare_cols, port)
# If the port is also a readwrite then add
# the same value as previous cycle
if port in self.write_ports:
try:
self.add_data(self.data_value[port][-1], port)
except:
self.add_data("0"*self.word_size, port)
self.add_data("0"*(self.word_size + self.num_spare_cols), port)
try:
self.add_wmask(self.wmask_value[port][-1], port)
except:
@@ -266,6 +286,7 @@ class simulation():
def add_noop_one_port(self, port):
""" Add the control values for a noop to a single port. Does not increment the period. """
self.add_control_one_port(port, "noop")
self.add_spare_wen("0" * self.num_spare_cols, port)
try:
self.add_address(self.addr_value[port][-1], port)
@@ -278,7 +299,7 @@ class simulation():
try:
self.add_data(self.data_value[port][-1], port)
except:
self.add_data("0"*self.word_size, port)
self.add_data("0"*(self.word_size + self.num_spare_cols), port)
try:
self.add_wmask(self.wmask_value[port][-1], port)
except:
@@ -374,6 +395,11 @@ class simulation():
for port in write_index:
for bit in range(self.num_wmasks):
pin_names.append("WMASK{0}_{1}".format(port,bit))
if self.num_spare_cols:
for port in write_index:
for bit in range(self.num_spare_cols):
pin_names.append("SPARE_WEN{0}_{1}".format(port,bit))
for read_output in read_index:
for i in range(dbits):