我在Verilog中有256位值:
reg [255:0] val;
Run Code Online (Sandbox Code Playgroud)
我想定义一个使用VPI调用外部C的系统任务$ foo,所以我可以像这样调用$ foo:
$foo(val);
Run Code Online (Sandbox Code Playgroud)
现在,在C定义函数"富",我不能简单地读取参数作为一个整数(PLI_INT32),因为我有太多的位,以适应在其中的一个.但是,我可以将参数作为字符串读取,这与字节数组相同.这是我写的:
static int foo(char *userdata) {
vpiHandle systfref, args_iter, argh;
struct t_vpi_value argval;
PLI_BYTE8 *value;
systfref = vpi_handle(vpiSysTfCall, NULL);
args_iter = vpi_iterate(vpiArgument, systfref);
argval.format = vpiStringVal;
argh = vpi_scan(args_iter);
vpi_get_value(argh, &argval);
value = argval.value.str;
int i;
for (i = 0; i < 32; i++) {
vpi_printf("%.2x ", value[i]);
}
vpi_printf("\n");
vpi_free_object(args_iter);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,此代码将参数作为字符串读取,然后打印出字符串中的每个字符(也称为字节).这几乎完美.但是,该字节00始终被读取为20.例如,如果我按如下方式分配Verilog reg:
val = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;
Run Code Online (Sandbox Code Playgroud)
并使用它调用它$foo(val),然后C函数在模拟时打印它:
VPI: 20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
Run Code Online (Sandbox Code Playgroud)
我已经使用许多不同的值对此进行了测试,并发现该字节00始终被映射到20,无论它出现在何处或出现多少次val.
另外,请注意,如果我将值读作a vpiHexStrVal,并打印字符串,它看起来很好.
那么,有两个问题:
20?这是一个错误吗?我错过了什么吗?注意:我正在使用Aldec进行模拟.
vpiStringVal当预期值是 ASCII 文本时使用,以便将该值作为指向 C 字符串的指针来获取。如果您想将其与需要 C 字符串的 C 函数一起使用,例如printf()使用%s格式,fopen()等,则这很有用。但是,C 字符串不能包含空字符(因为 null 用于终止 C 字符串),也不能表示 x 或 z 位,因此如果您需要区分任何可能的向量值,则不应使用这种格式。看起来您使用的模拟器将空字符格式化为空格(0x20);其他模拟器只是跳过它们,但这对你也没有帮助。要区分任何可能的向量值,请使用vpiVectorVal(最紧凑的表示)或vpiBinStrVal(每位具有一个 0/1/x/z 字符的二进制字符串)。