Skip to content

Instantly share code, notes, and snippets.

@tejainece
Last active March 15, 2023 15:50
Show Gist options
  • Save tejainece/708b2b6a9efba54ae022 to your computer and use it in GitHub Desktop.
Save tejainece/708b2b6a9efba54ae022 to your computer and use it in GitHub Desktop.
Passing and receiving different SystemVerilog datatypes with C/C++ using DPI
#include <stdio.h>
#include "dt.h"
void
add_bpuv(
const svBitVecVal* a,
const svBitVecVal* b,
svBitVecVal* c) {
for(int i = 0; i < 4; i++) {
c[i] = a[i] + b[i];
}
}
void
and_buv(
const svBit* a,
const svBit* b,
svBit* c) {
for(int i = 0; i < 4; i++) {
c[i] = a[i] & b[i];
}
}
void
add_bpv(
const svBitVecVal* a,
const svBitVecVal* b,
svBitVecVal* c) {
*c = *a + *b;
}
void
add_lpv(
const svLogicVecVal* a,
const svLogicVecVal* b,
svLogicVecVal* c) {
c->aval = a->aval + b->aval;
c->bval = 0;
}
void
add_struct(
const struct_t* a,
const struct_t* b,
struct_t* c) {
c->mem1 = a->mem1 + b->mem1;
c->mem2[0].aval = a->mem2[0].aval + b->mem2[0].aval;
c->mem2[0].bval = 0;
c->mem3[0] = a->mem3[0] + b->mem3[0];
}
svBit
and_bit(
svBit a,
svBit b) {
return a && b;
}
svLogic
and_logic(
svLogic a,
svLogic b) {
return a && b;
}
void
or_luv(
const svLogic* a,
const svLogic* b,
svLogic* c) {
for(int i = 0; i < 4; i++) {
c[i] = a[i] | b[i];
}
}
dt: dt_compile dt_csim
.PHONY: dt dt_compile dt_csim clean
dt_compile:
if [ -d work ]; then vdel -lib work -all; fi;
vlib work
vmap work work
vlog -sv -dpiheader dt.h tb_dt_dpi.sv
g++ -shared -Bsymbolic -I/home/$(whoami)/modelsim/modeltech/include/ -fPIC -o dt.so dt.cc
dt_csim:
LD_LIBRARY_PATH=/home/$(whoami)/modelsim/modeltech/lib64/; vsim -64 -c -sv_lib dt -do dt_restart.do -novopt tb_dt_dpi
clean:
vdel -all
typedef struct {
shortint mem1;
logic [7:0] mem2;
bit [7:0] mem3;
} struct_t;
module tb_dt_dpi(clk);
input reg clk;
typedef bit bitvec3up [3:0];
typedef logic logicvec3up [3:0];
bit b1, b2, b3;
logic l1, l2, l3;
bit [3:0] b4p1, b4p2, b4p3;
logic [3:0] l4p1, l4p2, l4p3;
bit b4u1[3:0], b4u2[3:0], b4u3 [3:0];
logic l4u1[3:0], l4u2[3:0], l4u3 [3:0];
bit [3:0] b4p4u1[3:0], b4p4u2[3:0], b4p4u3 [3:0];
struct_t struct1, struct2, struct3;
always #10 clk = ~clk;
initial begin
$display("Sending and receiving bit through DPI: ");
b1 = 1'b1;
b2 = 1'b1;
b3 = and_bit(b1, b2);
$display("%d b1=%b b2=%b b3=%b", $time, b1, b2, b3);
$display("Sending and receiving logic through DPI: ");
l1 = 1'b1;
l2 = 1'b1;
l3 = and_logic(l1, l2);
$display("%d l1=%b l2=%b l3=%b", $time, l1, l2, l3);
$display("Sending and receiving packed bit vector(size = 4) through DPI: ");
b4p1 = 4'b1010;
b4p2 = 4'b0010;
add_bpv(b4p1, b4p2, b4p3);
$display("%d b4p1=%b b4p2=%b b4p3=%b", $time, b4p1, b4p2, b4p3);
$display("Sending and receiving packed logic vector(size = 4) through DPI: ");
l4p1 = 4'b1010;
l4p2 = 4'b0010;
add_lpv(l4p1, l4p2, l4p3);
$display("%d l4p1=%b l4p2=%b l4p3=%b", $time, l4p1, l4p2, l4p3);
$display("Sending and receiving unpacked bit vector(size = 4) through DPI: ");
b4u1 = bitvec3up'(4'b1010);
b4u2 = bitvec3up'(4'b0010);
and_buv(b4u1, b4u2, b4u3);
$display("%d b4u1=%p b4u2=%p b4u3=%p", $time, b4u1, b4u2, b4u3);
$display("Sending and receiving unpacked logic vector(size = 4) through DPI: ");
l4u1 = logicvec3up'(4'b1010);
l4u2 = logicvec3up'(4'b0010);
or_luv(l4u1, l4u2, l4u3);
$display("%d l4u1=%p l4u2=%p l4u3=%p", $time, l4u1, l4u2, l4u3);
$display("Sending and receiving packed and unpacked bit vector(size = 4) through DPI: ");
b4p4u1 = '{5, 4, 2, 1};
b4p4u2 = '{5, 4, 2, 1};
add_bpuv(b4p4u1, b4p4u2, b4p4u3);
$display("%d b4p4u1=%p b4p4u2=%p b4p4u3=%p", $time, b4p4u1, b4p4u2, b4p4u3);
$display("Sending and receiving structures through DPI: ");
struct1 = '{1, 2, 3};
struct2 = '{4, 5, 6};
add_struct(struct1, struct2, struct3);
$display("%d struct1=%p struct2=%p struct3=%p", $time, struct1, struct2, struct3);
$finish;
end
import "DPI-C" context function bit and_bit(input bit a, b);
import "DPI-C" context function logic and_logic(input logic a, b);
//cannot return packed bit or logic arrays
import "DPI-C" context function void add_bpv(input bit [3:0] a, b, output bit [3:0] c);
import "DPI-C" context function void add_lpv(input logic [3:0] a, b, output logic [3:0] c);
//cannot return unpacked bit arrays
import "DPI-C" context function void and_buv(input bit a[3:0], b [3:0], output bit c [3:0]);
import "DPI-C" context function void or_luv(input logic a[3:0], b [3:0], output logic c [3:0]);
import "DPI-C" context function void add_bpuv(input bit [0:3]a[0:3], b [0:3], output bit [0:3]c [3:0]);
import "DPI-C" context function void add_struct(input struct_t a, b, output struct_t c);
endmodule
@udif
Copy link

udif commented Mar 15, 2023

Can you add an example for packed arrays wider than 32 bits? e.g. "bit [255:0]c"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment