pysv is a lightweight Python library that allows functional models to be written in Python and then executed inside standard SystemVerilog simulators, via DPI.
Documentation is here.
pysv is designed to be versatile and can be used directly or as a library in other hardware generator frameworks. It offers the following features:
- C/C++ and SystemVerilog binding code generation
- Foreign modules, e.g.
numpy
ortensorflow
. - Python functions
- Python classes
- Platform-independent compilation
Theoretically any simulator that supports SystemVerilog DPI semantics should work. Here is a list of simulators that have been tested:
- Cadence® Xcelium™
- Synopsys VCS®
- Mentor Questa®
- Vivado® Simulator
- Verilator
pysv leverages pybind11 to execute arbitrary Python code. As a result, here is a list of dependencies
- cmake 3.4 or newer
- Any C++ compiler that supports C++11:
- Clang/LLVM 3.3 or newer (for Apple Xcode’s clang, this is 5.0.0 or newer)
- GCC 4.8 or newer
- Python 3.6 or newer
Here is a simple example to show a Python class that uses numpy
for
computation.
import numpy as np
from pysv import sv, compile_lib, DataType, generate_sv_binding
class Array:
def __init__(self):
# constructor without any extra argument is exported to SV directly
self.__array = []
@sv()
def add_element(self, i):
self.__array.append(i)
@sv()
def min(self):
# call the numpy function
return np.min(self.__array)
@sv(return_type=DataType.Bit)
def exists(self, value):
return self.__exists(value)
def __exists(self, value):
# this function is not exposed to SystemVerilog
return value in self.__value
# compile the code into a shared library for DPI to load
# build the lib inside the ./build folder
# lib_path is the path to the shared library file
lib_path = compile_lib([Array], cwd="build")
# generate SV bindings
generate_sv_binding([Array], filename="array_pkg.sv", pkg_name="demo")
Now we can use the class directly with the SystemVerilog binding:
// import Array
import demo::*;
Array a = new();
a.add_element(1);
assert(a.exists(1));
assert(!a.exists(2));
// numpy under the hood!
assert(a.min() == 1);