mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 21:07:34 -04:00
Add a --start_seed argument to core_ibex/sim.py
If --iterations is 1, this is equivalent to the existing --seed argument (which we're keeping unchanged). If --iterations is 0 (reading iteration counts from the config) or positive, successive test iterations use successive seeds. So if you pass --start_seed 123 and run ten iterations, they will run with seeds 123, 124, ... through 133. Lots of the added code is to check that you don't do something silly like --seed=123 --iterations=10. Since the next patch will convert the Makefile which runs this script to using --start_seed, that's all dead code. Maybe we should get rid of that argument at some point.
This commit is contained in:
parent
f173e2baba
commit
a325430904
1 changed files with 84 additions and 21 deletions
|
@ -49,6 +49,37 @@ finally:
|
|||
sys.path = _OLD_SYS_PATH
|
||||
|
||||
|
||||
class SeedGen:
|
||||
'''A generator for seed values'''
|
||||
def __init__(self, fixed_seed, start_seed):
|
||||
self.fixed = False
|
||||
self.start_seed = 0
|
||||
|
||||
if fixed_seed is not None:
|
||||
if start_seed is not None:
|
||||
logging.error("Cannot pass both --seed and --start_seed.")
|
||||
sys.exit(RET_FAIL)
|
||||
|
||||
self.start_seed = fixed_seed
|
||||
self.fixed = True
|
||||
return
|
||||
|
||||
if start_seed is not None:
|
||||
self.start_seed = start_seed
|
||||
return
|
||||
|
||||
# Neither --seed nor --start_seed passed. Print out the seed so the
|
||||
# user can see what's going on.
|
||||
self.start_seed = random.getrandbits(32)
|
||||
logging.info("Random start seed chosen: {}".format(self.start_seed))
|
||||
|
||||
def gen(self, iteration):
|
||||
if iteration != 0:
|
||||
assert not self.fixed
|
||||
|
||||
return self.start_seed + iteration
|
||||
|
||||
|
||||
def subst_opt(string, name, enable, replacement):
|
||||
'''Substitute the <name> option in string
|
||||
|
||||
|
@ -276,7 +307,7 @@ def run_sim_commands(command_list, use_lsf):
|
|||
run_cmd(cmd, 300, check_return_code=True)
|
||||
|
||||
|
||||
def rtl_sim(sim_cmd, test_list, seed, opts,
|
||||
def rtl_sim(sim_cmd, test_list, seed_gen, opts,
|
||||
output_dir, bin_dir, lsf_cmd):
|
||||
"""Run the testbench in the simulator
|
||||
|
||||
|
@ -284,8 +315,9 @@ def rtl_sim(sim_cmd, test_list, seed, opts,
|
|||
still have placeholders for test-specific arguments. test_list is a list of
|
||||
test objects read from the testlist YAML file which gives the tests to run.
|
||||
|
||||
seed is the seed to use in the simulations (controls things like random
|
||||
delays on the bus). opts is a string of plusargs to give to the simulator.
|
||||
seed the seed generator to use to supply seeds for the simulations
|
||||
(controls things like random delays on the bus). opts is a string of
|
||||
plusargs to give to the simulator.
|
||||
|
||||
output_dir is the output directory for simulation files (and the directory
|
||||
in which the simulator gets run). bin_dir is the directory containing
|
||||
|
@ -302,7 +334,6 @@ def rtl_sim(sim_cmd, test_list, seed, opts,
|
|||
'out': output_dir,
|
||||
'sim_opts': opts,
|
||||
'cwd': _CORE_IBEX,
|
||||
'seed': str(seed)
|
||||
})
|
||||
|
||||
# Compute a list of pairs (cmd, dirname) where cmd is the command to run
|
||||
|
@ -310,7 +341,8 @@ def rtl_sim(sim_cmd, test_list, seed, opts,
|
|||
cmd_list = []
|
||||
for test in test_list:
|
||||
for i in range(test['iterations']):
|
||||
cmd_list.append(get_test_sim_cmd(sim_cmd, test, i,
|
||||
it_cmd = subst_vars(sim_cmd, {'seed': str(seed_gen.gen(i))})
|
||||
cmd_list.append(get_test_sim_cmd(it_cmd, test, i,
|
||||
output_dir, bin_dir, lsf_cmd))
|
||||
|
||||
run_sim_commands(cmd_list, lsf_cmd is not None)
|
||||
|
@ -451,6 +483,20 @@ def gen_cov(base_dir, simulator, lsf_cmd):
|
|||
sys.exit(RET_FAIL)
|
||||
|
||||
|
||||
def read_seed(arg):
|
||||
'''Read an argument to the --seed command line value'''
|
||||
try:
|
||||
seed = int(arg)
|
||||
if seed < 0:
|
||||
raise ValueError('bad seed')
|
||||
return seed
|
||||
|
||||
except ValueError:
|
||||
raise argparse.ArgumentTypeError('Bad argument for --seed ({}): '
|
||||
'must be a non-negative integer.'
|
||||
.format(arg))
|
||||
|
||||
|
||||
def main():
|
||||
'''Entry point when run as a script'''
|
||||
|
||||
|
@ -465,10 +511,6 @@ def main():
|
|||
'testlist.yaml'))
|
||||
parser.add_argument("--test", type=str, default="all",
|
||||
help="Test name, 'all' means all tests in the list")
|
||||
parser.add_argument("--seed", type=int,
|
||||
help=("Randomization seed; random if not specified"))
|
||||
parser.add_argument("--iterations", type=int, default=0,
|
||||
help="Override the iteration count in the test list")
|
||||
parser.add_argument("--simulator", type=str, default="vcs",
|
||||
help="RTL simulator to use (default: vcs)")
|
||||
parser.add_argument("--simulator_yaml",
|
||||
|
@ -495,9 +537,27 @@ def main():
|
|||
help=("LSF command. Run locally if lsf "
|
||||
"command is not specified"))
|
||||
|
||||
sg = (parser.
|
||||
add_argument_group('Seeds and iterations',
|
||||
'If none of the arguments in this section are '
|
||||
'used, a random starting seed will be picked and '
|
||||
'passed as --start_seed. The number of '
|
||||
'iterations for each test will be read from the '
|
||||
'configuration.'))
|
||||
|
||||
sg.add_argument("--seed", type=read_seed, metavar='S',
|
||||
help=("Randomization seed for the only iteration of each "
|
||||
"test. Implies --iterations=1. Equivalently, pass "
|
||||
"--start_seed and set iterations to 1."))
|
||||
sg.add_argument("--start_seed", type=read_seed, metavar='S',
|
||||
help=("Randomization seed for the first iteration of each "
|
||||
"test. Following iterations will use seeds S+1, "
|
||||
"S+2, and so on."))
|
||||
sg.add_argument("--iterations", type=int,
|
||||
help="Override the iteration count in the test list")
|
||||
|
||||
args = parser.parse_args()
|
||||
setup_logging(args.verbose)
|
||||
parser.set_defaults(verbose=False)
|
||||
|
||||
# If args.lsf_cmd is an empty string return an error message and exit from
|
||||
# the script, as doing nothing will result in arbitrary simulation timeouts
|
||||
|
@ -521,6 +581,8 @@ def main():
|
|||
compile_cmds = []
|
||||
sim_cmd = ""
|
||||
matched_list = []
|
||||
seed_gen = None
|
||||
|
||||
if steps['compile'] or steps['sim']:
|
||||
enables = {
|
||||
'cov_opts': args.en_cov,
|
||||
|
@ -530,7 +592,16 @@ def main():
|
|||
args.simulator_yaml, enables)
|
||||
|
||||
if steps['sim'] or steps['compare']:
|
||||
process_regression_list(args.testlist, args.test, args.iterations,
|
||||
seed_gen = SeedGen(args.seed, args.start_seed)
|
||||
if seed_gen.fixed:
|
||||
if not args.iterations:
|
||||
args.iterations = 1
|
||||
if args.iterations != 1:
|
||||
logging.error('Cannot set multiple --iterations with a '
|
||||
'fixed seed.')
|
||||
return RET_FAIL
|
||||
|
||||
process_regression_list(args.testlist, args.test, args.iterations or 0,
|
||||
matched_list, _RISCV_DV_ROOT)
|
||||
if not matched_list:
|
||||
raise RuntimeError("Cannot find %s in %s" %
|
||||
|
@ -542,16 +613,8 @@ def main():
|
|||
|
||||
# Run RTL simulation
|
||||
if steps['sim']:
|
||||
# Pick a seed: either the one we were given, or pick one at random. In
|
||||
# the latter case, print it out so the user can see what's going on.
|
||||
if args.seed is None or args.seed < 0:
|
||||
seed = random.getrandbits(32)
|
||||
logging.info("Random seed chosen: {}".format(seed))
|
||||
else:
|
||||
seed = args.seed
|
||||
|
||||
rtl_sim(sim_cmd, matched_list, seed, args.sim_opts,
|
||||
output_dir, bin_dir, args.lsf_cmd)
|
||||
rtl_sim(sim_cmd, matched_list, seed_gen,
|
||||
args.sim_opts, output_dir, bin_dir, args.lsf_cmd)
|
||||
|
||||
# Compare RTL & ISS simulation result.
|
||||
if steps['compare']:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue