3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-07-27 14:37:55 +00:00

Revert "Add groups to command reference"

This commit is contained in:
N. Engelhardt 2025-07-23 14:41:49 +00:00 committed by GitHub
parent 2223d7848b
commit 81f87ce6ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
124 changed files with 474 additions and 2035 deletions

1
docs/.gitignore vendored
View file

@ -1,4 +1,5 @@
/build/
/source/cmd
/source/generated
/source/_images/**/*.log
/source/_images/**/*.aux

View file

@ -47,7 +47,7 @@ help:
.PHONY: clean
clean: clean-examples
rm -rf $(BUILDDIR)/*
rm -rf util/__pycache__
rm -rf source/cmd util/__pycache__
rm -rf source/generated
$(MAKE) -C source/_images clean

View file

@ -18,8 +18,3 @@
.literal-block-wrapper .code-block-caption .caption-number {
padding-right: 0.5em
}
/* Don't double shrink text in a literal in an optionlist */
kbd .option>.literal {
font-size: revert;
}

View file

@ -29,7 +29,8 @@ ezSAT
The files in ``libs/ezsat`` provide a library for simplifying generating CNF
formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT
library is written by C. Wolf. It is used by the `sat` pass.
library is written by C. Wolf. It is used by the `sat` pass (see
:doc:`/cmd/sat`).
fst
---
@ -77,4 +78,4 @@ SubCircuit
The files in ``libs/subcircuit`` provide a library for solving the subcircuit
isomorphism problem. It is written by C. Wolf and based on the Ullmann Subgraph
Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the
`extract` pass.
extract pass (see :doc:`../cmd/extract`).

View file

@ -1,5 +0,0 @@
Writing output files
--------------------
.. autocmdgroup:: backends
:members:

View file

@ -1,5 +0,0 @@
Formal verification
-------------------
.. autocmdgroup:: formal
:members:

View file

@ -1,5 +0,0 @@
Reading input files
-------------------
.. autocmdgroup:: frontends
:members:

View file

