Skip to content

Commit 34fa5e4

Browse files
authored
Merge pull request #1 from bhavayarora-bosch/main
Extend SCVPI with additional VPI support, examples, and CI workflow
2 parents 21c5a69 + d42fe47 commit 34fa5e4

File tree

22 files changed

+2122
-437
lines changed

22 files changed

+2122
-437
lines changed

.github/workflows/ci.yaml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
env:
10+
COCOTB_ANSI_OUTPUT: 1
11+
FORCE_COLOR: 1
12+
13+
jobs:
14+
build:
15+
16+
runs-on: ubuntu-latest
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
python-version: ["3.14"]
21+
22+
steps:
23+
- uses: actions/checkout@v4
24+
25+
- name: Set up Python ${{ matrix.python-version }}
26+
uses: actions/setup-python@v6
27+
with:
28+
python-version: ${{ matrix.python-version }}
29+
30+
- name: Install uv
31+
uses: astral-sh/setup-uv@v7
32+
with:
33+
version: "0.9.27"
34+
enable-cache: true
35+
36+
- name: Install dependencies
37+
env:
38+
DEBIAN_FRONTEND: noninteractive
39+
run: |
40+
echo "::group::apt-get update"
41+
sudo apt-get update
42+
echo "::endgroup::"
43+
44+
echo "::group::apt-get install"
45+
sudo apt-get install --yes --no-install-recommends \
46+
iverilog \
47+
cpp \
48+
cmake \
49+
libsystemc \
50+
libsystemc-dev
51+
echo "::endgroup::"
52+
53+
- name: Run tests on Python ${{ matrix.python-version }}
54+
run: |
55+
uv venv
56+
source .venv/bin/activate
57+
uv sync --locked --all-extras --dev
58+
59+
for ex in basic adder TinyALU_SystemC; do
60+
make -C examples/$ex show-config
61+
make -C examples/$ex run-icarus
62+
done

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12

README.md

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,90 @@
1-
# scvpi
2-
Provides a stub implementation of (System)Verilog VPI functions for SystemC.
3-
Currently, this is just enough to allow cocotb to schedule coroutines.
4-
Access to signals, and other RTL-like things is not currently implemented. The purpose
5-
of this package is to enable running a Python testbench with high-level SystemC
6-
models.
1+
# SCVPI
72

3+
SCVPI is a VPI-compatible interface for SystemC that enables **cocotb**
4+
and cocotb-based frameworks such as **PyUVM** to run on SystemC models.
85

9-
## Using scvpi
6+
By providing a VPI-compatible layer, SCVPI allows Python-based
7+
verification environments to be reused across both RTL and SystemC,
8+
eliminating duplicated verification infrastructure and enabling a
9+
unified verification flow.
1010

11-
- Compile scvpi with your SystemC model
12-
- Add <scvpi>/src/scvpi.cpp to your SystemC files
13-
- Add <scvpi>/src as an include path
14-
15-
- Specify VPI libraries to load at runtime
16-
- Add +vpi=<path_to_so> to the SystemC command line
17-
11+
---
1812

13+
## Motivation
14+
15+
Python-based verification frameworks such as cocotb and PyUVM are widely
16+
used for RTL verification due to their productivity and reusability.
17+
However, these frameworks rely on the Verilog Procedural Interface (VPI)
18+
and therefore cannot be applied directly to SystemC models.
19+
20+
SystemC is commonly used for high-level modeling and virtual prototyping.
21+
This separation often leads to duplicated testbenches and inconsistent
22+
verification behavior between RTL and high-level models.
23+
24+
SCVPI bridges this gap by exposing a VPI-compatible interface for
25+
SystemC, allowing cocotb and PyUVM testbenches to execute on SystemC
26+
models without modification.
27+
28+
---
29+
30+
## What SCVPI Provides
31+
32+
- A VPI-compatible interface for SystemC
33+
- Coroutine scheduling support required by cocotb
34+
- Signal access and callback mechanisms required by PyUVM
35+
- Reuse of Python testbenches without modification
36+
- A unified verification flow across RTL and SystemC models
37+
38+
---
39+
40+
## Supported SystemC Signal Types
41+
42+
SCVPI currently supports direct value access for a subset of SystemC
43+
signal types, including:
44+
45+
- `sc_signal<bool>`
46+
- `sc_signal<int>` (treated as 32-bit)
47+
- `sc_signal<sc_int<4>>`
48+
- `sc_signal<sc_uint<3>>`
49+
- `sc_signal<sc_uint<8>>`
50+
- `sc_signal<sc_uint<16>>`
51+
52+
Signals with unsupported types are reported as unknown.
53+
54+
---
55+
56+
## Examples
57+
58+
The repository includes several examples demonstrating different usage
59+
scenarios:
60+
61+
- **examples/basic**
62+
Minimal sanity check demonstrating cocotb coroutine scheduling on a
63+
SystemC model.
64+
65+
- **examples/adder**
66+
A simple functional example with deterministic and randomized tests.
67+
68+
- **examples/TinyALU_SystemC**
69+
A SystemC implementation of the official PyUVM TinyALU example.
70+
The original PyUVM testbench is reused unchanged, demonstrating
71+
verification reuse between RTL and SystemC using SCVPI.
72+
73+
These examples serve as reference implementations for integrating SCVPI
74+
with SystemC models and reusing Python-based verification environments.
75+
76+
---
77+
78+
## Scope and Limitations
79+
80+
SCVPI is intended for verification of high-level SystemC models.
81+
It does not aim to replace RTL simulators or provide full Verilog
82+
compatibility. Performance characteristics may differ from RTL-based
83+
verification flows.
84+
85+
---
86+
87+
## License
88+
89+
This project is released under the applicable open-source license.
90+
Third-party examples and testbenches retain their original licenses.

