2010-02-17 60 views
6

传递一个256位线C函数我用Verilog有256位值:通过的Verilog VPI

reg [255:0] val; 

我要定义一个系统任务$ foo的使用召唤出外部C VPI的,所以我可以调用$ foo的是这样的:

$foo(val); 

现在,在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; 
} 

正如你所看到的,此代码读取参数作为一个字符串,然后打印出字符串中的每个字符(又名字节)。这工作几乎完美。但是,字节00始终读取为20。例如,如果我指定的Verilog REG如下:

val = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f; 

而且使用$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 

我曾与许多不同的值测试这并发现字节00始终映射到20,无论在val中出现的位置或次数。

此外,请注意,如果我读取的值为vpiHexStrVal,并打印字符串,它看起来很好。

于是,两个问题:

  1. 有没有更好的办法从我的Verilog 256位值来读取?
  2. 这是怎么回事20?这是一个错误?我错过了什么吗?

注意:我正在使用Aldec进行仿真。

回答

4

vpiStringVal用于希望值为ASCII文本时,以便获取值作为指向C字符串的指针。如果要将其与C字符串(如printf()%s格式,fopen()等)一起使用,这非常有用。但是,C字符串不能包含空字符(因为null用于终止C字符串),因此,也不能表示x或z位,所以如果你需要区分任何可能的矢量值,这不是应该使用的格式。它看起来像你正在使用的模拟器将空字符格式化为空格(0x20);其他模拟器跳过它们,但是这对你也没有帮助。要区分任何可能的矢量值,请使用vpiVectorVal(最简洁的表示形式)或vpiBinStrVal(每个位具有一个0/1/x/z字符的二进制字符串)。

+0

我不想使用'vpiBinStrVal'或'vpiVectorVal',因为一次输入格式不一致。我实际上希望数据格式化为32个8位值;我结束了拼接256位线并将其作为8个32位输入发送,可以读作“vpiIntVal”,并简单地将其转换为32字节的数组。 – pheaver

+0

确定但是'vpiVectorVal'允许你将这些位读为32位字;它一次不是一点点。 – mark4o

+0

是的,你是对的,我错过了。我的意思是我想要一个实际的积分值,而不是其中有'x'和'z'的东西。没有什么大不了的,我可以将其转换。 – pheaver