当我询问SystemVerilog 遍历层次结构
时,有人建议我使用 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
什么?
这是我的尝试:
#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;
}
}
}