Skip to content

Commit 7870eb3

Browse files
committed
sim: document.
This commit includes additional non-documentation changes, related to issues found while documenting it: - `Simulator.run_until()` no longer accepts a `run_passive=` argument. Passive no longer exist and in any case defaulting to `False` does not make a lot of sense from an API perspective. - `add_clock()`'s `phase=` argument, when specified, no longer has `period/2` added to it. This wasn't the documented behavior in first place and it makes no sense to do that. - `add_clock()` raises a `NameError` if a clock domain does not exist, instead of `ValueError`. - `add_clock()` raises a `DriverConflict` if a clock domain is already being driven by a clock, instead of `ValueError`. - GTKWave is no longer a part of the installation instructions, and both Surfer and GTKWave are recommended (in this order).
1 parent 3c1060f commit 7870eb3

File tree

16 files changed

+1179
-222
lines changed

16 files changed

+1179
-222
lines changed

amaranth/sim/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
from .core import *
1+
from .core import Simulator
2+
from ._async import DomainReset, BrokenTrigger, SimulatorContext, TickTrigger, TriggerCombination
3+
from ._pycoro import Settle, Delay, Tick, Passive, Active
24

35

46
__all__ = [
5-
"DomainReset", "BrokenTrigger", "Simulator",
7+
"DomainReset", "BrokenTrigger",
8+
"SimulatorContext", "Simulator", "TickTrigger", "TriggerCombination",
69
# deprecated
710
"Settle", "Delay", "Tick", "Passive", "Active",
811
]

amaranth/sim/_async.py

Lines changed: 496 additions & 30 deletions
Large diffs are not rendered by default.

amaranth/sim/_pycoro.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class Command:
1414

1515
class Settle(Command):
1616
@deprecated("The `Settle` command is deprecated per RFC 27. Use `add_testbench` to write "
17-
"testbenches; in them, an equivalent of `yield Settle()` is performed "
18-
"automatically.")
17+
"testbenches; there, an equivalent of `yield Settle()` is performed "
18+
"automatically after each `ctx.set()`.")
1919
def __init__(self):
2020
pass
2121

@@ -37,8 +37,7 @@ def __repr__(self):
3737
class Tick(Command):
3838
def __init__(self, domain="sync"):
3939
if not isinstance(domain, (str, ClockDomain)):
40-
raise TypeError("Domain must be a string or a ClockDomain instance, not {!r}"
41-
.format(domain))
40+
raise TypeError(f"Domain must be a string or a ClockDomain instance, not {domain!r}")
4241
assert domain != "comb"
4342
self.domain = domain
4443

amaranth/sim/core.py

Lines changed: 276 additions & 120 deletions
Large diffs are not rendered by default.

