hi all,
Now, I use the AXI4_VIP to verify my DUT.After I configured the DUT registers, I used the VIP’s master sequence to send write data and read data requests, and then the VIP Slave sequence detected that the DUT output had data, and then returned a random response.
The problem I encountered is that in the waveform returned in verdi is normal. However, the simulation cannot be stopped, and the body task of the slave sequence seems to have been monitoring data and cannot be exited. How can I solve this problem?
Thanks
master sequence and slave sequence are orginized by vitual sequece,then use start() to drive.
**"uvm_info("slave body", "Exiting...", UVM_LOW)" is not printed in sim log.** **master sequence :** class axi_master_directed_sequence extends svt_axi_master_base_sequence; ytb_frame_ctrl m_frame_ctrl; /** Parameter that controls the number of transactions that will be generated */ rand int unsigned sequence_length = 10; /** Constrain the sequence length to a reasonable value */ constraint reasonable_sequence_length { sequence_length <= 100; }
uvm_object_utils(axi_master_directed_sequence)
//`uvm_declare_p_sequencer(cache_vsqr)
function new(string name="axi_master_directed_sequence");
super.new(name);
m_frame_ctrl = ytb_frame_ctrl::get_instance("fc_instance");
endfunction
virtual task body();
svt_axi_master_transaction write_tran, read_tran;
svt_configuration get_cfg;
bit success;
bit[511:0] read_data1,read_data2;
svt_axi_slave_agent slv;
svt_axi_system_env sys_env;
bit status;
`uvm_info("master body", "Entered ...", UVM_LOW)
super.body();
if(!$cast(sys_env, p_sequencer.get_parent().get_parent()))
`uvm_fatal("body", "failed to cast to the system env")
slv=sys_env.slave[0];
status = uvm_config_db #(int unsigned)::get(null, get_full_name(),"sequence_length", sequence_length);
`uvm_info("body", $sformatf("sequence_length is %0d as a result of %0s.",
sequence_length, status ? “config DB” : “randomization”), UVM_LOW);
/** Obtain a handle to the port configuration */
p_sequencer.get_cfg(get_cfg);
if (!$cast(cfg, get_cfg)) begin
`uvm_fatal(“body”, “Unable to $cast the configuration to a svt_axi_port_configuration class”);
end
m_frame_ctrl.wait_cycle(10);
for(int i = 0; i < sequence_length; i++) begin
/** Set up the write transaction */
`uvm_create(write_tran)
write_tran.port_cfg = cfg;
write_tran.xact_type = svt_axi_transaction::WRITE;
write_tran.addr = 31'h100 | (31'h100 << i);
write_tran.burst_type = svt_axi_transaction::INCR;
write_tran.burst_size = svt_axi_transaction::BURST_SIZE_32BIT;
write_tran.atomic_type = svt_axi_transaction::NORMAL;
//write_tran.cache_type = 4'b1101;
write_tran.burst_length = 4;
write_tran.data = new[write_tran.burst_length];
write_tran.wstrb = new[write_tran.burst_length];
write_tran.data_user = new[write_tran.burst_length];
foreach (write_tran.data[i]) begin
write_tran.data[i] = write_tran.addr | i;
end
foreach(write_tran.wstrb[i]) begin
write_tran.wstrb[i] = 4'hf;
end
write_tran.wvalid_delay = new[write_tran.burst_length];
foreach (write_tran.wvalid_delay[i]) begin
write_tran.wvalid_delay[i]=0;
end
/** Send the write transaction */
$display("%t: addr: %x", $realtime, write_tran.addr);
`uvm_send(write_tran)
$display("%t: write done", $realtime);
/** Wait for the write transaction to complete */
get_response(rsp);
$display("%t: get write resp", $realtime);
/*read_data1 = slv.axi_slave_mem.read(write_tran.addr);
$display("data read from %x through backdoor: %32h", write_tran.addr , read_data1);
read_data2 = slv.axi_slave_mem.read(write_tran.addr + 'h80);
$display("data read from %x through backdoor: %32h",(write_tran.addr + 'h80),read_data2);*/
// Set up the read transaction
`uvm_create(read_tran)
read_tran.port_cfg = cfg;
read_tran.xact_type = svt_axi_transaction::READ;
//read_tran.addr =(i % 2 == 0)? (32'h0000_0100 | ('h100 << (i>>1))) : ((32'h0000_0100 | ('h100 << ((i-1)>>1)))+'h80);
read_tran.addr = 31'h100 | (31'h100 << i) ;
read_tran.burst_type = svt_axi_transaction::INCR;
read_tran.burst_size = svt_axi_transaction::BURST_SIZE_32BIT;
read_tran.atomic_type = svt_axi_transaction::NORMAL;
read_tran.burst_length = 4;
read_tran.rresp = new[read_tran.burst_length];
read_tran.data = new[read_tran.burst_length];
read_tran.rready_delay = new[read_tran.burst_length];
read_tran.data_user = new[read_tran.burst_length];
foreach (read_tran.rready_delay[i]) begin
read_tran.rready_delay[i]=0;
end
// Send the read transaction
$display("%t: addr: %x", $realtime, read_tran.addr);
`uvm_send(read_tran)
$display("%t: read done", $realtime);
// Wait for the read transaction to complete
get_response(rsp);
$display("%t: get read resp", $realtime);
end
`uvm_info("master body", "Exiting...", UVM_LOW)
endtask:body
endclass : axi_master_directed_sequence
slave sequence:
class axi_slave_random_response_sequence extends svt_axi_slave_base_sequence;
svt_axi_slave_transaction resp_req;
//ytb_frame_ctrl m_frame_ctrl;
/** UVM Object Utility macro */
`uvm_object_utils(axi_slave_random_response_sequence)
/** Class Constructor */
function new(string name="axi_slave_random_response_sequence");
super.new(name);
//m_frame_ctrl = ytb_frame_ctrl::get_instance("fc_instance");
endfunction
virtual task body();
//svt_configuration get_cfg;
`uvm_info("slave body", "Entered ...", UVM_LOW)
/*p_sequencer.get_cfg(get_cfg);
if (!$cast(cfg, get_cfg)) begin
`uvm_fatal("body", "Unable to $cast the configuration to a svt_axi_port_configuration class");
end*/
forever begin
/**
* Get the response request from the slave sequencer. The response request is
* provided to the slave sequencer by the slave port monitor, through
* TLM port.
*/
p_sequencer.response_request_port.peek(resp_req);
//resp_req.port_cfg = cfg;
//`uvm_info(get_full_name,"resp_req is asserted",UVM_LOW)
$cast(req,resp_req);
req.ZERO_DELAY_wt = 10;
req.SHORT_DELAY_wt = 20;
req.LONG_DELAY_wt = 100;
/* Demonstration of response randomization with constraints.
*/
`uvm_rand_send_with(req,
{
if (xact_type == svt_axi_transaction::READ) {
foreach(rresp[i]) rresp[i] inside {svt_axi_transaction::OKAY };
}
else
bresp inside {svt_axi_transaction::OKAY };
})
/*if(cfg.bus_inactivity_timeout == 1000)begin
break;
end*/
//$display("rresp.size: %0d", req.rresp.size);
//foreach (req.rresp[i]) begin
// $display("req.rresp[%0d]: %0d", i, req.rresp[i]);
//end
end
`uvm_info("slave body", "Exiting...", UVM_LOW)
endtask: body
endclass: axi_slave_random_response_sequence