[otbnsim] Add more functionality to testutil Add more functionality from the statistics test to the shared testutil module, making it available for other tests to use as well. Signed-off-by: Philipp Wagner <phw@lowrisc.org>
diff --git a/hw/ip/otbn/dv/otbnsim/test/simple_test.py b/hw/ip/otbn/dv/otbnsim/test/simple_test.py index 6f8f47e..1bf7711 100644 --- a/hw/ip/otbn/dv/otbnsim/test/simple_test.py +++ b/hw/ip/otbn/dv/otbnsim/test/simple_test.py
@@ -142,7 +142,7 @@ asm_file: str, expected_file: str) -> None: # Start by assembling and linking the input file - elf_file = asm_and_link_one_file(asm_file, str(tmpdir)) + elf_file = asm_and_link_one_file(asm_file, tmpdir) # Run the simulation. We can just pass a list of commands to stdin, and # don't need to do anything clever to track what's going on.
diff --git a/hw/ip/otbn/dv/otbnsim/test/stats_test.py b/hw/ip/otbn/dv/otbnsim/test/stats_test.py index 99fa087..c820a31 100644 --- a/hw/ip/otbn/dv/otbnsim/test/stats_test.py +++ b/hw/ip/otbn/dv/otbnsim/test/stats_test.py
@@ -7,31 +7,34 @@ from sim.sim import OTBNSim from sim.stats import ExecutionStats -from sim.elf import load_elf import testutil -def _run_sim_for_stats(asm_file: str, tmpdir: str) -> ExecutionStats: - """ Run the OTBN simulator, collect statistics, and return them. """ - - assert os.path.exists(asm_file) - elf_file = testutil.asm_and_link_one_file(asm_file, tmpdir) - - sim = OTBNSim() - load_elf(sim, elf_file) - - sim.start(0) +def _run_sim_for_stats(sim: OTBNSim) -> ExecutionStats: sim.run(verbose=False, collect_stats=True) - assert sim.stats + assert sim.stats return sim.stats + +def _simulate_asm_file(asm_file: str, tmpdir: py.path.local) -> ExecutionStats: + '''Run the OTBN simulator, collect statistics, and return them.''' + + sim = testutil.prepare_sim_for_asm_file(asm_file, tmpdir, start_addr=0) + return _run_sim_for_stats(sim) + + +def _simulate_asm_str(assembly: str, tmpdir: py.path.local) -> ExecutionStats: + sim = testutil.prepare_sim_for_asm_str(assembly, tmpdir, start_addr=0) + return _run_sim_for_stats(sim) + + def test_general_and_loop(tmpdir: py.path.local) -> None: '''Test the collection of general statistics as well as loop stats.''' asm_file = os.path.join(os.path.dirname(__file__), 'simple', 'loops', 'loops.s') - stats = _run_sim_for_stats(asm_file, str(tmpdir)) + stats = _simulate_asm_file(asm_file, tmpdir) # General statistics assert stats.stall_count == 2 @@ -58,7 +61,7 @@ asm_file = os.path.join(os.path.dirname(__file__), 'simple', 'subroutines', 'direct-call.s') - stats = _run_sim_for_stats(asm_file, str(tmpdir)) + stats = _simulate_asm_file(asm_file, tmpdir) exp = [{'call_site': 4, 'callee_func': 12, 'caller_func': 0}] assert stats.func_calls == exp @@ -69,7 +72,7 @@ asm_file = os.path.join(os.path.dirname(__file__), 'simple', 'subroutines', 'indirect-call.s') - stats = _run_sim_for_stats(asm_file, str(tmpdir)) + stats = _simulate_asm_file(asm_file, tmpdir) exp = [{'call_site': 8, 'callee_func': 16, 'caller_func': 0}] assert stats.func_calls == exp
diff --git a/hw/ip/otbn/dv/otbnsim/test/testutil.py b/hw/ip/otbn/dv/otbnsim/test/testutil.py index 7900e89..c37c01f 100644 --- a/hw/ip/otbn/dv/otbnsim/test/testutil.py +++ b/hw/ip/otbn/dv/otbnsim/test/testutil.py
@@ -2,8 +2,13 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +import py import os import subprocess +import tempfile + +from sim.elf import load_elf +from sim.sim import OTBNSim OTBN_DIR = os.path.join(os.path.dirname(__file__), '../../..') @@ -11,7 +16,7 @@ SIM_DIR = os.path.join(os.path.dirname(__file__), '..') -def asm_and_link_one_file(asm_path: str, work_dir: str) -> str: +def asm_and_link_one_file(asm_path: str, work_dir: py.path.local) -> str: '''Assemble and link file at asm_path in work_dir. Returns the path to the resulting ELF @@ -25,3 +30,33 @@ subprocess.run([otbn_as, '-o', obj_path, asm_path], check=True) subprocess.run([otbn_ld, '-o', elf_path, obj_path], check=True) return elf_path + + +def prepare_sim_for_asm_file(asm_file: str, tmpdir: py.path.local, start_addr: int = 0) -> OTBNSim: + '''Set up the simulation of a single assembly file. + + The returned simulation is ready to be run through the run() method. + + ''' + assert os.path.exists(asm_file) + elf_file = asm_and_link_one_file(asm_file, tmpdir) + + sim = OTBNSim() + load_elf(sim, elf_file) + + sim.state.ext_regs.write('START_ADDR', start_addr, False) + sim.state.ext_regs.commit() + sim.start() + return sim + + +def prepare_sim_for_asm_str(assembly: str, tmpdir: py.path.local, start_addr: int = 0) -> OTBNSim: + '''Set up the simulation for an assembly snippet passed as string. + + The returned simulation is ready to be run through the run() method. + + ''' + with tempfile.NamedTemporaryFile('w', dir=tmpdir) as fp: + fp.write(assembly) + fp.flush() + return prepare_sim_for_asm_file(fp.name, tmpdir, start_addr)