Hello Folks,
I am unable to get a response from the vsequencer to my register model sequence. I see that the register model sequence does generate the first transaction and when the response of this transaction comes back to the vsequencer the sequence hangs. I found on couple of forums that setting provides_responses bit to 1 in the adapter class should resolve this issue. However I am still not able to make this work.
Here are the steps that I followed to Integrate uvm_reg model in my uvm environment.
1. Generate the uvm_reg model using one iregGen/ralGen script
2. Instantiate the model in the uvm_env.
3. Instantiate the adapter class in uvm_env
4. Assign a sequencer and adapter class to the register model.
I am running the basic built-in register model sequence uvm_reg_hw_reset_seq.
*********************************************
AXI Adapter code
********************************************
class ps_regm_axi_adapter extends uvm_reg_adapter;
`uvm_object_utils(ps_regm_axi_adapter)
function new(string name = "ps_regm_axi_adapter");
super.new(name);
supports_byte_enable = 1;
provides_responses = 1;
endfunction : new
/* Convert RGM packet type to APB packet type */
virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
dummy_seq_item transfer = dummy_seq_item::type_id::create("dummy_seq_item");
transfer.set_cmd_type(((rw.kind == UVM_READ) ? AXI_READ : AXI_WRITE));
transfer.set_4byte_payload(0,rw.data);
transfer.addr = rw.addr;
`uvm_info(get_name(), $psprintf("Printing response (reg2bus): %s to addr: %h with Payload: %h", rw.kind.name(), rw.addr, rw.data),UVM_LOW);
return transfer;
endfunction : reg2bus
/* Convert APB packet type to RGM packet type */
virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
bit [3:0] [7:0] ret_data;
dummy_seq_item transfer;
if (!$cast(transfer,bus_item)) begin
`uvm_fatal("NOT_AXI_TYPE", "Provided bus_item is not of the correct type")
return;
end
assert(transfer.cmd_sprintf()) else $fatal;
rw.kind = (transfer.get_cmd_type() == AXI_WRITE)? UVM_WRITE : UVM_READ;
rw.addr = transfer.addr;
// rw.data = transfer.data[0];
transfer.get_4byte_payload(0,ret_data);
rw.data = ret_data;
`uvm_info(get_name(), $psprintf("Printing response (bus2reg): %s to addr: %h with Payload: %h", rw.kind.name(), rw.addr, rw.data),UVM_LOW);
endfunction : bus2reg
endclass :
*************************************
Sequence
************************************
//adapter sequence to handle requests on the regm_vseq
class axi_adapter_seq extends uvm_sequence #(dummy_seq_item);
`uvm_object_utils(axi_adapter_seq)
`uvm_declare_p_sequencer(ps_regm_vsequencer)
function new (string name="axi_adapter_seq");
super.new(name);
endfunction
task body();
dummy_seq_item transfer;
uvm_object cloned;
forever begin
p_sequencer.get_next_item(req);
transfer = dummy_seq_item::type_id::create();
if(req.get_cmd_type() == AXI_WRITE)begin
transfer.set_sequencer(p_sequencer.wr_seqr);
start_item(transfer);
p_sequencer.wr_seqr.initialize_axi3_transaction(transfer);
transfer.set_xfer_wrcmd_order(XAM_WRCMD_ORDER_CMD_BEFORE_DATA);
transfer.set_driver_return_item();
transfer.data.rand_mode(0);
transfer.data = req.data;
assert(transfer.randomize() with {addr == req.addr[31:0];
id == 0;
size == AXI_SIZE_4BYTE;
burst == AXI_BURST_TYPE_INCR;
prot == 0;
region == 0;
qos ==0;
}) else $fatal;
finish_item(transfer);
end
else begin
transfer.set_sequencer(p_sequencer.rd_seqr);
start_item(transfer);
p_sequencer.rd_seqr.initialize_axi3_transaction(transfer);
transfer.set_driver_return_item();
assert(transfer.randomize() with {addr == req.addr[31:0];
id == 0;
len ==0;
size == AXI_SIZE_4BYTE;
burst == AXI_BURST_TYPE_INCR;
prot == 0;
region == 0;
qos ==0;
}) else $fatal;
finish_item(transfer);
end
get_response(rsp);
req.data=rsp.data;
rp.print();
p_sequencer.item_done(req);
end
endtask
endclass : axi_adapter_seq
Any suggestion or pointer in the right direction will really be helpful.
Thanks,
Muffadal