У меня есть 256-битное значение в Verilog:
reg [255:0] val;
Я хочу определить системную задачу $ foo, которая вызывает внешний C с помощью VPI, поэтому я могу вызвать $ foo следующим образом:
$foo(val);
Теперь в определении C для функции 'foo' я не могу просто прочитать аргумент как целое число (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
и напечатал строку, он выглядит нормально.
Итак, два вопроса:
- Есть ли лучший способ чтения моего 256-битного значения из Verilog?
- Что происходит с
20
? Это ошибка? Я что-то упустил?
Примечание: я использую Aldec для симуляции.