Fix func test with row/col of 0. PEP8 cleanup. Smaller global test case.

This commit is contained in:
mrg 2020-09-29 11:35:58 -07:00
parent 4b5bbe755f
commit 0c280e062a
4 changed files with 59 additions and 43 deletions

View File

@ -121,4 +121,15 @@ class timing_graph():
def __str__(self): def __str__(self):
""" override print function output """ """ override print function output """
return "Nodes: {}\nEdges:{} ".format(list(self.graph), self.graph) str = ""
for n in self.graph:
str += n + "\n"
for d in self.graph[n]:
str += "\t\t-> " + d + "\n"
return str
def __repr__(self):
""" override print function output """
return str(self)

View File

@ -891,7 +891,6 @@ class delay(simulation):
target_period = 0.5 * (ub_period + lb_period) target_period = 0.5 * (ub_period + lb_period)
# key=input("press return to continue") # key=input("press return to continue")
def try_period(self, feasible_delays): def try_period(self, feasible_delays):
""" """
This tries to simulate a period and checks if the result This tries to simulate a period and checks if the result
@ -914,19 +913,19 @@ class delay(simulation):
if self.sram.col_addr_size>0 and "slew" in dname: if self.sram.col_addr_size>0 and "slew" in dname:
continue continue
if not relative_compare(results[port][dname],feasible_delays[port][dname],error_tolerance=0.05): if not relative_compare(results[port][dname], feasible_delays[port][dname], error_tolerance=0.05):
debug.info(2,"Delay too big {0} vs {1}".format(results[port][dname],feasible_delays[port][dname])) debug.info(2, "Delay too big {0} vs {1}".format(results[port][dname], feasible_delays[port][dname]))
return False return False
# key=raw_input("press return to continue") # key=raw_input("press return to continue")
delay_str = ', '.join("{0}={1}ns".format(mname, results[port][mname]) for mname in self.delay_meas_names) delay_str = ', '.join("{0}={1}ns".format(mname, results[port][mname]) for mname in self.delay_meas_names)
debug.info(2,"Successful period {0}, Port {2}, {1}".format(self.period, debug.info(2, "Successful period {0}, Port {2}, {1}".format(self.period,
delay_str, delay_str,
port)) port))
return True return True
def set_probe(self,probe_address, probe_data): def set_probe(self, probe_address, probe_data):
""" """
Probe address and data can be set separately to utilize other Probe address and data can be set separately to utilize other
functions in this characterizer besides analyze. functions in this characterizer besides analyze.
@ -942,16 +941,16 @@ class delay(simulation):
"""Calculates bitline column number of data bit under test using bit position and mux size""" """Calculates bitline column number of data bit under test using bit position and mux size"""
if self.sram.col_addr_size>0: if self.sram.col_addr_size>0:
col_address = int(probe_address[0:self.sram.col_addr_size],2) col_address = int(probe_address[0:self.sram.col_addr_size], 2)
else: else:
col_address = 0 col_address = 0
bl_column = int(self.sram.words_per_row*probe_data + col_address) bl_column = int(self.sram.words_per_row * probe_data + col_address)
return bl_column return bl_column
def get_address_row_number(self, probe_address): def get_address_row_number(self, probe_address):
"""Calculates wordline row number of data bit under test using address and column mux size""" """Calculates wordline row number of data bit under test using address and column mux size"""
return int(probe_address[self.sram.col_addr_size:],2) return int(probe_address[self.sram.col_addr_size:], 2)
def prepare_netlist(self): def prepare_netlist(self):
""" Prepare a trimmed netlist and regular netlist. """ """ Prepare a trimmed netlist and regular netlist. """
@ -965,7 +964,7 @@ class delay(simulation):
self.num_cols, self.num_cols,
self.word_size, self.word_size,
self.num_spare_rows) self.num_spare_rows)
self.trimsp.trim(self.probe_address,self.probe_data) self.trimsp.trim(self.probe_address, self.probe_data)
else: else:
# The non-reduced netlist file when it is disabled # The non-reduced netlist file when it is disabled
self.trim_sp_file = "{}sram.sp".format(OPTS.openram_temp) self.trim_sp_file = "{}sram.sp".format(OPTS.openram_temp)
@ -1000,9 +999,9 @@ class delay(simulation):
feasible_delays = self.find_feasible_period() feasible_delays = self.find_feasible_period()
# 2) Finds the minimum period without degrading the delays by X% # 2) Finds the minimum period without degrading the delays by X%
self.set_load_slew(max(loads),max(slews)) self.set_load_slew(max(loads), max(slews))
min_period = self.find_min_period(feasible_delays) min_period = self.find_min_period(feasible_delays)
debug.check(type(min_period)==float,"Couldn't find minimum period.") debug.check(type(min_period)==float, "Couldn't find minimum period.")
debug.info(1, "Min Period Found: {0}ns".format(min_period)) debug.info(1, "Min Period Found: {0}ns".format(min_period))
char_sram_data["min_period"] = round_time(min_period) char_sram_data["min_period"] = round_time(min_period)
@ -1036,14 +1035,14 @@ class delay(simulation):
self.targ_write_ports = self.write_ports self.targ_write_ports = self.write_ports
for slew in slews: for slew in slews:
for load in loads: for load in loads:
self.set_load_slew(load,slew) self.set_load_slew(load, slew)
# Find the delay, dynamic power, and leakage power of the trimmed array. # Find the delay, dynamic power, and leakage power of the trimmed array.
(success, delay_results) = self.run_delay_simulation() (success, delay_results) = self.run_delay_simulation()
debug.check(success,"Couldn't run a simulation. slew={0} load={1}\n".format(self.slew,self.load)) debug.check(success, "Couldn't run a simulation. slew={0} load={1}\n".format(self.slew, self.load))
debug.info(1, "Simulation Passed: Port {0} slew={1} load={2}".format("All", self.slew,self.load)) debug.info(1, "Simulation Passed: Port {0} slew={1} load={2}".format("All", self.slew, self.load))
# The results has a dict for every port but dicts can be empty (e.g. ports were not targeted). # The results has a dict for every port but dicts can be empty (e.g. ports were not targeted).
for port in self.all_ports: for port in self.all_ports:
for mname,value in delay_results[port].items(): for mname, value in delay_results[port].items():
if "power" in mname: if "power" in mname:
# Subtract partial array leakage and add full array leakage for the power measures # Subtract partial array leakage and add full array leakage for the power measures
measure_data[port][mname].append(value + leakage_offset) measure_data[port][mname].append(value + leakage_offset)
@ -1064,8 +1063,8 @@ class delay(simulation):
elif c=="1": elif c=="1":
inverse_address += "0" inverse_address += "0"
else: else:
debug.error("Non-binary address string",1) debug.error("Non-binary address string", 1)
return inverse_address+column_addr return inverse_address + column_addr
def gen_test_cycles_one_port(self, read_port, write_port): def gen_test_cycles_one_port(self, read_port, write_port):
"""Sets a list of key time-points [ns] of the waveform (each rising edge) """Sets a list of key time-points [ns] of the waveform (each rising edge)
@ -1075,10 +1074,10 @@ class delay(simulation):
inverse_address = self.calculate_inverse_address() inverse_address = self.calculate_inverse_address()
# For now, ignore data patterns and write ones or zeros # For now, ignore data patterns and write ones or zeros
data_ones = "1"*self.word_size data_ones = "1" * self.word_size
data_zeros = "0"*self.word_size data_zeros = "0" * self.word_size
wmask_ones = "1"*self.num_wmasks wmask_ones = "1" * self.num_wmasks
wmask_zeroes = "0"*self.num_wmasks wmask_zeroes = "0" * self.num_wmasks
if self.t_current == 0: if self.t_current == 0:
self.add_noop_all_ports("Idle cycle (no positive clock edge)") self.add_noop_all_ports("Idle cycle (no positive clock edge)")
@ -1094,10 +1093,10 @@ class delay(simulation):
data_zeros, data_zeros,
wmask_ones, wmask_ones,
write_port) write_port)
self.measure_cycles[write_port][sram_op.WRITE_ZERO] = len(self.cycle_times)-1 self.measure_cycles[write_port][sram_op.WRITE_ZERO] = len(self.cycle_times) - 1
self.add_noop_clock_one_port(write_port) self.add_noop_clock_one_port(write_port)
self.measure_cycles[write_port]["disabled_write0"] = len(self.cycle_times)-1 self.measure_cycles[write_port]["disabled_write0"] = len(self.cycle_times) - 1
# This also ensures we will have a H->L transition on the next read # This also ensures we will have a H->L transition on the next read
self.add_read("R data 1 address {} to set dout caps".format(inverse_address), self.add_read("R data 1 address {} to set dout caps".format(inverse_address),
@ -1107,12 +1106,11 @@ class delay(simulation):
self.add_read("R data 0 address {} to check W0 worked".format(self.probe_address), self.add_read("R data 0 address {} to check W0 worked".format(self.probe_address),
self.probe_address, self.probe_address,
read_port) read_port)
self.measure_cycles[read_port][sram_op.READ_ZERO] = len(self.cycle_times)-1 self.measure_cycles[read_port][sram_op.READ_ZERO] = len(self.cycle_times) - 1
self.add_noop_clock_one_port(read_port) self.add_noop_clock_one_port(read_port)
self.measure_cycles[read_port]["disabled_read0"] = len(self.cycle_times) - 1 self.measure_cycles[read_port]["disabled_read0"] = len(self.cycle_times) - 1
self.add_noop_all_ports("Idle cycle (if read takes >1 cycle)") self.add_noop_all_ports("Idle cycle (if read takes >1 cycle)")
self.add_write("W data 1 address {} to write value".format(self.probe_address), self.add_write("W data 1 address {} to write value".format(self.probe_address),
@ -1120,10 +1118,10 @@ class delay(simulation):
data_ones, data_ones,
wmask_ones, wmask_ones,
write_port) write_port)
self.measure_cycles[write_port][sram_op.WRITE_ONE] = len(self.cycle_times)-1 self.measure_cycles[write_port][sram_op.WRITE_ONE] = len(self.cycle_times) - 1
self.add_noop_clock_one_port(write_port) self.add_noop_clock_one_port(write_port)
self.measure_cycles[write_port]["disabled_write1"] = len(self.cycle_times)-1 self.measure_cycles[write_port]["disabled_write1"] = len(self.cycle_times) - 1
self.add_write("W data 0 address {} to clear din caps".format(inverse_address), self.add_write("W data 0 address {} to clear din caps".format(inverse_address),
inverse_address, inverse_address,
@ -1143,11 +1141,11 @@ class delay(simulation):
self.add_read("R data 1 address {} to check W1 worked".format(self.probe_address), self.add_read("R data 1 address {} to check W1 worked".format(self.probe_address),
self.probe_address, self.probe_address,
read_port) read_port)
self.measure_cycles[read_port][sram_op.READ_ONE] = len(self.cycle_times)-1 self.measure_cycles[read_port][sram_op.READ_ONE] = len(self.cycle_times) - 1
self.add_noop_all_ports("Idle cycle (if read takes >1 cycle))") self.add_noop_all_ports("Idle cycle (if read takes >1 cycle))")
def get_available_port(self,get_read_port): def get_available_port(self, get_read_port):
"""Returns the first accessible read or write port. """ """Returns the first accessible read or write port. """
if get_read_port and len(self.read_ports) > 0: if get_read_port and len(self.read_ports) > 0:
@ -1169,7 +1167,7 @@ class delay(simulation):
# Using this requires setting at least one port to target for simulation. # Using this requires setting at least one port to target for simulation.
if len(self.targ_write_ports) == 0 or len(self.targ_read_ports) == 0: if len(self.targ_write_ports) == 0 or len(self.targ_read_ports) == 0:
debug.error("Write and read port must be specified for characterization.",1) debug.error("Write and read port must be specified for characterization.", 1)
self.set_stimulus_variables() self.set_stimulus_variables()
# Get any available read/write port in case only a single write or read ports is being characterized. # Get any available read/write port in case only a single write or read ports is being characterized.

View File

@ -42,6 +42,8 @@ class functional(simulation):
self.set_stimulus_variables() self.set_stimulus_variables()
# For the debug signal names # For the debug signal names
self.wordline_row = 0
self.bitline_column = 0
self.create_signal_names() self.create_signal_names()
self.add_graph_exclusions() self.add_graph_exclusions()
self.create_graph() self.create_graph()

View File

@ -15,6 +15,7 @@ from globals import OPTS
from sram_factory import factory from sram_factory import factory
import debug import debug
class timing_sram_test(openram_test): class timing_sram_test(openram_test):
def runTest(self): def runTest(self):
@ -30,14 +31,18 @@ class timing_sram_test(openram_test):
reload(characterizer) reload(characterizer)
from characterizer import delay from characterizer import delay
from sram_config import sram_config from sram_config import sram_config
OPTS.local_array_size = 8 OPTS.local_array_size = 2
OPTS.route_supplies = False c = sram_config(word_size=4,
c = sram_config(word_size=8, num_words=16,
num_words=32,
num_banks=1) num_banks=1)
c.words_per_row=1
c.words_per_row=2
c.recompute_sizes() c.recompute_sizes()
# c = sram_config(word_size=8,
# num_words=32,
# num_banks=1)
# c.words_per_row=2
# c.recompute_sizes()
debug.info(1, "Testing timing for global hierarchical array") debug.info(1, "Testing timing for global hierarchical array")
s = factory.create(module_type="sram", sram_config=c) s = factory.create(module_type="sram", sram_config=c)