muffadal Posted March 28, 2015 Report Posted March 28, 2015 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 Quote
tudor.timi Posted March 28, 2015 Report Posted March 28, 2015 You showed us code code for a reg adapter, but then you also showed a vanilla bus sequence. What are you running there? Read section 5.9 of the UVM user guide for details about integrating a register model. Quote
muffadal Posted March 31, 2015 Author Report Posted March 31, 2015 Hi Tudor, Thanks for your response. I am running the adapter sequence on a dummy virutal sequencer. Here is the code for the dummy virutal sequencer. ******************************************** Virutal Sequencer ******************************************** class ps_regm_vsequencer extends uvm_sequencer #(dummy_seq_item); `uvm_component_utils(ps_regm_vsequencer) mst_rd_sequencer rd_seqr; mst_wr_sequencer wr_seqr; ps_axi_adapter_sequence adapter_seq; // axi_adapter reg2axi; function new (string name = "pmu_regm_vsequencer", uvm_component parent = null); super.new(name,parent); endfunction : new function void build_phase (uvm_phase phase); rd_seqr = mst_rd_sequencer::type_id::create("rd_seqr", this); wr_seqr = mst_wr_sequencer::type_id::create("wr_seqr", this); adapter_seq = ps_axi_adapter_sequence::type_id::create("adapter_seq", this); super.build(); endfunction : build_phase virtual task run(); adapter_seq.start(this); super.run(); endtask endclass: ps_regm_vsequencer I have gone through that section in the UVM user guide. However I am still stuck at this problem. I wish there was an easier way to debug this Quote
muffadal Posted April 3, 2015 Author Report Posted April 3, 2015 Hi All, After debugging this issue for couple of weeks I figured out the solution to this problem. In my testbench I had a define called UVM_DISABLE_AUTO_ITEM_RECORDING enabled. This define forces the driver to end a sequence through req.end_tr();. If you don't have this line in your driver the do_read task in uvm_reg_map will keep waiting at the bus_req.end_event.wait_on(). I removed this define and it all works now . The annoying part is since this is a SoC level testbench I had to digg into many files before I figured out that one of the files has this define. Thanks, Muffadal Quote
tudor.timi Posted April 3, 2015 Report Posted April 3, 2015 I'd say that that define is kinda broken. This is in part because because begin/end_tr trigger these begin/end_events which are used for other stuff too. Whether transaction recording is or is not enabled shouldn't affect the behavior of other aspects. Quote
muffadal Posted April 4, 2015 Author Report Posted April 4, 2015 Agree. There is already a mantis on fixing this issue and I am assuming this should be fixed for UVM-1.2 release. Quote
tudor.timi Posted April 4, 2015 Report Posted April 4, 2015 Could you please link the Mantis issue here for me? Thanks. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.