1616import sys
1717import functools
1818import operator
19- import typing
19+ from typing import Union , TYPE_CHECKING
2020
2121from pyrtl .pyrtlexceptions import PyrtlError , PyrtlInternalError
2222from pyrtl .core import working_block , _NameSanitizer , Block
2525from pyrtl .memory import RomBlock
2626from pyrtl .passes import two_way_concat , one_bit_selects
2727
28+ if TYPE_CHECKING :
29+ from pyrtl .simulation import SimulationTrace
30+
2831
2932def _natural_sort_key (key ):
3033 """ Convert the key into a form such that it will be sorted naturally,
@@ -103,31 +106,33 @@ def input_from_blif(
103106 clock_name : str = 'clk' , top_model : str = None ):
104107 """Read an open BLIF file or string as input, updating the block appropriately.
105108
109+ If ``merge_io_vectors`` is ``True``, then given 1-bit :class:`Input` wires ``a[0]``
110+ and ``a[1]``, these wires will be combined into a single 2-bit :class:`Input` wire
111+ ``a`` that can be accessed by name ``a`` in the block. Otherwise if
112+ ``merge_io_vectors`` is ``False``, the original 1-bit wires will be :class:`Input`
113+ wires of the block. This holds similarly for :class:`Output`.
114+
115+ ``input_from_blif`` assumes the following:
116+
117+ - There is only one single shared clock and reset
118+
119+ - Output is generated by Yosys with formals in a particular order
120+
121+ ``input_from_blif`` currently supports multi-module (unflattened) BLIF, though we
122+ recommend importing a flattened BLIF with a single module when possible. It
123+ currently ignores the reset signal (which it assumes is input only to the flip
124+ flops).
125+
106126 :param blif: An open BLIF file to read.
107127 :param block: The block where the logic will be added. Defaults to the
108128 :ref:`working_block`.
109- :param merge_io_vectors: If True, :class:`Input`/:class:`Output` wires whose
129+ :param merge_io_vectors: If `` True`` , :class:`Input`/:class:`Output` wires whose
110130 names differ only by a indexing subscript (e.g. 1-bit wires ``a[0]`` and
111- ``a[1]``) will be combined into a single :class:`Input`/:class:`Output`
112- (e.g. a 2-bit wire ``a``).
113- :param clock_name: The name of the clock (defaults to ``clk``). :param top_model:
114- name of top-level model to instantiate; if None, defaults to first model listed
115- in the BLIF.
116-
117- If ``merge_io_vectors`` is ``True``, then given 1-bit :class:`Input` wires
118- ``a[0]`` and ``a[1]``, these wires will be combined into a single 2-bit
119- :class:`Input` wire ``a`` that can be accessed by name ``a`` in the block.
120- Otherwise if ``merge_io_vectors`` is ``False``, the original 1-bit wires will be
121- :class:`Input` wires of the block. This holds similarly for :class:`Output`.
122-
123- This assumes the following:
124- * There is only one single shared clock and reset
125- * Output is generated by Yosys with formals in a particular order
126-
127- It currently supports multi-module (unflattened) BLIF, though we recommend importing
128- a flattened BLIF with a single module when possible. It currently ignores the reset
129- signal (which it assumes is input only to the flip flops).
130-
131+ ``a[1]``) will be combined into a single :class:`Input`/:class:`Output` (e.g. a
132+ 2-bit wire ``a``).
133+ :param clock_name: The name of the clock (defaults to ``clk``).
134+ :param top_model: name of top-level model to instantiate; if ``None``, defaults to
135+ first model listed in the BLIF.
131136 """
132137 import pyparsing
133138 from pyparsing import (Word , Literal , OneOrMore , ZeroOrMore ,
@@ -536,23 +541,23 @@ def input_from_verilog(
536541 """Read an open Verilog file or string as input via `Yosys
537542 <https://github.com/YosysHQ/yosys>`_ conversion, updating the block.
538543
539- :param verilog: An open Verilog file to read.
540- :param clock_name: The name of the clock (defaults to 'clk').
541- :param toplevel: Name of top-level module to instantiate; if None, defaults to first
542- model defined in the Verilog file.
543- :param leave_in_dir: If True, save the intermediate BLIF file created in the given
544- directory.
545- :param block: The block where the logic will be added. Defaults to the
546- :ref:`working_block`.
544+ This function is essentially a wrapper for :func:`input_from_blif`, with the added
545+ convenience of turning the Verilog into BLIF for import for you. This function
546+ passes a set of commands to Yosys as a script that normally produces BLIF files that
547+ can be successfully imported into PyRTL via :func:`input_from_blif`.
547548
548- Note: This function is essentially a wrapper for :func:`input_from_blif`, with
549- the added convenience of turning the Verilog into BLIF for import for you. This
550- function passes a set of commands to Yosys as a script that normally produces BLIF
551- files that can be successuflly imported into PyRTL via :func:`input_from_blif`. If the
552- Yosys conversion fails here, we recommend you create your own custom Yosys script to
553- try and produce BLIF yourself. Then you can import BLIF directly via
549+ If the Yosys conversion fails, we recommend you create your own custom Yosys script
550+ to try and produce BLIF yourself. Then you can import BLIF directly via
554551 :func:`input_from_blif`.
555552
553+ :param verilog: An open Verilog file to read.
554+ :param clock_name: The name of the clock (defaults to ``"clk"``).
555+ :param toplevel: Name of top-level module to instantiate; if ``None``, defaults to
556+ first model defined in the Verilog file.
557+ :param leave_in_dir: If ``True``, save the intermediate BLIF file created in the
558+ given directory.
559+ :param block: The block where the logic will be added. Defaults to the
560+ :ref:`working_block`.
556561 """
557562
558563 # Dev Notes:
@@ -619,9 +624,16 @@ def input_from_verilog(
619624 os .remove (tmp_blif_path )
620625
621626
622- def output_to_verilog (dest_file , add_reset : typing . Union [bool , str ] = True ,
627+ def output_to_verilog (dest_file , add_reset : Union [bool , str ] = True ,
623628 block : Block = None , initialize_registers : bool = False ):
624- """A function to walk the block and output it in Verilog format to the open file.
629+ """A function to walk the ``block`` and output it in Verilog format to the open
630+ file.
631+
632+ The Verilog module will be named ``toplevel``, with a clock input named ``clk``.
633+
634+ When possible, wires keep their names in the Verilog output. Wire names that do not
635+ satisfy Verilog's naming requirements, and wires that conflict with Verilog keywords
636+ are given new temporary names in the Verilog output.
625637
626638 :param dest_file: Open file where the Verilog output will be written.
627639 :param add_reset: If reset logic should be added. Allowable options are: ``False``
@@ -633,13 +645,6 @@ def output_to_verilog(dest_file, add_reset: typing.Union[bool, str] = True,
633645 When this argument is ``True``, a register like ``Register(name='foo',
634646 bitwidth=8, reset_value=4)`` generates Verilog like ``reg[7:0] foo = 8'd4;``.
635647 :param block: Block to be walked and exported. Defaults to the :ref:`working_block`.
636-
637- The Verilog module will be named ``toplevel``, with a clock input named ``clk``.
638-
639- When possible, wires keep their names in the Verilog output. Wire names that do not
640- satisfy Verilog's naming requirements, and wires that conflict with Verilog keywords
641- are given new temporary names in the Verilog output.
642-
643648 """
644649
645650 if not isinstance (add_reset , bool ):
@@ -906,39 +911,12 @@ def _to_verilog_footer(file):
906911
907912
908913def output_verilog_testbench (
909- dest_file , simulation_trace = None , toplevel_include : str = None ,
910- vcd : str = "waveform.vcd" , cmd : str = None ,
911- add_reset : typing .Union [bool , str ] = True , block : Block = None ):
912- """Output a Verilog testbench for the block/inputs used in the simulation
913- trace.
914-
915- :param dest_file: an open file to which the test bench will be printed.
916- :param SimulationTrace simulation_trace: a simulation trace from which the inputs
917- will be extracted for inclusion in the test bench. The test bench generated will
918- just replay the inputs played to the simulation cycle by cycle. The default
919- values for all registers and memories will be based on the trace, otherwise they
920- will be initialized to 0.
921- :param toplevel_include: name of the file containing the toplevel module this
922- testbench is testing. If not ``None``, an `include` directive will be added to
923- the top.
924- :param vcd: By default the testbench generator will include a command in the
925- testbench to write the output of the testbench execution to a ``.vcd`` file (via
926- `$dumpfile`), and this parameter is the name of the file to write. If ``None``
927- is specified, then no `dumpfile` will be used.
928- :param cmd: The string passed as ``cmd`` will be copied verbatim into the testbench
929- just before the end of each cycle. This is useful for doing things like printing
930- specific values during testbench evaluation. For example, ``cmd='$display("%d",
931- out);'`` will instruct the testbench to print the value of `out` every cycle,
932- which can be compared with a reference.
933- :param add_reset: If reset logic should be added. Allowable options are: ``False``
934- (meaning no reset logic is added), ``True`` (default, for adding synchronous
935- reset logic), and ``'asynchronous'`` (for adding asynchronous reset logic). The
936- value passed in here should match the argument passed to
937- :func:`output_to_verilog`.
914+ dest_file , simulation_trace : SimulationTrace = None ,
915+ toplevel_include : str = None , vcd : str = "waveform.vcd" , cmd : str = None ,
916+ add_reset : Union [bool , str ] = True , block : Block = None ):
917+ """Output a Verilog testbench for the block/inputs used in the simulation trace.
938918
939- :param block: Block containing design to test. Defaults to the :ref:`working_block`.
940-
941- If ``add_reset`` is not False, a ``rst`` input wire is added to the instantiated
919+ If ``add_reset`` is ``True``, a ``rst`` input wire is added to the instantiated
942920 ``toplevel`` module. The ``rst`` wire will be held low in the testbench, because
943921 initialization here occurs via the ``initial`` block. ``add_reset`` is provided for
944922 consistency with :func:`output_to_verilog`.
@@ -949,17 +927,44 @@ def output_verilog_testbench(
949927
950928 The test bench does not return any values.
951929
952- Example 1 ( writing testbench to a string) ::
930+ Example 1, writing testbench to a string::
953931
954932 with io.StringIO() as tbfile:
955933 pyrtl.output_verilog_testbench(dest_file=tbfile, simulation_trace=sim_trace)
956934
957- Example 2 ( testbench in same file as verilog) ::
935+ Example 2, testbench in same file as Verilog ::
958936
959937 with open('hardware.v', 'w') as fp:
960938 output_to_verilog(fp)
961939 output_verilog_testbench(fp, sim.tracer, vcd=None, cmd='$display("%d", out);')
962940
941+ :param dest_file: An open file to which the test bench will be printed.
942+ :param simulation_trace: A trace from which the inputs will be extracted for
943+ inclusion in the test bench. This is typically :attr:`Simulation.tracer`. The
944+ generated test bench will replay the :class:`Simulation`'s
945+ :class:`Inputs<Input>` cycle by cycle. The default values for all registers and
946+ memories will be based on the trace, otherwise they will be initialized to 0.
947+ :param toplevel_include: Name of the file containing the ``toplevel`` module this
948+ testbench is testing. If not ``None``, an ``include`` directive will be added
949+ for this file.
950+ :param vcd: By default, the testbench generator will generate a command to write the
951+ output of the testbench execution to a ``.vcd`` file, via ``$dumpfile``, and
952+ ``vcd`` is the name of the file to write. If ``None``, then no ``dumpfile`` will
953+ be used.
954+ :param cmd: The string passed as ``cmd`` will be copied verbatim into the testbench
955+ just before the end of each cycle. This is useful for doing things like printing
956+ specific values during testbench evaluation. For example::
957+
958+ cmd='$display("%d", out);'
959+
960+ will instruct the testbench to print the value of ``out`` every cycle.
961+
962+ :param add_reset: If reset logic should be added. Allowable options are: ``False``
963+ (meaning no reset logic is added), ``True`` (default, for adding synchronous
964+ reset logic), and ``'asynchronous'`` (for adding asynchronous reset logic). The
965+ value passed in here should match the argument passed to
966+ :func:`output_to_verilog`.
967+ :param block: Block containing design to test. Defaults to the :ref:`working_block`.
963968 """
964969 if not isinstance (add_reset , bool ):
965970 if add_reset != 'asynchronous' :
@@ -1103,13 +1108,12 @@ def default_value():
11031108def output_to_firrtl (open_file , rom_blocks : list [RomBlock ] = None , block : Block = None ):
11041109 """Output the block as FIRRTL code to the output file.
11051110
1106- :param open_file: File to write to.
1107- :param rom_blocks: List of ROM blocks to be initialized.
1108- :param block: Block to use (defaults to :ref:`working_block`).
1109-
1110- If ROM is initialized in PyRTL code, you can pass in the ``rom_blocks`` as a
1111+ If ROM is initialized in PyRTL code, you can pass in the :class:`RomBlocks` as a
11111112 list ``[rom1, rom2, ...]``.
11121113
1114+ :param open_file: File to write to.
1115+ :param rom_blocks: List of :class:`RomBlocks<RomBlock>` to be initialized.
1116+ :param block: Block to use (defaults to :ref:`working_block`).
11131117 """
11141118 block = working_block (block )
11151119
0 commit comments