.. _basics: First steps ########### This sections demonstrates the basic features of PyStim. Before getting started, make sure that development environment is set up to compile the included set of examples. Compiling examples ==================== Linux ----------- In below examples, we will compile the example located in the :file:`examples/math_factorial` directory. To compile we will use the Questa Sim simulator. You can use any other HDL simulator or Verilator by running the appropriate ``./run.sh`` script followed by simulator name. After installing the prerequisites, go to examples directory and run the following command inside one of the example directories: .. code-block:: bash $ source ../../scripts/environment $ ./run.sh questa The last line will both compile and run the example under Questa Sim. Import and initialization conventions ===================================== For brevity, all code examples assume that the following lines are present: .. code-block:: systemverilog import pystim_pkg::*; typedef pystim_pkg::pystim py; py::initialize_interpreter(); ... py::finalize_interpreter(); The :func:`pystim_pkg::initialize_interpreter` method should be invoked only once during the simulation. It starts up the Python interpreter and sets up the environment. The import statement is used to bring all the PyStim classes and functions into the current namespace. Some features may require additional method invocation, but those will be specified as needed. .. _simple_example: Creating bindings for a simple function ======================================= Let's start by creating Python bindings for an extremely simple function, which returns factorial of a number. The underlying Python ``factorial`` function is part of the ``math`` module. .. code-block:: systemverilog function int factorial(int x); automatic py_object result_obj; result_obj = py_module::import_("math").attr("factorial").call(py::int_(x)); return result_obj.cast_int().get_value(); endfunction For simplicity [#f1]_, we'll put both this function and the initialization code into a file named :file:`math_factorial.sv` with the following contents: .. code-block:: systemverilog import pystim_pkg::*; module math_factorial(); typedef pystim_pkg::pystim py; initial begin py::initialize_interpreter(); $display("Result: factorial(4) = %0d", factorial(4)); py::finalize_interpreter(); end function int factorial(int x); automatic py_object result_obj; result_obj = py_module::import_("math").attr("factorial").call(py::int_(x)); return result_obj.cast_int().get_value(); endfunction endmodule .. [#f1] In practice, implementation and initialization code will generally be located in separate files. The :func:`py_module::import_` imports the Python module named :class:``math``. The :func:`attr` function used to reference attribute waiting the module or class. The :func:`call` method invokes referenced method with the argument of type :class:`py_int`. :class:`py_int` is a SystemVerilog wrapper for Python integer type. The :class:`py_object` :func:`cast_int` method is used to convert the return value to an :class:`py_int` object. :class:`py_int` is a SystemVerilog wrapper for Python integer type. :func:`get_value` returns coresponding :class:`int` represented by :class:`py_int`. In the example above, the method calls the function :func:``factorial`` from the :class:``math`` module with the arguments ``x``. The :func:`py::int_` method is used to create an SystemVerilog wrapper for Python integer type. .. note:: Notice how little code was needed to expose Python methods: all details regarding the function's parameters and return value were automatically inferred using template metaprogramming. This overall approach and the used syntax are borrowed from pybind11, though the underlying implementation is very different. PyStim is a SystemVerilog package and shared library, hence it is not necessary to compile against any special libraries and there are no intermediate (magic) translation steps. On Linux, the above example can be compiled under Questa Sim using the following command: .. code-block:: bash $ source $PY_STIM_INSTALL_DIR/scripts/environment $ vlog -O0 +acc -f $PY_STIM_INSTALL_DIR/system_verilog/list/py_stim.f math_factorial.sv $ vsim -c -lib work math_factorial -do "run -all; quit" -l run.log -sv_lib $PY_STIM_INSTALL_DIR/lib/libpystim -gblso $PY_STIM_INSTALL_DIR/lib/libpystim.so # or using the run.sh script in examples/math_factorial directory For more details on the required compiler flags on Linux for different HDL simulators, see :ref:`compiling`. Building and running the above code will produce listed below output: .. code-block:: bash Result: factorial(4) = 24 .. _supported_types: Supported data types ==================== A large number of data types are supported out of the box and can be used seamlessly as functions arguments and return values. For a full overview, see the :doc:`advanced/cast/index` section.