求将svLogicVecVal*转换为uint8_t的API/库(DPI验证场景)
问题
在SystemVerilog中使用bit类型输入,需要转换为C语言的uint8_t类型,通过DPI验证Verilog结果时,编译C代码出现svLogicVecVal*与uint8_t*类型不兼容的警告,询问是否有可用的API或库实现该类型转换。
相关代码
SystemVerilog代码
//import "DPI-C" function int test_encrypt_ecb(); import "DPI-C" function void compute_bit(input bit i_value, output bit result); import "DPI-C" function bit get_bit(input bit i_value); import "DPI-C" function void compute_logic_vector(reg[127:0] i_value, reg[127:0] result, int asize);
C代码
void compute_reg_vector(const svLogicVecVal* i_value, svLogicVecVal* result, int asize) { log_info("dpi_c.compute_reg_vector(): input %s", svLogicVecVal2String(i_value, asize)); uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; int j =0; struct AES_ctx ctx; j++; AES_init_ctx(&ctx, key); f2(&ctx, i_value); int i; for(i=0;i<15;i++){ printf("ECB encrypt: "); memcpy(&result, i_value, 16); log_info("dpi_c.compute_reg_vector(): result %s", svLogicVecVal2String(result, asize)); }
void f2(const struct AES_ctx* ctx, uint8_t* buf) { Cipher((state_t*)buf, ctx->Ry); }
编译错误
warning: passing argument 2 of ‘f2’ from incompatible pointer type [enabled by default] note: expected ‘uint8_t *’ but argument is of type ‘const struct svLogicVecVal *’ void f2(const struct AES_ctx* ctx, uint8_t* buf); warning: ‘main’ is normally a non-static function [-Wmain] int main(void)
解决方案
核心问题说明
svLogicVecVal是SystemVerilog通过DPI传递向量类型时的内部数据结构,无法直接作为uint8_t*传递给C函数,必须手动转换或使用仿真器提供的工具函数完成类型映射。
1. 单个bit类型与uint8_t的转换
如果是单个bit类型(如compute_bit函数中的参数),DPI会将其映射为C语言的svLogic类型(而非svLogicVecVal),直接转换即可:
// 假设C函数接收svLogic类型的输入 void compute_bit(svLogic i_value, svLogic* result) { uint8_t input_val = (i_value == SV_LOGIC_1) ? 1 : 0; // 处理逻辑... *result = (处理后的uint8_t值 != 0) ? SV_LOGIC_1 : SV_LOGIC_0; }
2. 向量类型(如127:0 reg)转uint8_t数组
对于多bit向量,需要手动编写转换函数,将svLogicVecVal中的bit数据提取为uint8_t数组,反之亦然。
转换函数实现
#include <string.h> #include <svdpi.h> // 将svLogicVecVal转换为uint8_t数组 void svLogicVecToUint8(const svLogicVecVal* sv_vec, uint8_t* uint8_arr, int bit_size) { int byte_count = (bit_size + 7) / 8; memset(uint8_arr, 0, byte_count); for (int bit_idx = 0; bit_idx < bit_size; bit_idx++) { int byte_pos = bit_idx / 8; int bit_in_byte = bit_idx % 8; int sv_val_idx = bit_idx / 32; // 每个svLogicVecVal存储32位 int sv_bit_pos = bit_idx % 32; // 提取对应bit的值(仅处理0/1,若需处理X/Z需检查sv_vec[sv_val_idx].bits) if (sv_vec[sv_val_idx].val & (1 << sv_bit_pos)) { uint8_arr[byte_pos] |= (1 << bit_in_byte); } } } // 将uint8_t数组转换回svLogicVecVal void uint8ToSvLogicVec(const uint8_t* uint8_arr, svLogicVecVal* sv_vec, int bit_size) { int sv_val_count = (bit_size + 31) / 32; memset(sv_vec, 0, sizeof(svLogicVecVal) * sv_val_count); for (int bit_idx = 0; bit_idx < bit_size; bit_idx++) { int byte_pos = bit_idx / 8; int bit_in_byte = bit_idx % 8; int sv_val_idx = bit_idx / 32; int sv_bit_pos = bit_idx % 32; if (uint8_arr[byte_pos] & (1 << bit_in_byte)) { sv_vec[sv_val_idx].val |= (1 << sv_bit_pos); } } }
修改compute_reg_vector函数
void compute_reg_vector(const svLogicVecVal* i_value, svLogicVecVal* result, int asize) { log_info("dpi_c.compute_reg_vector(): input %s", svLogicVecVal2String(i_value, asize)); uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; struct AES_ctx ctx; AES_init_ctx(&ctx, key); // 转换输入向量为uint8_t数组 uint8_t input_buf[16] = {0}; svLogicVecToUint8(i_value, input_buf, asize); // 调用AES加密函数 f2(&ctx, input_buf); // 将加密结果转换回svLogicVecVal uint8ToSvLogicVec(input_buf, result, asize); for(int i=0; i<15; i++){ printf("ECB encrypt: "); log_info("dpi_c.compute_reg_vector(): result %s", svLogicVecVal2String(result, asize)); } }
3. 仿真器原生API选项(可选)
部分商用仿真器提供了简化转换的API,例如:
- Synopsys VCS: 使用
svGetArrayPtr直接获取向量的底层指针,但需确保SV端口类型为logic而非reg,且仅在VCS环境下有效:const uint8_t* input_buf = (const uint8_t*)svGetArrayPtr(i_value); - Mentor Questa: 类似提供
mq_get_array_ptr等函数,同样依赖仿真器环境。
这类方法兼容性较差,若需跨仿真器运行,建议使用手动转换函数。
4. 解决main函数警告
编译警告‘main’ is normally a non-static function是因为main函数被定义为static,只需去掉static修饰符,保留标准定义:
int main(void) { // 代码逻辑 }
内容的提问来源于stack exchange,提问作者jeff
相关产品推荐
相关产品推荐

