From 1bf0b9e6fb43a28ffeb7f3754e5ec4fb2a914b7b Mon Sep 17 00:00:00 2001 From: Jeremy Lau <30300826+fdxmw@users.noreply.github.com> Date: Thu, 16 May 2024 17:06:23 -0700 Subject: [PATCH] Improve CompiledSimulation's documentation, for consistency with Simulation's documentation. Fix a typo in step_multiple's type annotations. --- pyrtl/compilesim.py | 30 ++++++++++++++++-------------- pyrtl/simulation.py | 10 +++++----- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/pyrtl/compilesim.py b/pyrtl/compilesim.py index a2affc25..a509c1f8 100644 --- a/pyrtl/compilesim.py +++ b/pyrtl/compilesim.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import ctypes import subprocess import tempfile @@ -7,7 +9,7 @@ import sys import _ctypes -from .core import working_block +from .core import working_block, Block from .wire import Input, Output, Const, WireVector, Register from .memory import MemBlock, RomBlock from .pyrtlexceptions import PyrtlError, PyrtlInternalError @@ -66,29 +68,25 @@ class CompiledSimulation(object): good effect. In order to use this, you need: - - A 64-bit processor - GCC (tested on version 4.8.4) - A 64-bit build of Python If using the multiplication operand, only some architectures are supported: - - x86-64 / amd64 - arm64 / aarch64 - mips64 (untested) - default_value is currently only implemented for registers, not memories. + ``default_value`` is currently only implemented for registers, not memories. A Simulation step works as follows: 1. Registers are updated: - 1. (If this is the first step) With the default values passed in to the Simulation during instantiation and/or any reset values specified in the individual registers. 2. (Otherwise) With their next values calculated in the previous step (``r`` logic nets). - 2. The new values of these registers as well as the values of block inputs are propagated through the combinational logic. 3. Memory writes are performed (``@`` logic nets). @@ -103,8 +101,10 @@ class CompiledSimulation(object): """ def __init__( - self, tracer=True, register_value_map={}, memory_value_map={}, - default_value=0, block=None): + self, tracer: SimulationTrace = True, + register_value_map: dict[Register, int] = {}, + memory_value_map: dict[MemBlock, dict[int, int]] = {}, + default_value: int = 0, block: Block = None): self._dll = self._dir = None self.block = working_block(block) self.block.sanity_check() @@ -134,11 +134,11 @@ def __init__( self._create_dll() self._initialize_mems() - def inspect_mem(self, mem): + def inspect_mem(self, mem: MemBlock) -> dict[int, int]: """Get a view into the contents of a MemBlock.""" return DllMemInspector(self, mem) - def inspect(self, w): + def inspect(self, w: str) -> int: """Get the latest value of the wire given, if possible.""" if isinstance(w, WireVector): w = w.name @@ -152,7 +152,7 @@ def inspect(self, w): return vals[-1] raise PyrtlError('CompiledSimulation does not support inspecting internal WireVectors') - def step(self, inputs): + def step(self, inputs: dict[str, int]): """Run one step of the simulation. :param inputs: A mapping from input names to the values for the step. @@ -169,8 +169,10 @@ def step(self, inputs): """ self.run([inputs]) - def step_multiple(self, provided_inputs={}, expected_outputs={}, nsteps=None, - file=sys.stdout, stop_after_first_error=False): + def step_multiple(self, provided_inputs: dict[str, list[int]] = {}, + expected_outputs: dict[str, int] = {}, + nsteps: int = None, file=sys.stdout, + stop_after_first_error: bool = False): """Take the simulation forward N cycles, where N is the number of values for each provided input. @@ -290,7 +292,7 @@ def _sort_tuple(t): file.write("{0:>5} {1:>10} {2:>8} {3:>8}\n".format(step, name, expected, actual)) file.flush() - def run(self, inputs): + def run(self, inputs: list[dict[str, int]]): """ Run many steps of the simulation. :param inputs: A list of input mappings for each step; diff --git a/pyrtl/simulation.py b/pyrtl/simulation.py index 27276851..f5e7fe9d 100644 --- a/pyrtl/simulation.py +++ b/pyrtl/simulation.py @@ -267,8 +267,8 @@ def step(self, provided_inputs: dict[str, int]): # raise the appropriate exceptions check_rtl_assertions(self) - def step_multiple(self, provided_inputs: dict[str, int] = {}, - expected_outputs: dict[str, int] = {}, + def step_multiple(self, provided_inputs: dict[str, list[int]] = {}, + expected_outputs: dict[str, list[int]] = {}, nsteps: int = None, file=sys.stdout, stop_after_first_error: bool = False): """Take the simulation forward N cycles, based on the number of values @@ -529,7 +529,7 @@ class FastSimulation(object): def __init__( self, register_value_map: dict[Register, int] = {}, - memory_value_map: dict = {}, + memory_value_map: dict[MemBlock, dict[int, int]] = {}, default_value: int = 0, tracer: SimulationTrace = True, block: Block = None, code_file=None): """Instantiates a Fast Simulation instance. @@ -652,8 +652,8 @@ def step(self, provided_inputs: dict[str, int]): # check the rtl assertions check_rtl_assertions(self) - def step_multiple(self, provided_inputs: dict[str, int] = {}, - expected_outputs: dict[str, int] = {}, + def step_multiple(self, provided_inputs: dict[str, list[int]] = {}, + expected_outputs: dict[str, list[int]] = {}, nsteps: int = None, file=sys.stdout, stop_after_first_error: bool = False): """Take the simulation forward N cycles, where N is the number of