Iverilog 源码分析 -- VPI的实现

本文详细介绍了VPI(Verilog Programming Interface)的模块加载和工作流程。通过`vpip_load_module`加载动态链接库,设置回调函数以实现Verilog LRM预定义的37个功能。`vlog_startup_routines`列表用于注册自定义模块的启动函数,并逐个执行。在vpi/sys_table.cc中定义了多个自定义模块的启动函数,通过注册系统任务和函数来实现模块与模拟器的交互。例如,当调用`$time`时,系统会自动调用相应的编译和执行函数。VVP中的vpi_xxx.cc文件则提供了调用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是一个注册函数列表, 每个自定义的模块要首先在该列表里面注册:

void vpip_load_module(const char*name) {
    // buf 保存了模块的路径、名称
     dll = ivl_dlopen(buf, export_flag);
     
      void*function = ivl_dlsym(dll, "vpip_set_callback");
      if (function) {
            vpip_set_callback_t set_callback = (vpip_set_callback_t)function;
            if (!set_callback(&vpi_routines, vpip_routines_version)) ;
	          return;
            }
      }

      void*table = ivl_dlsym(dll, LU "vlog_startup_routines" TU);
      
      vpi_mode_flag = VPI_MODE_REGISTER;
      vlog_startup_routines_t*routines = (vlog_startup_routines_t*)table;
      for (unsigned tmp = 0 ;  routines[tmp] ;  tmp +
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值