PyStim Tutorial: Easily call Python functions from SystemVerilog

This tutorial provides a comprehensive step-by-step guide to using PyStim. It demonstrates how to call Python functions from SystemVerilog, enabling the writing of robust SystemVerilog code while maintaining Python’s simplicity for scripting and library reuse.

call python functions from SystemVerilog

Write Python Code

The first step is to write the Python code to expose to SystemVerilog. For this tutorial, we’ll implement simple arithmetic functions as an example.

Python Example Functions

Create a file named custom_math.py (or any name you prefer) and implement the Python functions listed below. These functions will then be callable from SystemVerilog.

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

These functions perform basic arithmetic operations and will be exposed to SystemVerilog. Once Python code is written, we can move forward with calling it from SystemVerilog.

SystemVerilog code

Here is the complete code of the add_numbers.sv file that includes both the SystemVerilog code and Python code invocation. This file integrates the arithmetic functions and Python bindings in one cohesive block. It represents the starting point for creating a functional Python module from SystemVerilog. The PyStim Library allows the creation of Python bindings for SystemVerilog without the need for C++ wrapper code generation. In SystemVerilog, you call Python functions by simply using their name. This same principle extends to accessing other Python entities – their attributes (including methods) and classes are referenced by attribute name with py_object::attr method.

import pystim_pkg::*;

module add_numbers();

    typedef pystim_pkg::pystim py;
 
    initial begin
        pystim_pkg::initialize_interpreter();
        begin
            py_module calc = py_module::import_("custom_math");
            py_object res = calc.attr("add").call(py::int_(1), py::float_(2.2));
            assert (res.cast_float().get_value() == 3.2) 
        end
        $display("Result: 1 + 2.2 = %f", res.cast_float().get_value());
        pystim_pkg::finalize_interpreter();
    end

endmodule

Refer to the GitHub page for the source code of this example and further illustrations of PyStim usage.

The SystemVerilog code demonstrates the invocation of the Python function add, which resides in the custom_math module. This function is called with the SystemVerilog variables of type py_int and py_float as its arguments. The return value of this Python function call is then stored in the SystemVerilog object res, which is declared as type py_object. It is important to note that py_object acts as the base class for all Python object wrappers within the PyStim framework. To operate on the specific type of the Python object returned, res must be cast to a more derived type. Furthermore, the py::isinstance<>() construct allows for runtime type checking of the Python object held by res.

Building and running the code.

Assuming the PyStim library is installed (refer to the installation guide if not), QuestaSim will be used to compile and run the code above. The code provided below is compatible with all Hardware Description Language (HDL) simulators operating within a Linux environment. Remember to add custom_math.py to PYTHONPATH.

# Include example Python files (custom_math.py) to PYTHONPATH. 
export PYTHONPATH=${PYTHONPATH}:${PATH_TO_CUSTOM_MATH_PY_DIR}

vlog -O0 +acc  -f $PY_STIM_INSTALL_DIR/examples/add_numbers/list/compile_list.f
vsim -voptargs=+acc -c  -lib work add_numbers -do "run -all; quit"  -l run.log   -sv_lib $PY_STIM_INSTALL_DIR/lib/libpystim -gblso $PY_STIM_INSTALL_DIR/lib/libpystim.so

The documentation and API pages provide further information on PyStim methods and their use cases.

Conclusion

By following this tutorial, you have learned how to:

  • Call Python functions from SystemVerilog.
  • Compile and run SystemVerilog with PyStim library.

PyStim simplifies bridging the gap between Python and SystemVerilog, enabling developers to build high-performance, Python-friendly extensions. With this knowledge, you can effectively combine the power of SystemVerilog with the simplicity of Python, unlocking new possibilities in your projects.