[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)