@ -1,152 +0,0 @@
Internal commands for developers
--------------------------------
.. autocmdgroup:: internal
:members:
Writing command help
--------------------
- use `chformal` as an example
- generated help content below
.. _chformal autocmd:
.. autocmd:: chformal
:noindex:
The ``formatted_help()`` method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``PrettyHelp::get_current()``
- ``PrettyHelp::set_group()``
+ used with ``.. autocmdgroup:: <group>``
+ can assign group and return false
+ if no group is set, will try to use ``source_location`` and assign group
from path to source file
- return value
+ true means help content added to current ``PrettyHelp``
+ false to use ``Pass::help()``
- adding content
+ help content is a list of ``ContentListing`` nodes, each one having a type,
body, and its own list of children ``ContentListing``\ s
+ ``PrettyHelp::get_root()`` returns the root ``ContentListing`` (``type="root"``)
+ ``ContentListing::{usage, option, codeblock, paragraph}`` each add a
``ContentListing`` to the current node, with type the same as the method
* the first argument is the body of the new node
* ``usage`` shows how to call the command (i.e. its "signature")
* ``paragraph`` content is formatted as a paragraph of text with line breaks
added automatically
* ``codeblock`` content is displayed verbatim, use line breaks as desired;
takes an optional ``language`` argument for assigning the language in RST
output for code syntax highlighting (use ``yoscrypt`` for yosys script
syntax highlighting)
* ``option`` lists a single option for the command, usually starting with a
dash (``-``); takes an optional second argument which adds a paragraph
node as a means of description
+ ``ContentListing::open_usage`` creates and returns a new usage node, can be
used to e.g. add text/options specific to a given usage of the command
+ ``ContentListing::open_option`` creates and returns a new option node, can
be used to e.g. add multiple paragraphs to an option's description
+ paragraphs are treated as raw RST, allowing for inline formatting and
references as if it were written in the RST file itself
.. literalinclude:: /generated/chformal.cc
:language: c++
:start-at: bool formatted_help()
:end-before: void execute
:caption: ``ChformalPass::formatted_help()`` from :file:`passes/cmds/chformal.cc`
Dumping command help to json
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- `help -dump-cells-json cmds.json`
+ generates a ``ContentListing`` for each command registered in Yosys
+ tries to parse unformatted ``Pass::help()`` output if
``Pass::formatted_help()`` is unimplemented or returns false
* if a line starts with four spaces followed by the name of the command then
a space, it is parsed as a signature (usage node)
* if a line is indented and starts with a dash (``-``), it is parsed as an
option
* anything else is parsed as a codeblock and added to either the root node
or the current option depending on the indentation
+ dictionary of command name to ``ContentListing``
* uses ``ContentListing::to_json()`` recursively for each node in root
* root node used for source location of class definition
* includes flags set during pass constructor (e.g. ``experimental_flag`` set
by ``Pass::experimental()``)
* also title (``short_help`` argument in ``Pass::Pass``), group, and class
name
+ dictionary of group name to list of commands in that group
- used by sphinx autodoc to generate help content
.. literalinclude:: /generated/cmds.json
:language: json
:start-at: "chformal": {
:end-before: "chparam": {
:caption: `chformal` in generated :file:`cmds.json`
.. note:: Synthesis command scripts are special cased
If the final block of help output starts with the string `"The following
commands are executed by this synthesis command:\n"`, then the rest of the
code block is formatted as ``yoscrypt`` (e.g. `synth_ice40`). The caveat
here is that if the ``script()`` calls ``run()`` on any commands *prior* to
the first ``check_label`` then the auto detection will break and revert to
unformatted code (e.g. `synth_fabulous`).
Command line rendering
~~~~~~~~~~~~~~~~~~~~~~
- if ``Pass::formatted_help()`` returns true, will call
``PrettyHelp::log_help()``
+ traverse over the children of the root node and render as plain text
+ effectively the reverse of converting unformatted ``Pass::help()`` text
+ lines are broken at 80 characters while maintaining indentation (controlled
by ``MAX_LINE_LEN`` in :file:`kernel/log_help.cc`)
+ each line is broken into words separated by spaces, if a given word starts
and ends with backticks they will be stripped
- if it returns false it will call ``Pass::help()`` which should call ``log()``
directly to print and format help text
+ if ``Pass::help()`` is not overridden then a default message about missing
help will be displayed
.. literalinclude:: /generated/chformal.log
:lines: 2-
RST generated from autocmd
~~~~~~~~~~~~~~~~~~~~~~~~~~
- below is the raw RST output from ``autocmd`` (``YosysCmdDocumenter`` class in
:file:`docs/util/cmd_documenter.py`) for `chformal` command
- heading will be rendered as a subheading of the most recent heading (see
`chformal autocmd`_ above rendered under `Writing command help`_)
- ``.. cmd:def:: <cmd>`` line is indexed for cross references with ``:cmd:ref:``
directive (`chformal autocmd`_ above uses ``:noindex:`` option so that
`chformal` still links to the correct location)
+ ``:title:`` option controls text that appears when hovering over the
`chformal` link
- commands with warning flags (experimental or internal) add a ``.. warning``
block before any of the help content
- if a command has no ``source_location`` the ``.. note`` at the bottom will
instead link to :doc:`/cmd/index_other`
.. autocmd_rst:: chformal

View file

@ -1,5 +0,0 @@
Yosys kernel commands
---------------------
.. autocmdgroup:: kernel
:members:

View file

@ -1,9 +0,0 @@
:orphan:
Other commands
==============
Unknown source location
.. autocmdgroup:: unknown
:members:

View file

@ -1,14 +0,0 @@
Passes
------
.. toctree::
:maxdepth: 2
:glob:
/cmd/index_passes_hierarchy
/cmd/index_passes_proc
/cmd/index_passes_fsm
/cmd/index_passes_memory
/cmd/index_passes_opt
/cmd/index_passes_techmap
/cmd/index_passes_*

View file

@ -1,5 +0,0 @@
Design modification
-------------------
.. autocmdgroup:: passes/cmds
:members:

View file

@ -1,5 +0,0 @@
Equivalence checking
--------------------
.. autocmdgroup:: passes/equiv
:members:

View file

@ -1,5 +0,0 @@
FSM handling
------------
.. autocmdgroup:: passes/fsm
:members:

View file

@ -1,5 +0,0 @@
Working with hierarchy
----------------------
.. autocmdgroup:: passes/hierarchy
:members:

View file

@ -1,5 +0,0 @@
Memory handling
---------------
.. autocmdgroup:: passes/memory
:members:

View file

@ -1,5 +0,0 @@
Optimization passes
-------------------
.. autocmdgroup:: passes/opt
:members:

View file

@ -1,5 +0,0 @@
Converting process blocks
-------------------------
.. autocmdgroup:: passes/proc
:members:

View file

@ -1,5 +0,0 @@
Simulating circuits
-------------------
.. autocmdgroup:: passes/sat
:members:

View file

@ -1,5 +0,0 @@
Design status
-------------
.. autocmdgroup:: passes/status
:members:

View file

@ -1,7 +0,0 @@
Technology mapping
------------------
.. seealso:: :doc:`/cmd/index_techlibs`
.. autocmdgroup:: passes/techmap
:members:

View file

@ -1,11 +0,0 @@
Technology libraries
====================
Listed in alphabetical order.
.. toctree::
:maxdepth: 2
:glob:
/cmd/index_techlibs_common
/cmd/index_techlibs_*

View file

@ -1,5 +0,0 @@
Achronix
------------------
.. autocmdgroup:: techlibs/achronix
:members:

View file

@ -1,5 +0,0 @@
Anlogic
------------------
.. autocmdgroup:: techlibs/anlogic
:members:

View file

@ -1,5 +0,0 @@
Generic
------------------
.. autocmdgroup:: techlibs/common
:members:

View file

@ -1,5 +0,0 @@
CoolRunner-II
------------------
.. autocmdgroup:: techlibs/coolrunner2
:members:

View file

@ -1,5 +0,0 @@
eASIC
------------------
.. autocmdgroup:: techlibs/easic
:members:

View file

@ -1,5 +0,0 @@
ECP5
------------------
.. autocmdgroup:: techlibs/ecp5
:members:

View file

@ -1,5 +0,0 @@
FABulous
------------------
.. autocmdgroup:: techlibs/fabulous
:members:

View file

@ -1,5 +0,0 @@
Gatemate
------------------
.. autocmdgroup:: techlibs/gatemate
:members:

View file

@ -1,5 +0,0 @@
Gowin
------------------
.. autocmdgroup:: techlibs/gowin
:members:

View file

@ -1,5 +0,0 @@
GreenPAK4
------------------
.. autocmdgroup:: techlibs/greenpak4
:members:

View file

@ -1,5 +0,0 @@
iCE40
------------------
.. autocmdgroup:: techlibs/ice40
:members:

View file

@ -1,5 +0,0 @@
Intel (MAX10, Cyclone IV)
-------------------------
.. autocmdgroup:: techlibs/intel
:members:

View file

@ -1,5 +0,0 @@
Intel ALM (Cyclone V, Arria V, Cyclone 10 GX)
---------------------------------------------
.. autocmdgroup:: techlibs/intel_alm
:members:

View file

@ -1,5 +0,0 @@
Lattice
------------------
.. autocmdgroup:: techlibs/lattice
:members:

View file

@ -1,5 +0,0 @@
Lattice Nexus
------------------
.. autocmdgroup:: techlibs/nexus
:members:

View file

@ -1,5 +0,0 @@
Microchip
------------------
.. autocmdgroup:: techlibs/microchip
:members:

View file

@ -1,5 +0,0 @@
Microchip - SmartFusion2/IGLOO2
-----------------------------------
.. autocmdgroup:: techlibs/sf2
:members:

View file

@ -1,5 +0,0 @@
NanoXplore
------------------
.. autocmdgroup:: techlibs/nanoxplore
:members:

View file

@ -1,5 +0,0 @@
QuickLogic
------------------
.. autocmdgroup:: techlibs/quicklogic
:members:

View file

@ -1,5 +0,0 @@
Xilinx
------------------
.. autocmdgroup:: techlibs/xilinx
:members:

View file

@ -1,3 +1,5 @@
.. _cmd_ref:
================================================================================
Command line reference
================================================================================
@ -5,31 +7,10 @@ Command line reference
.. literalinclude:: /generated/yosys
:start-at: Usage
.. _cmd_ref:
Command reference
-----------------
.. todo:: Can we warn on command groups that aren't included anywhere?
:ref:`List of all commands<cmd-cmd>`
.. toctree::
:maxdepth: 2
:caption: Command reference
:maxdepth: 1
:glob:
/appendix/env_vars
/cmd/index_frontends
/cmd/index_backends
/cmd/index_kernel
/cmd/index_formal
.. toctree::
:maxdepth: 3
/cmd/index_passes
/cmd/index_techlibs
.. toctree::
:maxdepth: 2
/cmd/index_internal
/appendix/env_vars
/cmd/*

View file

@ -1,23 +0,0 @@
#start:The following commands are executed by this synthesis command:
#end:$
begin:
hierarchy -check [-top <top> | -auto-top]
coarse:
proc [-ifx]
flatten (if -flatten)
future
opt_expr -keepdc
opt_clean
check
opt -noff -keepdc
wreduce -keepdc [-memx]
memory_dff (if -rdff)
memory_memx (if -memx)
opt_clean
memory_collect
opt -noff -keepdc -fast
check:
stat
check

View file

@ -43,12 +43,8 @@ html_static_path = ['_static', "_images"]
# default to no highlight
highlight_language = 'none'
# default single quotes to attempt auto reference, or fallback to yoscrypt
# default single quotes to attempt auto reference, or fallback to code
default_role = 'autoref'
rst_prolog = """
.. role:: yoscrypt(code)
:language: yoscrypt
"""
extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex']
@ -110,14 +106,12 @@ latex_elements = {
# custom cmd-ref parsing/linking
sys.path += [os.path.dirname(__file__) + "/../"]
extensions.append('util.custom_directives')
extensions.append('util.cmdref')
# use autodocs
extensions.append('sphinx.ext.autodoc')
extensions.append('util.cell_documenter')
extensions.append('util.cellref')
cells_json = Path(__file__).parent / 'generated' / 'cells.json'
extensions.append('util.cmd_documenter')
cmds_json = Path(__file__).parent / 'generated' / 'cmds.json'
from sphinx.application import Sphinx
def setup(app: Sphinx) -> None:

View file

@ -70,7 +70,7 @@ At the bottom of the `help` output for
`synth_ice40` is the complete list of commands called by this script.
Let's start with the section labeled ``begin``:
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: begin:
:end-before: flatten:
@ -143,8 +143,8 @@ line refers to the line numbers of the start/end of the corresponding ``always
@`` block. In the case of an ``initial`` block, we instead see the ``PROC``
referring to line 0.
To handle these, let us now introduce the next command: :cmd:title:`proc`.
`proc` is a macro command like `synth_ice40`. Rather than modifying the design
To handle these, let us now introduce the next command: :doc:`/cmd/proc`. `proc`
is a macro command like `synth_ice40`. Rather than modifying the design
directly, it instead calls a series of other commands. In the case of `proc`,
these sub-commands work to convert the behavioral logic of processes into
multiplexers and registers. Let's see what happens when we run it. For now, we
@ -188,7 +188,7 @@ opt_expr <adv_opt_expr>`.
.. note::
:cmd:title:`clean` can also be called with two semicolons after any command,
:doc:`/cmd/clean` can also be called with two semicolons after any command,
for example we could have called :yoscrypt:`opt_expr;;` instead of
:yoscrypt:`opt_expr; clean`. You may notice some scripts will end each line
with ``;;``. It is beneficial to run `clean` before inspecting intermediate
@ -215,8 +215,8 @@ Note that if we tried to run this command now then we would get an error. This
is because we already removed all of the modules other than ``addr_gen``. We
could restart our shell session, but instead let's use two new commands:
- :cmd:title:`design`, and
- :cmd:title:`read_verilog`.
- :doc:`/cmd/design`, and
- :doc:`/cmd/read_verilog`.
.. literalinclude:: /code_examples/fifo/fifo.out
:language: doscon
@ -251,7 +251,7 @@ our design won't run into this issue, we can skip the ``-defer``.
We can also run `proc` now to finish off the full :ref:`synth_begin`. Because
the design schematic is quite large, we will be showing just the data path for
the ``rdata`` output. If you would like to see the entire design for yourself,
you can do so with :cmd:title:`show`. Note that the `show` command only works
you can do so with :doc:`/cmd/show`. Note that the `show` command only works
with a single module, so you may need to call it with :yoscrypt:`show fifo`.
:ref:`show_intro` section in :doc:`/getting_started/scripting_intro` has more on
how to use `show`.
@ -283,7 +283,7 @@ Flattening
At this stage of a synthesis flow there are a few other commands we could run.
In `synth_ice40` we get these:
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: flatten:
:end-before: coarse:
@ -355,7 +355,7 @@ Part 1
In the iCE40 flow, we start with the following commands:
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: coarse:
:end-before: wreduce
@ -371,7 +371,7 @@ wasting time on something we know is impossible.
Next up is :yoscrypt:`opt -nodffe -nosdff` performing a set of simple
optimizations on the design. This command also ensures that only a specific
subset of FF types are included, in preparation for the next command:
:cmd:title:`fsm`. Both `opt` and `fsm` are macro commands which are explored in
:doc:`/cmd/fsm`. Both `opt` and `fsm` are macro commands which are explored in
more detail in :doc:`/using_yosys/synthesis/opt` and
:doc:`/using_yosys/synthesis/fsm` respectively.
@ -403,7 +403,7 @@ Part 2
The next group of commands performs a series of optimizations:
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-at: wreduce
:end-before: t:$mul
@ -411,7 +411,7 @@ The next group of commands performs a series of optimizations:
:caption: ``coarse`` section (part 2)
:name: synth_coarse2
First up is :cmd:title:`wreduce`. If we run this we get the following:
First up is :doc:`/cmd/wreduce`. If we run this we get the following:
.. literalinclude:: /code_examples/fifo/fifo.out
:language: doscon
@ -432,7 +432,7 @@ the schematic and see the output of that cell has now changed.
``rdata`` output after `wreduce`
The next two (new) commands are :cmd:title:`peepopt` and :cmd:title:`share`.
The next two (new) commands are :doc:`/cmd/peepopt` and :doc:`/cmd/share`.
Neither of these affect our design, and they're explored in more detail in
:doc:`/using_yosys/synthesis/opt`, so let's skip over them. :yoscrypt:`techmap
-map +/cmp2lut.v -D LUT_WIDTH=4` optimizes certain comparison operators by
@ -440,7 +440,7 @@ converting them to LUTs instead. The usage of `techmap` is explored more in
:doc:`/using_yosys/synthesis/techmap_synth`.
Our next command to run is
:cmd:title:`memory_dff`.
:doc:`/cmd/memory_dff`.
.. literalinclude:: /code_examples/fifo/fifo.out
:language: doscon
@ -475,7 +475,7 @@ will only be performed if called with the ``-dsp`` flag: :yoscrypt:`synth_ice40
-dsp`. While our example has nothing that could be mapped to DSPs we can still
take a quick look at the commands here and describe what they do.
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-at: t:$mul
:end-before: alumacc
@ -514,7 +514,7 @@ Part 4
That brings us to the fourth and final part for the iCE40 synthesis flow:
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-at: alumacc
:end-before: map_ram:
@ -543,7 +543,7 @@ Once these cells have been inserted, the call to `opt` can combine cells which
are now identical but may have been missed due to e.g. the difference between
`$add` and `$sub`.
The other new command in this part is :cmd:title:`memory`. `memory` is another
The other new command in this part is :doc:`/cmd/memory`. `memory` is another
macro command which we examine in more detail in
:doc:`/using_yosys/synthesis/memory`. For this document, let us focus just on
the step most relevant to our example: `memory_collect`. Up until this point,
@ -594,7 +594,7 @@ Memory blocks
Mapping to hard memory blocks uses a combination of `memory_libmap` and
`techmap`.
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: map_ram:
:end-before: map_ffram:
@ -636,7 +636,7 @@ into flip flops (the ``logic fallback``) with `memory_map`.
.. |techlibs/ice40/brams_map.v| replace:: :file:`techlibs/ice40/brams_map.v`
.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/main/techlibs/ice40/brams_map.v
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: map_ffram:
:end-before: map_gates:
@ -671,7 +671,7 @@ an explosion in cells as multi-bit `$mux` and `$adffe` are replaced with
single-bit `$_MUX_` and `$_DFFE_PP0P_` cells, while the `$alu` is replaced with
primitive `$_OR_` and `$_NOT_` gates and a `$lut` cell.
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: map_gates:
:end-before: map_ffs:
@ -700,7 +700,7 @@ mapped to hardware into gate-level primitives. This includes optimizing
`$_MUX_` cells where one of the inputs is a constant ``1'0``, replacing it
instead with an `$_AND_` cell.
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: map_ffs:
:end-before: map_luts:
@ -725,7 +725,7 @@ LUTs
`abc`. For more on what these do, and what the difference between these two
commands are, refer to :doc:`/using_yosys/synthesis/abc`.
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: map_luts:
:end-before: map_cells:
@ -742,7 +742,7 @@ commands are, refer to :doc:`/using_yosys/synthesis/abc`.
Finally we use `techmap` to map the generic `$lut` cells to iCE40 ``SB_LUT4``
cells.
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: map_cells:
:end-before: check:
@ -784,18 +784,19 @@ Final steps
The next section of the iCE40 synth flow performs some sanity checking and final
tidy up:
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
.. literalinclude:: /cmd/synth_ice40.rst
:language: yoscrypt
:start-after: check:
:end-before: blif:
:dedent:
:name: check
:caption: ``check`` section
The new commands here are:
- :cmd:title:`autoname`,
- :cmd:title:`stat`, and
- :cmd:title:`blackbox`.
- :doc:`/cmd/autoname`,
- :doc:`/cmd/stat`, and
- :doc:`/cmd/blackbox`.
The output from `stat` is useful for checking resource utilization; providing a
list of cells used in the design and the number of each, as well as the number
@ -834,9 +835,9 @@ Synthesis output
The iCE40 synthesis flow has the following output modes available:
- `write_blif`,
- `write_edif`, and
- `write_json`.
- :doc:`/cmd/write_blif`,
- :doc:`/cmd/write_edif`, and
- :doc:`/cmd/write_json`.
As an example, if we called :yoscrypt:`synth_ice40 -top fifo -json fifo.json`,
our synthesized ``fifo`` design will be output as :file:`fifo.json`. We can
@ -847,4 +848,4 @@ is beyond the scope of this documentation.
.. _nextpnr: https://github.com/YosysHQ/nextpnr
.. seealso:: :cmd:title:`synth_ice40`
.. seealso:: :doc:`/cmd/synth_ice40`

View file

@ -122,7 +122,7 @@ module.
Detailed documentation of the select framework can be found under
:doc:`/using_yosys/more_scripting/selections` or in the command reference at
:cmd:title:`select`.
:doc:`/cmd/select`.
.. _show_intro:
@ -219,7 +219,7 @@ those used in options, must be a single expression instead.
.. _GraphViz color docs: https://graphviz.org/doc/info/colors
For all of the options available to `show`, check the command reference at
:cmd:title:`show`.
:doc:`/cmd/show`.
.. seealso:: :ref:`interactive_show` on the
:doc:`/using_yosys/more_scripting/interactive_investigation` page.

View file

@ -5,7 +5,7 @@ Yosys Open SYnthesis Suite
Yosys is an open source framework for RTL synthesis. To learn more about Yosys,
see :doc:`/introduction`. For a quick guide on how to get started using Yosys,
check out :doc:`/getting_started/index`. For the complete list of commands
available, go to :ref:`cmd_ref`.
available, go to :ref:`commandindex`.
.. todo:: look into command ref improvements

View file

@ -323,10 +323,10 @@ tools).
design into an equivalent design that is easier to analyse.
- Commands such as `eval` and `sat` can be used to investigate the behavior of
the circuit.
- :cmd:title:`show`.
- :cmd:title:`dump`.
- :cmd:title:`add` and :cmd:title:`delete` can be used to modify and reorganize
a design dynamically.
- :doc:`/cmd/show`.
- :doc:`/cmd/dump`.
- :doc:`/cmd/add` and :doc:`/cmd/delete` can be used to modify and reorganize a
design dynamically.
The code used is included in the Yosys code base under
|code_examples/scrambler|_.
@ -358,7 +358,7 @@ reorganizing a module in Yosys and checking the resulting circuit.
.. figure:: /_images/code_examples/scrambler/scrambler_p02.*
:class: width-helper invert-helper
Analyzing the resulting circuit with :cmd:title:`eval`:
Analyzing the resulting circuit with :doc:`/cmd/eval`:
.. todo:: replace inline code

View file

@ -1,11 +1,9 @@
Loading a design
~~~~~~~~~~~~~~~~
.. TODO:: fill out this page better
keyword: Frontends
- :doc:`/cmd/index_frontends`
- :doc:`/cmd/read_verilog`
.. todo:: include ``read_verilog <<EOF``, also other methods of loading designs
@ -31,14 +29,20 @@ keyword: Frontends
.. note::
The Verific frontend for Yosys, which provides the `verific` command,
requires Yosys to be built with Verific. For full functionality, custom
modifications to the Verific source code from YosysHQ are required, but
limited useability can be achieved with some stock Verific builds. Check
The Verific frontend for Yosys, which provides the :cmd:ref:`verific`
command, requires Yosys to be built with Verific. For full functionality,
custom modifications to the Verific source code from YosysHQ are required,
but limited useability can be achieved with some stock Verific builds. Check
:doc:`/yosys_internals/extending_yosys/build_verific` for more.
Others:
- :doc:`/cmd/read`
- `GHDL plugin`_ for VHDL
- :doc:`/cmd/read_rtlil` (direct textual representation of Yosys internal state)
- :doc:`/cmd/read_aiger`
- :doc:`/cmd/read_blif`
- :doc:`/cmd/read_json`
- :doc:`/cmd/read_liberty`
.. _GHDL plugin: https://github.com/ghdl/ghdl-yosys-plugin

View file

@ -93,7 +93,7 @@ Special patterns can be used to select by object property or type. For example:
A:blabla`
- select all `$add` cells from the module foo: :yoscrypt:`select foo/t:$add`
A complete list of pattern expressions can be found in :cmd:title:`select`.
A complete list of pattern expressions can be found in :doc:`/cmd/select`.
Operations on selections
~~~~~~~~~~~~~~~~~~~~~~~~
@ -141,7 +141,7 @@ Some of the special ``%``-codes:
- ``%i``: intersection of top two elements on stack -- pop 2, push 1
- ``%n``: inverse of top element on stack -- pop 1, push 1
See :cmd:title:`select` for the full list.
See :doc:`/cmd/select` for the full list.
Expanding selections
^^^^^^^^^^^^^^^^^^^^
@ -354,7 +354,7 @@ boolean operations such as intersection (``%i``) and difference (``%d``) are
powerful tools for extracting the relevant portions of the circuit under
investigation.
Again, see :cmd:title:`select` for full documentation of these expressions.
Again, see :doc:`/cmd/select` for full documentation of these expressions.
Incremental selection
^^^^^^^^^^^^^^^^^^^^^

View file

@ -10,7 +10,7 @@ other commands:
:start-after: #end:
:caption: Passes called by `fsm`
See also :doc:`/cmd/index_passes_fsm`.
See also :doc:`/cmd/fsm`.
The algorithms used for FSM detection and extraction are influenced by a more
general reported technique :cite:p:`fsmextract`.

View file

@ -26,7 +26,7 @@ Some quick notes:
decoder logic and registers.
For more information about `memory`, such as disabling certain sub commands, see
:doc:`/cmd/index_passes_memory`.
:doc:`/cmd/memory`.
Example
-------

View file

@ -11,8 +11,8 @@ The `opt` macro command
The Yosys pass `opt` runs a number of simple optimizations. This includes
removing unused signals and cells and const folding. It is recommended to run
this pass after each major step in the synthesis script. This macro command
calls the following ``opt_*`` commands:
this pass after each major step in the synthesis script. As listed in
:doc:`/cmd/opt`, this macro command calls the following ``opt_*`` commands:
.. literalinclude:: /code_examples/macro_commands/opt.ys
:language: yoscrypt
@ -233,5 +233,7 @@ Other optimizations
.. todo:: more on the other optimizations
- Check :doc:`/cmd/index_passes_opt` for more.
- :doc:`/cmd/wreduce`
- :doc:`/cmd/peepopt`
- :doc:`/cmd/share`
- `abc` and `abc9`, see also: :doc:`abc`.

View file

@ -17,7 +17,7 @@ commands in a sensible order:
After all the ``proc_*`` commands, `opt_expr` is called. This can be disabled by
calling :yoscrypt:`proc -noopt`. For more information about `proc`, such as
disabling certain sub commands, see :doc:`/cmd/index_passes_proc`.
disabling certain sub commands, see :doc:`/cmd/proc`.
Many commands can not operate on modules with "processess" in them. Usually a
call to `proc` is the first command in the actual synthesis procedure after

View file

@ -6,23 +6,44 @@ Synth commands
Packaged ``synth_*`` commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A list of all synth commands included in Yosys for different platforms can be
found under :doc:`/cmd/index_techlibs`. Each command runs a script of sub
commands specific to the platform being targeted. Note that not all of these
scripts are actively maintained and may not be up-to-date.
The following is a list of all synth commands included in Yosys for different
platforms. Each command runs a script of sub commands specific to the platform
being targeted. Note that not all of these scripts are actively maintained and
may not be up-to-date.
- :doc:`/cmd/synth_achronix`
- :doc:`/cmd/synth_anlogic`
- :doc:`/cmd/synth_coolrunner2`
- :doc:`/cmd/synth_easic`
- :doc:`/cmd/synth_ecp5`
- :doc:`/cmd/synth_efinix`
- :doc:`/cmd/synth_fabulous`
- :doc:`/cmd/synth_gatemate`
- :doc:`/cmd/synth_gowin`
- :doc:`/cmd/synth_greenpak4`
- :doc:`/cmd/synth_ice40`
- :doc:`/cmd/synth_intel` (MAX10, Cyclone IV)
- :doc:`/cmd/synth_intel_alm` (Cyclone V, Arria V, Cyclone 10 GX)
- :doc:`/cmd/synth_lattice`
- :doc:`/cmd/synth_nexus`
- :doc:`/cmd/synth_quicklogic`
- :doc:`/cmd/synth_sf2`
- :doc:`/cmd/synth_xilinx`
General synthesis
~~~~~~~~~~~~~~~~~
In addition to the above hardware-specific synth commands, there is also
:cmd:title:`prep`. This command is limited to coarse-grain synthesis, without
:doc:`/cmd/prep`. This command is limited to coarse-grain synthesis, without
getting into any architecture-specific mappings or optimizations. Among other
things, this is useful for design verification.
The following commands are executed by the `prep` command:
.. literalinclude:: /code_examples/macro_commands/prep.ys
.. literalinclude:: /cmd/prep.rst
:start-at: begin:
:end-before: .. only:: latex
:dedent:
:doc:`/getting_started/example_synth` covers most of these commands and what
they do.

View file

@ -33,9 +33,9 @@ reader may find this map file as :file:`techlibs/common/techmap.v` in the Yosys
source tree.
Additional features have been added to techmap to allow for conditional mapping
of cells (see :doc:`/cmd/index_passes_techmap`). This can for example be useful
if the target architecture supports hardware multipliers for certain bit-widths
but not for others.
of cells (see :doc:`/cmd/techmap`). This can for example be useful if the target
architecture supports hardware multipliers for certain bit-widths but not for
others.
A usual synthesis flow would first use the techmap pass to directly map some RTL
cells to coarse-grain cells provided by the target architecture (if any) and

View file

@ -138,7 +138,7 @@ Previously, the interface to implement hashing on custom types was just
independently and then ad-hoc combined with the hash function with some xorshift
operations thrown in to mix bits together somewhat. A plugin can stay compatible
with both versions prior and after the break by implementing both interfaces
based on the existance and value of ``YS_HASHING_VERSION``.
based on the existance and value of `YS_HASHING_VERSION`.
.. code-block:: cpp
:caption: Example hash compatibility wrapper

View file

@ -96,7 +96,7 @@ Verilog Attributes and non-standard features
- The ``keep_hierarchy`` attribute on cells and modules keeps the `flatten`
command from flattening the indicated cells and modules.
- The ``gate_cost_equivalent`` attribute on a module can be used to specify
- The `gate_cost_equivalent` attribute on a module can be used to specify
the estimated cost of the module as a number of basic gate instances. See
the help message of command `keep_hierarchy` which interprets this
attribute.

View file

@ -1,443 +0,0 @@
#!/usr/bin/env python3
from __future__ import annotations
from dataclasses import dataclass
import json
from pathlib import Path, PosixPath, WindowsPath
import re
from typing import Any
from sphinx.application import Sphinx
from sphinx.ext import autodoc
from sphinx.ext.autodoc import Documenter
from sphinx.util import logging
logger = logging.getLogger(__name__)
# cmd signature
cmd_ext_sig_re = re.compile(
r'''^ ([\w/]+::)? # optional group
([\w$._]+?) # module name
(?:\.([\w_]+))? # optional: thing name
(::[\w_]+)? # attribute
\s* $ # and nothing more
''', re.VERBOSE)
class YosysCmdContentListing:
type: str
body: str
source_file: str
source_line: int
options: dict[str, str]
content: list[YosysCmdContentListing]
def __init__(
self,
type: str = "",
body: str = "",
source_file: str = "unknown",
source_line: int = 0,
options: dict[str, str] = {},
content: list[dict[str]] = [],
):
self.type = type
self.body = body
self.source_file = source_file
self.source_line = source_line
self.options = options
self.content = [YosysCmdContentListing(**c) for c in content]
class YosysCmd:
name: str
title: str
content: list[YosysCmdContentListing]
group: str
source_file: str
source_line: int
source_func: str
experimental_flag: bool
internal_flag: bool
def __init__(
self,
name:str = "", title:str = "",
content: list[dict[str]] = [],
group: str = 'unknown',
source_file: str = "",
source_line: int = 0,
source_func: str = "",
experimental_flag: bool = False,
internal_flag: bool = False,
) -> None:
self.name = name
self.title = title
self.content = [YosysCmdContentListing(**c) for c in content]
self.group = group
self.source_file = source_file
self.source_line = source_line
self.source_func = source_func
self.experimental_flag = experimental_flag
self.internal_flag = internal_flag
class YosysCmdGroupDocumenter(Documenter):
objtype = 'cmdgroup'
priority = 10
object: tuple[str, list[str]]
lib_key = 'groups'
option_spec = Documenter.option_spec.copy()
option_spec.update({
'caption': autodoc.annotation_option,
'members': autodoc.members_option,
'source': autodoc.bool_option,
'linenos': autodoc.bool_option,
})
__cmd_lib: dict[str, list[str] | dict[str]] | None = None
@property
def cmd_lib(self) -> dict[str, list[str] | dict[str]]:
if not self.__cmd_lib:
self.__cmd_lib = {}
cmds_obj: dict[str, dict[str, dict[str]]]
try:
with open(self.config.cmds_json, "r") as f:
cmds_obj = json.loads(f.read())
except FileNotFoundError:
logger.warning(
f"unable to find cmd lib at {self.config.cmds_json}",
type = 'cmdref',
subtype = 'cmd_lib'
)
cmds_obj = {}
for (name, obj) in cmds_obj.get(self.lib_key, {}).items():
self.__cmd_lib[name] = obj
return self.__cmd_lib
@classmethod
def can_document_member(
cls,
member: Any,
membername: str,
isattr: bool,
parent: Any
) -> bool:
return False
def parse_name(self) -> bool:
if not self.options.caption:
self.content_indent = ''
self.fullname = self.modname = self.name
return True
def import_object(self, raiseerror: bool = False) -> bool:
# get cmd
try:
self.object = (self.modname, self.cmd_lib[self.modname])
except KeyError:
if raiseerror:
raise
return False
self.real_modname = self.modname
return True
def get_sourcename(self) -> str:
return self.env.doc2path(self.env.docname)
def format_name(self) -> str:
return self.options.caption or ''
def format_signature(self, **kwargs: Any) -> str:
return self.modname
def add_directive_header(self, sig: str) -> None:
pass
def add_content(self, more_content: Any | None) -> None:
pass
def filter_members(
self,
members: list[tuple[str, Any]],
want_all: bool
) -> list[tuple[str, Any, bool]]:
return [(x[0], x[1], False) for x in members]
def get_object_members(
self,
want_all: bool
) -> tuple[bool, list[tuple[str, Any]]]:
ret: list[tuple[str, str]] = []
if want_all:
for member in self.object[1]:
ret.append((member, self.modname))
else:
memberlist = self.options.members or []
for name in memberlist:
if name in self.object:
ret.append((name, self.modname))
else:
logger.warning(('unknown module mentioned in :members: option: '
f'group {self.modname}, module {name}'),
type='cmdref')
return False, ret
def document_members(self, all_members: bool = False) -> None:
want_all = (all_members or
self.options.inherited_members or
self.options.members is autodoc.ALL)
# find out which members are documentable
members_check_module, members = self.get_object_members(want_all)
# document non-skipped members
memberdocumenters: list[tuple[Documenter, bool]] = []
for (mname, member, isattr) in self.filter_members(members, want_all):
classes = [cls for cls in self.documenters.values()
if cls.can_document_member(member, mname, isattr, self)]
if not classes:
# don't know how to document this member
continue
# prefer the documenter with the highest priority
classes.sort(key=lambda cls: cls.priority)
# give explicitly separated module name, so that members
# of inner classes can be documented
full_mname = self.format_signature() + '::' + mname
documenter = classes[-1](self.directive, full_mname, self.indent)
memberdocumenters.append((documenter, isattr))
member_order = self.options.member_order or self.config.autodoc_member_order
memberdocumenters = self.sort_members(memberdocumenters, member_order)
for documenter, isattr in memberdocumenters:
documenter.generate(
all_members=True, real_modname=self.real_modname,
check_module=members_check_module and not isattr)
def generate(
self,
more_content: Any | None = None,
real_modname: str | None = None,
check_module: bool = False,
all_members: bool = False
) -> None:
if not self.parse_name():
# need a cmd lib to import from
logger.warning(
f"don't know which cmd lib to import for autodocumenting {self.name}",
type = 'cmdref'
)
return
sourcename = self.get_sourcename()
imported_object = self.import_object();
if self.lib_key == 'groups' and self.name == 'unknown':
if imported_object:
logger.warning(f"Found commands assigned to group {self.name}: {[x[0] for x in self.object]}", type='cmdref')
else:
return
elif not imported_object:
log_msg = f"unable to load {self.name} with {type(self)}"
if self.lib_key == 'groups':
logger.info(log_msg, type = 'cmdref')
self.add_line(f'.. warning:: No commands found for group {self.name!r}', sourcename)
self.add_line('', sourcename)
self.add_line(' Documentation may have been built without ``source_location`` support.', sourcename)
self.add_line(' Try check :doc:`/cmd/index_other`.', sourcename)
else:
logger.warning(log_msg, type = 'cmdref')
return
# check __module__ of object (for members not given explicitly)
# if check_module:
# if not self.check_module():
# return
self.add_line('', sourcename)
# format the object's signature, if any
try:
sig = self.format_signature()
except Exception as exc:
logger.warning(('error while formatting signature for %s: %s'),
self.fullname, exc, type='cmdref')
return
# generate the directive header and options, if applicable
self.add_directive_header(sig)
self.add_line('', sourcename)
# e.g. the module directive doesn't have content
self.indent += self.content_indent
# add all content (from docstrings, attribute docs etc.)
self.add_content(more_content)
# document members, if possible
self.document_members(all_members)
class YosysCmdDocumenter(YosysCmdGroupDocumenter):
objtype = 'cmd'
priority = 15
object: YosysCmd
lib_key = 'cmds'
@classmethod
def can_document_member(
cls,
member: Any,
membername: str,
isattr: bool,
parent: Any
) -> bool:
if membername.startswith('$'):
return False
return isinstance(parent, YosysCmdGroupDocumenter)
def parse_name(self) -> bool:
try:
matched = cmd_ext_sig_re.match(self.name)
group, modname, thing, attribute = matched.groups()
except AttributeError:
logger.warning(('invalid signature for auto%s (%r)') % (self.objtype, self.name),
type='cmdref')
return False
self.modname = modname
self.groupname = group or ''
self.attribute = attribute or ''
self.fullname = ((self.modname) + (thing or ''))
return True
def import_object(self, raiseerror: bool = False) -> bool:
if super().import_object(raiseerror):
self.object = YosysCmd(self.modname, **self.object[1])
return True
return False
def get_sourcename(self) -> str:
try:
return self.object.source_file
except AttributeError:
return super().get_sourcename()
def format_name(self) -> str:
return self.object.name
def format_signature(self, **kwargs: Any) -> str:
return self.fullname + self.attribute
def add_directive_header(self, sig: str) -> None:
domain = getattr(self, 'domain', self.objtype)
directive = getattr(self, 'directivetype', 'def')
source_name = self.object.source_file
source_line = self.object.source_line
title = f'{self.object.name} - {self.object.title}'
self.add_line(title, source_name, source_line)
self.add_line('#' * len(title), source_name, source_line)
# cmd definition
self.add_line(f'.. {domain}:{directive}:: {sig}', source_name, source_line)
if self.object.title:
self.add_line(f' :title: {self.object.title}', source_name, source_line)
if self.options.noindex:
self.add_line(' :noindex:', source_name)
def add_content(self, more_content: Any | None) -> None:
# set sourcename and add content from attribute documentation
domain = getattr(self, 'domain', self.objtype)
source_name = self.object.source_file
source_line = self.object.source_line
if self.object.experimental_flag:
self.add_line(f'.. warning:: This command is experimental', source_name, source_line)
self.add_line('\n', source_name)
if self.object.internal_flag:
self.add_line(f'.. warning:: This command is intended for internal developer use only', source_name, source_line)
self.add_line('\n', source_name)
def render(content_list: YosysCmdContentListing, indent: int=0):
content_source = content_list.source_file or source_name
indent_str = ' '*indent
if content_list.type == 'usage':
if content_list.body:
self.add_line(f'{indent_str}.. {domain}:{content_list.type}:: {self.name}::{content_list.body}', content_source)
else:
self.add_line(f'{indent_str}.. {domain}:{content_list.type}:: {self.name}::', content_source)
self.add_line(f'{indent_str} :noindex:', source_name)
self.add_line('', source_name)
elif content_list.type == 'option':
self.add_line(f'{indent_str}:{content_list.type} {content_list.body}:', content_source)
elif content_list.type == 'text':
self.add_line(f'{indent_str}{content_list.body}', content_source)
self.add_line('', source_name)
elif content_list.type == 'code':
language_str = content_list.options.get('language', '')
self.add_line(f'{indent_str}.. code-block:: {language_str}', source_name)
self.add_line('', source_name)
for body_line in content_list.body.splitlines():
self.add_line(f'{indent_str} {body_line}', content_source)
self.add_line('', source_name)
else:
logger.warning(f"unknown content type '{content_list.type}'")
for content in content_list.content:
render(content, indent+1)
for content in self.object.content:
render(content)
if self.get_sourcename() != 'unknown':
self.add_line('\n', source_name)
self.add_line(f'.. note:: Help text automatically generated from :file:`{source_name}:{source_line}`', source_name)
# add additional content (e.g. from document), if present
if more_content:
for line, src in zip(more_content.data, more_content.items):
self.add_line(line, src[0], src[1])
def get_object_members(
self,
want_all: bool
) -> tuple[bool, list[tuple[str, Any]]]:
return False, []
class YosysCmdRstDocumenter(YosysCmdDocumenter):
objtype = 'cmd_rst'
priority = 0
@classmethod
def can_document_member(cls, *args) -> bool:
return False
def add_directive_header(self, sig):
source_name = self.object.source_file
cmd = self.object.name
self.add_line(f'.. code-block:: rst', source_name)
self.add_line(f' :caption: Generated rst for ``.. autocmd:: {cmd}``', source_name)
def add_content(self, more_content):
source_name = self.object.source_file
cmd = self.object.name
self.domain = 'cmd'
super().add_directive_header(cmd)
self.add_line('', source_name)
self.indent += self.content_indent
super().add_content(more_content)
def setup(app: Sphinx) -> dict[str, Any]:
app.add_config_value('cmds_json', False, 'html', [Path, PosixPath, WindowsPath])
app.setup_extension('sphinx.ext.autodoc')
app.add_autodocumenter(YosysCmdGroupDocumenter)
app.add_autodocumenter(YosysCmdDocumenter)
app.add_autodocumenter(YosysCmdRstDocumenter)
return {
'version': '2',
'parallel_read_safe': True,
}

View file

@ -4,21 +4,20 @@ from __future__ import annotations
import re
from typing import cast
import warnings
from docutils import nodes
from docutils.nodes import Node, Element, Text
from docutils.nodes import Node, Element, system_message
from docutils.parsers.rst import directives
from docutils.parsers.rst.states import Inliner
from sphinx.application import Sphinx
from sphinx.domains import Domain, Index
from sphinx.domains.std import StandardDomain
from sphinx.environment import BuildEnvironment
from sphinx.roles import XRefRole, SphinxRole
from sphinx.roles import XRefRole
from sphinx.directives import ObjectDescription
from sphinx.directives.code import container_wrapper
from sphinx.util.nodes import make_refnode
from sphinx.util.docfields import Field, GroupedField
from sphinx.util.docfields import Field
from sphinx import addnodes
class TocNode(ObjectDescription):
@ -32,7 +31,7 @@ class TocNode(ObjectDescription):
signode['ids'].append(idx)
def _object_hierarchy_parts(self, sig_node: addnodes.desc_signature) -> tuple[str, ...]:
if 'tocname' not in sig_node:
if 'fullname' not in sig_node:
return ()
modname = sig_node.get('module')
@ -58,56 +57,16 @@ class TocNode(ObjectDescription):
return '.'.join(parents + [name])
return ''
class NodeWithOptions(TocNode):
"""A custom node with options."""
doc_field_types = [
GroupedField('opts', label='Options', names=('option', 'options', 'opt', 'opts')),
]
def transform_content(self, contentnode: addnodes.desc_content) -> None:
"""hack `:option -thing: desc` into a proper option list with yoscrypt highlighting"""
newchildren = []
for node in contentnode:
newnode = node
if isinstance(node, nodes.field_list):
newnode = nodes.option_list()
for field in node:
is_option = False
option_list_item = nodes.option_list_item()
for child in field:
if isinstance(child, nodes.field_name):
option_group = nodes.option_group()
option_list_item += option_group
option = nodes.option()
option_group += option
name, text = child.rawsource.split(' ', 1)
is_option = name == 'option'
literal = nodes.literal(text=text)
literal['classes'] += ['code', 'highlight', 'yoscrypt']
literal['language'] = 'yoscrypt'
option += literal
if not is_option: warnings.warn(f'unexpected option \'{name}\' in {field.source}')
elif isinstance(child, nodes.field_body):
description = nodes.description()
description += child.children
option_list_item += description
if is_option:
newnode += option_list_item
newchildren.append(newnode)
contentnode.children = newchildren
class CommandNode(NodeWithOptions):
class CommandNode(TocNode):
"""A custom node that describes a command."""
name = 'cmd'
required_arguments = 1
option_spec = NodeWithOptions.option_spec.copy()
option_spec.update({
option_spec = {
'title': directives.unchanged,
'tags': directives.unchanged
})
}
def handle_signature(self, sig, signode: addnodes.desc_signature):
signode['fullname'] = sig
@ -134,46 +93,6 @@ class CommandNode(NodeWithOptions):
idx,
0))
class CommandUsageNode(NodeWithOptions):
"""A custom node that describes command usages"""
name = 'cmdusage'
option_spec = NodeWithOptions.option_spec
option_spec.update({
'usage': directives.unchanged,
})
def handle_signature(self, sig: str, signode: addnodes.desc_signature):
parts = sig.split('::')
if len(parts) > 2: parts.pop(0)
use = parts[-1]
signode['fullname'] = '::'.join(parts)
usage = self.options.get('usage', use)
if usage:
signode['tocname'] = usage
signode += addnodes.desc_name(text=usage)
return signode['fullname']
def add_target_and_index(
self,
name: str,
sig: str,
signode: addnodes.desc_signature
) -> None:
idx = ".".join(name.split("::"))
signode['ids'].append(idx)
if 'noindex' not in self.options:
tocname: str = signode.get('tocname', name)
objs = self.env.domaindata[self.domain]['objects']
# (name, sig, typ, docname, anchor, prio)
objs.append((name,
tocname,
type(self).name,
self.env.docname,
idx,
1))
class PropNode(TocNode):
name = 'prop'
fieldname = 'props'
@ -474,7 +393,7 @@ class TagIndex(Index):
lis.append((
dispname, 0, docname,
anchor,
'', '', ''
docname, '', typ
))
ret = [(k, v) for k, v in sorted(content.items())]
@ -513,19 +432,18 @@ class CommandIndex(Index):
Qualifier and description are not rendered e.g. in LaTeX output.
"""
content: dict[str, list[tuple]] = {}
content = {}
items = ((name, dispname, typ, docname, anchor)
for name, dispname, typ, docname, anchor, prio
in self.domain.get_objects()
if typ == self.name)
items = sorted(items, key=lambda item: item[0])
for name, dispname, typ, docname, anchor in items:
title = self.domain.data['obj2title'].get(name)
lis = content.setdefault(self.shortname, [])
lis.append((
dispname, 0, docname,
anchor,
'', '', title
'', '', typ
))
ret = [(k, v) for k, v in sorted(content.items())]
@ -589,27 +507,16 @@ class PropIndex(TagIndex):
return (ret, True)
class TitleRefRole(XRefRole):
"""XRefRole used which has the cmd title as the displayed text."""
pass
class OptionRole(SphinxRole):
def run(self) -> tuple[list[Node], list]:
return self.inliner.interpreted(self.rawtext, self.text, 'yoscrypt', self.lineno)
class CommandDomain(Domain):
name = 'cmd'
label = 'Yosys commands'
roles = {
'ref': XRefRole(),
'title': TitleRefRole(),
'option': OptionRole(),
'ref': XRefRole()
}
directives = {
'def': CommandNode,
'usage': CommandUsageNode,
}
indices = {
@ -635,7 +542,7 @@ class CommandDomain(Domain):
def resolve_xref(self, env, fromdocname, builder, typ,
target, node, contnode):
match = [(docname, anchor, name)
for name, sig, typ, docname, anchor, prio
in self.get_objects() if sig == target]
@ -645,17 +552,9 @@ class CommandDomain(Domain):
targ = match[0][1]
qual_name = match[0][2]
title = self.data['obj2title'].get(qual_name, targ)
if typ == 'title':
# caller wants the title in the content of the node
cmd = contnode.astext()
contnode = Text(f'{cmd} - {title}')
return make_refnode(builder, fromdocname, todocname,
targ, contnode)
else:
# cmd title as hover text
return make_refnode(builder, fromdocname, todocname,
targ, contnode, title)
return make_refnode(builder,fromdocname,todocname,
targ, contnode, title)
else:
print(f"Missing ref for {target} in {fromdocname} ")
return None
@ -693,18 +592,10 @@ class CellDomain(CommandDomain):
def autoref(name, rawtext: str, text: str, lineno, inliner: Inliner,
options=None, content=None):
words = text.split(' ')
if len(words) == 2 and words[0] == "help":
IsLinkable = True
thing = words[1]
else:
IsLinkable = len(words) == 1 and words[0][0] != '-'
thing = words[0]
if IsLinkable:
role = 'cell:ref' if thing[0] == '$' else 'cmd:ref'
text = f'{text} <{thing}>'
else:
role = 'yoscrypt'
role = 'cell:ref' if text[0] == '$' else 'cmd:ref'
if text.startswith("help ") and text.count(' ') == 1:
_, cmd = text.split(' ', 1)
text = f'{text} <{cmd}>'
return inliner.interpreted(rawtext, text, role, lineno)
def setup(app: Sphinx):
@ -731,7 +622,4 @@ def setup(app: Sphinx):
app.add_role('autoref', autoref)
return {
'version': '0.3',
'parallel_read_safe': False,
}
return {'version': '0.2'}