通过 SystemVerilog DPI-C 层传递 C 结构
Passing C structs through SystemVerilog DPI-C layer
SystemVerilog LRM 有一些示例展示了如何通过 DPI-C 层传递 SystemVerilog to\from C 中的结构。然而,当我尝试自己的示例时,它似乎在 Incisive 或 Vivado 模拟器中根本不起作用(它在 ModelSim 中起作用)。我想知道我是否做错了什么,或者这是否是模拟器的问题。我的例子如下:
#include <stdio.h>
typedef struct {
char f1;
int f2;
} s1;
void SimpleFcn(const s1 * in,s1 * out){
printf("In the C function the struct in has f1: %d\n",in->f1);
printf("In the C function the struct in has f2: %d\n",in->f2);
out->f1=!(in->f1);
out->f2=in->f2+1;
}
我把上面的代码编译成一个共享库:
gcc -c -fPIC -Wall -ansi -pedantic -Wno-long-long -fwrapv -O0 dpi_top.c -o dpi_top.o
gcc -shared -lm dpi_top.o -o dpi_top.so
和SystemVerilog代码:
`timescale 1ns / 1ns
typedef struct {
bit f1;
int f2;
} s1;
import "DPI-C" function void SimpleFcn(input s1 in,output s1 out);
module top();
s1 in,out;
initial
begin
in.f1=1'b0;
in.f2 = 400;
$display("The input struct in SV has f1: %h and f2:%d",in.f1,in.f2);
SimpleFcn(in,out);
$display("The output struct in SV has f1: %h and f2:%d",out.f1,out.f2);
end
endmodule
在 Incisive I 运行 它使用 i运行:
irun -sv_lib ./dpi_top.so -sv ./top.sv
但它是 SegV 的。
在 Vivado 中我 运行 它使用
xvlog -sv ./top.sv
xelab top -sv_root ./ -sv_lib dpi_top.so -R
在退出模拟之前运行一切正常,然后出现内存损坏:
Vivado Simulator 2017.4
Time resolution is 1 ns
run -all
The input struct in SV has f1: 0 and f2: 400
In the C function the struct in has f1: 0
In the C function the struct in has f2: 400
The output struct in SV has f1: 1 and f2: 401
exit
*** Error in `xsim.dir/work.top/xsimk': double free or corruption (!prev): 0x00000000009da2c0 ***
你很幸运,这在 Modelsim 中有效。您的 SystemVerilog 原型与您的 C 原型不匹配。您在 C 中将 f1
作为 byte
,在 SystemVerilog 中将 bit
作为 bit
。
Modelsim/Questa 有一个 -dpiheader 开关,可以生成一个 C 头文件,您可以将其 #include
放入 dpi_top.c 文件中。这样,当原型不匹配时,您会得到一个编译器错误,而不是一个不可预测的 运行 时间错误。这是您的 SV 代码的 C 原型。
typedef struct {
svBit f1;
int f2;
} s1;
void SimpleFcn(
const s1* in,
s1* out);
但我建议坚持使用 SystemVerilog 中的 C 兼容类型。
SystemVerilog LRM 有一些示例展示了如何通过 DPI-C 层传递 SystemVerilog to\from C 中的结构。然而,当我尝试自己的示例时,它似乎在 Incisive 或 Vivado 模拟器中根本不起作用(它在 ModelSim 中起作用)。我想知道我是否做错了什么,或者这是否是模拟器的问题。我的例子如下:
#include <stdio.h>
typedef struct {
char f1;
int f2;
} s1;
void SimpleFcn(const s1 * in,s1 * out){
printf("In the C function the struct in has f1: %d\n",in->f1);
printf("In the C function the struct in has f2: %d\n",in->f2);
out->f1=!(in->f1);
out->f2=in->f2+1;
}
我把上面的代码编译成一个共享库:
gcc -c -fPIC -Wall -ansi -pedantic -Wno-long-long -fwrapv -O0 dpi_top.c -o dpi_top.o
gcc -shared -lm dpi_top.o -o dpi_top.so
和SystemVerilog代码:
`timescale 1ns / 1ns
typedef struct {
bit f1;
int f2;
} s1;
import "DPI-C" function void SimpleFcn(input s1 in,output s1 out);
module top();
s1 in,out;
initial
begin
in.f1=1'b0;
in.f2 = 400;
$display("The input struct in SV has f1: %h and f2:%d",in.f1,in.f2);
SimpleFcn(in,out);
$display("The output struct in SV has f1: %h and f2:%d",out.f1,out.f2);
end
endmodule
在 Incisive I 运行 它使用 i运行:
irun -sv_lib ./dpi_top.so -sv ./top.sv
但它是 SegV 的。
在 Vivado 中我 运行 它使用
xvlog -sv ./top.sv
xelab top -sv_root ./ -sv_lib dpi_top.so -R
在退出模拟之前运行一切正常,然后出现内存损坏:
Vivado Simulator 2017.4
Time resolution is 1 ns
run -all
The input struct in SV has f1: 0 and f2: 400
In the C function the struct in has f1: 0
In the C function the struct in has f2: 400
The output struct in SV has f1: 1 and f2: 401
exit
*** Error in `xsim.dir/work.top/xsimk': double free or corruption (!prev): 0x00000000009da2c0 ***
你很幸运,这在 Modelsim 中有效。您的 SystemVerilog 原型与您的 C 原型不匹配。您在 C 中将 f1
作为 byte
,在 SystemVerilog 中将 bit
作为 bit
。
Modelsim/Questa 有一个 -dpiheader 开关,可以生成一个 C 头文件,您可以将其 #include
放入 dpi_top.c 文件中。这样,当原型不匹配时,您会得到一个编译器错误,而不是一个不可预测的 运行 时间错误。这是您的 SV 代码的 C 原型。
typedef struct {
svBit f1;
int f2;
} s1;
void SimpleFcn(
const s1* in,
s1* out);
但我建议坚持使用 SystemVerilog 中的 C 兼容类型。