是否可以将打包结构与 DPI 一起使用
Is it possible to use packed structs with DPI
假设我有一个压缩结构:
typedef struct packed {
logic a;
logic [7:0] b;
bit [7:0] c;
logic [7:0] [31:0] d;
} my_struct;
我想将它传递给 C 函数:
import "DPI" context function int my_dpi_function (input my_struct data);
如何读取 C 端的值?:
int my_dpi_function (void* data)
{
... ?
return 0;
}
你需要的类型定义在svdpi.h
header:
svLogicVecVal
所以,你需要这样的东西:
int my_dpi_function (svLogicVecVal* data)
{
...
return 0;
}
svLogicVecVal
本身就是一个结构。它有两个字段 - aval
和 bval
(或者有时,例如在 Cadence 中,a
和 b
)。来自 svdpi.h
:
typedef struct t_vpi_vecval {
#ifdef P1800_2005_VECVAL
uint32_t a;
uint32_t b;
#else
uint32_t aval;
uint32_t bval;
#endif
} s_vpi_vecval, *p_vpi_vecval;
#endif
/* (a chunk of) packed logic array */
typedef s_vpi_vecval svLogicVecVal;
aval
和 bval
字段是这样编码的(so-called "canonical representation"):
bval aval | 4-state verilog value
----------|----------------------
0 0 | 0
0 1 | 1
1 0 | X
1 1 | Z
因此,您可以访问 C 中的 aval
和 bval
字段。事实证明,对于宽度大于 32 位的向量,most-significant 32 位字是在最高指针地址。
https://www.edaplayground.com/x/2k33
SV
module test;
typedef struct packed {
logic a;
logic [7:0] b;
bit [7:0] c;
logic [7:0] [31:0] d;
} my_struct;
import "DPI-C" context function int my_dpi_function (logic [272:0] data);
initial
begin
automatic my_struct data = '{1'b0,8'hAA,8'h55,256'h0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF};
$display("%h",data);
my_dpi_function (data);
end
endmodule
C++
#include <iostream>
#include <iomanip>
#include <svdpi.h>
using namespace std;
extern "C" int my_dpi_function (svLogicVecVal* data) {
data+=8;
cout << "# C++: ";
for (int i=0; i<9; i++)
cout << std::hex << std::setw(8) << std::setfill('0') << (data--)->aval;
cout << "\n";
return 0;
}
假设我有一个压缩结构:
typedef struct packed {
logic a;
logic [7:0] b;
bit [7:0] c;
logic [7:0] [31:0] d;
} my_struct;
我想将它传递给 C 函数:
import "DPI" context function int my_dpi_function (input my_struct data);
如何读取 C 端的值?:
int my_dpi_function (void* data)
{
... ?
return 0;
}
你需要的类型定义在svdpi.h
header:
svLogicVecVal
所以,你需要这样的东西:
int my_dpi_function (svLogicVecVal* data)
{
...
return 0;
}
svLogicVecVal
本身就是一个结构。它有两个字段 - aval
和 bval
(或者有时,例如在 Cadence 中,a
和 b
)。来自 svdpi.h
:
typedef struct t_vpi_vecval { #ifdef P1800_2005_VECVAL uint32_t a; uint32_t b; #else uint32_t aval; uint32_t bval; #endif } s_vpi_vecval, *p_vpi_vecval; #endif /* (a chunk of) packed logic array */ typedef s_vpi_vecval svLogicVecVal;
aval
和 bval
字段是这样编码的(so-called "canonical representation"):
bval aval | 4-state verilog value
----------|----------------------
0 0 | 0
0 1 | 1
1 0 | X
1 1 | Z
因此,您可以访问 C 中的 aval
和 bval
字段。事实证明,对于宽度大于 32 位的向量,most-significant 32 位字是在最高指针地址。
https://www.edaplayground.com/x/2k33
SV
module test;
typedef struct packed {
logic a;
logic [7:0] b;
bit [7:0] c;
logic [7:0] [31:0] d;
} my_struct;
import "DPI-C" context function int my_dpi_function (logic [272:0] data);
initial
begin
automatic my_struct data = '{1'b0,8'hAA,8'h55,256'h0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF};
$display("%h",data);
my_dpi_function (data);
end
endmodule
C++
#include <iostream>
#include <iomanip>
#include <svdpi.h>
using namespace std;
extern "C" int my_dpi_function (svLogicVecVal* data) {
data+=8;
cout << "# C++: ";
for (int i=0; i<9; i++)
cout << std::hex << std::setw(8) << std::setfill('0') << (data--)->aval;
cout << "\n";
return 0;
}