У меня есть 256-разрядное значение в Verilog:
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
.
Кроме того, обратите внимание на это, если я считал значение в как a vpiHexStrVal
, и распечатайте строку, она выглядит хорошо.
Так, два вопроса:
20
? Действительно ли это - ошибка? Я пропускаю что-то?Примечание: Я использую Aldec для моделирования.
vpiStringVal
используется, когда ожидается, что значение будет текстом ASCII, чтобы получить значение как указатель на строку C. Это полезно, если вы хотите использовать его с функциями C, которые ожидают строку C, например printf ()
с форматом % s
, fopen ()
и т. д. Однако строки C не могут содержать нулевой символ (поскольку null используется для завершения строк C), а также не могут представлять биты x или z, поэтому это не тот формат, который следует использовать, если вам нужно различать любой возможный вектор значение. Похоже, что симулятор, который вы используете, форматирует нулевой символ как пробел (0x20); другие симуляторы их просто пропускают, но это вам тоже не помогает. Чтобы выделить любое возможное значение вектора, используйте либо vpiVectorVal
(наиболее компактное представление), либо vpiBinStrVal
(двоичную строку с одним символом 0/1 / x / z для каждого бита).