Verilog Процедурный интерфейс (ИВТ), первоначально известный как 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;$ инкремент (значение);$ display ("После приращения $ val =% d", val);
Предположим, что increment
системная задача увеличивает свой первый параметр на единицу. Используя C и механизм VPI, increment
задачу можно реализовать следующим образом:
// Реализует система приращений задача статического INT приращение ( символ * пользовательские данные ) { vpiHandle systfref , args_iter , Argh ; struct t_vpi_value argval ; значение int ; // Получить дескриптор списка аргументов systfref = vpi_handle ( vpiSysTfCall , NULL ); args_iter = vpi_iterate ( vpiArgument , systfref ); // захватить значение первого аргумента Argh = vpi_scan ( args_iter ); аргвал . format = vpiIntVal ; vpi_get_value ( Argh , & argval ); значение = argval . значение . целое число ; vpi_printf ( "Подпрограмма VPI получила% d \ n " , значение ); // Увеличиваем значение и возвращаем его в качестве первого аргумента argval . значение . целое число = значение + 1 ; vpi_put_value ( Argh , & argval , NULL , vpiNoDelay ); // Очистка и возврат vpi_free_object ( args_iter ); возврат 0 ; }
Также необходима функция, регистрирующая эту системную задачу. Эта функция вызывается перед обработкой или разрешением ссылок, когда она помещается во внешний видимый vlog_startup_routines[]
массив.
// Регистрирует системную задачу увеличения void register_increment () { s_vpi_systf_data data = { vpiSysTask , 0 , "$ increment" , increment , 0 , 0 , 0 }; vpi_register_systf ( & данные ); }// Содержит список функций с завершающим нулем, которые должны быть вызваны при запуске void ( * vlog_startup_routines []) () = { register_increment , 0 };
Код C компилируется в общий объект, который будет использоваться симулятором Verilog. Моделирование ранее упомянутого фрагмента Verilog теперь приведет к следующему результату:
Подпрограмма VPI получила 41После приращения $ val = 42