You can create a “ahbSlaveResponser.sv” that extends from vmm_xactor, and the responses are “transfer” level based, that is, if a burst read/write have 4 transfers, the Slave VIP will send 4 objects to its output channel, and you need to response 4 times.
In this xactor, do following:
1. Create function new with input/ouput channels that are connected to AHB Slave VIP, also pass the slave VIP handle to this class, this is because you will have to use this handle to access the internal memory in Slave VIP.
AhbSlave oSlave_mem; //handle for internal slave memory in slave VIP
dw_vip_ahb_slave_rvm slave_vip; //handle for slave VIP
dw_vip_ahb_slave_transfer resp_trans;
dw_vip_ahb_slave_transfer_channel o_output_chan;
dw_vip_ahb_slave_transfer_channel o_input_chan;
function ahbSlaveResponser::new(
dw_vip_ahb_slave_rvm slave_vip,
dw_vip_ahb_slave_transfer_channel o_output_chan =null,
dw_vip_ahb_slave_transfer_channel o_input_chan=null);
super.new("ahbSlaveResponser", "class");
this.o_output_chan = o_output_chan ;
this.o_input_chan = o_input_chan ;
this.slave_vip=slave_vip;
endfunction
2. Create a task main that always tries to pop object from the output channel from Slave VIP, and then decide whether it is a “READ” or “WRITE” operation:
task ahbSlaveResponser::main();
super.main();
oSlave_mem = slave_vip.getAhbSlave();
//Slave VIP response
while(1) begin
wait_if_stopped_or_empty(o_output_chan);
o_output_chan.peek(resp_trans);
case(resp_trans.m_bHwrite)
0: recv_read();
1: recv_write();
endcase
o_output_chan.get(resp_trans);
end
endtask
3. Implement the response for READ/WRITE operations,
//for WRITE, receives data from the object from Slave VIP output channel ;
task ahbSlaveResponser::recv_write();
bit[31:0] wdata;
dw_vip_ahb_slave_transfer cpy_trans;
$cast(cpy_trans,resp_trans.copy());
o_input_chan.put(cpy_trans); //response status first
cpy_trans.notify.wait_for(vmm_data::ENDED); //wait data transfer complete
cpy_trans.display("SLAVE RECV ::\t"); //debug, display content
wdata=cpy_trans.m_bvHdata; // store the transfer data from slave VIP to user-defined variable
endtask
// for READ, provide the rdata by “set_mem” to VIP internal slave memory, then slave VIP will use this data to generate response to Master
task ahbSlaveResponser::recv_read();
logic[7:0] rdata;
rdata=$random();
for(int i=0;i<=4;i++) begin
oSlave_mem.set_mem(0,resp_trans.m_bvHaddr+i, 8, rdata); //provide read data, 4 bytes for 32bit data bus
$display($time,,"set_mem[%0h]=%0h",resp_trans.m_bvHaddr+i,rdata);
rdata++;
end
o_input_chan.put(resp_trans); //response status
resp_trans.notify.wait_for(vmm_data::ENDED); //wait read transfer complete
resp_trans.display("SLAVE RESP ::\t");
endtask