Процедурный интерфейс Verilog - Verilog Procedural Interface
В Процедурный интерфейс 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 ++
C ++ интегрируется с VPI (PLI 2.0) и PLI 1.0 за счет использования ключевого слова extern C / C ++, встроенного в компиляторы C ++.
Пример
В качестве примера рассмотрим следующий фрагмент кода Verilog:
val = 41; $ increment (val); $ display ("После $ increment, val =% d", val);
Предположим, что приращение
системная задача увеличивает свой первый параметр на единицу. Используя C и механизм VPI, приращение
Задача может быть реализована следующим образом:
// Реализует системную задачу приращениястатический int приращение(char *данные пользователя) { vpiHandle systfref, args_iter, ах; структура t_vpi_value Аргвал; int ценить; // Получение дескриптора списка аргументов systfref = vpi_handle(vpiSysTfCall, НОЛЬ); args_iter = vpi_iterate(vpiArgument, systfref); // Получаем значение первого аргумента ах = vpi_scan(args_iter); Аргвал.формат = vpiIntVal; vpi_get_value(ах, &Аргвал); ценить = Аргвал.ценить.целое число; vpi_printf("Подпрограмма VPI получена% d п", ценить); // Увеличиваем значение и возвращаем его в качестве первого аргумента Аргвал.ценить.целое число = ценить + 1; vpi_put_value(ах, &Аргвал, НОЛЬ, vpiNoDelay); // Очистка и возврат vpi_free_object(args_iter); возвращаться 0;}
Также необходима функция, регистрирующая эту системную задачу. Эта функция вызывается перед обработкой или разрешением ссылок, когда она помещается в видимый извне vlog_startup_routines []
множество.
// Регистрирует системную задачу приращенияпустота register_increment() { s_vpi_systf_data данные = {vpiSysTask, 0, "$ инкремент", приращение, 0, 0, 0}; vpi_register_systf(&данные);}// Содержит завершающийся нулем список функций, которые должны быть вызваны при запускепустота (*vlog_startup_routines[])() = { register_increment, 0};
Код C компилируется в общий объект, который будет использоваться симулятором Verilog. Моделирование ранее упомянутого фрагмента Verilog теперь приведет к следующему результату:
Подпрограмма VPI получила 41 После инкремента $, val = 42
Смотрите также
Источники
Исходники для интерфейса Verilog VPI
- Бирюзовый, за C ++
- JOVE, за Ява
- Рубин-ВПИ, за Рубин
- ScriptEDA, за Perl, Python, Tcl
- Cocotb, за Python
- OrigenSim, за Рубин