Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
View this page
Toggle table of contents sidebar

# 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 `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:

    $ 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:

    import pystim_pkg::*;

    typedef pystim_pkg::pystim py;

    py::initialize_interpreter();
    ...
    py::finalize_interpreter();

The `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.

## 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.

    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 [1], we’ll put both this function and the initialization code into a file named `math_factorial.sv` with the following contents:

    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

[1]

In practice, implementation and initialization code will generally be located in separate files.

The `py_module::import_()` imports the Python module named :class:`math`. The `attr()` function used to reference attribute waiting the module or class. The `call()` method invokes referenced method with the argument of type `py_int`. `py_int` is a SystemVerilog wrapper for Python integer type. The `py_object` `cast_int()` method is used to convert the return value to an `py_int` object. `py_int` is a SystemVerilog wrapper for Python integer type. `get_value()` returns coresponding `int` represented by `py_int`. In the example above, the method calls the function :func:`factorial` from the :class:`math` module with the arguments `x`. The `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:

    $ 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 Build systems.

Building and running the above code will produce listed below output:

    Result: factorial(4)  = 24

## 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 Type conversions section.