diff --git a/.editorconfig b/.editorconfig index 572b73bd2..bbe9c3107 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,6 +11,10 @@ indent_style = space indent_size = 2 trim_trailing_whitespace = false +[*.rst] +indent_style = space +indent_size = 3 + [*.yml] indent_style = space indent_size = 2 diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 2a5b7e024..b6c9a51ac 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -55,11 +55,6 @@ jobs: submodules: true persist-credentials: false - uses: actions/setup-python@v5 - - name: Get Boost Source - shell: bash - run: | - mkdir -p boost - curl -L https://github.com/boostorg/boost/releases/download/boost-1.86.0/boost-1.86.0-b2-nodocs.tar.gz | tar --strip-components=1 -xzC boost - name: Get FFI shell: bash run: | @@ -103,21 +98,16 @@ jobs: CIBW_BEFORE_ALL: bash ./.github/workflows/wheels/cibw_before_all.sh CIBW_ENVIRONMENT: > OPTFLAGS=-O3 - CXXFLAGS=-I./boost/pfx/include - LINKFLAGS=-L./boost/pfx/lib PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig - makeFlags='BOOST_PYTHON_LIB=./boost/pfx/lib/libboost_python*.a' PATH="$PWD/bison/src:$PATH" CIBW_ENVIRONMENT_MACOS: > OPTFLAGS=-O3 - CXXFLAGS=-I./boost/pfx/include - LINKFLAGS=-L./boost/pfx/lib PKG_CONFIG_PATH=./ffi/pfx/lib/pkgconfig MACOSX_DEPLOYMENT_TARGET=11 - makeFlags='BOOST_PYTHON_LIB=./boost/pfx/lib/libboost_python*.a CONFIG=clang' + makeFlags='CONFIG=clang' PATH="$PWD/bison/src:$PATH" CIBW_BEFORE_BUILD: bash ./.github/workflows/wheels/cibw_before_build.sh - CIBW_TEST_COMMAND: python3 {project}/tests/arch/ecp5/add_sub.py + CIBW_TEST_COMMAND: python3 {project}/tests/pyosys/run_tests.py - uses: actions/upload-artifact@v4 with: name: python-wheels-${{ matrix.os.runner }} diff --git a/.github/workflows/wheels/cibw_before_build.sh b/.github/workflows/wheels/cibw_before_build.sh index 018b0e0df..1ce96b291 100644 --- a/.github/workflows/wheels/cibw_before_build.sh +++ b/.github/workflows/wheels/cibw_before_build.sh @@ -1,8 +1,8 @@ set -e set -x -# Don't use objects from previous compiles on Windows/macOS -make clean +# Don't use Python objects from previous compiles +make clean-py # DEBUG: show python3 and python3-config outputs if [ "$(uname)" != "Linux" ]; then @@ -11,24 +11,3 @@ if [ "$(uname)" != "Linux" ]; then fi python3 --version python3-config --includes - -# Build boost -cd ./boost -## Delete the artefacts from previous builds (if any) -rm -rf ./pfx -## Bootstrap bjam -./bootstrap.sh --prefix=./pfx -## Build Boost against current version of Python, only for -## static linkage (Boost is statically linked because system boost packages -## wildly vary in versions, including the libboost_python3 version) -./b2\ - -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu)\ - --prefix=./pfx\ - --with-filesystem\ - --with-system\ - --with-python\ - cxxflags="$(python3-config --includes) -std=c++17 -fPIC"\ - cflags="$(python3-config --includes) -fPIC"\ - link=static\ - variant=release\ - install diff --git a/CODEOWNERS b/CODEOWNERS index 46d37ad2f..4617c39bb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -38,7 +38,8 @@ techlibs/gowin/ @pepijndevos techlibs/gatemate/ @pu-cc # pyosys -misc/*.py @btut +pyosys/* @donn +setup.py @donn backends/firrtl @ucbjrl @azidar diff --git a/Makefile b/Makefile index a092646e0..d68fdfdad 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ all: top-all YOSYS_SRC := $(dir $(firstword $(MAKEFILE_LIST))) VPATH := $(YOSYS_SRC) -CXXSTD ?= c++17 +export CXXSTD ?= c++17 CXXFLAGS := $(CXXFLAGS) -Wall -Wextra -ggdb -I. -I"$(YOSYS_SRC)" -MD -MP -D_YOSYS_ -fPIC -I$(PREFIX)/include LIBS := $(LIBS) -lstdc++ -lm PLUGIN_LINKFLAGS := @@ -133,10 +133,6 @@ LINKFLAGS += -rdynamic ifneq ($(shell :; command -v brew),) BREW_PREFIX := $(shell brew --prefix)/opt $(info $$BREW_PREFIX is [${BREW_PREFIX}]) -ifeq ($(ENABLE_PYOSYS),1) -CXXFLAGS += -I$(BREW_PREFIX)/boost/include -LINKFLAGS += -L$(BREW_PREFIX)/boost/lib -L$(BREW_PREFIX)/boost-python3/lib -endif CXXFLAGS += -I$(BREW_PREFIX)/readline/include -I$(BREW_PREFIX)/flex/include LINKFLAGS += -L$(BREW_PREFIX)/readline/lib -L$(BREW_PREFIX)/flex/lib PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) @@ -348,31 +344,24 @@ ifeq ($(ENABLE_LIBYOSYS),1) TARGETS += libyosys.so endif +PY_WRAPPER_FILE = pyosys/wrappers + +# running make clean on just those and then recompiling saves a lot of +# time when running cibuildwheel +PYTHON_OBJECTS = pyosys/wrappers.o kernel/drivers.o kernel/yosys.o passes/cmds/plugin.o + ifeq ($(ENABLE_PYOSYS),1) # python-config --ldflags includes -l and -L, but LINKFLAGS is only -L LINKFLAGS += $(filter-out -l%,$(shell $(PYTHON_CONFIG) --ldflags)) LIBS += $(shell $(PYTHON_CONFIG) --libs) EXE_LIBS += $(filter-out $(LIBS),$(shell $(PYTHON_CONFIG_FOR_EXE) --libs)) -CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DWITH_PYTHON +PYBIND11_INCLUDE ?= $(shell $(PYTHON_EXECUTABLE) -m pybind11 --includes) +CXXFLAGS += -I$(PYBIND11_INCLUDE) -DYOSYS_ENABLE_PYTHON +CXXFLAGS += $(shell $(PYTHON_CONFIG) --includes) -DYOSYS_ENABLE_PYTHON -# Detect name of boost_python library. Some distros use boost_python-py, other boost_python, some only use the major version number, some a concatenation of major and minor version numbers -CHECK_BOOST_PYTHON = (echo "int main(int argc, char ** argv) {return 0;}" | $(CXX) -xc -o /dev/null $(LINKFLAGS) $(EXE_LIBS) $(LIBS) -l$(1) - > /dev/null 2>&1 && echo "-l$(1)") -BOOST_PYTHON_LIB ?= $(shell \ - $(call CHECK_BOOST_PYTHON,boost_python-py$(subst .,,$(PYTHON_VERSION))) || \ - $(call CHECK_BOOST_PYTHON,boost_python-py$(PYTHON_MAJOR_VERSION)) || \ - $(call CHECK_BOOST_PYTHON,boost_python$(subst .,,$(PYTHON_VERSION))) || \ - $(call CHECK_BOOST_PYTHON,boost_python$(PYTHON_MAJOR_VERSION)) \ -) - -ifeq ($(BOOST_PYTHON_LIB),) -$(error BOOST_PYTHON_LIB could not be detected. Please define manually) -endif - -LIBS += $(BOOST_PYTHON_LIB) -lboost_system -lboost_filesystem -PY_WRAPPER_FILE = kernel/python_wrappers OBJS += $(PY_WRAPPER_FILE).o -PY_GEN_SCRIPT= py_wrap_generator -PY_WRAP_INCLUDES := $(shell $(PYTHON_EXECUTABLE) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()") +PY_GEN_SCRIPT = pyosys/generator.py +PY_WRAP_INCLUDES := $(shell $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) --print-includes) endif # ENABLE_PYOSYS ifeq ($(ENABLE_READLINE),1) @@ -786,9 +775,9 @@ endif $(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(CXX) $(CXXFLAGS) -x c++ -o $@ -E -P - ifeq ($(ENABLE_PYOSYS),1) -$(PY_WRAPPER_FILE).cc: misc/$(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES) +$(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT) pyosys/wrappers_tpl.cc $(PY_WRAP_INCLUDES) pyosys/hashlib.h $(Q) mkdir -p $(dir $@) - $(P) $(PYTHON_EXECUTABLE) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")" + $(P) $(PYTHON_EXECUTABLE) $(PY_GEN_SCRIPT) $(PY_WRAPPER_FILE).cc endif %.o: %.cpp @@ -1035,12 +1024,12 @@ ifeq ($(ENABLE_LIBYOSYS),1) if [ -n "$(STRIP)" ]; then $(INSTALL_SUDO) $(STRIP) -S $(DESTDIR)$(LIBDIR)/libyosys.so; fi ifeq ($(ENABLE_PYOSYS),1) $(INSTALL_SUDO) mkdir -p $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys + $(INSTALL_SUDO) cp pyosys/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/__init__.py $(INSTALL_SUDO) cp libyosys.so $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/libyosys.so $(INSTALL_SUDO) cp -r share $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys ifeq ($(ENABLE_ABC),1) $(INSTALL_SUDO) cp yosys-abc $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/yosys-abc endif - $(INSTALL_SUDO) cp misc/__init__.py $(DESTDIR)$(PYTHON_DESTDIR)/$(subst -,_,$(PROGRAM_PREFIX))pyosys/ endif endif ifeq ($(ENABLE_PLUGINS),1) @@ -1130,12 +1119,10 @@ DOC_TARGET ?= html docs: docs/prep $(Q) $(MAKE) -C docs $(DOC_TARGET) -clean: +clean: clean-py rm -rf share - rm -rf kernel/*.pyh - rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) $(PY_WRAPPER_FILE).cc + rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) rm -f kernel/version_*.o kernel/version_*.cc - rm -f kernel/python_wrappers.o rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d rm -rf tests/asicworld/*.out tests/asicworld/*.log rm -rf tests/hana/*.out tests/hana/*.log @@ -1149,8 +1136,14 @@ clean: rm -f $(addsuffix /run-test.mk,$(MK_TEST_DIRS)) -$(MAKE) -C docs clean rm -rf docs/util/__pycache__ + rm -f libyosys.so + +clean-py: + rm -f $(PY_WRAPPER_FILE).inc.cc $(PY_WRAPPER_FILE).cc + rm -f $(PYTHON_OBJECTS) rm -f *.whl rm -f libyosys.so + rm -rf kernel/*.pyh clean-abc: $(MAKE) -C abc DEP= clean diff --git a/docs/.gitignore b/docs/.gitignore index 09bb59048..30a903f9a 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -6,3 +6,4 @@ /source/_images/**/*.svg /source/_images/**/*.dot /source/_images/code_examples +/venv diff --git a/docs/source/code_examples/pyosys/pass.py b/docs/source/code_examples/pyosys/pass.py new file mode 100644 index 000000000..2108b48ab --- /dev/null +++ b/docs/source/code_examples/pyosys/pass.py @@ -0,0 +1,37 @@ +from pyosys import libyosys as ys + +class AllEnablePass(ys.Pass): + def __init__(self): + super().__init__( + "all_enable", + "makes all _DFF_P_ registers require an enable signal" + ) + + def execute(self, args, design): + ys.log_header(design, "Adding enable signals\n") + ys.log_push() + top_module = design.top_module() + + if "\\enable" not in top_module.wires_: + enable_line = top_module.addWire("\\enable") + enable_line.port_input = True + top_module.fixup_ports() + + for cell in top_module.cells_.values(): + if cell.type != "$_DFF_P_": + continue + cell.type = "$_DFFE_PP_" + cell.setPort("\\E", ys.SigSpec(enable_line)) + ys.log_pop() + +p = AllEnablePass() # register the pass + +# using the pass + +design = ys.Design() +ys.run_pass("read_verilog tests/simple/fiedler-cooley.v", design) +ys.run_pass("hierarchy -check -auto-top", design) +ys.run_pass("synth", design) +ys.run_pass("all_enable", design) +ys.run_pass("write_verilog out.v", design) +ys.run_pass("synth_ice40 -json out.json", design) diff --git a/docs/source/code_examples/pyosys/simple_database.py b/docs/source/code_examples/pyosys/simple_database.py new file mode 100644 index 000000000..4cfe6b586 --- /dev/null +++ b/docs/source/code_examples/pyosys/simple_database.py @@ -0,0 +1,51 @@ +from pyosys import libyosys as ys + +# loading design +design = ys.Design() + +ys.run_pass("read_verilog tests/simple/fiedler-cooley.v", design) +ys.run_pass("hierarchy -check -auto-top", design) + +# top module inspection +top_module = design.top_module() + +for id, wire in top_module.wires_.items(): + if not wire.port_input and not wire.port_output: + continue + description = "input" if wire.port_input else "output" + description += " " + wire.name.str() + if wire.width != 1: + frm = wire.start_offset + to = wire.start_offset + wire.width + if wire.upto: + to, frm = frm, to + description += f" [{to}:{frm}]" + print(description) + +# synth + +ys.run_pass("synth", design) + +# adding the enable line + +enable_line = top_module.addWire("\\enable") +enable_line.port_input = True +top_module.fixup_ports() + +# hooking the enable line to the internal dff cells + +for cell in top_module.cells_.values(): + if cell.type != "$_DFF_P_": + continue + cell.type = "$_DFFE_PP_" + cell.setPort("\\E", ys.SigSpec(enable_line)) + +# run check + +top_module.check() +ys.run_pass("stat", design) + +# write outputs + +ys.run_pass("write_verilog out.v", design) +ys.run_pass("synth_ice40 -json out.json", design) diff --git a/docs/source/using_yosys/index.rst b/docs/source/using_yosys/index.rst index b243d431e..93dd3629b 100644 --- a/docs/source/using_yosys/index.rst +++ b/docs/source/using_yosys/index.rst @@ -17,3 +17,4 @@ ways Yosys can interact with designs for a deeper investigation. more_scripting/index bugpoint verilog + pyosys diff --git a/docs/source/using_yosys/pyosys.rst b/docs/source/using_yosys/pyosys.rst new file mode 100644 index 000000000..8aa7fd4fe --- /dev/null +++ b/docs/source/using_yosys/pyosys.rst @@ -0,0 +1,208 @@ +Scripting with Pyosys +===================== + +Pyosys is a limited subset of the Yosys C++ API (aka "libyosys") made available +using the Python programming language. + +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 CPython 3.8 or higher. You can access Pyosys using one of two +methods: + +1. Compiling Yosys with the Makefile flag ``ENABLE_PYOSYS=1`` + + This adds the flag ``-y`` to the Yosys binary, which allows you to execute + Python scripts using an interpreter embedded in Yosys itself: + + ``yosys -y ./my_pyosys_script.py`` + +2. Installing the Pyosys wheels + + On macOS and GNU/Linux you can install pre-built wheels of Yosys using + ``pip``: + + ``python3 -m pip install pyosys`` + + Which then allows you to run your scripts as follows: + + ``python3 ./my_pyosys_script.py`` + + +Scripting and Database Inspection +--------------------------------- + +To start with, you have to import libyosys as follows: + +.. code-block:: python + + from pyosys import libyosys + + +As a reminder, Python allows you to alias imported modules and objects, so +this import may be preferable for terseness: + +.. code-block:: python + + from pyosys import libyosys as ys + + +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 like conditional execution, loops, and functions: + +.. code-block:: python + + do_flatten = True + + ys.run_pass("read_verilog tests/simple/fiedler-cooley.v") + ys.run_pass("hierarchy -check -auto-top") + if do_flatten: + ys.run_pass("flatten") + +…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. + +.. literalinclude:: /code_examples/pyosys/simple_database.py + :start-after: loading design + :end-before: top module inspection + :language: python + +What's new here is that you can manually inspect the design's database. This +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: + +.. literalinclude:: /code_examples/pyosys/simple_database.py + :start-after: top module inspection + :end-before: # synth + :language: python + +.. tip:: + + 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 + 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 + to manually instantiate the right underlying C++ object(s) yourself. + +Modifying the Database +---------------------- + +.. warning:: + + Any modifications to the database may invalidate previous references held + by Python, just as if you were writing C++. Pyosys does not currently attempt + to keep deleted objects alive if a reference is held by Python. + +You are not restricted to inspecting the database either: you have the ability +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`): + +.. literalinclude:: /code_examples/pyosys/simple_database.py + :start-after: # synth + :end-before: adding the enable line + :language: python + +Next, we need to add the new port. The method for this is ``Module::addWire``\. + +.. tip:: + + IdString is Yosys's internal representation of strings used as identifiers + within Verilog designs. They are efficient as only integers are stored and + passed around, but they can be translated to and from normal strings at will. + + Pyosys will automatically cast Python strings to IdStrings for you, but the + rules around IdStrings apply, namely that *broadly*: + + - Identifiers for internal cells must start with ``$``\. + - All other identifiers must start with ``\``\. + +.. literalinclude:: /code_examples/pyosys/simple_database.py + :start-after: adding the enable line + :end-before: hooking the enable line + :language: python + +Notice how we modified the wire then called a method to make Yosys re-process +the ports. + +Next, we can iterate over all constituent cells, and if they are of the type +``$_DFF_P_``, we do two things: + +1. Change their type to ``$_DFFE_PP_`` to enable hooking up an enable signal. +2. Hooking up the enable signal. + +.. literalinclude:: /code_examples/pyosys/simple_database.py + :start-after: hooking the enable line + :end-before: run check + :language: python + +To verify that you did everything correctly, it is prudent to call ``.check()`` +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 + :end-before: write output + :language: python + +And then finally, write your outputs. Here, I choose an intermediate Verilog +file and :yoscrypt:`synth_ice40` to map it to the iCE40 architecture. + +.. literalinclude:: /code_examples/pyosys/simple_database.py + :start-after: write output + :language: python + +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 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 + +In general, abstract classes and virtual methods are not really supported by +Pyosys due to their complexity, but there are two exceptions which are: + +- ``Pass`` in ``kernel/register.h`` +- ``Monitor`` in ``kernel/rtlil.h`` diff --git a/docs/source/yosys_internals/hashing.rst b/docs/source/yosys_internals/hashing.rst index 1993e617a..1255f6f7c 100644 --- a/docs/source/yosys_internals/hashing.rst +++ b/docs/source/yosys_internals/hashing.rst @@ -36,7 +36,7 @@ The main characteristics are: all compilers, standard libraries and architectures. In addition to ``dict`` and ``pool`` there is also an ``idict`` that -creates a bijective map from ``K`` to the integers. For example: +creates a bijective map from ``K`` to incrementing integers. For example: :: diff --git a/examples/python-api/pass.py b/examples/python-api/pass.py index dbef0a13f..d5e5868b0 100755 --- a/examples/python-api/pass.py +++ b/examples/python-api/pass.py @@ -1,22 +1,25 @@ #!/usr/bin/python3 -import libyosys as ys +from pyosys import libyosys as ys + +from pathlib import Path import matplotlib.pyplot as plt -import numpy as np + +__file_dir__ = Path(__file__).absolute().parent class CellStatsPass(ys.Pass): def __init__(self): super().__init__("cell_stats", "Shows cell stats as plot") - def py_help(self): + def help(self): ys.log("This pass uses the matplotlib library to display cell stats\n") - def py_execute(self, args, design): + def execute(self, args, design): ys.log_header(design, "Plotting cell stats\n") cell_stats = {} - for module in design.selected_whole_modules_warn(): + for module in design.all_selected_whole_modules(): for cell in module.selected_cells(): if cell.type.str() in cell_stats: cell_stats[cell.type.str()] += 1 @@ -26,7 +29,14 @@ class CellStatsPass(ys.Pass): plt.xticks(range(len(cell_stats)), list(cell_stats.keys())) plt.show() - def py_clear_flags(self): + def clear_flags(self): ys.log("Clear Flags - CellStatsPass\n") -p = CellStatsPass() +p = CellStatsPass() # register + +if __name__ == "__main__": + design = ys.Design() + ys.run_pass(f"read_verilog {__file_dir__.parents[1] / 'tests' / 'simple' / 'fiedler-cooley.v'}", design) + ys.run_pass("prep", design) + ys.run_pass("opt -full", design) + ys.run_pass("cell_stats", design) diff --git a/kernel/driver.cc b/kernel/driver.cc index bbe4e46f3..795fd9fc5 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -37,6 +37,12 @@ # include #endif +#ifdef YOSYS_ENABLE_PYTHON +# include +# include +namespace py = pybind11; +#endif + #include #include #include @@ -91,9 +97,10 @@ int main(int argc, char **argv) log_error_stderr = true; yosys_banner(); yosys_setup(); -#ifdef WITH_PYTHON - PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str()); - PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str()); +#ifdef YOSYS_ENABLE_PYTHON + py::object sys = py::module_::import("sys"); + sys.attr("path").attr("append")(proc_self_dirname()); + sys.attr("path").attr("append")(proc_share_dirname()); #endif if (argc == 2) @@ -226,10 +233,10 @@ int main(int argc, char **argv) cxxopts::value(),"") ("C,tcl-interactive", "enters TCL interactive shell mode") #endif // YOSYS_ENABLE_TCL -#ifdef WITH_PYTHON +#ifdef YOSYS_ENABLE_PYTHON ("y,py-scriptfile", "execute the Python