7

我在 Verilog 中有一个 256 位的值:

reg [255:0] val;

我想定义一个使用 VPI 调用外部 C 的系统任务 $foo,所以我可以像这样调用 $foo:

$foo(val);

现在,在函数 'foo' 的 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

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

所以,两个问题:

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

注意:我正在使用 Aldec 进行模拟。

4

1 回答 1

4

vpiStringVal当值预期为 ASCII 文本时使用,以便将值作为指向 C 字符串的指针。如果您想将它与需要 C 字符串的 C 函数一起使用,例如格式、等,这很有printf()用。但是,C 字符串不能包含空字符(因为空用于终止 C 字符串),也不能表示 x 或 z 位,因此如果您需要区分任何可能的向量值,则不应使用这种格式。看起来您正在使用的模拟器将空字符格式化为空格(0x20);其他模拟器只是跳过它们,但这也对你没有帮助。要区分任何可能的向量值,请使用(最紧凑的表示形式)或(每位具有一个 0/​​1/x/z 字符的二进制字符串)。%sfopen()vpiVectorValvpiBinStrVal

于 2010-02-18T03:02:40.960 回答