当我启动适配器序列以进行寄存器读取和随后的写入时,完成读取操作后,execute_op会挂起。任何人都可以推理出这种情况下可能出现的问题吗?
class apb_rgm_master_sequencer extends apb_master_sequencer;
`uvm_component_utils(apb_rgm_master_sequencer)
uvm_blocking_put_imp_reg_apb #(uvm_rgm_reg_op, apb_rgm_master_sequencer) reg_req_export;
uvm_analysis_port#(uvm_rgm_reg_op) reg_rsp_port;
apb_rgm_adapter_seq adapter_seq;
function new(string name, uvm_component parent);
super.new(name, parent);
reg_req_export = new("reg_req_export",this);
reg_rsp_port = new("reg_rsp_port",this);
adapter_seq = apb_rgm_adapter_seq::type_id::create("adapter_seq",this);
endfunction // new
virtual task run_phase(uvm_phase phase);
fork
adapter_seq.start(this);
super.run_phase(phase);
join_none
endtask // run
task put_reg_apb(uvm_rgm_reg_op op);
adapter_seq.execute_op(op);
endtask
endclass
以下是适配器序列的实现
class apb_rgm_adapter_seq extends apb_master_base_sequence;
`uvm_declare_p_sequencer(apb_rgm_master_sequencer)
//Note::Instead of using the `uvm_sequence_utils, we use the `uvm_object_utils and the
//`uvm_declare_p_sequencer to not register the adapter sequence in the sequencer. This
//prevents it from being randomly picked and executed again in the sequencer random traffic.
`uvm_object_utils(apb_rgm_adapter_seq)
// Register Operation Handle used by the adapter sequence
uvm_rgm_reg_op m_reg_cur_op_h;
int address=0;
// ---------------------------------------------------------------------------
function new(string name="apb_rgm_adapter_seq");
super.new(name);
endfunction // new
// ---------------------------------------------------------------------------
virtual task body();
process_response();
endtask // body
// ---------------------------------------------------------------------------
virtual task execute_op(uvm_rgm_reg_op op);
apb_configuration get_cfg;
m_reg_cur_op_h = op;
/** 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 apb_apb_port_configuration class");
end
$display("apb_adapter_seq :: op.get_address() = %h", op.get_address());
address = op.get_address;
`uvm_create(req)
if(op.get_direction() == uvm_rgm_pkg::OP_WR) begin
$display("apb_rgm_master_sequencer start of WR req :: address() = %h", req.address);
if (!req.randomize() with {
req.address == address;
req.cfg == cfg;
req.xact_type == apb_transaction::WRITE;
req.data == op.get_reg_value();
req.pprot1 == apb_transaction::SECURE;
} ) begin
`uvm_fatal(get_name(), "APB WR Req Randomize failed")
end
req.address = address;
$display("apb_rgm_master_sequencer before WR req :: address() = %h", req.address);
`uvm_send(req)
$display("apb_rgm_master_sequencer After WR req :: address() = %h", req.address);
end
else begin
$display("apb_rgm_master_sequencer start of RD req :: address() = %h", req.address);
if (!req.randomize() with {
req.address == address;
req.cfg == cfg;
req.xact_type == apb_transaction::READ;
req.pprot1 == apb_transaction::SECURE;
} ) begin
`uvm_fatal(get_name(), "APB RD Req Randomize failed")
end
req.address = address;
$display("apb_rgm_master_sequencer before RD req :: address() = %h", req.address);
`uvm_send(req)
$display("apb_rgm_master_sequencer After RD req :: address() = %h", req.address);
end
endtask // execute_op
// ---------------------------------------------------------------------------
virtual task process_response();
while(1) begin
$display("apb_rgm_master_sequencer waiting for the response of address sent");
get_response(rsp);
`uvm_info("process_response ",$sformatf("Response received for address - %h data - %h", rsp.address, rsp.data), UVM_LOW)
m_reg_cur_op_h.set_reg_value(rsp.data);
p_sequencer.reg_rsp_port.write(m_reg_cur_op_h);
end
endtask
endclass // apb_rgm_adapter_seq
没有随机分组失败或任何错误,但事务未进行到DUT。