Skip to main content

rustdv_gpi_sys/
rustdv_gpi_sys.rs

1//! # rustdv-gpi-sys
2//!
3//! Raw FFI declarations for the simulator programming interface.
4//!
5//! **Deviation from design-doc D2.1** (documented in STATUS.md): the design
6//! calls for bindgen-generated bindings to cocotb's `gpi.h`. This sandbox has
7//! no cocotb GPI build and a zero-external-dependency constraint (no bindgen),
8//! so v0 binds the IEEE 1800 **VPI** C API directly — the same API cocotb's
9//! GPI wraps for Icarus. The declarations below are a hand-written subset of
10//! `vpi_user.h`, sufficient for: hierarchy lookup, value get/set, time query,
11//! and callbacks. The safe layer (`rustdv-gpi`) exposes a GPI-shaped API so
12//! that swapping this crate for real gpi.h bindings later is contained.
13//!
14//! Everything here is `unsafe extern "C"`; no logic lives in this crate
15//! (the `-sys` discipline, design-doc D2.1).
16
17#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
18
19use std::os::raw::{c_char, c_void};
20
21pub type PLI_INT32 = i32;
22pub type PLI_UINT32 = u32;
23pub type PLI_BYTE8 = c_char;
24
25/// Opaque simulator object handle (`vpiHandle`).
26pub type vpiHandle = *mut c_void;
27
28// ---------------------------------------------------------------------------
29// Properties (vpi_get / vpi_get_str)
30// ---------------------------------------------------------------------------
31pub const vpiType: PLI_INT32 = 1;
32pub const vpiName: PLI_INT32 = 2;
33pub const vpiFullName: PLI_INT32 = 3;
34pub const vpiSize: PLI_INT32 = 4;
35pub const vpiFile: PLI_INT32 = 5;
36pub const vpiLineNo: PLI_INT32 = 6;
37pub const vpiTimeUnit: PLI_INT32 = 11;
38pub const vpiTimePrecision: PLI_INT32 = 12;
39
40// ---------------------------------------------------------------------------
41// Object type codes (vpi_get(vpiType, ...) results / vpi_iterate types)
42// ---------------------------------------------------------------------------
43pub const vpiConstant: PLI_INT32 = 7;
44pub const vpiIntegerVar: PLI_INT32 = 25;
45pub const vpiMemory: PLI_INT32 = 29;
46pub const vpiModule: PLI_INT32 = 32;
47pub const vpiNet: PLI_INT32 = 36;
48pub const vpiParameter: PLI_INT32 = 41;
49pub const vpiPort: PLI_INT32 = 44;
50pub const vpiReg: PLI_INT32 = 48;
51pub const vpiRealVar: PLI_INT32 = 47;
52// SystemVerilog variable types (sv_vpi_user.h)
53pub const vpiLongIntVar: PLI_INT32 = 610;
54pub const vpiShortIntVar: PLI_INT32 = 611;
55pub const vpiIntVar: PLI_INT32 = 612;
56pub const vpiByteVar: PLI_INT32 = 614;
57pub const vpiEnumVar: PLI_INT32 = 617;
58pub const vpiBitVar: PLI_INT32 = 620;
59
60// ---------------------------------------------------------------------------
61// Value formats (t_vpi_value.format)
62// ---------------------------------------------------------------------------
63pub const vpiBinStrVal: PLI_INT32 = 1;
64pub const vpiOctStrVal: PLI_INT32 = 2;
65pub const vpiDecStrVal: PLI_INT32 = 3;
66pub const vpiHexStrVal: PLI_INT32 = 4;
67pub const vpiScalarVal: PLI_INT32 = 5;
68pub const vpiIntVal: PLI_INT32 = 6;
69pub const vpiRealVal: PLI_INT32 = 7;
70pub const vpiStringVal: PLI_INT32 = 8;
71pub const vpiVectorVal: PLI_INT32 = 9;
72pub const vpiSuppressVal: PLI_INT32 = 10;
73
74// Scalar values
75pub const vpi0: PLI_INT32 = 0;
76pub const vpi1: PLI_INT32 = 1;
77pub const vpiZ: PLI_INT32 = 2;
78pub const vpiX: PLI_INT32 = 3;
79
80// ---------------------------------------------------------------------------
81// Time types (t_vpi_time.type)
82// ---------------------------------------------------------------------------
83pub const vpiScaledRealTime: PLI_INT32 = 1;
84pub const vpiSimTime: PLI_INT32 = 2;
85pub const vpiSuppressTime: PLI_INT32 = 3;
86
87// ---------------------------------------------------------------------------
88// vpi_put_value flags
89// ---------------------------------------------------------------------------
90pub const vpiNoDelay: PLI_INT32 = 1;
91pub const vpiInertialDelay: PLI_INT32 = 2;
92pub const vpiForceFlag: PLI_INT32 = 5;
93pub const vpiReleaseFlag: PLI_INT32 = 6;
94
95// ---------------------------------------------------------------------------
96// vpi_control operations
97// ---------------------------------------------------------------------------
98pub const vpiStop: PLI_INT32 = 66;
99pub const vpiFinish: PLI_INT32 = 67;
100pub const vpiReset: PLI_INT32 = 68;
101
102// ---------------------------------------------------------------------------
103// Callback reasons (t_cb_data.reason)
104// ---------------------------------------------------------------------------
105pub const cbValueChange: PLI_INT32 = 1;
106pub const cbStmt: PLI_INT32 = 2;
107pub const cbForce: PLI_INT32 = 3;
108pub const cbRelease: PLI_INT32 = 4;
109pub const cbAtStartOfSimTime: PLI_INT32 = 5;
110pub const cbReadWriteSynch: PLI_INT32 = 6;
111pub const cbReadOnlySynch: PLI_INT32 = 7;
112pub const cbNextSimTime: PLI_INT32 = 8;
113pub const cbAfterDelay: PLI_INT32 = 9;
114pub const cbEndOfCompile: PLI_INT32 = 10;
115pub const cbStartOfSimulation: PLI_INT32 = 11;
116pub const cbEndOfSimulation: PLI_INT32 = 12;
117
118// ---------------------------------------------------------------------------
119// Structs
120// ---------------------------------------------------------------------------
121
122#[repr(C)]
123#[derive(Clone, Copy)]
124pub struct t_vpi_time {
125    /// One of vpiScaledRealTime / vpiSimTime / vpiSuppressTime.
126    /// (Named `type` in vpi_user.h; `type` is reserved in Rust.)
127    pub type_: PLI_INT32,
128    pub high: PLI_UINT32,
129    pub low: PLI_UINT32,
130    pub real: f64,
131}
132
133#[repr(C)]
134#[derive(Clone, Copy)]
135pub union u_vpi_value_union {
136    pub str_: *mut PLI_BYTE8,
137    pub scalar: PLI_INT32,
138    pub integer: PLI_INT32,
139    pub real: f64,
140    pub time: *mut t_vpi_time,
141    pub vector: *mut c_void,
142    pub strength: *mut c_void,
143    pub misc: *mut PLI_BYTE8,
144}
145
146#[repr(C)]
147#[derive(Clone, Copy)]
148pub struct t_vpi_value {
149    pub format: PLI_INT32,
150    pub value: u_vpi_value_union,
151}
152
153#[repr(C)]
154pub struct t_cb_data {
155    pub reason: PLI_INT32,
156    pub cb_rtn: Option<extern "C" fn(*mut t_cb_data) -> PLI_INT32>,
157    pub obj: vpiHandle,
158    pub time: *mut t_vpi_time,
159    pub value: *mut t_vpi_value,
160    pub index: PLI_INT32,
161    pub user_data: *mut PLI_BYTE8,
162}
163
164// ---------------------------------------------------------------------------
165// Functions. Resolved at load time against the simulator (vvp exports them
166// to dlopen'ed VPI modules).
167// ---------------------------------------------------------------------------
168extern "C" {
169    pub fn vpi_handle_by_name(name: *const PLI_BYTE8, scope: vpiHandle) -> vpiHandle;
170    pub fn vpi_handle_by_index(object: vpiHandle, index: PLI_INT32) -> vpiHandle;
171    pub fn vpi_iterate(type_: PLI_INT32, ref_: vpiHandle) -> vpiHandle;
172    pub fn vpi_scan(iterator: vpiHandle) -> vpiHandle;
173    pub fn vpi_get(property: PLI_INT32, object: vpiHandle) -> PLI_INT32;
174    pub fn vpi_get_str(property: PLI_INT32, object: vpiHandle) -> *mut PLI_BYTE8;
175    pub fn vpi_get_value(expr: vpiHandle, value_p: *mut t_vpi_value);
176    pub fn vpi_put_value(
177        object: vpiHandle,
178        value_p: *mut t_vpi_value,
179        time_p: *mut t_vpi_time,
180        flags: PLI_INT32,
181    ) -> vpiHandle;
182    pub fn vpi_get_time(object: vpiHandle, time_p: *mut t_vpi_time);
183    pub fn vpi_register_cb(cb_data_p: *mut t_cb_data) -> vpiHandle;
184    pub fn vpi_remove_cb(cb_obj: vpiHandle) -> PLI_INT32;
185    pub fn vpi_free_object(object: vpiHandle) -> PLI_INT32;
186    pub fn vpi_control(operation: PLI_INT32, ...) -> PLI_INT32;
187    pub fn vpi_printf(format: *const PLI_BYTE8, ...) -> PLI_INT32;
188}