RAL access stuck and not executed

Hi,

I have the following issue:

  1. some register reads/writes done successfully

  2. RAL VIP driver waits at seq_item_port.get_next_item();

  3. From the test: reg_name.read(status, value);

  4. reg2bus() in the adapter is completed

  5. In the reg_map, I see printout: $sformatf(“Reading address 'h%0h via map "%s"…”,
    addrs[i], get_full_name()), UVM_FULL);

  6. After this, in the reg_map, there is a following code that gets stuck:
    bus_req.set_sequencer(sequencer);
    rw.parent.start_item(bus_req,rw.prior);

    if (rw.parent != null && i == 0) begin
    rw.parent.mid_do(rw);
    end

    rw.parent.finish_item(bus_req);
    bus_req.end_event.wait_on();

Driver does not receive transaction from sequencer (read is not executed on the bus) and simulation just hangs until some timeout is reached.
Since finish_item() is the one that sends transaction to the driver (and I do not have the option to add printouts in the UVM code), I suspect code is stuck before that, at start_item(), but even that is strange, since driver is already waiting at get_next_item().

Any suggestions please?

Thank you.

In reply to v-markovic:

Hi,

Can you paste code of driver? there may chance that get_next_item is not doing properly.
otherwise everything is very smooth in uvm_reg_map. Personally, i don’t see anything which runs infinite in uvm_reg_map.

Kindly paste the code of your driver run_phase.

In reply to mitesh.patel:

Hi, basically this is the flow (also driver code is below):

  • reg1.write() issued

  • reg2bus() done, Driver gets transaction from Sequencer

  • reg1.is_busy() = 1 (this register becomes busy)

  • trans starts on the bus

  • trans ends on the bus, Driver calls end_tr() and item_done(), waiting for new transaction from Sequencer

  • reg1.is_busy() = 0

  • after some time

  • new reg2.read() issued

  • reg2bus() done

  • reg2.is_busy() = 1 (this register becomes busy)

  • Driver never gets transaction from the Sequencer

  • reg2.is_busy() = 1 remains forever

    virtual task run_phase(uvm_phase phase);
    m_req=new();
    m_req.enable_recording(“drv_item”);
    void’(this.begin_tr(m_req,“sent_items”));
    this.end_tr(m_req);
    // Drive initial signal values to IF

    // Call main driving task
    do_access();
    endtask: run_phase

    task do_access();
    forever begin
    uvm_info(get_type_name(), $sformatf("Wait a transaction from sequencer"), UVM_LOW); seq_item_port.get_next_item(m_req); uvm_info(get_type_name(), $sformatf(“Got a transaction from sequencer, wait mbox_full=0”), UVM_LOW);

          // Wait some condition
          while (...) @(posedge clk);
    
          `uvm_info(get_type_name(), $sformatf("Driving a transaction: %s\n", m_req.sprint()), UVM_LOW);
    
          void'(this.begin_tr(m_req,"sent_items"));
    
          // Drive signals to IF
          ...
    
          // Wait some small delay
          ...
    
          `uvm_info(get_type_name(), $sformatf("Ending a transaction"), UVM_LOW);
          this.end_tr(m_req);
    
          seq_item_port.item_done();
          `uvm_info(get_type_name(), $sformatf("Emit item_done()"), UVM_LOW);
      end
    

    endtask: do_access

In reply to v-markovic:

A few remarks to your code:

(1) What is your intention to use begin_tr/end_tr? These instructions are used to mark the begin and the end of a transaction for transaction recording.
(2) What is the reason for using bus_req.end_event.wait_on();? Where is this event triggered.?
(3) Why you are calling rw.parent.mid_do(rw);?
Where are you setting this instruction: bus_req.set_sequencer(sequencer);? It should be done in your env.
Because I do not see all your code there might be more weaknesses.

In reply to chr_sue:

(1) I think this is the intention, to record transactions so they can be monitored on the wave.
(2) and (3) Not sure, since this code is the UVM source code, uvm_reg_map, but I will inestigate.

Yes, set_sequencer() is called in env.

Thanks for remarks.

In reply to v-markovic:

My recommedndation is to comment-out all begin_tr/end_tr. This will ease your debug process.
BTW all simulators offer a built-inn transaction recodingat maybe different places. Then you do not need any begin_tr/end_tr. But you have to make sure you have overwritten the method do_record for the seq_item.

The thing is that when I call reg.write(), on the next clock cycle I see that:
env.reg_agent.seqr.has_do_available()=1

which is not the case for all previous transactions which are executed correctly.
Could this somehow be the reason for transaction not being sent from sequencer to the driver?
It remains env.reg_agent.seqr.has_do_available()=1 forever, and never changes back to 0.

In reply to v-markovic:

The RAL is not designed to work with its command on the pinlevel.
Finally you do not need the function has_do_available().

What I see in your contributions on top is you are mixing structural with execution aspects.

bus_req.set_sequencer(sequencer);

Is the wrong command. You have to specify the sequencer for executing register sequences in your environment.
Simply follow the guidelines the UVM Cookbook is recommending. See here the details:
https://verificationacademy.com/cookbook/registers

Actually I am specifying sequencer in my env, according to cookbook.
The code:
bus_req.set_sequencer(sequencer);
is something I just put above in the post, it is from UVM source code (uvm_reg_map), I do not use it in my env. I just wanted to give more details about what is the flow.

Basically everything is connected and working properly until this one transaction, when something differently happens. I don’t think the problem is in the UVM, it is definitely in my env, but it is very difficult to trace why driver does not receive transaction from sequencer. This is why I am trying to add different printouts in my env by calling some predefined UVM functions, like has_do_available() etc.

In reply to v-markovic:

In your env you have to do (best is to do this in the connect_phase of your env):

if (regmodel.get_parent() == null) begin
      my_adapter reg2ad = my_adapter::type_id::create("reg2ad",,get_full_name());
      regmodel.default_map.set_sequencer(m_sequencer, reg2ad);  // Add adapter      
      regmodel.default_map.set_base_addr(BASE_ADDR_REGION);   // System base address
    end

Note the set_sequencer has a 2nd argument.

Yes, this is exactly how it is connected in my env.
I see that for all transactions that are executed:
env.m_reg_agent.sequencer.m_req_fifo.used() = 1
but for the last one that gets stuck I see that (after I call reg.write(…)):
env.m_reg_agent.sequencer.m_req_fifo.used() = 0

Looks like sequencer is not getting transaction at all.

In reply to v-markovic:

The sequencer is generating the transactions. Looks like something went wrong with the handshake between sequencer and driver.
Which approach you are using? get or get_next_item.

I am using get_next_item().

So it looks like sequencer generates transactions correctly for some time, but then for some reason it stops. Strange…I was also trying to see if I have some “disable fork” statements that may have caused the problem, but looks like it is not the case.
I wonder what would make sequencer stop generating transactions.

I also see that driver is locked at get_next_item() and waits, which is ok, but does not get anything from sequencer.
Maybe something between the sequence and the sequencer stops working

In reply to v-markovic:

If it does not get an item you should look to your sequence body task, what happens there.

I just have:

regmodel.reg.some_field.set(0);
regmodel.reg.update();

I see only reg2bus() is executed, but something is stuck after that.

In reply to v-markovic:

The set is modifying the mirror register. The update command will update the DUT register field.
What are the next commands?

There are few commands but they are never reached, regmodel.reg.update() never returns

In reply to v-markovic:

Instead of set/update try write. See what happens here.

Same behavior.
I will try using disable fork statement or stop_sequencer() or something like that, maybe I get some results