Процедурный интерфейс Verilog
( Процедурный интерфейс Verilog VPI), первоначально известный как PLI 2.0, представляет собой интерфейс, в первую очередь предназначенный для C. программирования языка Он позволяет поведенческому коду Verilog вызывать функции C, а функциям C — вызывать стандартные системные задачи Verilog. Процедурный интерфейс Verilog является частью стандарта интерфейса языка программирования IEEE 1364 ; самая последняя редакция стандарта датируется 2005 годом. VPI иногда также называют PLI 2, поскольку он заменяет устаревший интерфейс языка программ (PLI) .
Хотя PLI 1 был устаревшим в пользу VPI (он же PLI 2), PLI 1 по-прежнему широко используется поверх VPI из-за его гораздо более широко документированного функционального интерфейса tf_put, tf_get, который описан во многих справочниках verilog.
Использование С++
[ редактировать ]C++ интегрируется с VPI (PLI 2.0) и PLI 1.0 с помощью ключевого слова extern C/C++, встроенного в компиляторы C++.
Пример
[ редактировать ]В качестве примера рассмотрим следующий фрагмент кода Verilog:
val = 41;
$increment(val);
$display("After $increment, val=%d", val);
Предположим, increment
системная задача увеличивает свой первый параметр на единицу. Используя C и механизм VPI, increment
задачу можно реализовать следующим образом:
// Implements the increment system task
static int increment(char *userdata) {
vpiHandle systfref, args_iter, argh;
struct t_vpi_value argval;
int value;
// Obtain a handle to the argument list
systfref = vpi_handle(vpiSysTfCall, NULL);
args_iter = vpi_iterate(vpiArgument, systfref);
// Grab the value of the first argument
argh = vpi_scan(args_iter);
argval.format = vpiIntVal;
vpi_get_value(argh, &argval);
value = argval.value.integer;
vpi_printf("VPI routine received %d\n", value);
// Increment the value and put it back as first argument
argval.value.integer = value + 1;
vpi_put_value(argh, &argval, NULL, vpiNoDelay);
// Cleanup and return
vpi_free_object(args_iter);
return 0;
}
Также необходима функция, регистрирующая эту системную задачу. Эта функция вызывается до разработки или разрешения ссылок, когда она помещается во внешне видимую область. vlog_startup_routines[]
множество.
// Registers the increment system task
void register_increment() {
s_vpi_systf_data data = {vpiSysTask, 0, "$increment", increment, 0, 0, 0};
vpi_register_systf(&data);
}
// Contains a zero-terminated list of functions that have to be called at startup
void (*vlog_startup_routines[])() = {
register_increment,
0
};
Код C компилируется в общий объект, который будет использоваться симулятором Verilog. Моделирование ранее упомянутого фрагмента Verilog теперь приведет к следующему результату:
VPI routine received 41 After $increment, val=42
См. также
[ редактировать ]Источники
[ редактировать ]Исходники интерфейса Verilog VPI
[ редактировать ]- Бирюзовый , для C++
- ДЖОВЕ , для Java
- Ruby-VPI для Ruby
- ScriptEDA для Perl , Python , Tcl
- Cocotb [1] для Python
- OrigenSim для Ruby