首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SystemVerilog VPI在vpiForceFlag之后释放回调句柄

SystemVerilog VPI在vpiForceFlag之后释放回调句柄
EN

Stack Overflow用户
提问于 2017-08-26 07:15:04
回答 1查看 913关注 0票数 3

当我问SystemVerilog looping through hierarchy时,有人建议我使用SystemVerilog VPI代码来解决这个问题。我张贴了我的尝试,但意识到,在强迫净值后,我需要释放它。vpi_put_value(vpi_handle_by_index(net,position),&val,NULL,vpiForceFlag);

我使用由release_reg()触发的回调函数cbForce执行。

我的问题是,因为我在许多网上循环,所以我想在每次回调之后释放句柄cb_handle = vpi_register_cb(&cb_data_s);

我的尝试是将回调句柄cb_handle传递给回调函数,但它会创建一个分段错误。

在每个vpi_remove_cb之后,怎样才是正确的vpiReleaseFlag方式?

以下是我的尝试:

代码语言:javascript
复制
#include <sv_vpi_user.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define NULL 0

typedef struct {
  vpiHandle net_handle;
  vpiHandle cb_handle;
} handle_struct;

//Callback function to relase the vpiForceFlag
int release_reg(p_cb_data cb_data_p) {
  vpi_printf ("Releasing bits \n");
  handle_struct *hdls;
  hdls = (handle_struct *)cb_data_p->user_data;
  vpi_put_value(hdls->net_handle,cb_data_p->value,NULL,vpiReleaseFlag);

  vpi_remove_cb(hdls->cb_handle); //<- this line causes the pb.
  return(0);
}

void reg_flips() {
  vpiHandle module_iter;
  vpiHandle module_obj;
  vpiHandle module_regblk;
  vpiHandle reg_nets;
  vpiHandle put_handle;

  //Starting from the RegBlock
  module_regblk = vpi_handle_by_name("DUT.RegBlock",NULL);
  //Iterator over all register in RegBlock
  module_iter = vpi_iterate(vpiModule,module_regblk);

  while (module_iter) {
    module_obj = vpi_scan(module_iter);
    if (module_obj) {
      const char* module_name;
      module_name = vpi_get_str(vpiName, module_obj);
      reg_nets = vpi_iterate(vpiReg,module_obj); //Iterator over all registers within regblock
      while (reg_nets) {
        vpiHandle net;
        net = vpi_scan(reg_nets);
        if (net) {
          const char* net_name = vpi_get_str(vpiName, net);  
          int position = rand()%32; //Position of the bit flip
          vpiHandle obj_net;
          obj_net = vpi_handle_by_index(net,position); //Getting the net of given position
          s_vpi_value val_after; //Value of the net before bit flip
          s_vpi_value val_before; //value of the net after bit flip
          val_before.format = vpiIntVal;
          val_after.format = vpiIntVal;
          vpi_get_value(obj_net,&val_before); //Getting the initial value of the net
          val_after.value.integer = val_before.value.integer ^ 1; //Flipping the bit
          vpi_printf ("Forcing bits in %s - %s[%d] = %d\n",module_name,net_name,position,val_after.value.integer);
            //Forcing the value at a given position.                      

          put_handle = vpi_put_value(obj_net,&val_after,NULL,vpiForceFlag);
          //Here we define the parameter for the callback function that will release the force statement
          vpiHandle cb_handle;
          s_cb_data  cb_data_s; //Callback object
          s_vpi_time time_s; //VPI time object
          handle_struct *hdls;
          hdls = (handle_struct *)malloc(sizeof(hdls));
          hdls->net_handle = obj_net;
          hdls->cb_handle = cb_handle;

          time_s.type = vpiSimTime; //Simulation time
          cb_data_s.reason = cbForce; //Callback is triggered by a force statement
          cb_data_s.obj = put_handle; //For cbforce handle of the vpi_put_value needed
          //cb_data_s.user_data = malloc(sizeof(hdls));
          cb_data_s.user_data = hdls;
          cb_data_s.cb_rtn = release_reg; //Function to execute in the callback
          cb_data_s.time = &time_s;
          cb_data_s.value = &val_after; //Releasing to the same value
          cb_handle = vpi_register_cb(&cb_data_s); //PB We need to call vpi_remove_cb on the cb_handle
          vpi_release_handle(cb_handle);
        }
        else {
          reg_nets = NULL;
        }
      }
    }
    else {
      module_iter = NULL;
    }
  }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-26 22:38:49

以下是关于如何使用vpi在不强制的情况下将值注入(注入)信号的一些建议。

首先,正如您所提到的,大多数信号可以在模拟周期内由verilog重新评估,因此有可能您的值会被verilog覆盖。关于如何避免这种情况,有几种方法可以考虑(可能更多)。

  1. 一个明显的问题是,在模拟中,只存在于原始输入中,这些输入实际上是任何非驱动变量。
  2. 在触发器处于非活动状态时,将信号保存在触发器逻辑的输出中。也就是说,如果你有一个@(posedge clk)存款在时钟变化,当它下降。
  3. 潜在地,你可以储存在任何由这种触发器驱动的信号中,除非你有一个组合回路,这将导致对这个信号的重新评估。
  4. 您还可以根据需要,在模拟时间事件(如cbNextSimTimecbNBASynch或其他事件)上安排注射。

所有这些都有利于生成一个单一的模拟事件,根据它重新评估所有的负载。很可能在接下来的几个模拟周期中,这个注入会被覆盖。

然而,在某些情况下,需要将一个值force为多个时钟周期的信号。在部队事件中立即释放它是没有任何意义的。这与简单的注入行为相同。

此外,您还必须记住,一些模拟器牺牲了强制和注入能力进行优化。因此,您需要了解在编译中使用哪些限定符和/或如何配置模拟器,以允许强制或注入寄存器和/或网。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45892889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档