Передача 256-битного провода в функцию C через Verilog VPI - PullRequest
6 голосов
/ 17 февраля 2010

У меня есть 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 и напечатал строку, он выглядит нормально.

Итак, два вопроса:

  1. Есть ли лучший способ чтения моего 256-битного значения из Verilog?
  2. Что происходит с 20? Это ошибка? Я что-то упустил?

Примечание: я использую Aldec для симуляции.

1 Ответ

4 голосов
/ 18 февраля 2010

vpiStringVal используется, когда ожидается, что значение будет текстом ASCII, чтобы получить значение в качестве указателя на строку C. Это полезно, если вы хотите использовать его с функциями C, которые ожидают строку C, такую ​​как printf() с форматом %s, fopen() и т. Д. Однако строки C не могут содержать нулевой символ (так как используется null для завершения строк C), а также не может представлять биты x или z, так что это не тот формат, который следует использовать, если вам необходимо различить любое возможное значение вектора. Похоже, симулятор, который вы используете, форматирует нулевой символ как пробел (0x20); другие симуляторы просто пропускают их, но это тоже не поможет. Чтобы различить любое возможное значение вектора, используйте vpiVectorVal (наиболее компактное представление) или vpiBinStrVal (двоичная строка с одним символом 0/1 / x / z для каждого бита).

...