Skip to content

Commit 9d1a3ec

Browse files
committed
Improve WireVector documentation:
* Add a new section on `WireVector` coercion. * Create a `WireVectorLike` type alias for valid inputs to `as_wires`: `WireVector | int | bool | str`. * Add a lot of examples. * Add more links. * Start adding some `:raises:` annotations. * Disable generated documentation for `Input.__init__` and `Output.__init__`. Sphinx was using the docstring from the base class, which was confusing. * Remove unnecessary `:rtype:` annotations. Sphinx retrieves the return type from type annotations. * Update Sphinx dependencies.
1 parent 445a25f commit 9d1a3ec

File tree

7 files changed

+667
-272
lines changed

7 files changed

+667
-272
lines changed

docs/basic.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,13 @@ Input Pins
4040
.. autoclass:: pyrtl.wire.Input
4141
:members:
4242
:show-inheritance:
43-
:special-members: __init__
4443

4544
Output Pins
4645
-----------
4746

4847
.. autoclass:: pyrtl.wire.Output
4948
:members:
5049
:show-inheritance:
51-
:special-members: __init__
5250

5351
Constants
5452
---------

docs/helpers.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Reductions
8686
.. autofunction:: pyrtl.corecircuits.rtl_any
8787
.. autofunction:: pyrtl.corecircuits.rtl_all
8888

89+
.. _extended_logic_and_arithmetic:
90+
8991
Extended Logic and Arithmetic
9092
-----------------------------
9193

docs/index.rst

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,15 @@ design.
7676
PyRTL Classes:
7777
--------------
7878

79-
Perhaps the most important class to understand is :class:`.WireVector`, which
80-
is the basic type from which you build all hardware. If you are coming to
81-
PyRTL from Verilog, a :class:`.WireVector` is closest to a multi-bit `wire`.
82-
Every new :class:`.WireVector` builds a set of wires which you can then connect
83-
with other :class:`.WireVector` through overloaded operations such as
84-
`addition` or `bitwise or`. A bunch of other related classes, including
85-
:class:`.Input`, :class:`.Output`, :class:`.Const`, and :class:`.Register` are
86-
all derived from :class:`.WireVector`. Coupled with :class:`.MemBlock` (and
87-
:class:`.RomBlock`), this is all a user needs to create a functional hardware
88-
design.
79+
Perhaps the most important class to understand is :class:`.WireVector`, which is the
80+
basic type from which you build all hardware. If you are coming to PyRTL from Verilog, a
81+
:class:`.WireVector` is closest to a multi-bit `wire`. Every new :class:`.WireVector`
82+
builds a set of wires which you can then connect with other :class:`.WireVector` through
83+
overloaded operations such as :meth:`~.WireVector.__add__` or
84+
:meth:`~.WireVector.__or__`. A bunch of other related classes, including
85+
:class:`.Input`, :class:`.Output`, :class:`.Const`, and :class:`.Register` are all
86+
derived from :class:`.WireVector`. Coupled with :class:`.MemBlock` (and
87+
:class:`.RomBlock`), this is all a user needs to create a functional hardware design.
8988

9089
.. inheritance-diagram:: pyrtl.wire.WireVector
9190
pyrtl.wire.Input
@@ -134,15 +133,20 @@ which we are implicitly working. Hardware transforms may make a new
134133
Errors
135134
^^^^^^
136135

137-
Finally, when things go wrong you may hit on one of two ``Exceptions``, neither
138-
of which is likely recoverable automatically (which is why we limited them to
139-
only two). The intention is that ``PyrtlError`` is intended to capture end
140-
user errors such as invalid constant strings and mis-matched bitwidths. In
141-
contrast, ``PyrtlInternalError`` captures internal invariants and assertions
142-
over the core logic graph which should never be hit when constructing designs
143-
in the normal ways. If you hit a confusing ``PyrtlError`` or any
144-
``PyrtlInternalError`` feel free to file an issue.
136+
Finally, when things go wrong you may hit an :class:`Exception`, neither of which is
137+
likely recoverable automatically (which is why we limited them to only two). The
138+
intention is that :class:`.PyrtlError` is intended to capture end user errors such as
139+
invalid constant strings and mis-matched bitwidths. In contrast,
140+
:class:`.PyrtlInternalError` captures internal invariants and assertions over the core
141+
logic graph which should never be encountered when constructing designs in the normal
142+
ways. If you hit a confusing :class:`.PyrtlError` or any :class:`.PyrtlInternalError`
143+
feel free to file an issue.
144+
145+
.. autoclass:: pyrtl.pyrtlexceptions.PyrtlError
146+
:members:
145147

