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