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:
parent
2223d7848b
commit
81f87ce6ed
124 changed files with 474 additions and 2035 deletions
1
.github/workflows/prepare-docs.yml
vendored
1
.github/workflows/prepare-docs.yml
vendored
|
@ -59,6 +59,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: cmd-ref-${{ github.sha }}
|
name: cmd-ref-${{ github.sha }}
|
||||||
path: |
|
path: |
|
||||||
|
docs/source/cmd
|
||||||
docs/source/generated
|
docs/source/generated
|
||||||
docs/source/_images
|
docs/source/_images
|
||||||
docs/source/code_examples
|
docs/source/code_examples
|
||||||
|
|
36
Makefile
36
Makefile
|
@ -115,6 +115,12 @@ BISON ?= bison
|
||||||
STRIP ?= strip
|
STRIP ?= strip
|
||||||
AWK ?= awk
|
AWK ?= awk
|
||||||
|
|
||||||
|
ifneq ($(shell :; command -v rsync),)
|
||||||
|
RSYNC_CP ?= rsync -rc
|
||||||
|
else
|
||||||
|
RSYNC_CP ?= cp -ru
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(OS), Darwin)
|
ifeq ($(OS), Darwin)
|
||||||
PLUGIN_LINKFLAGS += -undefined dynamic_lookup
|
PLUGIN_LINKFLAGS += -undefined dynamic_lookup
|
||||||
LINKFLAGS += -rdynamic
|
LINKFLAGS += -rdynamic
|
||||||
|
@ -526,6 +532,7 @@ LIBS_VERIFIC += -Wl,--whole-archive $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VE
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(ENABLE_COVER),1)
|
ifeq ($(ENABLE_COVER),1)
|
||||||
CXXFLAGS += -DYOSYS_ENABLE_COVER
|
CXXFLAGS += -DYOSYS_ENABLE_COVER
|
||||||
endif
|
endif
|
||||||
|
@ -627,7 +634,6 @@ $(eval $(call add_include_file,frontends/blif/blifparse.h))
|
||||||
$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h))
|
$(eval $(call add_include_file,backends/rtlil/rtlil_backend.h))
|
||||||
|
|
||||||
OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o
|
OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o kernel/io.o kernel/gzip.o
|
||||||
OBJS += kernel/log_help.o
|
|
||||||
OBJS += kernel/binding.o kernel/tclapi.o
|
OBJS += kernel/binding.o kernel/tclapi.o
|
||||||
OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o
|
OBJS += kernel/cellaigs.o kernel/celledges.o kernel/cost.o kernel/satgen.o kernel/scopeinfo.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o kernel/sexpr.o
|
||||||
OBJS += kernel/drivertools.o kernel/functional.o
|
OBJS += kernel/drivertools.o kernel/functional.o
|
||||||
|
@ -1028,8 +1034,19 @@ ifeq ($(ENABLE_PYOSYS),1)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
docs/source/generated/cmds.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
# also others, but so long as it doesn't fail this is enough to know we tried
|
||||||
$(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cmds-json $@'
|
docs/source/cmd/abc.rst: $(TARGETS) $(EXTRA_TARGETS)
|
||||||
|
$(Q) mkdir -p docs/source/cmd
|
||||||
|
$(Q) mkdir -p temp/docs/source/cmd
|
||||||
|
$(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-command-reference-manual'
|
||||||
|
$(Q) $(RSYNC_CP) temp/docs/source/cmd docs/source
|
||||||
|
$(Q) rm -rf temp
|
||||||
|
docs/source/cell/word_add.rst: $(TARGETS) $(EXTRA_TARGETS)
|
||||||
|
$(Q) mkdir -p docs/source/cell
|
||||||
|
$(Q) mkdir -p temp/docs/source/cell
|
||||||
|
$(Q) cd temp && ./../$(PROGRAM_PREFIX)yosys -p 'help -write-rst-cells-manual'
|
||||||
|
$(Q) $(RSYNC_CP) temp/docs/source/cell docs/source
|
||||||
|
$(Q) rm -rf temp
|
||||||
|
|
||||||
docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
docs/source/generated/cells.json: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
||||||
$(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@'
|
$(Q) ./$(PROGRAM_PREFIX)yosys -p 'help -dump-cells-json $@'
|
||||||
|
@ -1046,15 +1063,6 @@ docs/source/generated/functional/rosette.diff: backends/functional/smtlib.cc bac
|
||||||
PHONY: docs/gen/functional_ir
|
PHONY: docs/gen/functional_ir
|
||||||
docs/gen/functional_ir: docs/source/generated/functional/smtlib.cc docs/source/generated/functional/rosette.diff
|
docs/gen/functional_ir: docs/source/generated/functional/smtlib.cc docs/source/generated/functional/rosette.diff
|
||||||
|
|
||||||
docs/source/generated/%.log: docs/source/generated $(TARGETS) $(EXTRA_TARGETS)
|
|
||||||
$(Q) ./$(PROGRAM_PREFIX)yosys -qQT -h '$*' -l $@
|
|
||||||
|
|
||||||
docs/source/generated/chformal.cc: passes/cmds/chformal.cc docs/source/generated
|
|
||||||
$(Q) cp $< $@
|
|
||||||
|
|
||||||
PHONY: docs/gen/chformal
|
|
||||||
docs/gen/chformal: docs/source/generated/chformal.log docs/source/generated/chformal.cc
|
|
||||||
|
|
||||||
PHONY: docs/gen docs/usage docs/reqs
|
PHONY: docs/gen docs/usage docs/reqs
|
||||||
docs/gen: $(TARGETS)
|
docs/gen: $(TARGETS)
|
||||||
$(Q) $(MAKE) -C docs gen
|
$(Q) $(MAKE) -C docs gen
|
||||||
|
@ -1090,7 +1098,7 @@ docs/reqs:
|
||||||
$(Q) $(MAKE) -C docs reqs
|
$(Q) $(MAKE) -C docs reqs
|
||||||
|
|
||||||
.PHONY: docs/prep
|
.PHONY: docs/prep
|
||||||
docs/prep: docs/source/generated/cells.json docs/source/generated/cmds.json docs/gen docs/usage docs/gen/functional_ir docs/gen/chformal
|
docs/prep: docs/source/cmd/abc.rst docs/source/generated/cells.json docs/gen docs/usage docs/gen/functional_ir
|
||||||
|
|
||||||
DOC_TARGET ?= html
|
DOC_TARGET ?= html
|
||||||
docs: docs/prep
|
docs: docs/prep
|
||||||
|
@ -1114,7 +1122,7 @@ clean:
|
||||||
rm -f tests/tools/cmp_tbdata
|
rm -f tests/tools/cmp_tbdata
|
||||||
rm -f $(addsuffix /run-test.mk,$(MK_TEST_DIRS))
|
rm -f $(addsuffix /run-test.mk,$(MK_TEST_DIRS))
|
||||||
-$(MAKE) -C docs clean
|
-$(MAKE) -C docs clean
|
||||||
rm -rf docs/util/__pycache__
|
rm -rf docs/source/cmd docs/util/__pycache__
|
||||||
rm -f *.whl
|
rm -f *.whl
|
||||||
rm -f libyosys.so
|
rm -f libyosys.so
|
||||||
|
|
||||||
|
|
|
@ -116,9 +116,7 @@ struct MemContentsTest {
|
||||||
|
|
||||||
struct FunctionalTestGeneric : public Pass
|
struct FunctionalTestGeneric : public Pass
|
||||||
{
|
{
|
||||||
FunctionalTestGeneric() : Pass("test_generic", "test the generic compute graph") {
|
FunctionalTestGeneric() : Pass("test_generic", "test the generic compute graph") {}
|
||||||
internal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
|
|
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
|
@ -1,4 +1,5 @@
|
||||||
/build/
|
/build/
|
||||||
|
/source/cmd
|
||||||
/source/generated
|
/source/generated
|
||||||
/source/_images/**/*.log
|
/source/_images/**/*.log
|
||||||
/source/_images/**/*.aux
|
/source/_images/**/*.aux
|
||||||
|
|
|
@ -47,7 +47,7 @@ help:
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: clean-examples
|
clean: clean-examples
|
||||||
rm -rf $(BUILDDIR)/*
|
rm -rf $(BUILDDIR)/*
|
||||||
rm -rf util/__pycache__
|
rm -rf source/cmd util/__pycache__
|
||||||
rm -rf source/generated
|
rm -rf source/generated
|
||||||
$(MAKE) -C source/_images clean
|
$(MAKE) -C source/_images clean
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,3 @@
|
||||||
.literal-block-wrapper .code-block-caption .caption-number {
|
.literal-block-wrapper .code-block-caption .caption-number {
|
||||||
padding-right: 0.5em
|
padding-right: 0.5em
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't double shrink text in a literal in an optionlist */
|
|
||||||
kbd .option>.literal {
|
|
||||||
font-size: revert;
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ ezSAT
|
||||||
|
|
||||||
The files in ``libs/ezsat`` provide a library for simplifying generating CNF
|
The files in ``libs/ezsat`` provide a library for simplifying generating CNF
|
||||||
formulas for SAT solvers. It also contains bindings of MiniSAT. The ezSAT
|
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
|
fst
|
||||||
---
|
---
|
||||||
|
@ -77,4 +78,4 @@ SubCircuit
|
||||||
The files in ``libs/subcircuit`` provide a library for solving the 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 problem. It is written by C. Wolf and based on the Ullmann Subgraph
|
||||||
Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the
|
Isomorphism Algorithm :cite:p:`UllmannSubgraphIsomorphism`. It is used by the
|
||||||
`extract` pass.
|
extract pass (see :doc:`../cmd/extract`).
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
Writing output files
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: backends
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Formal verification
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: formal
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Reading input files
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: frontends
|
|
||||||
:members:
|
|
|
@ -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
|
|
|
@ -1,5 +0,0 @@
|
||||||
Yosys kernel commands
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: kernel
|
|
||||||
:members:
|
|
|
@ -1,9 +0,0 @@
|
||||||
:orphan:
|
|
||||||
|
|
||||||
Other commands
|
|
||||||
==============
|
|
||||||
|
|
||||||
Unknown source location
|
|
||||||
|
|
||||||
.. autocmdgroup:: unknown
|
|
||||||
:members:
|
|
|
@ -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_*
|
|
|
@ -1,5 +0,0 @@
|
||||||
Design modification
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/cmds
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Equivalence checking
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/equiv
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
FSM handling
|
|
||||||
------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/fsm
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Working with hierarchy
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/hierarchy
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Memory handling
|
|
||||||
---------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/memory
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Optimization passes
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/opt
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Converting process blocks
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/proc
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Simulating circuits
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/sat
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Design status
|
|
||||||
-------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/status
|
|
||||||
:members:
|
|
|
@ -1,7 +0,0 @@
|
||||||
Technology mapping
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. seealso:: :doc:`/cmd/index_techlibs`
|
|
||||||
|
|
||||||
.. autocmdgroup:: passes/techmap
|
|
||||||
:members:
|
|
|
@ -1,11 +0,0 @@
|
||||||
Technology libraries
|
|
||||||
====================
|
|
||||||
|
|
||||||
Listed in alphabetical order.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
:glob:
|
|
||||||
|
|
||||||
/cmd/index_techlibs_common
|
|
||||||
/cmd/index_techlibs_*
|
|
|
@ -1,5 +0,0 @@
|
||||||
Achronix
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/achronix
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Anlogic
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/anlogic
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Generic
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/common
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
CoolRunner-II
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/coolrunner2
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
eASIC
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/easic
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
ECP5
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/ecp5
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
FABulous
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/fabulous
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Gatemate
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/gatemate
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Gowin
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/gowin
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
GreenPAK4
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/greenpak4
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
iCE40
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/ice40
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Intel (MAX10, Cyclone IV)
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/intel
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Intel ALM (Cyclone V, Arria V, Cyclone 10 GX)
|
|
||||||
---------------------------------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/intel_alm
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Lattice
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/lattice
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Lattice Nexus
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/nexus
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Microchip
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/microchip
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Microchip - SmartFusion2/IGLOO2
|
|
||||||
-----------------------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/sf2
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
NanoXplore
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/nanoxplore
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
QuickLogic
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/quicklogic
|
|
||||||
:members:
|
|
|
@ -1,5 +0,0 @@
|
||||||
Xilinx
|
|
||||||
------------------
|
|
||||||
|
|
||||||
.. autocmdgroup:: techlibs/xilinx
|
|
||||||
:members:
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _cmd_ref:
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
Command line reference
|
Command line reference
|
||||||
================================================================================
|
================================================================================
|
||||||
|
@ -5,31 +7,10 @@ Command line reference
|
||||||
.. literalinclude:: /generated/yosys
|
.. literalinclude:: /generated/yosys
|
||||||
:start-at: Usage
|
: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::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:caption: Command reference
|
||||||
|
:maxdepth: 1
|
||||||
|
:glob:
|
||||||
|
|
||||||
/appendix/env_vars
|
/appendix/env_vars
|
||||||
/cmd/index_frontends
|
/cmd/*
|
||||||
/cmd/index_backends
|
|
||||||
/cmd/index_kernel
|
|
||||||
/cmd/index_formal
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 3
|
|
||||||
|
|
||||||
/cmd/index_passes
|
|
||||||
/cmd/index_techlibs
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
/cmd/index_internal
|
|
||||||
|
|
|
@ -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
|
|
|
@ -43,12 +43,8 @@ html_static_path = ['_static', "_images"]
|
||||||
# default to no highlight
|
# default to no highlight
|
||||||
highlight_language = 'none'
|
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'
|
default_role = 'autoref'
|
||||||
rst_prolog = """
|
|
||||||
.. role:: yoscrypt(code)
|
|
||||||
:language: yoscrypt
|
|
||||||
"""
|
|
||||||
|
|
||||||
extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex']
|
extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.bibtex']
|
||||||
|
|
||||||
|
@ -110,14 +106,12 @@ latex_elements = {
|
||||||
|
|
||||||
# custom cmd-ref parsing/linking
|
# custom cmd-ref parsing/linking
|
||||||
sys.path += [os.path.dirname(__file__) + "/../"]
|
sys.path += [os.path.dirname(__file__) + "/../"]
|
||||||
extensions.append('util.custom_directives')
|
extensions.append('util.cmdref')
|
||||||
|
|
||||||
# use autodocs
|
# use autodocs
|
||||||
extensions.append('sphinx.ext.autodoc')
|
extensions.append('sphinx.ext.autodoc')
|
||||||
extensions.append('util.cell_documenter')
|
extensions.append('util.cellref')
|
||||||
cells_json = Path(__file__).parent / 'generated' / 'cells.json'
|
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
|
from sphinx.application import Sphinx
|
||||||
def setup(app: Sphinx) -> None:
|
def setup(app: Sphinx) -> None:
|
||||||
|
|
|
@ -70,7 +70,7 @@ At the bottom of the `help` output for
|
||||||
`synth_ice40` is the complete list of commands called by this script.
|
`synth_ice40` is the complete list of commands called by this script.
|
||||||
Let's start with the section labeled ``begin``:
|
Let's start with the section labeled ``begin``:
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: begin:
|
:start-after: begin:
|
||||||
:end-before: flatten:
|
: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``
|
@`` block. In the case of an ``initial`` block, we instead see the ``PROC``
|
||||||
referring to line 0.
|
referring to line 0.
|
||||||
|
|
||||||
To handle these, let us now introduce the next command: :cmd:title:`proc`.
|
To handle these, let us now introduce the next command: :doc:`/cmd/proc`. `proc`
|
||||||
`proc` is a macro command like `synth_ice40`. Rather than modifying the design
|
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`,
|
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
|
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
|
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::
|
.. 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
|
for example we could have called :yoscrypt:`opt_expr;;` instead of
|
||||||
:yoscrypt:`opt_expr; clean`. You may notice some scripts will end each line
|
:yoscrypt:`opt_expr; clean`. You may notice some scripts will end each line
|
||||||
with ``;;``. It is beneficial to run `clean` before inspecting intermediate
|
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
|
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:
|
could restart our shell session, but instead let's use two new commands:
|
||||||
|
|
||||||
- :cmd:title:`design`, and
|
- :doc:`/cmd/design`, and
|
||||||
- :cmd:title:`read_verilog`.
|
- :doc:`/cmd/read_verilog`.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/fifo/fifo.out
|
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||||
:language: doscon
|
: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
|
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 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,
|
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`.
|
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
|
:ref:`show_intro` section in :doc:`/getting_started/scripting_intro` has more on
|
||||||
how to use `show`.
|
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.
|
At this stage of a synthesis flow there are a few other commands we could run.
|
||||||
In `synth_ice40` we get these:
|
In `synth_ice40` we get these:
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: flatten:
|
:start-after: flatten:
|
||||||
:end-before: coarse:
|
:end-before: coarse:
|
||||||
|
@ -355,7 +355,7 @@ Part 1
|
||||||
|
|
||||||
In the iCE40 flow, we start with the following commands:
|
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
|
:language: yoscrypt
|
||||||
:start-after: coarse:
|
:start-after: coarse:
|
||||||
:end-before: wreduce
|
: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
|
Next up is :yoscrypt:`opt -nodffe -nosdff` performing a set of simple
|
||||||
optimizations on the design. This command also ensures that only a specific
|
optimizations on the design. This command also ensures that only a specific
|
||||||
subset of FF types are included, in preparation for the next command:
|
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
|
more detail in :doc:`/using_yosys/synthesis/opt` and
|
||||||
:doc:`/using_yosys/synthesis/fsm` respectively.
|
:doc:`/using_yosys/synthesis/fsm` respectively.
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ Part 2
|
||||||
|
|
||||||
The next group of commands performs a series of optimizations:
|
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
|
:language: yoscrypt
|
||||||
:start-at: wreduce
|
:start-at: wreduce
|
||||||
:end-before: t:$mul
|
:end-before: t:$mul
|
||||||
|
@ -411,7 +411,7 @@ The next group of commands performs a series of optimizations:
|
||||||
:caption: ``coarse`` section (part 2)
|
:caption: ``coarse`` section (part 2)
|
||||||
:name: synth_coarse2
|
: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
|
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||||
:language: doscon
|
:language: doscon
|
||||||
|
@ -432,7 +432,7 @@ the schematic and see the output of that cell has now changed.
|
||||||
|
|
||||||
``rdata`` output after `wreduce`
|
``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
|
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
|
: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
|
-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`.
|
:doc:`/using_yosys/synthesis/techmap_synth`.
|
||||||
|
|
||||||
Our next command to run is
|
Our next command to run is
|
||||||
:cmd:title:`memory_dff`.
|
:doc:`/cmd/memory_dff`.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/fifo/fifo.out
|
.. literalinclude:: /code_examples/fifo/fifo.out
|
||||||
:language: doscon
|
: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
|
-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.
|
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
|
:language: yoscrypt
|
||||||
:start-at: t:$mul
|
:start-at: t:$mul
|
||||||
:end-before: alumacc
|
:end-before: alumacc
|
||||||
|
@ -514,7 +514,7 @@ Part 4
|
||||||
|
|
||||||
That brings us to the fourth and final part for the iCE40 synthesis flow:
|
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
|
:language: yoscrypt
|
||||||
:start-at: alumacc
|
:start-at: alumacc
|
||||||
:end-before: map_ram:
|
: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
|
are now identical but may have been missed due to e.g. the difference between
|
||||||
`$add` and `$sub`.
|
`$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
|
macro command which we examine in more detail in
|
||||||
:doc:`/using_yosys/synthesis/memory`. For this document, let us focus just on
|
: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,
|
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
|
Mapping to hard memory blocks uses a combination of `memory_libmap` and
|
||||||
`techmap`.
|
`techmap`.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: map_ram:
|
:start-after: map_ram:
|
||||||
:end-before: map_ffram:
|
: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| replace:: :file:`techlibs/ice40/brams_map.v`
|
||||||
.. _techlibs/ice40/brams_map.v: https://github.com/YosysHQ/yosys/tree/main/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
|
:language: yoscrypt
|
||||||
:start-after: map_ffram:
|
:start-after: map_ffram:
|
||||||
:end-before: map_gates:
|
: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
|
single-bit `$_MUX_` and `$_DFFE_PP0P_` cells, while the `$alu` is replaced with
|
||||||
primitive `$_OR_` and `$_NOT_` gates and a `$lut` cell.
|
primitive `$_OR_` and `$_NOT_` gates and a `$lut` cell.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: map_gates:
|
:start-after: map_gates:
|
||||||
:end-before: map_ffs:
|
: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
|
`$_MUX_` cells where one of the inputs is a constant ``1'0``, replacing it
|
||||||
instead with an `$_AND_` cell.
|
instead with an `$_AND_` cell.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: map_ffs:
|
:start-after: map_ffs:
|
||||||
:end-before: map_luts:
|
:end-before: map_luts:
|
||||||
|
@ -725,7 +725,7 @@ LUTs
|
||||||
`abc`. For more on what these do, and what the difference between these two
|
`abc`. For more on what these do, and what the difference between these two
|
||||||
commands are, refer to :doc:`/using_yosys/synthesis/abc`.
|
commands are, refer to :doc:`/using_yosys/synthesis/abc`.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: map_luts:
|
:start-after: map_luts:
|
||||||
:end-before: map_cells:
|
: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``
|
Finally we use `techmap` to map the generic `$lut` cells to iCE40 ``SB_LUT4``
|
||||||
cells.
|
cells.
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: map_cells:
|
:start-after: map_cells:
|
||||||
:end-before: check:
|
:end-before: check:
|
||||||
|
@ -784,18 +784,19 @@ Final steps
|
||||||
The next section of the iCE40 synth flow performs some sanity checking and final
|
The next section of the iCE40 synth flow performs some sanity checking and final
|
||||||
tidy up:
|
tidy up:
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/synth_ice40.ys
|
.. literalinclude:: /cmd/synth_ice40.rst
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
:start-after: check:
|
:start-after: check:
|
||||||
|
:end-before: blif:
|
||||||
:dedent:
|
:dedent:
|
||||||
:name: check
|
:name: check
|
||||||
:caption: ``check`` section
|
:caption: ``check`` section
|
||||||
|
|
||||||
The new commands here are:
|
The new commands here are:
|
||||||
|
|
||||||
- :cmd:title:`autoname`,
|
- :doc:`/cmd/autoname`,
|
||||||
- :cmd:title:`stat`, and
|
- :doc:`/cmd/stat`, and
|
||||||
- :cmd:title:`blackbox`.
|
- :doc:`/cmd/blackbox`.
|
||||||
|
|
||||||
The output from `stat` is useful for checking resource utilization; providing a
|
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
|
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:
|
The iCE40 synthesis flow has the following output modes available:
|
||||||
|
|
||||||
- `write_blif`,
|
- :doc:`/cmd/write_blif`,
|
||||||
- `write_edif`, and
|
- :doc:`/cmd/write_edif`, and
|
||||||
- `write_json`.
|
- :doc:`/cmd/write_json`.
|
||||||
|
|
||||||
As an example, if we called :yoscrypt:`synth_ice40 -top fifo -json fifo.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
|
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
|
.. _nextpnr: https://github.com/YosysHQ/nextpnr
|
||||||
|
|
||||||
.. seealso:: :cmd:title:`synth_ice40`
|
.. seealso:: :doc:`/cmd/synth_ice40`
|
||||||
|
|
|
@ -122,7 +122,7 @@ module.
|
||||||
|
|
||||||
Detailed documentation of the select framework can be found under
|
Detailed documentation of the select framework can be found under
|
||||||
:doc:`/using_yosys/more_scripting/selections` or in the command reference at
|
:doc:`/using_yosys/more_scripting/selections` or in the command reference at
|
||||||
:cmd:title:`select`.
|
:doc:`/cmd/select`.
|
||||||
|
|
||||||
.. _show_intro:
|
.. _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
|
.. _GraphViz color docs: https://graphviz.org/doc/info/colors
|
||||||
|
|
||||||
For all of the options available to `show`, check the command reference at
|
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
|
.. seealso:: :ref:`interactive_show` on the
|
||||||
:doc:`/using_yosys/more_scripting/interactive_investigation` page.
|
:doc:`/using_yosys/more_scripting/interactive_investigation` page.
|
||||||
|
|
|
@ -5,7 +5,7 @@ Yosys Open SYnthesis Suite
|
||||||
Yosys is an open source framework for RTL synthesis. To learn more about Yosys,
|
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,
|
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
|
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
|
.. todo:: look into command ref improvements
|
||||||
|
|
||||||
|
|
|
@ -323,10 +323,10 @@ tools).
|
||||||
design into an equivalent design that is easier to analyse.
|
design into an equivalent design that is easier to analyse.
|
||||||
- Commands such as `eval` and `sat` can be used to investigate the behavior of
|
- Commands such as `eval` and `sat` can be used to investigate the behavior of
|
||||||
the circuit.
|
the circuit.
|
||||||
- :cmd:title:`show`.
|
- :doc:`/cmd/show`.
|
||||||
- :cmd:title:`dump`.
|
- :doc:`/cmd/dump`.
|
||||||
- :cmd:title:`add` and :cmd:title:`delete` can be used to modify and reorganize
|
- :doc:`/cmd/add` and :doc:`/cmd/delete` can be used to modify and reorganize a
|
||||||
a design dynamically.
|
design dynamically.
|
||||||
|
|
||||||
The code used is included in the Yosys code base under
|
The code used is included in the Yosys code base under
|
||||||
|code_examples/scrambler|_.
|
|code_examples/scrambler|_.
|
||||||
|
@ -358,7 +358,7 @@ reorganizing a module in Yosys and checking the resulting circuit.
|
||||||
.. figure:: /_images/code_examples/scrambler/scrambler_p02.*
|
.. figure:: /_images/code_examples/scrambler/scrambler_p02.*
|
||||||
:class: width-helper invert-helper
|
: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
|
.. todo:: replace inline code
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
Loading a design
|
Loading a design
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. TODO:: fill out this page better
|
|
||||||
|
|
||||||
keyword: Frontends
|
keyword: Frontends
|
||||||
|
|
||||||
- :doc:`/cmd/index_frontends`
|
- :doc:`/cmd/read_verilog`
|
||||||
|
|
||||||
.. todo:: include ``read_verilog <<EOF``, also other methods of loading designs
|
.. todo:: include ``read_verilog <<EOF``, also other methods of loading designs
|
||||||
|
|
||||||
|
@ -31,14 +29,20 @@ keyword: Frontends
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The Verific frontend for Yosys, which provides the `verific` command,
|
The Verific frontend for Yosys, which provides the :cmd:ref:`verific`
|
||||||
requires Yosys to be built with Verific. For full functionality, custom
|
command, requires Yosys to be built with Verific. For full functionality,
|
||||||
modifications to the Verific source code from YosysHQ are required, but
|
custom modifications to the Verific source code from YosysHQ are required,
|
||||||
limited useability can be achieved with some stock Verific builds. Check
|
but limited useability can be achieved with some stock Verific builds. Check
|
||||||
:doc:`/yosys_internals/extending_yosys/build_verific` for more.
|
:doc:`/yosys_internals/extending_yosys/build_verific` for more.
|
||||||
|
|
||||||
Others:
|
Others:
|
||||||
|
|
||||||
|
- :doc:`/cmd/read`
|
||||||
- `GHDL plugin`_ for VHDL
|
- `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
|
.. _GHDL plugin: https://github.com/ghdl/ghdl-yosys-plugin
|
||||||
|
|
|
@ -93,7 +93,7 @@ Special patterns can be used to select by object property or type. For example:
|
||||||
A:blabla`
|
A:blabla`
|
||||||
- select all `$add` cells from the module foo: :yoscrypt:`select foo/t:$add`
|
- 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
|
Operations on selections
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -141,7 +141,7 @@ Some of the special ``%``-codes:
|
||||||
- ``%i``: intersection of top two elements on stack -- pop 2, push 1
|
- ``%i``: intersection of top two elements on stack -- pop 2, push 1
|
||||||
- ``%n``: inverse of top element on stack -- pop 1, 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
|
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
|
powerful tools for extracting the relevant portions of the circuit under
|
||||||
investigation.
|
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
|
Incremental selection
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -10,7 +10,7 @@ other commands:
|
||||||
:start-after: #end:
|
:start-after: #end:
|
||||||
:caption: Passes called by `fsm`
|
: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
|
The algorithms used for FSM detection and extraction are influenced by a more
|
||||||
general reported technique :cite:p:`fsmextract`.
|
general reported technique :cite:p:`fsmextract`.
|
||||||
|
|
|
@ -26,7 +26,7 @@ Some quick notes:
|
||||||
decoder logic and registers.
|
decoder logic and registers.
|
||||||
|
|
||||||
For more information about `memory`, such as disabling certain sub commands, see
|
For more information about `memory`, such as disabling certain sub commands, see
|
||||||
:doc:`/cmd/index_passes_memory`.
|
:doc:`/cmd/memory`.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -11,8 +11,8 @@ The `opt` macro command
|
||||||
|
|
||||||
The Yosys pass `opt` runs a number of simple optimizations. This includes
|
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
|
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
|
this pass after each major step in the synthesis script. As listed in
|
||||||
calls the following ``opt_*`` commands:
|
:doc:`/cmd/opt`, this macro command calls the following ``opt_*`` commands:
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/opt.ys
|
.. literalinclude:: /code_examples/macro_commands/opt.ys
|
||||||
:language: yoscrypt
|
:language: yoscrypt
|
||||||
|
@ -233,5 +233,7 @@ Other optimizations
|
||||||
|
|
||||||
.. todo:: more on the 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`.
|
- `abc` and `abc9`, see also: :doc:`abc`.
|
||||||
|
|
|
@ -17,7 +17,7 @@ commands in a sensible order:
|
||||||
|
|
||||||
After all the ``proc_*`` commands, `opt_expr` is called. This can be disabled by
|
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
|
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
|
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
|
call to `proc` is the first command in the actual synthesis procedure after
|
||||||
|
|
|
@ -6,23 +6,44 @@ Synth commands
|
||||||
Packaged ``synth_*`` commands
|
Packaged ``synth_*`` commands
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
A list of all synth commands included in Yosys for different platforms can be
|
The following is a list of all synth commands included in Yosys for different
|
||||||
found under :doc:`/cmd/index_techlibs`. Each command runs a script of sub
|
platforms. Each command runs a script of sub commands specific to the platform
|
||||||
commands specific to the platform being targeted. Note that not all of these
|
being targeted. Note that not all of these scripts are actively maintained and
|
||||||
scripts are actively maintained and may not be up-to-date.
|
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
|
General synthesis
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
In addition to the above hardware-specific synth commands, there is also
|
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
|
getting into any architecture-specific mappings or optimizations. Among other
|
||||||
things, this is useful for design verification.
|
things, this is useful for design verification.
|
||||||
|
|
||||||
The following commands are executed by the `prep` command:
|
The following commands are executed by the `prep` command:
|
||||||
|
|
||||||
.. literalinclude:: /code_examples/macro_commands/prep.ys
|
.. literalinclude:: /cmd/prep.rst
|
||||||
:start-at: begin:
|
:start-at: begin:
|
||||||
|
:end-before: .. only:: latex
|
||||||
|
:dedent:
|
||||||
|
|
||||||
:doc:`/getting_started/example_synth` covers most of these commands and what
|
:doc:`/getting_started/example_synth` covers most of these commands and what
|
||||||
they do.
|
they do.
|
||||||
|
|
|
@ -33,9 +33,9 @@ reader may find this map file as :file:`techlibs/common/techmap.v` in the Yosys
|
||||||
source tree.
|
source tree.
|
||||||
|
|
||||||
Additional features have been added to techmap to allow for conditional mapping
|
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
|
of cells (see :doc:`/cmd/techmap`). This can for example be useful if the target
|
||||||
if the target architecture supports hardware multipliers for certain bit-widths
|
architecture supports hardware multipliers for certain bit-widths but not for
|
||||||
but not for others.
|
others.
|
||||||
|
|
||||||
A usual synthesis flow would first use the techmap pass to directly map some RTL
|
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
|
cells to coarse-grain cells provided by the target architecture (if any) and
|
||||||
|
|
|
@ -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
|
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
|
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
|
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
|
.. code-block:: cpp
|
||||||
:caption: Example hash compatibility wrapper
|
:caption: Example hash compatibility wrapper
|
||||||
|
|
|
@ -96,7 +96,7 @@ Verilog Attributes and non-standard features
|
||||||
- The ``keep_hierarchy`` attribute on cells and modules keeps the `flatten`
|
- The ``keep_hierarchy`` attribute on cells and modules keeps the `flatten`
|
||||||
command from flattening the indicated cells and modules.
|
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 estimated cost of the module as a number of basic gate instances. See
|
||||||
the help message of command `keep_hierarchy` which interprets this
|
the help message of command `keep_hierarchy` which interprets this
|
||||||
attribute.
|
attribute.
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
|
@ -4,21 +4,20 @@ from __future__ import annotations
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import cast
|
from typing import cast
|
||||||
import warnings
|
|
||||||
|
|
||||||
from docutils import nodes
|
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 import directives
|
||||||
from docutils.parsers.rst.states import Inliner
|
from docutils.parsers.rst.states import Inliner
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.domains import Domain, Index
|
from sphinx.domains import Domain, Index
|
||||||
from sphinx.domains.std import StandardDomain
|
from sphinx.domains.std import StandardDomain
|
||||||
from sphinx.environment import BuildEnvironment
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.roles import XRefRole, SphinxRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
from sphinx.directives.code import container_wrapper
|
from sphinx.directives.code import container_wrapper
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
from sphinx.util.docfields import Field, GroupedField
|
from sphinx.util.docfields import Field
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
|
||||||
class TocNode(ObjectDescription):
|
class TocNode(ObjectDescription):
|
||||||
|
@ -32,7 +31,7 @@ class TocNode(ObjectDescription):
|
||||||
signode['ids'].append(idx)
|
signode['ids'].append(idx)
|
||||||
|
|
||||||
def _object_hierarchy_parts(self, sig_node: addnodes.desc_signature) -> tuple[str, ...]:
|
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 ()
|
return ()
|
||||||
|
|
||||||
modname = sig_node.get('module')
|
modname = sig_node.get('module')
|
||||||
|
@ -58,56 +57,16 @@ class TocNode(ObjectDescription):
|
||||||
return '.'.join(parents + [name])
|
return '.'.join(parents + [name])
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
class NodeWithOptions(TocNode):
|
class CommandNode(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):
|
|
||||||
"""A custom node that describes a command."""
|
"""A custom node that describes a command."""
|
||||||
|
|
||||||
name = 'cmd'
|
name = 'cmd'
|
||||||
required_arguments = 1
|
required_arguments = 1
|
||||||
|
|
||||||
option_spec = NodeWithOptions.option_spec.copy()
|
option_spec = {
|
||||||
option_spec.update({
|
|
||||||
'title': directives.unchanged,
|
'title': directives.unchanged,
|
||||||
'tags': directives.unchanged
|
'tags': directives.unchanged
|
||||||
})
|
}
|
||||||
|
|
||||||
def handle_signature(self, sig, signode: addnodes.desc_signature):
|
def handle_signature(self, sig, signode: addnodes.desc_signature):
|
||||||
signode['fullname'] = sig
|
signode['fullname'] = sig
|
||||||
|
@ -134,46 +93,6 @@ class CommandNode(NodeWithOptions):
|
||||||
idx,
|
idx,
|
||||||
0))
|
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):
|
class PropNode(TocNode):
|
||||||
name = 'prop'
|
name = 'prop'
|
||||||
fieldname = 'props'
|
fieldname = 'props'
|
||||||
|
@ -474,7 +393,7 @@ class TagIndex(Index):
|
||||||
lis.append((
|
lis.append((
|
||||||
dispname, 0, docname,
|
dispname, 0, docname,
|
||||||
anchor,
|
anchor,
|
||||||
'', '', ''
|
docname, '', typ
|
||||||
))
|
))
|
||||||
ret = [(k, v) for k, v in sorted(content.items())]
|
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.
|
Qualifier and description are not rendered e.g. in LaTeX output.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
content: dict[str, list[tuple]] = {}
|
content = {}
|
||||||
items = ((name, dispname, typ, docname, anchor)
|
items = ((name, dispname, typ, docname, anchor)
|
||||||
for name, dispname, typ, docname, anchor, prio
|
for name, dispname, typ, docname, anchor, prio
|
||||||
in self.domain.get_objects()
|
in self.domain.get_objects()
|
||||||
if typ == self.name)
|
if typ == self.name)
|
||||||
items = sorted(items, key=lambda item: item[0])
|
items = sorted(items, key=lambda item: item[0])
|
||||||
for name, dispname, typ, docname, anchor in items:
|
for name, dispname, typ, docname, anchor in items:
|
||||||
title = self.domain.data['obj2title'].get(name)
|
|
||||||
lis = content.setdefault(self.shortname, [])
|
lis = content.setdefault(self.shortname, [])
|
||||||
lis.append((
|
lis.append((
|
||||||
dispname, 0, docname,
|
dispname, 0, docname,
|
||||||
anchor,
|
anchor,
|
||||||
'', '', title
|
'', '', typ
|
||||||
))
|
))
|
||||||
ret = [(k, v) for k, v in sorted(content.items())]
|
ret = [(k, v) for k, v in sorted(content.items())]
|
||||||
|
|
||||||
|
@ -589,27 +507,16 @@ class PropIndex(TagIndex):
|
||||||
|
|
||||||
return (ret, True)
|
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):
|
class CommandDomain(Domain):
|
||||||
name = 'cmd'
|
name = 'cmd'
|
||||||
label = 'Yosys commands'
|
label = 'Yosys commands'
|
||||||
|
|
||||||
roles = {
|
roles = {
|
||||||
'ref': XRefRole(),
|
'ref': XRefRole()
|
||||||
'title': TitleRefRole(),
|
|
||||||
'option': OptionRole(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
directives = {
|
directives = {
|
||||||
'def': CommandNode,
|
'def': CommandNode,
|
||||||
'usage': CommandUsageNode,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
indices = {
|
indices = {
|
||||||
|
@ -646,15 +553,7 @@ class CommandDomain(Domain):
|
||||||
qual_name = match[0][2]
|
qual_name = match[0][2]
|
||||||
title = self.data['obj2title'].get(qual_name, targ)
|
title = self.data['obj2title'].get(qual_name, targ)
|
||||||
|
|
||||||
if typ == 'title':
|
return make_refnode(builder,fromdocname,todocname,
|
||||||
# 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)
|
targ, contnode, title)
|
||||||
else:
|
else:
|
||||||
print(f"Missing ref for {target} in {fromdocname} ")
|
print(f"Missing ref for {target} in {fromdocname} ")
|
||||||
|
@ -693,18 +592,10 @@ class CellDomain(CommandDomain):
|
||||||
|
|
||||||
def autoref(name, rawtext: str, text: str, lineno, inliner: Inliner,
|
def autoref(name, rawtext: str, text: str, lineno, inliner: Inliner,
|
||||||
options=None, content=None):
|
options=None, content=None):
|
||||||
words = text.split(' ')
|
role = 'cell:ref' if text[0] == '$' else 'cmd:ref'
|
||||||
if len(words) == 2 and words[0] == "help":
|
if text.startswith("help ") and text.count(' ') == 1:
|
||||||
IsLinkable = True
|
_, cmd = text.split(' ', 1)
|
||||||
thing = words[1]
|
text = f'{text} <{cmd}>'
|
||||||
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'
|
|
||||||
return inliner.interpreted(rawtext, text, role, lineno)
|
return inliner.interpreted(rawtext, text, role, lineno)
|
||||||
|
|
||||||
def setup(app: Sphinx):
|
def setup(app: Sphinx):
|
||||||
|
@ -731,7 +622,4 @@ def setup(app: Sphinx):
|
||||||
|
|
||||||
app.add_role('autoref', autoref)
|
app.add_role('autoref', autoref)
|
||||||
|
|
||||||
return {
|
return {'version': '0.2'}
|
||||||
'version': '0.3',
|
|
||||||
'parallel_read_safe': False,
|
|
||||||
}
|
|
|
@ -90,10 +90,10 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void array(const T &&values)
|
void array(const T &&values)
|
||||||
{
|
{
|
||||||
begin_array();
|
begin_object();
|
||||||
for (auto &item : values)
|
for (auto &item : values)
|
||||||
value(item);
|
value(item);
|
||||||
end_array();
|
end_object();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,151 +0,0 @@
|
||||||
/*
|
|
||||||
* yosys -- Yosys Open SYnthesis Suite
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 Krystine Dawn <krystinedawn@yosyshq.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
|
||||||
|
|
||||||
Json ContentListing::to_json() {
|
|
||||||
Json::object object;
|
|
||||||
object["type"] = type;
|
|
||||||
if (body.length()) object["body"] = body;
|
|
||||||
if (strcmp(source_file, "unknown") != 0) object["source_file"] = source_file;
|
|
||||||
if (source_line != 0) object["source_line"] = source_line;
|
|
||||||
object["options"] = Json(options);
|
|
||||||
Json::array content_array;
|
|
||||||
for (auto child : _content) content_array.push_back(child->to_json());
|
|
||||||
object["content"] = content_array;
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContentListing::usage(const string &text,
|
|
||||||
const source_location location)
|
|
||||||
{
|
|
||||||
log_assert(type.compare("root") == 0);
|
|
||||||
add_content("usage", text, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContentListing::option(const string &text, const string &description,
|
|
||||||
const source_location location)
|
|
||||||
{
|
|
||||||
auto option = open_option(text);
|
|
||||||
if (description.length())
|
|
||||||
option->add_content("text", description, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContentListing::codeblock(const string &code, const string &language,
|
|
||||||
const source_location location)
|
|
||||||
{
|
|
||||||
add_content("code", code, location);
|
|
||||||
back()->set_option("language", language);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContentListing::paragraph(const string &text,
|
|
||||||
const source_location location)
|
|
||||||
{
|
|
||||||
add_content("text", text, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentListing* ContentListing::open_usage(const string &text,
|
|
||||||
const source_location location)
|
|
||||||
{
|
|
||||||
usage(text, location);
|
|
||||||
return back();
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentListing* ContentListing::open_option(const string &text,
|
|
||||||
const source_location location)
|
|
||||||
{
|
|
||||||
log_assert(type.compare("root") == 0 || type.compare("usage") == 0);
|
|
||||||
auto option = new ContentListing("option", text, location);
|
|
||||||
add_content(option);
|
|
||||||
return option;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAX_LINE_LEN 80
|
|
||||||
void log_pass_str(const std::string &pass_str, std::string indent_str, bool leading_newline=false) {
|
|
||||||
if (pass_str.empty())
|
|
||||||
return;
|
|
||||||
std::istringstream iss(pass_str);
|
|
||||||
if (leading_newline)
|
|
||||||
log("\n");
|
|
||||||
for (std::string line; std::getline(iss, line);) {
|
|
||||||
log("%s", indent_str.c_str());
|
|
||||||
auto curr_len = indent_str.length();
|
|
||||||
std::istringstream lss(line);
|
|
||||||
for (std::string word; std::getline(lss, word, ' ');) {
|
|
||||||
while (word[0] == '`' && word.back() == '`')
|
|
||||||
word = word.substr(1, word.length()-2);
|
|
||||||
if (curr_len + word.length() >= MAX_LINE_LEN-1) {
|
|
||||||
curr_len = 0;
|
|
||||||
log("\n%s", indent_str.c_str());
|
|
||||||
}
|
|
||||||
if (word.length()) {
|
|
||||||
log("%s ", word.c_str());
|
|
||||||
curr_len += word.length() + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void log_pass_str(const std::string &pass_str, int indent=0, bool leading_newline=false) {
|
|
||||||
std::string indent_str(indent*4, ' ');
|
|
||||||
log_pass_str(pass_str, indent_str, leading_newline);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrettyHelp *current_help = nullptr;
|
|
||||||
|
|
||||||
PrettyHelp::PrettyHelp()
|
|
||||||
{
|
|
||||||
_prior = current_help;
|
|
||||||
_root_listing = ContentListing("root", "");
|
|
||||||
|
|
||||||
current_help = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrettyHelp::~PrettyHelp()
|
|
||||||
{
|
|
||||||
current_help = _prior;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrettyHelp *PrettyHelp::get_current()
|
|
||||||
{
|
|
||||||
if (current_help == nullptr)
|
|
||||||
new PrettyHelp();
|
|
||||||
return current_help;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrettyHelp::log_help()
|
|
||||||
{
|
|
||||||
for (auto content : _root_listing.get_content()) {
|
|
||||||
if (content->type.compare("usage") == 0) {
|
|
||||||
log_pass_str(content->body, 1, true);
|
|
||||||
log("\n");
|
|
||||||
} else if (content->type.compare("option") == 0) {
|
|
||||||
log_pass_str(content->body, 1);
|
|
||||||
for (auto text : content->get_content()) {
|
|
||||||
log_pass_str(text->body, 2);
|
|
||||||
log("\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log_pass_str(content->body, 0);
|
|
||||||
log("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* yosys -- Yosys Open SYnthesis Suite
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 Krystine Dawn <krystinedawn@yosyshq.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LOG_HELP_H
|
|
||||||
#define LOG_HELP_H
|
|
||||||
|
|
||||||
#include "kernel/yosys_common.h"
|
|
||||||
#include "kernel/json.h"
|
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
class ContentListing {
|
|
||||||
vector<ContentListing *> _content;
|
|
||||||
public:
|
|
||||||
string type;
|
|
||||||
string body;
|
|
||||||
const char* source_file;
|
|
||||||
int source_line;
|
|
||||||
std::map<string, string> options;
|
|
||||||
|
|
||||||
ContentListing(
|
|
||||||
string type = "root", string body = "",
|
|
||||||
const char* source_file = "unknown", int source_line = 0
|
|
||||||
) : type(type), body(body), source_file(source_file), source_line(source_line) {
|
|
||||||
_content = {};
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentListing(string type, string body, source_location location) :
|
|
||||||
ContentListing(type, body, location.file_name(), location.line()) { }
|
|
||||||
|
|
||||||
void add_content(ContentListing *new_content) {
|
|
||||||
_content.push_back(new_content);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_content(string type, string body, source_location location) {
|
|
||||||
auto new_content = new ContentListing(type, body, location);
|
|
||||||
add_content(new_content);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool has_content() { return _content.size() != 0; }
|
|
||||||
const vector<ContentListing *> get_content() {
|
|
||||||
const vector<ContentListing *> content = _content;
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
ContentListing* back() {
|
|
||||||
return _content.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_option(string key, string val = "") {
|
|
||||||
options[key] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void usage(
|
|
||||||
const string &text,
|
|
||||||
const source_location location = source_location::current()
|
|
||||||
);
|
|
||||||
void option(
|
|
||||||
const string &text,
|
|
||||||
const string &description = "",
|
|
||||||
const source_location location = source_location::current()
|
|
||||||
);
|
|
||||||
void codeblock(
|
|
||||||
const string &code,
|
|
||||||
const string &language = "none",
|
|
||||||
const source_location location = source_location::current()
|
|
||||||
);
|
|
||||||
void paragraph(
|
|
||||||
const string &text,
|
|
||||||
const source_location location = source_location::current()
|
|
||||||
);
|
|
||||||
|
|
||||||
ContentListing* open_usage(
|
|
||||||
const string &text,
|
|
||||||
const source_location location = source_location::current()
|
|
||||||
);
|
|
||||||
ContentListing* open_option(
|
|
||||||
const string &text,
|
|
||||||
const source_location location = source_location::current()
|
|
||||||
);
|
|
||||||
|
|
||||||
Json to_json();
|
|
||||||
};
|
|
||||||
|
|
||||||
class PrettyHelp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
string group = "unknown";
|
|
||||||
|
|
||||||
private:
|
|
||||||
PrettyHelp *_prior;
|
|
||||||
ContentListing _root_listing;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PrettyHelp();
|
|
||||||
~PrettyHelp();
|
|
||||||
|
|
||||||
static PrettyHelp *get_current();
|
|
||||||
|
|
||||||
bool has_content() { return _root_listing.has_content(); }
|
|
||||||
const vector<ContentListing *> get_content() {
|
|
||||||
return _root_listing.get_content();
|
|
||||||
}
|
|
||||||
ContentListing* get_root() {
|
|
||||||
return &_root_listing;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_group(const string g) { group = g; }
|
|
||||||
bool has_group() { return group.compare("unknown") != 0; }
|
|
||||||
|
|
||||||
void log_help();
|
|
||||||
};
|
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "kernel/satgen.h"
|
#include "kernel/satgen.h"
|
||||||
#include "kernel/json.h"
|
#include "kernel/json.h"
|
||||||
#include "kernel/gzip.h"
|
#include "kernel/gzip.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -42,8 +41,7 @@ std::map<std::string, Backend*> backend_register;
|
||||||
|
|
||||||
std::vector<std::string> Frontend::next_args;
|
std::vector<std::string> Frontend::next_args;
|
||||||
|
|
||||||
Pass::Pass(std::string name, std::string short_help, source_location location) :
|
Pass::Pass(std::string name, std::string short_help) : pass_name(name), short_help(short_help)
|
||||||
pass_name(name), short_help(short_help), location(location)
|
|
||||||
{
|
{
|
||||||
next_queued_pass = first_queued_pass;
|
next_queued_pass = first_queued_pass;
|
||||||
first_queued_pass = this;
|
first_queued_pass = this;
|
||||||
|
@ -118,19 +116,9 @@ void Pass::post_execute(Pass::pre_post_exec_state_t state)
|
||||||
|
|
||||||
void Pass::help()
|
void Pass::help()
|
||||||
{
|
{
|
||||||
auto prettyHelp = PrettyHelp();
|
|
||||||
if (formatted_help()) {
|
|
||||||
prettyHelp.log_help();
|
|
||||||
} else {
|
|
||||||
log("\n");
|
log("\n");
|
||||||
log("No help message for command `%s'.\n", pass_name.c_str());
|
log("No help message for command `%s'.\n", pass_name.c_str());
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Pass::formatted_help()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pass::clear_flags()
|
void Pass::clear_flags()
|
||||||
|
@ -393,8 +381,8 @@ void ScriptPass::help_script()
|
||||||
script();
|
script();
|
||||||
}
|
}
|
||||||
|
|
||||||
Frontend::Frontend(std::string name, std::string short_help, source_location location) :
|
Frontend::Frontend(std::string name, std::string short_help) :
|
||||||
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help, location),
|
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "read_" + name, short_help),
|
||||||
frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
|
frontend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -539,8 +527,8 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Backend::Backend(std::string name, std::string short_help, source_location location) :
|
Backend::Backend(std::string name, std::string short_help) :
|
||||||
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "write_" + name, short_help, location),
|
Pass(name.rfind("=", 0) == 0 ? name.substr(1) : "write_" + name, short_help),
|
||||||
backend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
|
backend_name(name.rfind("=", 0) == 0 ? name.substr(1) : name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -693,23 +681,6 @@ static string get_cell_name(string name) {
|
||||||
return is_code_getter(name) ? name.substr(0, name.length()-1) : name;
|
return is_code_getter(name) ? name.substr(0, name.length()-1) : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_warning_flags(Pass *pass) {
|
|
||||||
bool has_warnings = false;
|
|
||||||
const string name = pass->pass_name;
|
|
||||||
if (pass->experimental_flag) {
|
|
||||||
if (!has_warnings) log("\n");
|
|
||||||
has_warnings = true;
|
|
||||||
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", name.c_str());
|
|
||||||
}
|
|
||||||
if (pass->internal_flag) {
|
|
||||||
if (!has_warnings) log("\n");
|
|
||||||
has_warnings = true;
|
|
||||||
log("WARNING: THE '%s' COMMAND IS INTENDED FOR INTERNAL DEVELOPER USE ONLY.\n", name.c_str());
|
|
||||||
}
|
|
||||||
if (has_warnings)
|
|
||||||
log("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct CellHelpMessages {
|
static struct CellHelpMessages {
|
||||||
dict<string, SimHelper> cell_help;
|
dict<string, SimHelper> cell_help;
|
||||||
CellHelpMessages() {
|
CellHelpMessages() {
|
||||||
|
@ -735,72 +706,37 @@ struct HelpPass : public Pass {
|
||||||
log(" help <celltype>+ .... print verilog code for given cell type\n");
|
log(" help <celltype>+ .... print verilog code for given cell type\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
bool dump_cmds_json(PrettyJson &json) {
|
void write_cmd_rst(std::string cmd, std::string title, std::string text)
|
||||||
// init json
|
{
|
||||||
json.begin_object();
|
FILE *f = fopen(stringf("docs/source/cmd/%s.rst", cmd.c_str()).c_str(), "wt");
|
||||||
json.entry("version", "Yosys command reference");
|
// make header
|
||||||
json.entry("generator", yosys_version_str);
|
size_t char_len = cmd.length() + 3 + title.length();
|
||||||
|
std::string title_line = "\n";
|
||||||
|
title_line.insert(0, char_len, '=');
|
||||||
|
fprintf(f, "%s", title_line.c_str());
|
||||||
|
fprintf(f, "%s - %s\n", cmd.c_str(), title.c_str());
|
||||||
|
fprintf(f, "%s\n", title_line.c_str());
|
||||||
|
|
||||||
bool raise_error = false;
|
// render html
|
||||||
std::map<string, vector<string>> groups;
|
fprintf(f, ".. cmd:def:: %s\n", cmd.c_str());
|
||||||
|
fprintf(f, " :title: %s\n\n", title.c_str());
|
||||||
json.name("cmds"); json.begin_object();
|
fprintf(f, " .. only:: html\n\n");
|
||||||
// iterate over commands
|
|
||||||
for (auto &it : pass_register) {
|
|
||||||
auto name = it.first;
|
|
||||||
auto pass = it.second;
|
|
||||||
auto title = pass->short_help;
|
|
||||||
|
|
||||||
auto cmd_help = PrettyHelp();
|
|
||||||
auto has_pretty_help = pass->formatted_help();
|
|
||||||
|
|
||||||
if (!has_pretty_help) {
|
|
||||||
enum PassUsageState {
|
|
||||||
PUState_none,
|
|
||||||
PUState_signature,
|
|
||||||
PUState_options,
|
|
||||||
PUState_optionbody,
|
|
||||||
};
|
|
||||||
|
|
||||||
source_location null_source;
|
|
||||||
string current_buffer = "";
|
|
||||||
auto root_listing = cmd_help.get_root();
|
|
||||||
auto current_listing = root_listing;
|
|
||||||
|
|
||||||
// dump command help
|
|
||||||
std::ostringstream buf;
|
|
||||||
log_streams.push_back(&buf);
|
|
||||||
pass->help();
|
|
||||||
log_streams.pop_back();
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << buf.str();
|
std::string textcp = text;
|
||||||
|
ss << text;
|
||||||
// parse command help
|
bool IsUsage = true;
|
||||||
|
int blank_count = 0;
|
||||||
size_t def_strip_count = 0;
|
size_t def_strip_count = 0;
|
||||||
auto current_state = PUState_none;
|
bool WasDefinition = false;
|
||||||
auto catch_verific = false;
|
for (std::string line; std::getline(ss, line, '\n');) {
|
||||||
auto blank_lines = 2;
|
|
||||||
for (string line; std::getline(ss, line, '\n');) {
|
|
||||||
// find position of first non space character
|
// find position of first non space character
|
||||||
std::size_t first_pos = line.find_first_not_of(" \t");
|
std::size_t first_pos = line.find_first_not_of(" \t");
|
||||||
std::size_t last_pos = line.find_last_not_of(" \t");
|
std::size_t last_pos = line.find_last_not_of(" \t");
|
||||||
if (first_pos == std::string::npos) {
|
if (first_pos == std::string::npos) {
|
||||||
switch (current_state)
|
// skip formatting empty lines
|
||||||
{
|
if (!WasDefinition)
|
||||||
case PUState_signature:
|
fputc('\n', f);
|
||||||
root_listing->usage(current_buffer, null_source);
|
blank_count += 1;
|
||||||
current_listing = root_listing;
|
|
||||||
current_state = PUState_none;
|
|
||||||
current_buffer = "";
|
|
||||||
break;
|
|
||||||
case PUState_none:
|
|
||||||
case PUState_optionbody:
|
|
||||||
blank_lines += 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// skip empty lines
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,138 +744,117 @@ struct HelpPass : public Pass {
|
||||||
std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1);
|
std::string stripped_line = line.substr(first_pos, last_pos - first_pos +1);
|
||||||
bool IsDefinition = stripped_line[0] == '-';
|
bool IsDefinition = stripped_line[0] == '-';
|
||||||
IsDefinition &= stripped_line[1] != ' ' && stripped_line[1] != '>';
|
IsDefinition &= stripped_line[1] != ' ' && stripped_line[1] != '>';
|
||||||
bool IsDedent = def_strip_count && first_pos < def_strip_count;
|
bool IsDedent = def_strip_count && first_pos <= def_strip_count;
|
||||||
bool IsIndent = def_strip_count < first_pos;
|
bool IsIndent = first_pos == 2 || first_pos == 4;
|
||||||
|
if (cmd.compare(0, 7, "verific") == 0)
|
||||||
|
// verific.cc has strange and different formatting from the rest
|
||||||
|
IsIndent = false;
|
||||||
|
|
||||||
// line looks like a signature
|
// another usage block
|
||||||
bool IsSignature = stripped_line.find(name) == 0 && (stripped_line.length() == name.length() || stripped_line.at(name.size()) == ' ');
|
bool NewUsage = stripped_line.find(cmd) == 0;
|
||||||
|
|
||||||
if (IsSignature && first_pos <= 4 && (blank_lines >= 2 || current_state == PUState_signature)) {
|
if (IsUsage) {
|
||||||
if (current_state == PUState_options || current_state == PUState_optionbody) {
|
if (stripped_line.compare(0, 4, "See ") == 0) {
|
||||||
current_listing->codeblock(current_buffer, "none", null_source);
|
// description refers to another function
|
||||||
current_buffer = "";
|
fprintf(f, "\n %s\n", stripped_line.c_str());
|
||||||
} else if (current_state == PUState_signature) {
|
|
||||||
root_listing->usage(current_buffer, null_source);
|
|
||||||
current_buffer = "";
|
|
||||||
} else if (current_state == PUState_none && !current_buffer.empty()) {
|
|
||||||
current_listing->codeblock(current_buffer, "none", null_source);
|
|
||||||
current_buffer = "";
|
|
||||||
}
|
|
||||||
current_listing = root_listing;
|
|
||||||
current_state = PUState_signature;
|
|
||||||
def_strip_count = first_pos;
|
|
||||||
catch_verific = false;
|
|
||||||
} else if (IsDedent) {
|
|
||||||
def_strip_count = first_pos;
|
|
||||||
if (current_state == PUState_optionbody) {
|
|
||||||
if (!current_buffer.empty()) {
|
|
||||||
current_listing->codeblock(current_buffer, "none", null_source);
|
|
||||||
current_buffer = "";
|
|
||||||
}
|
|
||||||
if (IsIndent) {
|
|
||||||
current_state = PUState_options;
|
|
||||||
current_listing = root_listing->back();
|
|
||||||
} else {
|
} else {
|
||||||
current_state = PUState_none;
|
// usage should be the first line of help output
|
||||||
current_listing = root_listing;
|
fprintf(f, "\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
|
||||||
|
WasDefinition = true;
|
||||||
}
|
}
|
||||||
} else {
|
IsUsage = false;
|
||||||
current_state = PUState_none;
|
} else if (IsIndent && NewUsage && (blank_count >= 2 || WasDefinition)) {
|
||||||
}
|
// another usage block
|
||||||
}
|
fprintf(f, "\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
|
||||||
|
WasDefinition = true;
|
||||||
if (IsDefinition && !catch_verific && current_state != PUState_signature) {
|
def_strip_count = 0;
|
||||||
if (!current_buffer.empty()) {
|
} else if (IsIndent && IsDefinition && (blank_count || WasDefinition)) {
|
||||||
current_listing->codeblock(current_buffer, "none", null_source);
|
// format definition term
|
||||||
current_buffer = "";
|
fprintf(f, "\n\n .. code:: yoscrypt\n\n %s\n\n ", stripped_line.c_str());
|
||||||
}
|
WasDefinition = true;
|
||||||
current_state = PUState_options;
|
|
||||||
current_listing = root_listing->open_option(stripped_line, null_source);
|
|
||||||
def_strip_count = first_pos;
|
def_strip_count = first_pos;
|
||||||
} else {
|
} else {
|
||||||
if (current_state == PUState_options) {
|
if (IsDedent) {
|
||||||
current_state = PUState_optionbody;
|
fprintf(f, "\n\n ::\n");
|
||||||
|
def_strip_count = first_pos;
|
||||||
|
} else if (WasDefinition) {
|
||||||
|
fprintf(f, "::\n");
|
||||||
|
WasDefinition = false;
|
||||||
}
|
}
|
||||||
if (current_buffer.empty())
|
fprintf(f, "\n %s", line.substr(def_strip_count, std::string::npos).c_str());
|
||||||
current_buffer = stripped_line;
|
|
||||||
else if (current_state == PUState_signature && IsIndent)
|
|
||||||
current_buffer += stripped_line;
|
|
||||||
else if (current_state == PUState_none) {
|
|
||||||
current_buffer += (blank_lines > 0 ? "\n\n" : "\n") + line;
|
|
||||||
} else
|
|
||||||
current_buffer += (blank_lines > 0 ? "\n\n" : "\n") + stripped_line;
|
|
||||||
if (stripped_line.compare("Command file parser supports following commands in file:") == 0)
|
|
||||||
catch_verific = true;
|
|
||||||
}
|
|
||||||
blank_lines = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!current_buffer.empty()) {
|
blank_count = 0;
|
||||||
if (current_buffer.size() > 64 && current_buffer.substr(0, 64).compare("The following commands are executed by this synthesis command:\n\n") == 0) {
|
|
||||||
current_listing->paragraph(current_buffer.substr(0, 62), null_source);
|
|
||||||
current_listing->codeblock(current_buffer.substr(64), "yoscrypt", null_source);
|
|
||||||
} else
|
|
||||||
current_listing->codeblock(current_buffer, "none", null_source);
|
|
||||||
current_buffer = "";
|
|
||||||
}
|
}
|
||||||
|
fputc('\n', f);
|
||||||
|
|
||||||
|
// render latex
|
||||||
|
fprintf(f, ".. only:: latex\n\n");
|
||||||
|
fprintf(f, " ::\n\n");
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss2 << textcp;
|
||||||
|
for (std::string line; std::getline(ss2, line, '\n');) {
|
||||||
|
fprintf(f, " %s\n", line.c_str());
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
void write_cell_rst(Yosys::SimHelper cell, Yosys::CellType ct)
|
||||||
|
{
|
||||||
|
// open
|
||||||
|
FILE *f = fopen(stringf("docs/source/cell/%s.rst", cell.filesafe_name().c_str()).c_str(), "wt");
|
||||||
|
|
||||||
|
// make header
|
||||||
|
string title_line;
|
||||||
|
if (cell.title.length())
|
||||||
|
title_line = stringf("%s - %s", cell.name.c_str(), cell.title.c_str());
|
||||||
|
else title_line = cell.name;
|
||||||
|
string underline = "\n";
|
||||||
|
underline.insert(0, title_line.length(), '=');
|
||||||
|
fprintf(f, "%s\n", title_line.c_str());
|
||||||
|
fprintf(f, "%s\n", underline.c_str());
|
||||||
|
|
||||||
|
// help text, with cell def for links
|
||||||
|
fprintf(f, ".. cell:def:: %s\n", cell.name.c_str());
|
||||||
|
if (cell.title.length())
|
||||||
|
fprintf(f, " :title: %s\n\n", cell.title.c_str());
|
||||||
|
else
|
||||||
|
fprintf(f, " :title: %s\n\n", cell.name.c_str());
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << cell.desc;
|
||||||
|
for (std::string line; std::getline(ss, line, '\n');) {
|
||||||
|
fprintf(f, " %s\n", line.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// attempt auto group
|
// properties
|
||||||
if (!cmd_help.has_group()) {
|
fprintf(f, "\nProperties");
|
||||||
string source_file = pass->location.file_name();
|
fprintf(f, "\n----------\n\n");
|
||||||
bool has_source = source_file.compare("unknown") != 0;
|
dict<string, bool> prop_dict = {
|
||||||
if (pass->internal_flag)
|
{"is_evaluable", ct.is_evaluable},
|
||||||
cmd_help.group = "internal";
|
{"is_combinatorial", ct.is_combinatorial},
|
||||||
else if (source_file.find("backends/") == 0 || (!has_source && name.find("read_") == 0))
|
{"is_synthesizable", ct.is_synthesizable},
|
||||||
cmd_help.group = "backends";
|
};
|
||||||
else if (source_file.find("frontends/") == 0 || (!has_source && name.find("write_") == 0))
|
for (auto &it : prop_dict) {
|
||||||
cmd_help.group = "frontends";
|
fprintf(f, "- %s: %s\n", it.first.c_str(), it.second ? "true" : "false");
|
||||||
else if (has_source) {
|
|
||||||
auto last_slash = source_file.find_last_of('/');
|
|
||||||
if (last_slash != string::npos) {
|
|
||||||
auto parent_path = source_file.substr(0, last_slash);
|
|
||||||
cmd_help.group = parent_path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// implicit !has_source
|
|
||||||
else if (name.find("equiv") == 0)
|
|
||||||
cmd_help.group = "passes/equiv";
|
|
||||||
else if (name.find("fsm") == 0)
|
|
||||||
cmd_help.group = "passes/fsm";
|
|
||||||
else if (name.find("memory") == 0)
|
|
||||||
cmd_help.group = "passes/memory";
|
|
||||||
else if (name.find("opt") == 0)
|
|
||||||
cmd_help.group = "passes/opt";
|
|
||||||
else if (name.find("proc") == 0)
|
|
||||||
cmd_help.group = "passes/proc";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groups.count(cmd_help.group) == 0) {
|
// source code
|
||||||
groups[cmd_help.group] = vector<string>();
|
fprintf(f, "\nSimulation model (Verilog)");
|
||||||
|
fprintf(f, "\n--------------------------\n\n");
|
||||||
|
fprintf(f, ".. code-block:: verilog\n");
|
||||||
|
fprintf(f, " :caption: %s\n\n", cell.source.c_str());
|
||||||
|
std::stringstream ss2;
|
||||||
|
ss2 << cell.code;
|
||||||
|
for (std::string line; std::getline(ss2, line, '\n');) {
|
||||||
|
fprintf(f, " %s\n", line.c_str());
|
||||||
}
|
}
|
||||||
groups[cmd_help.group].push_back(name);
|
|
||||||
|
|
||||||
// write to json
|
// footer
|
||||||
json.name(name.c_str()); json.begin_object();
|
fprintf(f, "\n.. note::\n\n");
|
||||||
json.entry("title", title);
|
fprintf(f, " This page was auto-generated from the output of\n");
|
||||||
json.name("content"); json.begin_array();
|
fprintf(f, " ``help %s``.\n", cell.name.c_str());
|
||||||
for (auto content : cmd_help.get_content())
|
|
||||||
json.value(content->to_json());
|
|
||||||
json.end_array();
|
|
||||||
json.entry("group", cmd_help.group);
|
|
||||||
json.entry("source_file", pass->location.file_name());
|
|
||||||
json.entry("source_line", pass->location.line());
|
|
||||||
json.entry("source_func", pass->location.function_name());
|
|
||||||
json.entry("experimental_flag", pass->experimental_flag);
|
|
||||||
json.entry("internal_flag", pass->internal_flag);
|
|
||||||
json.end_object();
|
|
||||||
}
|
|
||||||
json.end_object();
|
|
||||||
|
|
||||||
json.entry("groups", groups);
|
// close
|
||||||
|
fclose(f);
|
||||||
json.end_object();
|
|
||||||
return raise_error;
|
|
||||||
}
|
}
|
||||||
bool dump_cells_json(PrettyJson &json) {
|
bool dump_cells_json(PrettyJson &json) {
|
||||||
// init json
|
// init json
|
||||||
|
@ -1045,7 +960,11 @@ struct HelpPass : public Pass {
|
||||||
log("=");
|
log("=");
|
||||||
log("\n");
|
log("\n");
|
||||||
it.second->help();
|
it.second->help();
|
||||||
log_warning_flags(it.second);
|
if (it.second->experimental_flag) {
|
||||||
|
log("\n");
|
||||||
|
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (args[1] == "-cells") {
|
else if (args[1] == "-cells") {
|
||||||
|
@ -1059,9 +978,44 @@ struct HelpPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// this option is undocumented as it is for internal use only
|
||||||
|
else if (args[1] == "-write-rst-command-reference-manual") {
|
||||||
|
for (auto &it : pass_register) {
|
||||||
|
std::ostringstream buf;
|
||||||
|
log_streams.push_back(&buf);
|
||||||
|
it.second->help();
|
||||||
|
if (it.second->experimental_flag) {
|
||||||
|
log("\n");
|
||||||
|
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
|
log_streams.pop_back();
|
||||||
|
write_cmd_rst(it.first, it.second->short_help, buf.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this option is also undocumented as it is for internal use only
|
||||||
|
else if (args[1] == "-write-rst-cells-manual") {
|
||||||
|
bool raise_error = false;
|
||||||
|
for (auto &it : yosys_celltypes.cell_types) {
|
||||||
|
auto name = it.first.str();
|
||||||
|
if (cell_help_messages.contains(name)) {
|
||||||
|
write_cell_rst(cell_help_messages.get(name), it.second);
|
||||||
|
} else {
|
||||||
|
log("ERROR: Missing cell help for cell '%s'.\n", name.c_str());
|
||||||
|
raise_error |= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (raise_error) {
|
||||||
|
log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (pass_register.count(args[1])) {
|
else if (pass_register.count(args[1])) {
|
||||||
pass_register.at(args[1])->help();
|
pass_register.at(args[1])->help();
|
||||||
log_warning_flags(pass_register.at(args[1]));
|
if (pass_register.at(args[1])->experimental_flag) {
|
||||||
|
log("\n");
|
||||||
|
log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", args[1].c_str());
|
||||||
|
log("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (cell_help_messages.contains(args[1])) {
|
else if (cell_help_messages.contains(args[1])) {
|
||||||
auto help_cell = cell_help_messages.get(args[1]);
|
auto help_cell = cell_help_messages.get(args[1]);
|
||||||
|
@ -1090,17 +1044,7 @@ struct HelpPass : public Pass {
|
||||||
log("No such command or cell type: %s\n", args[1].c_str());
|
log("No such command or cell type: %s\n", args[1].c_str());
|
||||||
return;
|
return;
|
||||||
} else if (args.size() == 3) {
|
} else if (args.size() == 3) {
|
||||||
// this option is undocumented as it is for internal use only
|
if (args[1] == "-dump-cells-json") {
|
||||||
if (args[1] == "-dump-cmds-json") {
|
|
||||||
PrettyJson json;
|
|
||||||
if (!json.write_to_file(args[2]))
|
|
||||||
log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
|
|
||||||
if (dump_cmds_json(json)) {
|
|
||||||
log_abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this option is undocumented as it is for internal use only
|
|
||||||
else if (args[1] == "-dump-cells-json") {
|
|
||||||
PrettyJson json;
|
PrettyJson json;
|
||||||
if (!json.write_to_file(args[2]))
|
if (!json.write_to_file(args[2]))
|
||||||
log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
|
log_error("Can't open file `%s' for writing: %s\n", args[2].c_str(), strerror(errno));
|
||||||
|
@ -1108,8 +1052,6 @@ struct HelpPass : public Pass {
|
||||||
log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
|
log_error("One or more cells defined in celltypes.h are missing help documentation.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
log("Unknown help command: `%s %s'\n", args[1].c_str(), args[2].c_str());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,62 +23,27 @@
|
||||||
#include "kernel/yosys_common.h"
|
#include "kernel/yosys_common.h"
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
|
|
||||||
#include <version>
|
|
||||||
#if __cpp_lib_source_location == 201907L
|
|
||||||
#include <source_location>
|
|
||||||
using std::source_location;
|
|
||||||
#elif defined(__has_include)
|
|
||||||
# if __has_include(<experimental/source_location>)
|
|
||||||
#include <experimental/source_location>
|
|
||||||
using std::experimental::source_location;
|
|
||||||
# else
|
|
||||||
#define SOURCE_FALLBACK
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
#define SOURCE_FALLBACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SOURCE_FALLBACK
|
|
||||||
struct source_location { // dummy placeholder
|
|
||||||
int line() const { return 0; }
|
|
||||||
int column() const { return 0; }
|
|
||||||
const char* file_name() const { return "unknown"; }
|
|
||||||
const char* function_name() const { return "unknown"; }
|
|
||||||
static const source_location current(...) { return source_location(); }
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct Pass
|
struct Pass
|
||||||
{
|
{
|
||||||
std::string pass_name, short_help;
|
std::string pass_name, short_help;
|
||||||
source_location location;
|
Pass(std::string name, std::string short_help = "** document me **");
|
||||||
Pass(std::string name, std::string short_help = "** document me **",
|
|
||||||
source_location location = source_location::current());
|
|
||||||
// Prefer overriding 'Pass::on_shutdown()' if possible
|
// Prefer overriding 'Pass::on_shutdown()' if possible
|
||||||
virtual ~Pass();
|
virtual ~Pass();
|
||||||
|
|
||||||
// Makes calls to log() to generate help message
|
|
||||||
virtual void help();
|
virtual void help();
|
||||||
// Uses PrettyHelp::get_current() to produce a more portable formatted help message
|
|
||||||
virtual bool formatted_help();
|
|
||||||
virtual void clear_flags();
|
virtual void clear_flags();
|
||||||
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
|
virtual void execute(std::vector<std::string> args, RTLIL::Design *design) = 0;
|
||||||
|
|
||||||
int call_counter;
|
int call_counter;
|
||||||
int64_t runtime_ns;
|
int64_t runtime_ns;
|
||||||
bool experimental_flag = false;
|
bool experimental_flag = false;
|
||||||
bool internal_flag = false;
|
|
||||||
|
|
||||||
void experimental() {
|
void experimental() {
|
||||||
experimental_flag = true;
|
experimental_flag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void internal() {
|
|
||||||
internal_flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pre_post_exec_state_t {
|
struct pre_post_exec_state_t {
|
||||||
Pass *parent_pass;
|
Pass *parent_pass;
|
||||||
int64_t begin_ns;
|
int64_t begin_ns;
|
||||||
|
@ -116,8 +81,7 @@ struct ScriptPass : Pass
|
||||||
RTLIL::Design *active_design;
|
RTLIL::Design *active_design;
|
||||||
std::string active_run_from, active_run_to;
|
std::string active_run_from, active_run_to;
|
||||||
|
|
||||||
ScriptPass(std::string name, std::string short_help = "** document me **", source_location location = source_location::current()) :
|
ScriptPass(std::string name, std::string short_help = "** document me **") : Pass(name, short_help) { }
|
||||||
Pass(name, short_help, location) { }
|
|
||||||
|
|
||||||
virtual void script() = 0;
|
virtual void script() = 0;
|
||||||
|
|
||||||
|
@ -135,8 +99,7 @@ struct Frontend : Pass
|
||||||
static std::string last_here_document;
|
static std::string last_here_document;
|
||||||
|
|
||||||
std::string frontend_name;
|
std::string frontend_name;
|
||||||
Frontend(std::string name, std::string short_help = "** document me **",
|
Frontend(std::string name, std::string short_help = "** document me **");
|
||||||
source_location location = source_location::current());
|
|
||||||
void run_register() override;
|
void run_register() override;
|
||||||
~Frontend() override;
|
~Frontend() override;
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override final;
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override final;
|
||||||
|
@ -152,8 +115,7 @@ struct Frontend : Pass
|
||||||
struct Backend : Pass
|
struct Backend : Pass
|
||||||
{
|
{
|
||||||
std::string backend_name;
|
std::string backend_name;
|
||||||
Backend(std::string name, std::string short_help = "** document me **",
|
Backend(std::string name, std::string short_help = "** document me **");
|
||||||
source_location location = source_location::current());
|
|
||||||
void run_register() override;
|
void run_register() override;
|
||||||
~Backend() override;
|
~Backend() override;
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override final;
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override final;
|
||||||
|
|
|
@ -22,18 +22,12 @@
|
||||||
#include "kernel/celledges.h"
|
#include "kernel/celledges.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/utils.h"
|
#include "kernel/utils.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct CheckPass : public Pass {
|
struct CheckPass : public Pass {
|
||||||
CheckPass() : Pass("check", "check for obvious problems in the design") { }
|
CheckPass() : Pass("check", "check for obvious problems in the design") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -71,62 +70,62 @@ static bool is_triggered_check_cell(RTLIL::Cell * cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ChformalPass : public Pass {
|
struct ChformalPass : public Pass {
|
||||||
ChformalPass() : Pass("chformal", "change formal constraints of the design") {}
|
ChformalPass() : Pass("chformal", "change formal constraints of the design") { }
|
||||||
|
void help() override
|
||||||
bool formatted_help() override {
|
{
|
||||||
auto *help = PrettyHelp::get_current();
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
help->set_group("formal");
|
log("\n");
|
||||||
|
log(" chformal [types] [mode] [options] [selection]\n");
|
||||||
auto content_root = help->get_root();
|
log("\n");
|
||||||
|
log("Make changes to the formal constraints of the design. The [types] options\n");
|
||||||
content_root->usage("chformal [types] [mode] [options] [selection]");
|
log("the type of constraint to operate on. If none of the following options are\n");
|
||||||
content_root->paragraph(
|
log("given, the command will operate on all constraint types:\n");
|
||||||
"Make changes to the formal constraints of the design. The [types] options "
|
log("\n");
|
||||||
"the type of constraint to operate on. If none of the following options are "
|
log(" -assert $assert cells, representing assert(...) constraints\n");
|
||||||
"given, the command will operate on all constraint types:"
|
log(" -assume $assume cells, representing assume(...) constraints\n");
|
||||||
);
|
log(" -live $live cells, representing assert(s_eventually ...)\n");
|
||||||
|
log(" -fair $fair cells, representing assume(s_eventually ...)\n");
|
||||||
content_root->option("-assert", "`$assert` cells, representing ``assert(...)`` constraints");
|
log(" -cover $cover cells, representing cover() statements\n");
|
||||||
content_root->option("-assume", "`$assume` cells, representing ``assume(...)`` constraints");
|
log("\n");
|
||||||
content_root->option("-live", "`$live` cells, representing ``assert(s_eventually ...)``");
|
log(" Additionally chformal will operate on $check cells corresponding to the\n");
|
||||||
content_root->option("-fair", "`$fair` cells, representing ``assume(s_eventually ...)``");
|
log(" selected constraint types.\n");
|
||||||
content_root->option("-cover", "`$cover` cells, representing ``cover()`` statements");
|
log("\n");
|
||||||
content_root->paragraph(
|
log("Exactly one of the following modes must be specified:\n");
|
||||||
"Additionally chformal will operate on `$check` cells corresponding to the "
|
log("\n");
|
||||||
"selected constraint types."
|
log(" -remove\n");
|
||||||
);
|
log(" remove the cells and thus constraints from the design\n");
|
||||||
|
log("\n");
|
||||||
content_root->paragraph("Exactly one of the following modes must be specified:");
|
log(" -early\n");
|
||||||
|
log(" bypass FFs that only delay the activation of a constraint. When inputs\n");
|
||||||
content_root->option("-remove", "remove the cells and thus constraints from the design");
|
log(" of the bypassed FFs do not remain stable between clock edges, this may\n");
|
||||||
content_root->option("-early",
|
log(" result in unexpected behavior.\n");
|
||||||
"bypass FFs that only delay the activation of a constraint. When inputs "
|
log("\n");
|
||||||
"of the bypassed FFs do not remain stable between clock edges, this may "
|
log(" -delay <N>\n");
|
||||||
"result in unexpected behavior."
|
log(" delay activation of the constraint by <N> clock cycles\n");
|
||||||
);
|
log("\n");
|
||||||
content_root->option("-delay <N>", "delay activation of the constraint by <N> clock cycles");
|
log(" -skip <N>\n");
|
||||||
content_root->option("-skip <N>", "ignore activation of the constraint in the first <N> clock cycles");
|
log(" ignore activation of the constraint in the first <N> clock cycles\n");
|
||||||
auto cover_option = content_root->open_option("-coverenable");
|
log("\n");
|
||||||
cover_option->paragraph(
|
log(" -coverenable\n");
|
||||||
"add cover statements for the enable signals of the constraints"
|
log(" add cover statements for the enable signals of the constraints\n");
|
||||||
);
|
log("\n");
|
||||||
#ifdef YOSYS_ENABLE_VERIFIC
|
#ifdef YOSYS_ENABLE_VERIFIC
|
||||||
cover_option->paragraph(
|
log(" Note: For the Verific frontend it is currently not guaranteed that a\n");
|
||||||
"Note: For the Verific frontend it is currently not guaranteed that a "
|
log(" reachable SVA statement corresponds to an active enable signal.\n");
|
||||||
"reachable SVA statement corresponds to an active enable signal."
|
log("\n");
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
content_root->option("-assert2assume");
|
log(" -assert2assume\n");
|
||||||
content_root->option("-assert2cover");
|
log(" -assert2cover\n");
|
||||||
content_root->option("-assume2assert");
|
log(" -assume2assert\n");
|
||||||
content_root->option("-live2fair");
|
log(" -live2fair\n");
|
||||||
content_root->option("-fair2live", "change the roles of cells as indicated. these options can be combined");
|
log(" -fair2live\n");
|
||||||
content_root->option("-lower",
|
log(" change the roles of cells as indicated. these options can be combined\n");
|
||||||
"convert each $check cell into an $assert, $assume, $live, $fair or "
|
log("\n");
|
||||||
"$cover cell. If the $check cell contains a message, also produce a "
|
log(" -lower\n");
|
||||||
"$print cell."
|
log(" convert each $check cell into an $assert, $assume, $live, $fair or\n");
|
||||||
);
|
log(" $cover cell. If the $check cell contains a message, also produce a\n");
|
||||||
return true;
|
log(" $print cell.\n");
|
||||||
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -27,18 +26,15 @@
|
||||||
# include <io.h>
|
# include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "kernel/register.h"
|
||||||
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct CoverPass : public Pass {
|
struct CoverPass : public Pass {
|
||||||
CoverPass() : Pass("cover", "print code coverage counters") {
|
CoverPass() : Pass("cover", "print code coverage counters") { }
|
||||||
internal();
|
|
||||||
}
|
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "kernel/modtools.h"
|
#include "kernel/modtools.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
@ -953,11 +952,6 @@ struct DftTagWorker {
|
||||||
|
|
||||||
struct DftTagPass : public Pass {
|
struct DftTagPass : public Pass {
|
||||||
DftTagPass() : Pass("dft_tag", "create tagging logic for data flow tracking") {}
|
DftTagPass() : Pass("dft_tag", "create tagging logic for data flow tracking") {}
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("formal");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -19,18 +19,12 @@
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct EdgetypePass : public Pass {
|
struct EdgetypePass : public Pass {
|
||||||
EdgetypePass() : Pass("edgetypes", "list all types of edges in selection") { }
|
EdgetypePass() : Pass("edgetypes", "list all types of edges in selection") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -21,9 +21,7 @@ struct ExampleWorker
|
||||||
|
|
||||||
struct ExampleDtPass : public Pass
|
struct ExampleDtPass : public Pass
|
||||||
{
|
{
|
||||||
ExampleDtPass() : Pass("example_dt", "drivertools example") {
|
ExampleDtPass() : Pass("example_dt", "drivertools example") {}
|
||||||
internal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/log.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
@ -38,11 +38,6 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct ExecPass : public Pass {
|
struct ExecPass : public Pass {
|
||||||
ExecPass() : Pass("exec", "execute commands in the operating system shell") { }
|
ExecPass() : Pass("exec", "execute commands in the operating system shell") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/utils.h"
|
#include "kernel/utils.h"
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
@ -111,11 +110,6 @@ struct FutureWorker {
|
||||||
|
|
||||||
struct FuturePass : public Pass {
|
struct FuturePass : public Pass {
|
||||||
FuturePass() : Pass("future", "resolve future sampled value functions") {}
|
FuturePass() : Pass("future", "resolve future sampled value functions") {}
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("formal");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "kernel/register.h"
|
||||||
|
#include "kernel/rtlil.h"
|
||||||
#include "kernel/utils.h"
|
#include "kernel/utils.h"
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/log.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -424,12 +425,6 @@ public:
|
||||||
struct GliftPass : public Pass {
|
struct GliftPass : public Pass {
|
||||||
GliftPass() : Pass("glift", "create GLIFT models and optimization problems") {}
|
GliftPass() : Pass("glift", "create GLIFT models and optimization problems") {}
|
||||||
|
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("formal");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <optional>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
|
@ -69,10 +71,7 @@ std::optional<uint64_t> current_mem_bytes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InternalStatsPass : public Pass {
|
struct InternalStatsPass : public Pass {
|
||||||
InternalStatsPass() : Pass("internal_stats", "print internal statistics") {
|
InternalStatsPass() : Pass("internal_stats", "print internal statistics") { }
|
||||||
experimental();
|
|
||||||
internal();
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -18,19 +18,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct LogPass : public Pass {
|
struct LogPass : public Pass {
|
||||||
LogPass() : Pass("log", "print text and log files") { }
|
LogPass() : Pass("log", "print text and log files") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -17,19 +17,14 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/log.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct LoggerPass : public Pass {
|
struct LoggerPass : public Pass {
|
||||||
LoggerPass() : Pass("logger", "set logger properties") { }
|
LoggerPass() : Pass("logger", "set logger properties") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -142,11 +141,6 @@ struct LtpWorker
|
||||||
|
|
||||||
struct LtpPass : public Pass {
|
struct LtpPass : public Pass {
|
||||||
LtpPass() : Pass("ltp", "print longest topological path") { }
|
LtpPass() : Pass("ltp", "print longest topological path") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
#ifdef YOSYS_ENABLE_PLUGINS
|
#ifdef YOSYS_ENABLE_PLUGINS
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
|
@ -123,11 +122,6 @@ void load_plugin(std::string, std::vector<std::string>)
|
||||||
|
|
||||||
struct PluginPass : public Pass {
|
struct PluginPass : public Pass {
|
||||||
PluginPass() : Pass("plugin", "load and list loaded plugins") { }
|
PluginPass() : Pass("plugin", "load and list loaded plugins") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "kernel/rtlil.h"
|
#include "kernel/rtlil.h"
|
||||||
#include "kernel/utils.h"
|
#include "kernel/utils.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
@ -39,11 +38,6 @@ static RTLIL::SigBit canonical_bit(RTLIL::SigBit bit)
|
||||||
|
|
||||||
struct PortarcsPass : Pass {
|
struct PortarcsPass : Pass {
|
||||||
PortarcsPass() : Pass("portarcs", "derive port arcs for propagation delay") {}
|
PortarcsPass() : Pass("portarcs", "derive port arcs for propagation delay") {}
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,18 +19,12 @@
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct PortlistPass : public Pass {
|
struct PortlistPass : public Pass {
|
||||||
PortlistPass() : Pass("portlist", "list (top-level) ports") { }
|
PortlistPass() : Pass("portlist", "list (top-level) ports") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -18,18 +18,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct PrintAttrsPass : public Pass {
|
struct PrintAttrsPass : public Pass {
|
||||||
PrintAttrsPass() : Pass("printattrs", "print attributes of selected objects") { }
|
PrintAttrsPass() : Pass("printattrs", "print attributes of selected objects") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
// Tarjan, R. E. (1972), "Depth-first search and linear graph algorithms", SIAM Journal on Computing 1 (2): 146-160, doi:10.1137/0201010
|
// Tarjan, R. E. (1972), "Depth-first search and linear graph algorithms", SIAM Journal on Computing 1 (2): 146-160, doi:10.1137/0201010
|
||||||
// http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm
|
// http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/log.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -250,11 +252,6 @@ struct SccWorker
|
||||||
|
|
||||||
struct SccPass : public Pass {
|
struct SccPass : public Pass {
|
||||||
SccPass() : Pass("scc", "detect strongly connected components (logic loops)") { }
|
SccPass() : Pass("scc", "detect strongly connected components (logic loops)") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -18,19 +18,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct ScratchpadPass : public Pass {
|
struct ScratchpadPass : public Pass {
|
||||||
ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { }
|
ScratchpadPass() : Pass("scratchpad", "get/set values in the scratchpad") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -1084,11 +1085,6 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct SelectPass : public Pass {
|
struct SelectPass : public Pass {
|
||||||
SelectPass() : Pass("select", "modify and view the list of selected objects") { }
|
SelectPass() : Pass("select", "modify and view the list of selected objects") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
@ -1668,11 +1664,6 @@ struct SelectPass : public Pass {
|
||||||
|
|
||||||
struct CdPass : public Pass {
|
struct CdPass : public Pass {
|
||||||
CdPass() : Pass("cd", "a shortcut for 'select -module <name>'") { }
|
CdPass() : Pass("cd", "a shortcut for 'select -module <name>'") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
@ -1785,11 +1776,6 @@ static void log_matches(const char *title, Module *module, const T &list)
|
||||||
|
|
||||||
struct LsPass : public Pass {
|
struct LsPass : public Pass {
|
||||||
LsPass() : Pass("ls", "list modules or objects in modules") { }
|
LsPass() : Pass("ls", "list modules or objects in modules") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -17,18 +17,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
struct SetenvPass : public Pass {
|
struct SetenvPass : public Pass {
|
||||||
SetenvPass() : Pass("setenv", "set an environment variable") { }
|
SetenvPass() : Pass("setenv", "set an environment variable") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/log.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
|
@ -657,11 +658,6 @@ struct ShowWorker
|
||||||
|
|
||||||
struct ShowPass : public Pass {
|
struct ShowPass : public Pass {
|
||||||
ShowPass() : Pass("show", "generate schematics using graphviz") { }
|
ShowPass() : Pass("show", "generate schematics using graphviz") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/timinginfo.h"
|
#include "kernel/timinginfo.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
@ -276,11 +275,6 @@ struct StaWorker
|
||||||
|
|
||||||
struct StaPass : public Pass {
|
struct StaPass : public Pass {
|
||||||
StaPass() : Pass("sta", "perform static timing analysis") { }
|
StaPass() : Pass("sta", "perform static timing analysis") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "kernel/cost.h"
|
#include "kernel/cost.h"
|
||||||
#include "kernel/gzip.h"
|
#include "kernel/gzip.h"
|
||||||
#include "libs/json11/json11.hpp"
|
#include "libs/json11/json11.hpp"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -368,11 +367,6 @@ void read_liberty_cellarea(dict<IdString, cell_area_t> &cell_area, string libert
|
||||||
|
|
||||||
struct StatPass : public Pass {
|
struct StatPass : public Pass {
|
||||||
StatPass() : Pass("stat", "print some statistics") { }
|
StatPass() : Pass("stat", "print some statistics") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -18,19 +18,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/register.h"
|
||||||
#include "kernel/log_help.h"
|
#include "kernel/rtlil.h"
|
||||||
|
#include "kernel/log.h"
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct TeePass : public Pass {
|
struct TeePass : public Pass {
|
||||||
TeePass() : Pass("tee", "redirect command output to file") { }
|
TeePass() : Pass("tee", "redirect command output to file") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -21,18 +21,12 @@
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/utils.h"
|
#include "kernel/utils.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct TorderPass : public Pass {
|
struct TorderPass : public Pass {
|
||||||
TorderPass() : Pass("torder", "print cells in topological order") { }
|
TorderPass() : Pass("torder", "print cells in topological order") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
@ -61,11 +60,6 @@ struct TraceMonitor : public RTLIL::Monitor
|
||||||
|
|
||||||
struct TracePass : public Pass {
|
struct TracePass : public Pass {
|
||||||
TracePass() : Pass("trace", "redirect command output to file") { }
|
TracePass() : Pass("trace", "redirect command output to file") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
@ -102,11 +96,6 @@ struct TracePass : public Pass {
|
||||||
|
|
||||||
struct DebugPass : public Pass {
|
struct DebugPass : public Pass {
|
||||||
DebugPass() : Pass("debug", "run command with debug log messages enabled") { }
|
DebugPass() : Pass("debug", "run command with debug log messages enabled") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
|
@ -818,11 +817,6 @@ struct VizWorker
|
||||||
|
|
||||||
struct VizPass : public Pass {
|
struct VizPass : public Pass {
|
||||||
VizPass() : Pass("viz", "visualize data flow graph") { }
|
VizPass() : Pass("viz", "visualize data flow graph") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -19,18 +19,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
PRIVATE_NAMESPACE_BEGIN
|
PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct WriteFileFrontend : public Frontend {
|
struct WriteFileFrontend : public Frontend {
|
||||||
WriteFileFrontend() : Frontend("=write_file", "write a text to a file") { }
|
WriteFileFrontend() : Frontend("=write_file", "write a text to a file") { }
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("passes/status");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "kernel/sigtools.h"
|
#include "kernel/sigtools.h"
|
||||||
#include "kernel/utils.h"
|
#include "kernel/utils.h"
|
||||||
#include "kernel/yosys.h"
|
#include "kernel/yosys.h"
|
||||||
#include "kernel/log_help.h"
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
@ -1101,11 +1100,6 @@ struct XpropWorker
|
||||||
|
|
||||||
struct XpropPass : public Pass {
|
struct XpropPass : public Pass {
|
||||||
XpropPass() : Pass("xprop", "formal x propagation") {}
|
XpropPass() : Pass("xprop", "formal x propagation") {}
|
||||||
bool formatted_help() override {
|
|
||||||
auto *help = PrettyHelp::get_current();
|
|
||||||
help->set_group("formal");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void help() override
|
void help() override
|
||||||
{
|
{
|
||||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue