|
发表于 2022-8-2 21:21:07
|
显示全部楼层
本帖最后由 qsh123_123 于 2022-8-10 12:20 编辑
C侧的DPI只需要改造一下结构体指针的取地址即可:
========C 侧 =========
#include<svdpi.h>
void sm4_setkey_enc_dpi(sm4_context ctx,
unsigned char key[16])
{
sm4_context *ctx_tmp = (sm4_context*) ctx;
sm4_setkey_enc(&ctx_tmp, key);
C接口的typedef结构体,可以直接在sv侧定义对应的同名结构体,数据结构反向排列一下:
======SV 侧 ========
typedef struct
{
unsigned longint sk[32];
int mode;
}sm4_context;
inport "DPI-C" function void sm4_setkey_enc_dpi(inout sm4_context ctx,
input bit key[16]);
---------------------------------------
顺便补充回答一些可能产生的疑问,楼主的代码报的是内存溢出问题,这里面有两个地方都导致内存爆了:
1,原始的C函数sm4_setkey_enc的第二个参数key[16],声明的类型unsigned char在C侧映射到sv侧是svBit/svLogicVec32数据类型,虽然bit本身是个2值变量,但因为映射时为了跟logic/reg这类4值变量兼容的原因(需要存储0/1/x/z这4种状态,用aval和bval两个bit来存储;且4值变量的赋值还有强度/优先级的问题所以还需要额外的cval和dval来存储),所以在映射的时候,1位svBit映射需要一个字节来存储映射(内存存储以字节为单位),对应成C侧同样一个字节的unsigned char;你在sv侧使用了svBitVecVal改造成多个比特的svBit的向量,SV侧的input bit [7:0] key[16]这样的8个svBit的变量,映射到C侧是8*16字节的内存空间来存储,而C侧的unsigned char key[16]则只需要1*16字节来存储,所以内存爆了;
2,C侧的结构体里面的成员unsigned long sk[32], 其中unsigned long (int)在32位系统和64位系统分别是4字节和8字节,直接改造成bit[31:0] sk[32]是不对的,假如是32位系统或许不会报内存溢出(待定),但64位系统会报错;直接改造成对应的longint就可以了,加多个unsigned前缀即可;另外,C侧的结构体共享到SV侧的时候,是按照word/byte反方向来排列的。所以sv侧的结构体内部需要上下倒过来排列一下。 |
|