148+
.. autoclass:: pyrtl.pyrtlexceptions.PyrtlInternalError
149+
:members:
146150

147151
Reference Guide
148152
===============

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,5 @@ sphinxcontrib-serializinghtml==2.0.0
6767
# via sphinx
6868
typing-extensions==4.14.0
6969
# via beautifulsoup4
70-
urllib3==2.4.0
70+
urllib3==2.5.0
7171
# via requests

pyrtl/conditional.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@
5757
5858
Every PyRTL wire, register, and memory must have a value in every cycle. PyRTL does not
5959
support "don't care" or ``X`` values. To satisfy this requirement, conditional
60-
assignment must assign some value to wires in :data:`conditional_assignment` blocks when
61-
a value is not specified. This can happen when:
60+
assignment must always assign a value to every wire in a :data:`conditional_assignment`
61+
block, even if the :data:`conditional_assignment` does not specify a value. This can
62+
happen when:
6263
6364
#. A condition is ``True``, but no value is specified for a wire or register in that
6465
condition's ``with`` block. In the example above, no value is specified for ``r1`` in
@@ -154,8 +155,8 @@ def make_adder(x: pyrtl.WireVector) -> pyrtl.WireVector:
154155
``output`` conditional would not make sense, especially if ``output`` is used elsewhere
155156
in the circuit.
156157
157-
For more :data:`conditional_assignment` examples, see the state machine example in
158-
``examples/example3-statemachine.py``.
158+
For more :data:`conditional_assignment` examples, see `the state machine example
159+
<https://github.com/UCSBarchlab/PyRTL/blob/development/examples/example3-statemachine.py>`_.
159160
160161
"""
161162
# Use the objects "conditional_assignment" and "otherwise" as described above. The
@@ -172,9 +173,10 @@ def make_adder(x: pyrtl.WireVector) -> pyrtl.WireVector:
172173
#
173174

174175

175-
def currently_under_condition():
176-
"""Returns ``True`` if execution is currently in the context of a
177-
:data:`conditional_assignment`.
176+
def currently_under_condition() -> bool:
177+
"""
178+
:return: ``True`` iff execution is currently in the context of a
179+
:data:`conditional_assignment`.
178180
179181
"""
180182
return _depth > 0
@@ -236,8 +238,8 @@ def _reset_conditional_state():
236238
conditional_assignment = _ConditionalAssignment()
237239
"""Context manager implementing PyRTL's ``conditional_assignment``.
238240
239-
:param dict defaults: Dictionary mapping from WireVector to its default value in this
240-
``conditional_assignment`` block. ``defaults`` are not supported for
241+
:param dict defaults: Dictionary mapping from :class:`.WireVector` to its default value
242+
in this ``conditional_assignment`` block. ``defaults`` are not supported for
241243
:class:`.MemBlock`.
242244
243245
"""

pyrtl/corecircuits.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from .pyrtlexceptions import PyrtlError, PyrtlInternalError
77
from .core import LogicNet, working_block
8-
from .wire import Const, WireVector, WrappedWireVector
8+
from .wire import Const, WireVector, WireVectorLike, WrappedWireVector
99
from pyrtl.rtllib import barrel
1010
from pyrtl.rtllib import muxes
1111
from .conditional import otherwise
@@ -391,7 +391,7 @@ def match_bitwidth(*args, **opt):
391391
return (wv.zero_extended(max_len) for wv in args)
392392

393393

394-
def as_wires(val, bitwidth=None, truncating=True, block=None):
394+
def as_wires(val: WireVectorLike, bitwidth=None, truncating=True, block=None):
395395
"""Return wires from `val` which may be wires, integers (including
396396
IntEnums), strings, or bools.
397397

0 commit comments

Comments
 (0)