amaranth/sim/pysim.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ def add_var(path, var_type, var_size, var_init, value):
142142
suffix = f"[{var_size - 1}:0]"
143143
else:
144144
suffix = ""
145-
self.gtkw_signal_names[signal].append(".".join((*var_scope, field_name)) + suffix)
145+
self.gtkw_signal_names[signal].append(
146+
".".join((*var_scope, field_name)) + suffix)
146147
else:
147148
self.vcd_writer.register_alias(
148149
scope=var_scope, name=field_name,

docs/_code/up_counter.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,29 @@ def elaborate(self, platform):
4747

4848

4949
dut = UpCounter(25)
50-
def bench():
50+
async def bench(ctx):
5151
# Disabled counter should not overflow.
52-
yield dut.en.eq(0)
52+
ctx.set(dut.en, 0)
5353
for _ in range(30):
54-
yield
55-
assert not (yield dut.ovf)
54+
await ctx.tick()
55+
assert not ctx.get(dut.ovf)
5656

5757
# Once enabled, the counter should overflow in 25 cycles.
58-
yield dut.en.eq(1)
59-
for _ in range(25):
60-
yield
61-
assert not (yield dut.ovf)
62-
yield
63-
assert (yield dut.ovf)
58+
ctx.set(dut.en, 1)
59+
for _ in range(24):
60+
await ctx.tick()
61+
assert not ctx.get(dut.ovf)
62+
await ctx.tick()
63+
assert ctx.get(dut.ovf)
6464

6565
# The overflow should clear in one cycle.
66-
yield
67-
assert not (yield dut.ovf)
66+
await ctx.tick()
67+
assert not ctx.get(dut.ovf)
6868

6969

7070
sim = Simulator(dut)
7171
sim.add_clock(1e-6) # 1 MHz
72-
sim.add_sync_process(bench)
72+
sim.add_testbench(bench)
7373
with sim.write_vcd("up_counter.vcd"):
7474
sim.run()
7575
# --- CONVERT ---
-32.9 KB
Binary file not shown.

docs/changes.rst

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,23 @@ Migrating from version 0.4
2929

3030
Apply the following changes to code written against Amaranth 0.4 to migrate it to version 0.5:
3131

32-
* Replace uses of ``m.Case()`` with no patterns with ``m.Default()``
33-
* Replace uses of ``Value.matches()`` with no patterns with ``Const(1)``
34-
* Update uses of ``amaranth.utils.log2_int(need_pow2=False)`` to :func:`amaranth.utils.ceil_log2`
35-
* Update uses of ``amaranth.utils.log2_int(need_pow2=True)`` to :func:`amaranth.utils.exact_log2`
36-
* Update uses of ``reset=`` keyword argument to ``init=``
37-
* Convert uses of ``Simulator.add_sync_process`` used as testbenches to ``Simulator.add_testbench``
38-
* Convert other uses of ``Simulator.add_sync_process`` to ``Simulator.add_process``
39-
* Replace uses of ``amaranth.hdl.Memory`` with ``amaranth.lib.memory.Memory``
40-
* Replace imports of ``amaranth.asserts.{Assert, Assume, Cover}`` with imports from ``amaranth.hdl``
41-
* Remove any usage of ``name=`` with assertions, possibly replacing them with custom messages
42-
* Ensure all elaboratables are subclasses of :class:`Elaboratable`
32+
* Replace uses of :py:`m.Case()` with no patterns with :py:`m.Default()`.
33+
* Replace uses of :py:`Value.matches()` with no patterns with :py:`Const(1)`.
34+
* Update uses of :py:`amaranth.utils.log2_int(need_pow2=False)` to :func:`amaranth.utils.ceil_log2`.
35+
* Update uses of :py:`amaranth.utils.log2_int(need_pow2=True)` to :func:`amaranth.utils.exact_log2`.
36+
* Update uses of :py:`reset=` keyword argument to :py:`init=`.
37+
* Convert uses of :py:`Simulator.add_sync_process` used as testbenches to :meth:`Simulator.add_testbench <amaranth.sim.Simulator.add_testbench>`.
38+
* Convert other uses of :py:`Simulator.add_sync_process` to :meth:`Simulator.add_process <amaranth.sim.Simulator.add_process>`.
39+
* Convert simulator processes and testbenches to use the new async API.
40+
* Replace uses of :py:`amaranth.hdl.Memory` with :class:`amaranth.lib.memory.Memory`.
41+
* Replace imports of :py:`amaranth.asserts.Assert`, :py:`Assume`, and :py:`Cover` with imports from :py:`amaranth.hdl`.
42+
* Remove uses of :py:`name=` keyword argument of :py:`Assert`, :py:`Assume`, and :py:`Cover`; a message can be used instead.
43+
* Ensure all elaboratables are subclasses of :class:`Elaboratable`.
4344
* Ensure clock domains aren't used outside the module that defines them, or its submodules; move clock domain definitions upwards in the hierarchy as necessary
44-
* Remove uses of ``amaranth.lib.coding.*`` by inlining or copying the implementation of the modules
45-
* Update uses of ``platform.request`` to pass ``dir="-"`` and use :mod:`amaranth.lib.io` buffers
45+
* Remove uses of :py:`amaranth.lib.coding.*` by inlining or copying the implementation of the modules.
46+
* Update uses of :py:`platform.request` to pass :py:`dir="-"` and use :mod:`amaranth.lib.io` buffers.
47+
* Update uses of :meth:`Simulator.add_clock <amaranth.sim.Simulator.add_clock>` with explicit :py:`phase` to take into account simulator no longer adding implicit :py:`period / 2`. (Previously, :meth:`Simulator.add_clock <amaranth.sim.Simulator.add_clock>` was documented to first toggle the clock at the time :py:`phase`, but actually first toggled the clock at :py:`period / 2 + phase`.)
48+
* Update uses of :meth:`Simulator.run_until <amaranth.sim.Simulator.run_until>` to remove the :py:`run_passive=True` argument. If the code uses :py:`run_passive=False`, ensure it still works with the new behavior.
4649

4750

4851
Implemented RFCs
@@ -51,6 +54,7 @@ Implemented RFCs
5154
.. _RFC 17: https://amaranth-lang.org/rfcs/0017-remove-log2-int.html
5255
.. _RFC 27: https://amaranth-lang.org/rfcs/0027-simulator-testbenches.html
5356
.. _RFC 30: https://amaranth-lang.org/rfcs/0030-component-metadata.html
57+
.. _RFC 36: https://amaranth-lang.org/rfcs/0036-async-testbench-functions.html
5458
.. _RFC 39: https://amaranth-lang.org/rfcs/0039-empty-case.html
5559
.. _RFC 43: https://amaranth-lang.org/rfcs/0043-rename-reset-to-init.html
5660
.. _RFC 45: https://amaranth-lang.org/rfcs/0045-lib-memory.html
@@ -68,6 +72,7 @@ Implemented RFCs
6872
* `RFC 17`_: Remove ``log2_int``
6973
* `RFC 27`_: Testbench processes for the simulator
7074
* `RFC 30`_: Component metadata
75+
* `RFC 36`_: Async testbench functions
7176
* `RFC 39`_: Change semantics of no-argument ``m.Case()``
7277
* `RFC 43`_: Rename ``reset=`` to ``init=``
7378
* `RFC 45`_: Move ``hdl.Memory`` to ``lib.Memory``
@@ -94,12 +99,12 @@ Language changes
9499
* Added: :meth:`ShapeCastable.from_bits` method. (`RFC 51`_)
95100
* Added: IO values, :class:`IOPort` objects, :class:`IOBufferInstance` objects. (`RFC 53`_)
96101
* Added: :class:`MemoryData` objects. (`RFC 62`_)
97-
* Changed: ``m.Case()`` with no patterns is never active instead of always active. (`RFC 39`_)
98-
* Changed: ``Value.matches()`` with no patterns is ``Const(0)`` instead of ``Const(1)``. (`RFC 39`_)
99-
* Changed: ``Signal(range(stop), init=stop)`` warning has been changed into a hard error and made to trigger on any out-of range value.
100-
* Changed: ``Signal(range(0))`` is now valid without a warning.
101-
* Changed: ``Shape.cast(range(1))`` is now ``unsigned(0)``. (`RFC 46`_)
102-
* Changed: the ``reset=`` argument of :class:`Signal`, :meth:`Signal.like`, :class:`amaranth.lib.wiring.Member`, :class:`amaranth.lib.cdc.FFSynchronizer`, and ``m.FSM()`` has been renamed to ``init=``. (`RFC 43`_)
102+
* Changed: :py:`m.Case()` with no patterns is never active instead of always active. (`RFC 39`_)
103+
* Changed: :py:`Value.matches()` with no patterns is :py:`Const(0)` instead of :py:`Const(1)`. (`RFC 39`_)
104+
* Changed: :py:`Signal(range(stop), init=stop)` warning has been changed into a hard error and made to trigger on any out-of range value.
105+
* Changed: :py:`Signal(range(0))` is now valid without a warning.
106+
* Changed: :py:`Shape.cast(range(1))` is now :py:`unsigned(0)`. (`RFC 46`_)
107+
* Changed: the :py:`reset=` argument of :class:`Signal`, :meth:`Signal.like`, :class:`amaranth.lib.wiring.Member`, :class:`amaranth.lib.cdc.FFSynchronizer`, and :py:`m.FSM()` has been renamed to :py:`init=`. (`RFC 43`_)
103108
* Changed: :class:`Shape` has been made immutable and hashable.
104109
* Changed: :class:`Assert`, :class:`Assume`, :class:`Cover` have been moved to :mod:`amaranth.hdl` from :mod:`amaranth.asserts`. (`RFC 50`_)
105110
* Changed: :class:`Instance` IO ports now accept only IO values, not plain values. (`RFC 53`_)
@@ -127,17 +132,21 @@ Standard library changes
127132
* Added: :mod:`amaranth.lib.meta`, :class:`amaranth.lib.wiring.ComponentMetadata`. (`RFC 30`_)
128133
* Deprecated: :mod:`amaranth.lib.coding`. (`RFC 63`_)
129134
* Removed: (deprecated in 0.4) :mod:`amaranth.lib.scheduler`. (`RFC 19`_)
130-
* Removed: (deprecated in 0.4) :class:`amaranth.lib.fifo.FIFOInterface` with ``fwft=False``. (`RFC 20`_)
131-
* Removed: (deprecated in 0.4) :class:`amaranth.lib.fifo.SyncFIFO` with ``fwft=False``. (`RFC 20`_)
135+
* Removed: (deprecated in 0.4) :class:`amaranth.lib.fifo.FIFOInterface` with :py:`fwft=False`. (`RFC 20`_)
136+
* Removed: (deprecated in 0.4) :class:`amaranth.lib.fifo.SyncFIFO` with :py:`fwft=False`. (`RFC 20`_)
132137

133138

134139
Toolchain changes
135140
-----------------
136141

137-
* Added: ``Simulator.add_testbench``. (`RFC 27`_)
142+
* Added: :meth:`Simulator.add_testbench <amaranth.sim.Simulator.add_testbench>`. (`RFC 27`_)
143+
* Added: async function support in :meth:`Simulator.add_testbench <amaranth.sim.Simulator.add_testbench>` and :meth:`Simulator.add_process <amaranth.sim.Simulator.add_process>`. (`RFC 36`_)
138144
* Added: support for :class:`amaranth.hdl.Assert` in simulation. (`RFC 50`_)
139-
* Deprecated: ``Settle`` simulation command. (`RFC 27`_)
140-
* Deprecated: ``Simulator.add_sync_process``. (`RFC 27`_)
145+
* Changed: :meth:`Simulator.add_clock <amaranth.sim.Simulator.add_clock>` no longer implicitly adds :py:`period / 2` when :py:`phase` is specified, actually matching the documentation.
146+
* Changed: :meth:`Simulator.run_until <amaranth.sim.Simulator.run_until>` always runs the simulation until the given deadline, even when no critical processes or testbenches are present.
147+
* Deprecated: :py:`Settle` simulation command. (`RFC 27`_)
148+
* Deprecated: :py:`Simulator.add_sync_process`. (`RFC 27`_)
149+
* Deprecated: the :py:`run_passive` argument to :meth:`Simulator.run_until <amaranth.sim.Simulator.run_until>` has been deprecated, and does nothing.
141150
* Removed: (deprecated in 0.4) use of mixed-case toolchain environment variable names, such as ``NMIGEN_ENV_Diamond`` or ``AMARANTH_ENV_Diamond``; use upper-case environment variable names, such as ``AMARANTH_ENV_DIAMOND``.
142151

143152

@@ -150,7 +159,7 @@ Platform integration changes
150159
* Added: :meth:`BuildPlan.extract`.
151160
* Added: ``build.sh`` begins with ``#!/bin/sh``.
152161
* Changed: ``IntelPlatform`` renamed to ``AlteraPlatform``.
153-
* Deprecated: argument ``run_script=`` in :meth:`BuildPlan.execute_local`.
162+
* Deprecated: argument :py:`run_script=` in :meth:`BuildPlan.execute_local`.
154163
* Removed: (deprecated in 0.4) :mod:`vendor.intel`, :mod:`vendor.lattice_ecp5`, :mod:`vendor.lattice_ice40`, :mod:`vendor.lattice_machxo2_3l`, :mod:`vendor.quicklogic`, :mod:`vendor.xilinx`. (`RFC 18`_)
155164

156165

docs/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
autodoc_preserve_defaults = True
4040
autodoc_inherit_docstrings = False
4141

42+
# Amaranth mostly does not include typehints, and showing them in some places but not others is
43+
# worse than not showing them at all.
44+
autodoc_typehints = "none"
45+
4246
napoleon_google_docstring = False
4347
napoleon_numpy_docstring = True
4448
napoleon_use_ivar = True

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Language & toolchain
1515
guide
1616
reference
1717
stdlib
18+
simulator
1819
platform
1920
changes
2021
contrib

0 commit comments

Comments
 (0)