mirror of https://github.com/VLSIDA/OpenRAM.git
Fix func test with row/col of 0. PEP8 cleanup. Smaller global test case.
This commit is contained in:
parent
4b5bbe755f
commit
0c280e062a
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue