From 449135a9d4c1817611bbf3edf8e887bc9ae6b485 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:29:40 +1300 Subject: [PATCH] Docs: adding other macro command lists Also updates `macro_commands.py` to skip empty lines, and moves comment stripping earlier in parsing. --- .../code_examples/macro_commands/fsm.ys | 27 ++++++ .../code_examples/macro_commands/memory.ys | 15 +++ .../code_examples/macro_commands/proc.ys | 14 +++ docs/source/using_yosys/synthesis/fsm.rst | 95 ++++--------------- docs/source/using_yosys/synthesis/memory.rst | 23 +++-- docs/source/using_yosys/synthesis/proc.rst | 21 ++-- docs/source/using_yosys/synthesis/synth.rst | 3 +- docs/tests/macro_commands.py | 15 ++- 8 files changed, 111 insertions(+), 102 deletions(-) create mode 100644 docs/source/code_examples/macro_commands/fsm.ys create mode 100644 docs/source/code_examples/macro_commands/memory.ys create mode 100644 docs/source/code_examples/macro_commands/proc.ys diff --git a/docs/source/code_examples/macro_commands/fsm.ys b/docs/source/code_examples/macro_commands/fsm.ys new file mode 100644 index 000000000..627df1209 --- /dev/null +++ b/docs/source/code_examples/macro_commands/fsm.ys @@ -0,0 +1,27 @@ +#start:It also calls opt_clean as needed: +#end:Options: +# Identify and extract FSMs: +fsm_detect +fsm_extract + +# Basic optimizations: +fsm_opt +opt_clean +fsm_opt + +# Expanding to nearby gate-logic (if called with -expand): +fsm_expand +opt_clean +fsm_opt + +# Re-code FSM states (unless called with -norecode): +fsm_recode + +# Print information about FSMs: +fsm_info + +# Export FSMs in KISS2 file format (if called with -export): +fsm_export + +# Map FSMs to RTL cells (unless called with -nomap): +fsm_map diff --git a/docs/source/code_examples/macro_commands/memory.ys b/docs/source/code_examples/macro_commands/memory.ys new file mode 100644 index 000000000..ea4800a1c --- /dev/null +++ b/docs/source/code_examples/macro_commands/memory.ys @@ -0,0 +1,15 @@ +#start:passes in a useful order: +#end:This converts memories to word-wide DFFs and address decoders +opt_mem +opt_mem_priority +opt_mem_feedback +memory_bmux2rom +memory_dff +opt_clean +memory_share +opt_mem_widen +memory_memx (when called with -memx) +opt_clean +memory_collect +memory_bram -rules <bram_rules> (when called with -bram) +memory_map (skipped if called with -nomap) diff --git a/docs/source/code_examples/macro_commands/proc.ys b/docs/source/code_examples/macro_commands/proc.ys new file mode 100644 index 000000000..7a78ce0c6 --- /dev/null +++ b/docs/source/code_examples/macro_commands/proc.ys @@ -0,0 +1,14 @@ +#start: passes in the most common order. +#end: This replaces the processes +proc_clean # removes empty branches and processes +proc_rmdead # removes unreachable branches +proc_prune +proc_init # special handling of “initial” blocks +proc_arst # identifies modeling of async resets +proc_rom +proc_mux # converts decision trees to multiplexer networks +proc_dlatch +proc_dff # extracts registers from processes +proc_memwr +proc_clean # this should remove all the processes, provided all went fine +opt_expr -keepdc diff --git a/docs/source/using_yosys/synthesis/fsm.rst b/docs/source/using_yosys/synthesis/fsm.rst index 11da17eba..e1ed55133 100644 --- a/docs/source/using_yosys/synthesis/fsm.rst +++ b/docs/source/using_yosys/synthesis/fsm.rst @@ -5,79 +5,22 @@ The :cmd:ref:`fsm` command identifies, extracts, optimizes (re-encodes), and re-synthesizes finite state machines. It again is a macro that calls a series of other commands: -#. :cmd:ref:`fsm_detect` identifies FSM state registers and marks them - with the ``(* fsm_encoding = "auto" *)`` attribute, if they do not have the - ``fsm_encoding`` set already. Mark registers with ``(* fsm_encoding = "none" - *)`` to disable FSM optimization for a register. -#. :cmd:ref:`fsm_extract` replaces the entire FSM (logic and state registers) - with a ``$fsm`` cell. -#. :cmd:ref:`fsm_opt` optimizes the FSM. Called multiple times. -#. :cmd:ref:`fsm_expand` optionally merges additional auxilliary gates into the - ``$fsm`` cell. -#. :cmd:ref:`fsm_recode` also optimizes the FSM. -#. :cmd:ref:`fsm_info` logs internal FSM information. -#. :cmd:ref:`fsm_export` optionally exports each FSM to KISS2 files. -#. :cmd:ref:`fsm_map` converts the (optimized) ``$fsm`` cell back to logic and - registers. +.. literalinclude:: /code_examples/macro_commands/fsm.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`fsm` See also :doc:`/cmd/fsm`. -The fsm pass performs finite-state-machine (FSM) extraction and recoding. The -fsm pass simply executes the following other passes: - -- Identify and extract FSMs: - - - fsm_detect - - fsm_extract - -- Basic optimizations: - - - fsm_opt - - opt_clean - - fsm_opt - -- Expanding to nearby gate-logic (if called with -expand): - - - fsm_expand - - opt_clean - - fsm_opt - -- Re-code FSM states (unless called with -norecode): - - - fsm_recode - -- Print information about FSMs: - - - fsm_info - -- Export FSMs in KISS2 file format (if called with -export): - - - fsm_export - -- Map FSMs to RTL cells (unless called with -nomap): - - - fsm_map - -The fsm_detect pass identifies FSM state registers and marks them using the -``\fsm_encoding = "auto"`` attribute. The fsm_extract extracts all FSMs marked -using the ``\fsm_encoding`` attribute (unless ``\fsm_encoding`` is set to -"none") and replaces the corresponding RTL cells with a ``$fsm`` cell. All other -``fsm_`` passes operate on these ``$fsm`` cells. The fsm_map call finally -replaces the ``$fsm`` cells with RTL cells. - -Note that these optimizations operate on an RTL netlist. I.e. the :cmd:ref:`fsm` -pass should be executed after the proc pass has transformed all -``RTLIL::Process`` objects to RTL cells. - The algorithms used for FSM detection and extraction are influenced by a more general reported technique :cite:p:`fsmextract`. FSM detection ~~~~~~~~~~~~~ -The fsm_detect pass identifies FSM state registers. It sets the ``\fsm_encoding -= "auto"`` attribute on any (multi-bit) wire that matches the following -description: +The :cmd:ref:`fsm_detect` pass identifies FSM state registers. It sets the +``\fsm_encoding = "auto"`` attribute on any (multi-bit) wire that matches the +following description: - Does not already have the ``\fsm_encoding`` attribute. - Is not an output of the containing module. @@ -101,7 +44,7 @@ results. FSM extraction ~~~~~~~~~~~~~~ -The fsm_extract pass operates on all state signals marked with the +The :cmd:ref:`fsm_extract` pass operates on all state signals marked with the (``\fsm_encoding != "none"``) attribute. For each state signal the following information is determined: @@ -142,8 +85,8 @@ given set of result signals using a set of signal-value assignments. It can also be passed a list of stop-signals that abort the ConstEval algorithm if the value of a stop-signal is needed in order to calculate the result signals. -The fsm_extract pass uses the ConstEval class in the following way to create a -transition table. For each state: +The :cmd:ref:`fsm_extract` pass uses the ConstEval class in the following way to +create a transition table. For each state: 1. Create a ConstEval object for the module containing the FSM 2. Add all control inputs to the list of stop signals @@ -163,8 +106,9 @@ drivers for the control outputs are disconnected. FSM optimization ~~~~~~~~~~~~~~~~ -The fsm_opt pass performs basic optimizations on ``$fsm`` cells (not including -state recoding). The following optimizations are performed (in this order): +The :cmd:ref:`fsm_opt` pass performs basic optimizations on ``$fsm`` cells (not +including state recoding). The following optimizations are performed (in this +order): - Unused control outputs are removed from the ``$fsm`` cell. The attribute ``\unused_bits`` (that is usually set by the :cmd:ref:`opt_clean` pass) is @@ -188,10 +132,11 @@ state recoding). The following optimizations are performed (in this order): FSM recoding ~~~~~~~~~~~~ -The fsm_recode pass assigns new bit pattern to the states. Usually this also -implies a change in the width of the state signal. At the moment of this writing -only one-hot encoding with all-zero for the reset state is supported. +The :cmd:ref:`fsm_recode` pass assigns new bit pattern to the states. Usually +this also implies a change in the width of the state signal. At the moment of +this writing only one-hot encoding with all-zero for the reset state is +supported. -The fsm_recode pass can also write a text file with the changes performed by it -that can be used when verifying designs synthesized by Yosys using Synopsys -Formality. +The :cmd:ref:`fsm_recode` pass can also write a text file with the changes +performed by it that can be used when verifying designs synthesized by Yosys +using Synopsys Formality. diff --git a/docs/source/using_yosys/synthesis/memory.rst b/docs/source/using_yosys/synthesis/memory.rst index 71da211d5..f2bfe9650 100644 --- a/docs/source/using_yosys/synthesis/memory.rst +++ b/docs/source/using_yosys/synthesis/memory.rst @@ -7,19 +7,22 @@ The :cmd:ref:`memory` command In the RTL netlist, memory reads and writes are individual cells. This makes consolidating the number of ports for a memory easier. The :cmd:ref:`memory` pass transforms memories to an implementation. Per default that is logic for -address decoders and registers. It also is a macro command that the other common -``memory_*`` commands in a sensible order: +address decoders and registers. It also is a macro command that calls the other +common ``memory_*`` passes in a sensible order: -.. todo:: fill out missing :cmd:ref:`memory` subcommands descriptions +.. literalinclude:: /code_examples/macro_commands/memory.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`memory` -#. :cmd:ref:`memory_bmux2rom` -#. :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. -#. :cmd:ref:`memory_share` -#. :cmd:ref:`memory_memx` -#. :cmd:ref:`memory_collect` collects all read and write cells for a memory and +.. todo:: Make ``memory_*`` notes less quick + +Some quick notes: + +- :cmd:ref:`memory_dff` merges registers into the memory read- and write cells. +- :cmd:ref:`memory_collect` collects all read and write cells for a memory and transforms them into one multi-port memory cell. -#. :cmd:ref:`memory_bram` -#. :cmd:ref:`memory_map` takes the multi-port memory cell and transforms it to +- :cmd:ref:`memory_map` takes the multi-port memory cell and transforms it to address decoder logic and registers. For more information about :cmd:ref:`memory`, such as disabling certain sub diff --git a/docs/source/using_yosys/synthesis/proc.rst b/docs/source/using_yosys/synthesis/proc.rst index 498e1264a..265930c8c 100644 --- a/docs/source/using_yosys/synthesis/proc.rst +++ b/docs/source/using_yosys/synthesis/proc.rst @@ -1,26 +1,21 @@ Converting process blocks ~~~~~~~~~~~~~~~~~~~~~~~~~ +.. role:: yoscrypt(code) + :language: yoscrypt + The Verilog frontend converts ``always``-blocks to RTL netlists for the expressions and "processess" for the control- and memory elements. The :cmd:ref:`proc` command then transforms these "processess" to netlists of RTL multiplexer and register cells. It also is a macro command that calls the other ``proc_*`` commands in a sensible order: -#. :cmd:ref:`proc_clean` removes empty branches and processes. -#. :cmd:ref:`proc_rmdead` removes unreachable branches. -#. :cmd:ref:`proc_prune` -#. :cmd:ref:`proc_init` special handling of "initial" blocks. -#. :cmd:ref:`proc_arst` identifies modeling of async resets. -#. :cmd:ref:`proc_rom` -#. :cmd:ref:`proc_mux` converts decision trees to multiplexer networks. -#. :cmd:ref:`proc_dlatch` -#. :cmd:ref:`proc_dff` extracts registers from processes. -#. :cmd:ref:`proc_memwr` -#. :cmd:ref:`proc_clean` this should remove all the processes, provided all went - fine. +.. literalinclude:: /code_examples/macro_commands/proc.ys + :language: yoscrypt + :start-after: #end: + :caption: Passes called by :cmd:ref:`proc` -After all the ``proc_*`` commands, :yoscrypt:`opt_expr` is called. This can be +After all the ``proc_*`` commands, :cmd:ref:`opt_expr` is called. This can be disabled by calling :yoscrypt:`proc -noopt`. For more information about :cmd:ref:`proc`, such as disabling certain sub commands, see :doc:`/cmd/proc`. diff --git a/docs/source/using_yosys/synthesis/synth.rst b/docs/source/using_yosys/synthesis/synth.rst index c9ec45b8a..15d701fb4 100644 --- a/docs/source/using_yosys/synthesis/synth.rst +++ b/docs/source/using_yosys/synthesis/synth.rst @@ -43,4 +43,5 @@ The following commands are executed by the :cmd:ref:`prep` command: :end-before: .. raw:: latex :dedent: -The following sections will get more into what each of these commands do. +:doc:`/getting_started/example_synth` covers most of these commands and what +they do. diff --git a/docs/tests/macro_commands.py b/docs/tests/macro_commands.py index 7942e4d31..faf2baa53 100755 --- a/docs/tests/macro_commands.py +++ b/docs/tests/macro_commands.py @@ -35,7 +35,12 @@ for macro in MACRO_SOURCE.glob("*.ys"): # immediately after. start = f.readline() end = f.readline() - expected_content = f.readlines() + file_content = f.readlines() + expected_content = [] + for line in file_content: + line = line.split("#")[0].strip() + if line: + expected_content.append(line) # parse {command.ys} if "#start:" not in start or "#end:" not in end: logging.error(f"Missing start and/or end string in {relative_path}, see {THIS_FILE}") @@ -49,7 +54,11 @@ for macro in MACRO_SOURCE.glob("*.ys"): logging.error(f"Couldn't find {start!r} and/or {end!r} in `yosys -h {command}` output") raise_error = True continue - actual_content = match.group(1).strip().splitlines() + match_content = match.group(1).strip().splitlines() + actual_content = [] + for line in match_content: + if line: + actual_content.append(line) # iterate over and compare expected v actual for (expected, actual) in zip(expected_content, actual_content): expected = expected.strip() @@ -59,7 +68,7 @@ for macro in MACRO_SOURCE.glob("*.ys"): continue # rip apart formatting to match line parts - pattern = r"(?P<cmd>\S+)(?P<pass> \[.*\])?(?P<opt>.*?)(?P<cond> \(.*\))?(?P<comment>\s+#.*)?" + pattern = r"(?P<cmd>\S+)(?P<pass> \[.*\])?(?P<opt>.*?)(?P<cond>\s+\(.*\))?" try: expected_dict = re.fullmatch(pattern, expected).groupdict() except AttributeError: