Iverilog 源码分析 -- VPI的实现
在IVerilog中VVP可以通過-m或者-M制定需要加載的模塊,本文介紹一下VPI的模塊工作機制。
每個模塊通過vpip_load_module來加載指定的動態鏈接庫, 然后在動態鏈接庫里面找到“vpip_set_callback”函數來設定vpip_routines_s 結構內的函數指針,這些函數是VerilogLRM預定義的37個函數, 參考Verilog LRM 27章: VPI routines definition, 這些函數定義在vvp/vpi_private.cc里面;
然后查找vlog_startup_routines 內指定的啟動函數并且逐個執行;
vlog_startup_routines是一個注冊函數列表, 每個自定義的模塊要首先在該列表里面注冊:
VPI 的模塊啟動函數設定在vpi/sys_table.cc, 設定如下:
void (*vlog_startup_routines[])(void) = {sys_convert_register,sys_countdrivers_register,sys_darray_register,sys_fileio_register,sys_finish_register,sys_deposit_register,sys_display_register,sys_plusargs_register,sys_queue_register,sys_random_register,sys_random_mti_register,sys_readmem_register,sys_scanf_register,sys_time_register,sys_lxt_or_vcd_register,sys_sdf_register,sys_special_register,table_model_register,vams_simparam_register,0 };這里定義了很多的自定義加載模塊, 每個模塊通過如下的方式來注冊函數進行模塊與simulator之間的交互, 使得用戶模塊可以訪問simulator的內存狀態信息。
typedef struct t_vpi_systf_data {PLI_INT32 type;PLI_INT32 sysfunctype;const char *tfname;PLI_INT32 (*calltf) (ICARUS_VPI_CONST PLI_BYTE8*);PLI_INT32 (*compiletf)(ICARUS_VPI_CONST PLI_BYTE8*);PLI_INT32 (*sizetf) (ICARUS_VPI_CONST PLI_BYTE8*);ICARUS_VPI_CONST PLI_BYTE8 *user_data; } s_vpi_systf_data, *p_vpi_systf_data;s_vpi_systf_data tf_data;vpiHandle res;tf_data.type = vpiSysFunc;tf_data.tfname = "$time";tf_data.sysfunctype = vpiTimeFunc;tf_data.calltf = sys_time_calltf;tf_data.compiletf = sys_no_arg_compiletf;tf_data.sizetf = 0;tf_data.user_data = "$time";res = vpi_register_systf(&tf_data);vpip_make_systf_system_defined(res);每當在Verilog里面調用$time(), 系統自動調用compiletf指針指向的函數,來檢驗函數調用的參數檢查, 通過calltf函數指針來執行相關的操作。
在VVP目錄下面, 存在很多的vpi_xxx.cc文檔, 他們實現了VVP調用vpi模塊的框架函數。
| vpi_modules.cc | 實現了load_vpi_module, 其功能如上面分析 |
| vpi_task.cc | 記錄系統函數或者系統任務, 任務的調用等 |
| vpi_scope.cc | 定義了__vpiScope以及其字對象, 主要記錄了模塊以及子模塊,參考: VPI scope |
| vpi_signal.cc | 定義了signal的屬性信息, 以及不同類型的valuechange的類定義 |
總結
以上是生活随笔為你收集整理的Iverilog 源码分析 -- VPI的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解析this指针
- 下一篇: YMTC X3 NAND 232L 终露