通过 Verilog VPI 将 256 位连线传递给 C 函数

发布于 2024-08-22 02:44:59 字数 1514 浏览 7 评论 0原文

我在 Verilog 中有一个 256 位值:

reg [255:0] val;

我想定义一个系统任务 $foo,它使用 VPI 调用外部 C,因此我可以像这样调用 $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 中的位置或次数。

另请注意,如果我将值读取为 vpiHexStrVal 并打印字符串,它看起来不错。

那么,有两个问题:

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

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

I have a 256-bit value in Verilog:

reg [255:0] val;

I want to define a system task $foo that calls out to external C using the VPI, so I can call $foo like this:

$foo(val);

Now, in the C definition for the function 'foo', I cannot simply read the argument as an integer (PLI_INT32), because I have too many bits to fit in one of those. But, I can read the argument as a string, which is the same thing as an array of bytes. Here is what I wrote:

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;
}

As you can see, this code reads the argument as a string and then prints out each character (aka byte) in the string. This works almost perfectly. However, the byte 00 always gets read as 20. For example, if I assign the Verilog reg as follows:

 val = 256'h000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;

And call it using $foo(val), then the C function prints this at simulation time:

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

I have tested this with many different values and have found that the byte 00 always gets mapped to 20, no matter where or how many times it appears in val.

Also, note that if I read the value in as a vpiHexStrVal, and print the string, it looks fine.

So, two questions:

  1. Is there a better way to read in my 256-bit value from the Verilog?
  2. What's going on with the 20? Is this a bug? Am I missing something?

Note: I am using Aldec for simulation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话已封尘 2024-08-29 02:44:59

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

vpiStringVal is used when the value is expected to be ASCII text, in order to get the value as a pointer to a C string. This is useful if you want to use it with C functions that expect a C string, such as printf() with the %s format, fopen(), etc. However, C strings cannot contain the null character (since null is used to terminate C strings), and also cannot represent x or z bits, so this is not a format that should be used if you need to distinguish any possible vector value. It looks like the simulator you are using formats the null character as a space (0x20); other simulators just skip them, but that doesn't help you either. To distinguish any possible vector value use either vpiVectorVal (the most compact representation) or vpiBinStrVal (a binary string with one 0/1/x/z character for each bit).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文