From 440e331ae03079a0743f48aa21cfc03191e6608d Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Fri, 3 Oct 2025 11:50:44 +0300 Subject: [PATCH] docs: proofread pyosys.rst Primarily address feedback from @KrystalDelusion (thanks!) --- docs/source/using_yosys/pyosys.rst | 59 ++++++++++++++++++------------ 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/docs/source/using_yosys/pyosys.rst b/docs/source/using_yosys/pyosys.rst index 7e3b0f77d..8aa7fd4fe 100644 --- a/docs/source/using_yosys/pyosys.rst +++ b/docs/source/using_yosys/pyosys.rst @@ -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 `_ 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