Commit f2d02647 authored by Martin Jeřábek's avatar Martin Jeřábek

allow for test randomization

parent eb13decc
......@@ -315,6 +315,8 @@ entity tb_feature is
-- Timeout in simulation time. 0 means no limit
timeout : string := "0 ms";
seed : natural := 0;
hw_reset_on_new_test : boolean := true;
test_name : string
......@@ -360,7 +362,7 @@ architecture tb of tb_feature is
signal bl_force : boolean := false;
-- test internal signals
signal iteration_done : boolean;
signal iteration_done : boolean := false;
signal mem_bus : mem_bus_arr_t := (OTHERS => mem_bus_init);
......@@ -409,10 +411,14 @@ begin
variable o : feature_outputs_t;
begin
test_runner_setup(runner, runner_cfg);
--Set the process to run and wait until it comes out of reset
iteration_done <= false;
run <= true;
error_ctr <= 0;
apply_rand_seed(seed, 0, rand_ctr);
report "Restarting mem_bus(1)";
restart_mem_bus(mem_bus(1));
report "Restarting mem_bus(1)";
......
......@@ -73,6 +73,9 @@ use work.CAN_FD_register_map.all;
use work.CAN_FD_frame_format.all;
entity sanity_test is
generic (
seed : natural := 0
);
port (
-- Input trigger, test starts running when true
......@@ -503,15 +506,13 @@ begin
-- Clock generation
----------------------------------------------------------------------------
clock_generic : for i in 1 to NODE_COUNT generate
clock_gen_1 : process
constant period : natural := f100_Mhz;
constant duty : natural := 50;
variable epsilon : natural;
clock_gen_1:process
begin
epsilon := epsilon_v(i);
generate_clock(period, duty, epsilon, mem_aux_clk(i));
timestamp_v(i) <= std_logic_vector(unsigned(timestamp_v(i)) + 1);
wait for 0 ns;
report "Epsilon:" & natural'image(epsilon_v(i));
clock_gen_proc(f100_mhz, 50, epsilon_v(i), mem_aux_clk(i));
end process;
timestamp_gen_proc(mem_aux_clk(i), timestamp_v(i));
end generate clock_generic;
......@@ -550,6 +551,7 @@ begin
-- 500 ps equals approximately 10 cm of conductor! This is coarse estimate,
-- however purpose of this simulation is not to examine exact propagation
-- delays via different physical channels! This simple estimate is enough.
-- TODO: may be optimized by eschewing bus_clk and delaying the signals directly
----------------------------------------------------------------------------
bus_clk_proc : process
begin
......@@ -617,8 +619,9 @@ begin
variable gaus_par : rand_distribution_par_type;
variable exp_par : rand_distribution_par_type;
begin
apply_rand_seed(seed, 0, rand_ctr);
loop
if (do_noise) then
-- Generate noise pulse with gauss distribution
gaus_par(GAUSS_iterations) := real(iter_am);
gaus_par(GAUSS_mean) := nw_mean;
......@@ -642,10 +645,10 @@ begin
noise_force <= aux;
wait for integer(noise_time) * 1 ns;
else
wait for 10 ns;
end if;
end loop;
end process;
----------------------------------------------------------------------------
......@@ -688,6 +691,7 @@ begin
variable fault_state : SW_fault_state;
begin
if (do_restart_mem_if(i)) then
apply_rand_seed(seed, i, rand_ctr_gen(i));
restart_mem_bus(mb_arr(i));
wait for 10 ns;
......
......@@ -73,6 +73,8 @@ entity tb_sanity is
-- Timeout in simulation time. 0 means no limit.
timeout : string := "0 ms";
seed : natural := 0;
topology : string;
bus_len_v : string; --bus_length_type;
trv_del_v : string; --anat_nc_t;
......@@ -221,6 +223,9 @@ begin
end generate;
t_sanity: entity work.sanity_test
generic map (
seed => seed
)
port map (
iterations => iterations,
log_level => log_level,
......
......@@ -23,7 +23,8 @@ entity tb_{{test}} is generic (
log_level : log_lvl_type := info_l;
error_beh : err_beh_type := quit;
error_tol : natural := 0;
timeout : string := "0 ms"
timeout : string := "0 ms";
seed : natural := 0
); end entity;
architecture tb of tb_{{test}} is
component vunittb_wrapper is generic (
......@@ -32,7 +33,8 @@ architecture tb of tb_{{test}} is
log_level : log_lvl_type;
error_beh : err_beh_type;
error_tol : natural;
timeout : string
timeout : string;
seed : natural
); end component;
for all:vunittb_wrapper use configuration work.tbconf_{{test}};
begin
......@@ -42,7 +44,8 @@ begin
log_level => log_level,
error_beh => error_beh,
error_tol => error_tol,
timeout => timeout);
timeout => timeout,
seed => seed);
end architecture;
-- -----------------------------------------------------------------------------
{% endfor %}
......@@ -6,9 +6,11 @@ import logging
from pathlib import Path
from jinja2 import Environment, PackageLoader
from pprint import pprint
import random
__all__ = ['add_sources', 'add_common_sources', 'get_common_modelsim_init_files',
'add_flags', 'dict_merge', 'vhdl_serialize', 'dump_sim_options', 'TestsBase']
'add_flags', 'dict_merge', 'vhdl_serialize', 'dump_sim_options',
'TestsBase', 'get_seed']
d = Path(abspath(__file__)).parent
log = logging.getLogger(__name__)
......@@ -88,6 +90,19 @@ def add_flags(ui, lib, build):
ui.set_sim_option("modelsim.init_files.after_load", modelsim_init_files)
def get_seed(cfg):
if 'seed' in cfg and 'randomize' in cfg:
log.warning('Both "seed" and "randomize" are set - seed takes precedence')
if 'seed' in cfg:
seed = cfg['seed']
elif cfg.get('randomize', False):
# only 31 bits
seed = int(random.random() * 2**31) & 0x7FFFFFFF
else:
seed = 0
return seed
def dict_merge(up, *lowers):
for lower in lowers:
for k, v in lower.items():
......
import logging
from pathlib import Path
from .test_common import add_sources, TestsBase, dict_merge, get_common_modelsim_init_files
from .test_common import add_sources, TestsBase, dict_merge, \
get_common_modelsim_init_files, get_seed
from textwrap import dedent
log = logging.getLogger(__name__)
......@@ -54,7 +55,8 @@ class FeatureTests(TestsBase):
'iterations' : cfg['iterations'],
'log_level' : cfg['log_level'] + '_l',
'error_tol' : cfg['error_tolerance'],
'test_name' : name
'test_name' : name,
'seed' : get_seed(cfg)
}
tb.add_config(name, generics=generics)
......
import logging
from .test_common import TestsBase, add_sources, dict_merge, vhdl_serialize
from .test_common import TestsBase, add_sources, dict_merge, vhdl_serialize, \
get_seed
log = logging.getLogger(__name__)
......@@ -56,6 +57,7 @@ class SanityTests(TestsBase):
'iterations' : cfg['iterations'],
'log_level' : cfg['log_level'] + '_l',
'error_tol' : cfg['error_tolerance'],
'seed' : get_seed(cfg),
'topology' : cfg['topology'],
#'bm' : vhdl_serialize(bm),
'bus_len_v' : vhdl_serialize(cfg['bus_len_v']),
......
import re
import logging
from textwrap import dedent
from .test_common import add_sources, dict_merge, TestsBase, get_common_modelsim_init_files
from .test_common import add_sources, dict_merge, TestsBase, \
get_common_modelsim_init_files, get_seed
from pprint import pprint
log = logging.getLogger(__name__)
......@@ -18,16 +19,19 @@ class UnitTests(TestsBase):
unit_tests = lib.get_test_benches('*_unit_test')
for name, cfg in config['tests'].items():
dict_merge(cfg, default)
tb = lib.get_test_benches('*tb_{}_unit_test'.format(name), allow_empty=True)
tb = lib.get_test_benches('*tb_{}_unit_test'.format(name),
allow_empty=True)
if not len(tb):
pprint([x.name for x in unit_tests])
raise RuntimeError('Testbench {}_unit_test does not exist (but specified in config).'.format(name))
raise RuntimeError('Testbench {}_unit_test does not exist'
+ ' (but specified in config).'.format(name))
assert len(tb) == 1
tb = tb[0]
tb.set_generic('timeout', cfg['timeout'])
tb.set_generic('iterations', cfg['iterations'])
tb.set_generic('log_level', cfg['log_level'] + '_l')
tb.set_generic('error_tol', cfg['error_tolerance'])
tb.set_generic('seed', get_seed(cfg))
# generate & set per-test modelsim tcl file
tcl = build / 'modelsim_init_{}.tcl'.format(name)
......
_default: &default
log_level: info
error_tolerance: 0
# seed: 0 # optional; use to reconstruct results from randomized runs
# randomize: false
unit:
default:
<<: *default
......
_default: &default
log_level: info
error_tolerance: 0
randomize: true
unit:
default:
<<: *default
......
......@@ -65,7 +65,9 @@ entity vunittb_wrapper is
error_tol : natural := 0;
-- Timeout in simulation time. 0 means no limit
timeout : string := "0 ms"
timeout : string := "0 ms";
seed : natural := 0
);
end entity;
......@@ -75,6 +77,9 @@ architecture tb of vunittb_wrapper is
signal t_run : boolean;
begin
i_test: CAN_test
generic map (
seed => seed
)
port map (
iterations => iterations,
log_level => log_level,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment