3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-10-08 17:01:57 +00:00

docs: proofread pyosys.rst

Primarily address feedback from @KrystalDelusion (thanks!)
This commit is contained in:
Mohamed Gaber 2025-10-03 11:50:44 +03:00
parent 93fae3c606
commit 440e331ae0
No known key found for this signature in database

View file

@ -4,17 +4,21 @@ Scripting with Pyosys
Pyosys is a limited subset of the Yosys C++ API (aka "libyosys") made available
using the Python programming language.
It offers access both to writing Yosys scripts like ``.ys`` and ``.tcl`` files
with the amenities of the Python programming language (functions, flow control,
etc), but also allows some access to internal data structures at the same time
unlike those two platforms, allowing you to also implement complex functionality
that is would otherwise not possible without writing custom passes using C++.
Like ``.ys`` and ``.tcl`` scripts, Pyosys provides an interface to write Yosys
scripts in the Python programming language, giving you the benefits of
a type system, control flow, object-oriented programming, and more; especially
that the other options lack a type system and control flow/OOP in Tcl is
limited.
Though unlike these two, Pyosys goes a bit further, allowing you to use the
Yosys API to implement advanced functionality that would otherwise require
custom passes written in C++.
Getting Pyosys
--------------
Pyosys supports Python 3.8.1 or higher. You can access Pyosys using one of two
Pyosys supports CPython 3.8 or higher. You can access Pyosys using one of two
methods:
1. Compiling Yosys with the Makefile flag ``ENABLE_PYOSYS=1``
@ -26,8 +30,8 @@ methods:
2. Installing the Pyosys wheels
On macOS and GNU/Linux (specifically, not musllinux,) you can install
pre-built wheels of Yosys using ``pip`` as follows:
On macOS and GNU/Linux you can install pre-built wheels of Yosys using
``pip``:
``python3 -m pip install pyosys``
@ -56,7 +60,7 @@ this import may be preferable for terseness:
Now, scripting is actually quite similar to ``.ys`` and ``.tcl`` script in that
you can provide mostly text commands. Albeit, you can construct your scripts
to use Python's amenities including flow controls, loops, and functions:
to use Python's amenities like conditional execution, loops, and functions:
.. code-block:: python
@ -67,9 +71,9 @@ to use Python's amenities including flow controls, loops, and functions:
if do_flatten:
ys.run_pass("flatten")
…but this does not provide anything that Tcl scripts do not provide you with.
The real power of using Pyosys comes from the fact you can manually instantiate,
manage, and interact with the design database.
…but this does not strictly provide anything that Tcl scripts do not provide you
with. The real power of using Pyosys comes from the fact you can manually
instantiate, manage, and interact with the design database.
As an example, here is the same script with a manually instantiated design.
@ -79,8 +83,8 @@ As an example, here is the same script with a manually instantiated design.
:language: python
What's new here is that you can manually inspect the design's database. This
gives you access to huge chunk of the design database API as in declared in the
``kernel/rtlil.h`` header.
gives you access to a huge chunk of the design database API as declared in
the ``kernel/rtlil.h`` header.
For example, here's how to list the input and output ports of the top module
of your design:
@ -95,12 +99,18 @@ of your design:
C++ data structures in Yosys are bridged to Python such that they have a
pretty similar API to Python objects, for example:
- ``std::vector`` supports the same methods as iterables in Python.
- ``std::set`` and hashlib ``pool`` support the same methods as ``set``\s in
- ``std::vector`` supports the same methods as
`iterables <https://docs.python.org/3/glossary.html#term-iterable>`_ in
Python.
- ``std::set`` and hashlib ``pool`` support the same methods as ``set``\s in
Python. While ``set`` is ordered, ``pool`` is not and modifications may
cause a complete reordering of the set.
- ``dict`` supports the same methods as ``dict``\s in Python, albeit it is
unordered, and modifications may cause a complete reordering of the
dictionary.
- ``idict`` uses a custom set of methods because it doesn't map very cleanly
to an existing Python data structure. See ``pyosys/hashlib.h`` for more
info.
For most operations, the Python equivalents are also supported as arguments
where they will automatically be cast to the right type, so you do not have
@ -121,8 +131,8 @@ to modify it, and introduce new elements and/or changes to your design.
As a demonstrative example, let's assume we want to add an enable line to all
flip-flops in our fiedler-cooley design.
First of all, we will run :yoscrypt:`synth` to convert all of the logic to Yosys's
internal cell structure (see :ref:`sec:celllib_gates`):
First of all, we will run :yoscrypt:`synth` to convert all of the logic to
Yosys's internal cell structure (see :ref:`sec:celllib_gates`):
.. literalinclude:: /code_examples/pyosys/simple_database.py
:start-after: # synth
@ -163,7 +173,8 @@ Next, we can iterate over all constituent cells, and if they are of the type
:language: python
To verify that you did everything correctly, it is prudent to call ``.check()``
on the module you're manipulating as follows:
on the module you're manipulating as follows after you're done with a set of
changes:
.. literalinclude:: /code_examples/pyosys/simple_database.py
:start-after: run check
@ -177,15 +188,15 @@ file and :yoscrypt:`synth_ice40` to map it to the iCE40 architecture.
:start-after: write output
:language: python
And voila, you will note that in the intermediate output, all ``always @``
statements have an ``if (enable)``\.
And voilà, you will note that in the intermediate output, all ``always @``
statements should have an ``if (enable)``\.
Encapsulating as Passes
-----------------------
Just like when writing C++, you can encapsulate behavior in terms of "passes",
which are the commands you access using ``run_pass``\. This adds it to a global
registry of commands that you can use using ``run_pass``.
Just like when writing C++, you can encapsulate routines in terms of "passes",
which adds your Pass to a global registry of commands accessible using
``run_pass``\.
.. literalinclude:: /code_examples/pyosys/pass.py
:language: python