Skip to content

Commit 30fb11c

Browse files
committed
Improve documentation for wire_struct's _value constructor argument.
1 parent 3df3313 commit 30fb11c

1 file changed

Lines changed: 37 additions & 7 deletions

File tree

pyrtl/helperfuncs.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,22 +1470,17 @@ def wire_struct(wire_struct_spec):
14701470
14711471
1. Provide a driver for *each* component wire, for example::
14721472
1473-
>>> byte = Byte(high=0xA, low=0xB)
1473+
>>> byte = Byte(high=0xA, low=0xB)
14741474
14751475
Note how the component names (``high``, ``low``) are used as keyword args for the
14761476
constructor. Drivers must be provided for *all* components.
14771477
14781478
2. Provide a driver for the entire ``@wire_struct``, for example::
14791479
1480-
>>> byte = Byte(Byte=0xAB)
1480+
>>> byte = Byte(Byte=0xAB)
14811481
14821482
Note how the class name (``Byte``) is used as a keyword arg for the constructor.
14831483
1484-
If the class name is not known, the special name ``_value`` can be used instead::
1485-
1486-
>>> UnknownDynamicType = Byte
1487-
>>> unknown_dynamic_type = UnknownDynamicType(_value=0xAB)
1488-
14891484
Accessing Slices
14901485
----------------
14911486
@@ -1620,6 +1615,41 @@ class CacheLine:
16201615
16211616
No values are specified for ``input_byte`` because its value is not known until
16221617
simulation time.
1618+
1619+
Generic Usage
1620+
-------------
1621+
1622+
.. doctest only::
1623+
1624+
>>> import pyrtl
1625+
>>> pyrtl.reset_working_block()
1626+
1627+
Functions can work with ``@wire_struct`` instances generically. For example, we can
1628+
define a function that accepts any ``@wire_struct`` and returns the same type of
1629+
``@wire_struct``, with all of the argument's fields bitwise-inverted::
1630+
1631+
>>> def invert_all_fields(output_name, any_wire_struct):
1632+
... # Retrieve the argument wire_struct's class.
1633+
... OutputClass = type(any_wire_struct)
1634+
... # Instantiate that class, specifying its full value.
1635+
... return OutputClass(name=output_name, _value=~any_wire_struct)
1636+
1637+
>>> input_byte = Byte(name="input_byte", concatenated_type=pyrtl.Input)
1638+
>>> output_byte = invert_all_fields("output_byte", input_byte)
1639+
1640+
>>> sim = pyrtl.Simulation()
1641+
>>> sim.step({"input_byte": 0})
1642+
>>> hex(sim.inspect("output_byte"))
1643+
'0xff'
1644+
1645+
``invert_all_fields`` uses ``type(any_wire_struct)`` to retrieve the argument
1646+
``@wire_struct``'s class, and instantiates that class for the function's return
1647+
value.
1648+
1649+
This uses the special constructor ``kwarg`` ``_value``, rather than the name of the
1650+
class, to specify the full value for the returned ``@wire_struct`` object. In this
1651+
example, we must use ``_value`` instead of the name of the class (``Byte``) because
1652+
``any_wire_struct`` might not be a ``Byte``.
16231653
"""
16241654
# Convert the decorated class' annotations (dict of attr_name: attr_value)
16251655
# to a list of _ComponentMetas.

0 commit comments

Comments
 (0)