Sorry for posting something which is related (a bit) with specific simulator but hopefully this could be of some interest. BTW, I am moving to Questa from IUS, just FYI
I am encapsulating into a class a fifo verifcation unit for a mixed VHDL (DUT RTL) and SV (tes bench evironment.
This is why I need forcing and mirroring (unfortunately cannot ‘bind’ since the VHDL RTL uses unconstrained array defined, and looks like SV cannot handle this)
I actually got rid of ‘forcing’, having issues with mirroring. Below is an over simplified code for sake of simplicity.
Some initial comments:
the task set() forks fine, i.e. i can see the effect of forcing value into the signal eep into dut
the contructor get the dut path form the caller
SIMFORCE and SIM_MIRROR re macros hiding the simulation dependent suff underneat (e.g. $nc_mirror or $init_spy … please ignore this)
class cl_fifo_bfm;
typedef struct packed {
bit overflow; //: std_bit;
} status_t;
typedef struct packed {
bit irq_req_en; //: std_bit;
bit half_mode; //: std_bit;
} control_t;
// private variables
local rand control_t _control;
local status_t _status;
local string _dutInst = "";
//
// apply control register to the DUT
//
task set;
`SIM_FORCE(
$sformatf("%s.mif_fifo_control.irq_req_en", this._dutInst), // dst
"", // place holder???
$sformatf("2#%b", this._control.irq_req_en) // src
);
`SIM_FORCE(
$sformatf("%s.mif_fifo_control.half_mode", this._dutInst), // dst
"", // place holder???
$sformatf("2#%b", this._control.half_mode) // src
);
endtask: set
//
// no half mode
//
constraint c0 {
this._control.half_mode >= 1;
}
task mirror();
logic _overflow;
`SIM_MIRROR(
$sformatf("%m/_overflow"), // dest
$sformatf("%s/fifo_status.overflow", this._dutInst) // src
);
// assign #10ps this._status.overflow = _overflow;
endtask:mirror
function new(string inst);
this._dutInst = inst; // instance of the fifo mif_fifo_control
`SIM_MIRROR(
$sformatf("%m/this._status.overflow"), // dest
$sformatf("%s/fifo_status.overflow", this._dutInst) // src
);
endfunction: new
endclass: cl_fifo_bfm
here is how I create two istances of the class (one FIFO for inphase and one for quadrature)
static cl_fifo_bfm fifo_bfm [2];
initial begin
fifo_bfm[0] = new( $sformatf("%s/i_hm_core/i_fifo_monitor/i_fifo1_i", dut_path) );
fifo_bfm[1] = new( $sformatf("%s/i_hm_core/i_fifo_monitor/i_fifo1_q", dut_path) );
fifo_bfm[0].mirror();
fifo_bfm[1].mirror();
end
The task mirror() compiles and executes but I cannot see the signal correctly mirrorer: the toggle in the DUT but not in the _status members.
Mirroring fron the constructor does not work either.
Can you see any problem in this approach? e.g. task calling in an initial block? anything else?
As I said, foring works like a charm
foreach(fifo_bfm[j])
begin: p_iq
fifo_bfm[j].randomize();
fifo_bfm[j].set();
end: p_iq
thanks for the help