examples/TinyALU_SystemC/Makefile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
SYSTEMC ?= /usr
2+
CXX ?= g++
3+
4+
ROOT ?= ../..
5+
SCVPI_SRC := $(ROOT)/src
6+
7+
CXXFLAGS += -I$(SYSTEMC)/include -I./hdl -I$(SCVPI_SRC) -export-dynamic
8+
LDFLAGS += -L$(SYSTEMC)/lib-linux64 -ldl -lsystemc
9+
10+
COCOTB_CMD = $(shell command -v uv >/dev/null 2>&1 && echo "uv run cocotb-config" || echo "cocotb-config")
11+
COCOTB_LIBPYTHON = $(shell $(COCOTB_CMD) --libpython 2>/dev/null || echo "")
12+
COCOTB_LIBPYTHON_DIR = $(dir $(COCOTB_LIBPYTHON))
13+
COCOTB_PYTHON_BIN = $(shell $(COCOTB_CMD) --python-bin 2>/dev/null || echo "python3")
14+
COCOTB_LIB_DIR = $(shell $(COCOTB_CMD) --lib-dir 2>/dev/null || echo "")
15+
COCOTB_VPI_ICARUS = $(COCOTB_LIB_DIR)/libcocotbvpi_icarus.vpl
16+
17+
COCOTB_ENV = \
18+
PYTHONPATH=.:$$PYTHONPATH \
19+
PYGPI_PYTHON_BIN=$(COCOTB_PYTHON_BIN) \
20+
COCOTB_TEST_MODULES=testbench \
21+
LD_LIBRARY_PATH=$(SYSTEMC)/lib-linux64:$(COCOTB_LIBPYTHON_DIR):$$LD_LIBRARY_PATH
22+
23+
.PHONY: all
24+
all: test
25+
26+
test: hdl/main.cpp hdl/tinyalu_systemc.h $(SCVPI_SRC)/scvpi.cpp
27+
$(CXX) $(CXXFLAGS) $(SCVPI_SRC)/scvpi.cpp hdl/main.cpp -o test $(LDFLAGS)
28+
29+
.PHONY: run-icarus
30+
run-icarus: test
31+
@$(COCOTB_ENV) ./test -m $(COCOTB_VPI_ICARUS)
32+
33+
.PHONY: clean
34+
clean:
35+
rm -f test
36+
37+
.PHONY: show-config
38+
show-config:
39+
@echo "=== TinyALU SystemC Configuration ==="
40+
@echo "SYSTEMC: $(SYSTEMC)"
41+
@echo "CXX: $(CXX)"
42+
@echo "SCVPI_SRC: $(SCVPI_SRC)"
43+
@echo ""
44+
@echo "=== Cocotb Configuration ==="
45+
@echo "COCOTB_PYTHON_BIN: $(COCOTB_PYTHON_BIN)"
46+
@echo "COCOTB_LIBPYTHON: $(COCOTB_LIBPYTHON)"
47+
@echo "COCOTB_VPI_ICARUS: $(COCOTB_VPI_ICARUS)"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <systemc>
2+
#include "tinyalu_systemc.h"
3+
4+
extern "C" void scvpi_autoregister_all();
5+
6+
SC_MODULE(Top) {
7+
sc_signal<bool> reset_n{"reset_n"};
8+
sc_signal<bool> clk{"clk"};
9+
sc_signal<bool> start{"start"};
10+
11+
sc_signal<sc_dt::sc_uint<8>> A{"A"};
12+
sc_signal<sc_dt::sc_uint<8>> B{"B"};
13+
sc_signal<sc_dt::sc_uint<3>> op{"op"};
14+
15+
sc_signal<bool> done{"done"};
16+
sc_signal<sc_dt::sc_uint<16>> result{"result"};
17+
18+
tinyalu dut{"tinyalu"};
19+
20+
SC_CTOR(Top) {
21+
dut.reset_n(reset_n);
22+
dut.clk(clk);
23+
dut.start(start);
24+
dut.A(A);
25+
dut.B(B);
26+
dut.op(op);
27+
dut.done(done);
28+
dut.result(result);
29+
}
30+
};
31+
32+
int sc_main(int argc, char* argv[]) {
33+
34+
Top top{"top"};
35+
scvpi_autoregister_all();
36+
37+
sc_core::sc_set_stop_mode(sc_core::SC_STOP_IMMEDIATE);
38+
sc_core::sc_start();
39+
return 0;
40+
}

0 commit comments

Comments
 (0)