UVM:Sequencer send_request not able to put to fifo
//uvm factory registery
`uvm_object_utils(ahb_slave_write_wait_seq)
//semaphore for multi-thread
semaphore phase_lock = new(1);
//uvm standard method: new
function new(string name = "ahb_slave_write_wait_seq");
super.new(name);
endfunction
//user define method: beat_transfer
virtual task beat_transfer();
ahb_slave_item req;
ahb_slave_item rsp;
req = new();
rsp = new();
forever begin
phase_lock.get();//get the key
`uvm_info(get_name(), $sformatf("slave start_item"), UVM_HIGH);
//get request
start_item(req);
assert(req.randomize() with{req.hresp == 2'b00;});
`uvm_info(get_name(), $sformatf("req.hready_low_cycle is %0d", req.hready_low_cycle), UVM_HIGH);
finish_item(req);
`uvm_info(get_name(), $sformatf("slave finish_item"), UVM_HIGH);
phase_lock.put();//put back the key
//put response
start_item(rsp);
rsp.my_copy(req);
if(rsp.hresp == 2'b00) begin//when slave agent response is OKAY, load wdata to memory
if(rsp.cmd) begin
memory[req.addr] = req.wdata;
end
else begin
if(!memory.exists(rsp.addr)) begin
memory[rsp.addr] = 32'heeeeffff;
end
assert(rsp.randomize() with {rsp.rdata == memory[rsp.addr];});
`uvm_info(get_name(), $sformatf("rsp.hready_low_cycle is %0d", rsp.hready_low_cycle), UVM_HIGH);
end
end
finish_item(rsp);
end
endtask
//uvm standard method: body
virtual task body();
//multi-thread
fork
beat_transfer();
beat_transfer();
join
endtask;
endclass
//:ts=4,sw=4
仿真时出现
uvm_fatal:Sequencer send_request not able to put to fifo, depth;1
这条消息打印自uvm_sequencer_param_base.svh,为什么m_req_fifo的depth size怎么会是1,怎么样改变其depth呢?
信号量可能都被释放,那个都start item 了,但是get却还没完成。
1.1d,没有这个语句。
1.1d中对应的uvm_fatal是Concurrent calls to get_next_item() not supported,在uvm_sequencer_params_base.svh的298行,具体是什么意思,get_next_item需要满足什么规则呢?
我的driver如下:
class ahb_slave_driver extends uvm_driver#(ahb_slave_item);
//uvm factory registery
`uvm_component_utils(ahb_slave_driver)
virtual s_if s_if0;
ahb_slave_item req;
ahb_slave_item rsp;
semaphore phase_lock = new(1);
//uvm standard method: new
function new(string name = "ahb_slave_driver", uvm_component parent);
super.new(name, parent);
endfunction
//user define method: beat_transfer
virtual task beat_transfer();
forever begin
phase_lock.get();//get the key
//address_phase
seq_item_port.get_next_item(req);
`uvm_info(get_name(), $sformatf("slave get_next_item"), UVM_HIGH);
if(req.hready_low_cycle != 0) begin
this.s_if0.HREADY <= 1'b0;
repeat(req.hready_low_cycle) begin//slave hready delay
@(posedge this.s_if0.HCLK);
end
this.s_if0.HREADY <= 1'b1;
end
req.addr = this.s_if0.HADDR;
req.cmd = this.s_if0.HWRITE;
if(req.cmd == 1) begin
req.wdata = this.s_if0.HWDATA;
end
@(posedge this.s_if0.HCLK);
seq_item_port.item_done();
`uvm_info(get_name(), $sformatf("slave item_done"), UVM_HIGH);
phase_lock.put();//put back the key
//data phase
seq_item_port.get_next_item(rsp);
if(rsp.hresp[1] == 1'b1) begin//retry and split
if(rsp.hresp[0] == 1'b1) begin
this.s_if0.HSPLIT <= 1'b1;
end
this.s_if0.HRESP <= rsp.hresp;
this.s_if0.HREADY <= 1'b0;
@(posedge this.s_if0.HCLK);
this.s_if0.HREADY <= 1'b1;
@(posedge this.s_if0.HCLK);
this.s_if0.HRESP <= OKAY;
break;
end
if(rsp.hready_low_cycle != 0) begin
this.s_if0.HREADY <= 1'b0;
repeat(rsp.hready_low_cycle) begin//slave hready delay
@(posedge this.s_if0.HCLK);
end
this.s_if0.HREADY <= 1'b1;
end
//rdata must drive to ahb bus synchronize with HCLK
@(posedge this.s_if0.HCLK) begin
if(rsp.cmd == 0) begin
this.s_if0.HRDATA <= rsp.rdata;
end
end
seq_item_port.item_done();
end
endtask
//user define method: transaction_transfer
virtual task transaction_transfer();
forever begin
@(this.s_if0.HCLK);//加上这句话和不加这句话的区别很大呀,不知道为什么
if(this.s_if0.HSEL) begin
//HREADY for bus grant
this.s_if0.HREADY <= 1'b1;
//burst with pipeline address_phase and data_phase
fork
beat_transfer();
beat_transfer();
join
end
end
endtask
//uvm standard method: run_phase
virtual task run_phase(uvm_phase phase);
@(posedge this.s_if0.HRESETn);
this.s_if0.HREADY <= 1'b1;
this.s_if0.HRESP <= OKAY;
this.s_if0.HRDATA <= 'h0;
this.s_if0.HSPLIT <= 'h0;
//ahb slave transaction
fork
transaction_transfer();
join
////split//应该执行不到这里,此时已经drop obbjection
//if(this.s_if0.HSPLIT == 1'b1) begin
//repeat(6) begin
//@(posedge this.s_if0.HCLK);
//end
//this.s_if0.HSPLIT <= 1'b0;
//end
endtask
endclass
//:ts=4, sw=4