How to make a uvm sequence active across multiple phases?

Is there anyway to keep a uvm sequence alive across multiple phases? For example if I start a sequence in configure_phase, this sequence (its body) will finish(?) at the end of configure_phase.

Here is the use model, we have a background/passive sequence extended from uvm_reg_sequence. It works as a translation sequence for some RAL based access. We want to keep this sequence running from configure_phase all the way to the end of main_phase. Is it possible? Or I have to re-start this sequence in main_phase?

Thanks if anyone can comment!

It seems it is actually persistent. But for some reason the sequence probably gets stuck at configure_phase. In main_phase, I kill the sequence and start it again.

In reply to eda2k4:

In reply to eda2k4:

This is definitely the wrong way. The sequence has to run across all these sub-phases.
But consider. It is not recommended to use these sub-sequences. Using simply run_phase you would not run into this issue.

Currently we are using run_phase. We start to see issue when we want to replace run_phase with multiple run-time phases.

It is a bit tricky because two sequence/sequencer pairs are involved and one sequence acts as a RAL proxy. It runs into a deadlock condition where one sequence (RAL access) is trying to do a write (through uvm_reg_map’s do_write) to keep pushing more sequence item to reg_seqr but the other sequence stops fetching request.

In reply to chr_sue:

In reply to eda2k4:

Could you please explain how two sequencers are serving 1 driver? Or is this incorrect.
A RAL sequence is always dedicated for a specific functional interface and it converts the RAL command into bus cycles. Running another sequence on the same interface sequencer is useless.

It is layered sequencer. uvm_reg_sequence provides a hook-up so you can add a upstream sequencer (reg_seqr). This would allow some extra translation before sending a RAL request eventually to DUT.

In reply to chr_sue:

In reply to eda2k4:

Did you follow the recommendations for integrating the RAL to your environment? Do you have an adapter with bus2regg and reg2bus functions?

Hi Chris,

This is a layered sequencer implementation, so it is slightly different to common RAL use model. when uvm_reg_map.set_sequencer is called, only layered (proxy) sequencer is given and there is no adapter (null). Adapter is instead used in “proxy” sequence, which is running on another sequencer.

This use model is explained in Accellera’s “UVM 1.2 User’s Guide”, section 5.9.2.3 “Register Sequence Running on a Layered Register Sequencer”.

In reply to chr_sue:

In reply to eda2k4:

I had a look to the UVM 1.2 UserGuide. What I see is there is an adapter. See the code from chapter 5.9.2.3:

typedef uvm_reg_sequence #(uvm_sequence #(apb_rw)) reg2apb_seq_t;
class block_env extends uvm_env;
block_reg_model regmodel;
uvm_sequencer#(uvm_reg_item) reg_seqr;
apb_agent apb;
reg2apb_seq_t reg2apb_seq;
virtual function void connect_phase(uvm_phase phase);
if (regmodel.get_parent() == null) begin
regmodel.default_map.set_sequencer(reg_seqr,null);
reg2apb_seq = reg2apb_seq_t::type_id::create(“reg2apb_seq”,,
get_full_name());
reg2apb_seq.reg_seqr = reg_seqr;
reg2apb_seq.adapter =
reg2apb_adapter::type_id::create(“reg2apb”,,
get_full_name());
regmodel.set_auto_predict(1);
end
endfunction
virtual task run();
reg2apb_seq.start(apb.sequencer);
endtask
endclass

And there is no independent sequence running on the low-layer sequencer. There runs the converted sequence on the agents sequencer. In this case it is the apb_sequencer.

In reply to chr_sue:

I guess the terminology I’m using is a bit confusing…

Yes, there is always an adapter, otherwise there is no way to map RAL to DUT transaction. The difference is where to “call” this adapter. In common use case we call uvm_reg_map.set_sequencer(seqr, adapter) to tell RAL which seqr to use, and how to convert abstract level RAL to transaction through a adapter. Then we use RAL-level “sequence” just to do RAL writes/reads. There is no extra sequence involved. Adapter in this case will go to m_adapter of uvm_reg_map, then do_write and do_bus_write, where RAL is converted into BUS transaction.

In this layered example reg2apb_seq or uvm_reg_sequence is the translation (low-layer) sequence I was talking about. It is not needed in common RAL case. There is also an extra sequencer (reg_seqr). This is on top of the sequencer typically in bus agent. uvm_req_sequence also has a adapter to do RAL/bus transaction conversion. In this case RAL/BUS transaction conversion is “done” here instead of through uvm_reg_map directly. But again it will go through uvm_reg_map do_bus_write eventually.

Now back to the issue I’m facing. In uvm_reg_sequence’s body, there is a forever loop to fetch item from reg_seqr. What I’m seeing is that the loop gets stuck when phases moves from configure to main.

    forever begin
      uvm_reg_item reg_item;
      reg_seqr.peek(reg_item);
      do_reg_item(reg_item);
      reg_seqr.get(reg_item);
      #0;
    end

In reply to eda2k4:

This samll piece of code does not really show what is going on. Your problem will not happen when you use simply run_phase instead of the sub-phases of the run_phase. Did you try it?

Yes, it used to work when everything was in run_phase. Now we want to split run_phase into multiple run-time phases for “save and restore” purpose, then we start to see misbehavior.

That piece of code is the outmost loop on “consumer” side. It might not show the real reason. It gets stuck at reg_seqr.peek, meaning the uvm_tlm_fifo in uvm_sequencer is empty. That fifo is fed by “producer” or RAL side operation. I feel the whole thing gets stuck at uvm_sequencer_base::m_wait_arb_not_equal(), possibly some deadlock occurs.

Since it works if I kill the “translation” sequence and restart it in main_phase, i’m trying to see if kill() does something special, probably reset some queue etc, which can avoid the deadlock.

In reply to chr_sue:

In reply to eda2k4:
Again, a deadlock cannot be caused by the TLM constructs. It is caused by the transactors whoch have to consider the timing.

BTW I do not understand why you want to switch to an approach which is not recommended, using the sub-phases of the run_phase.
It looks like you are violating rules while dealing with the sub-phases.
And I do not understand what you mean with “save and restore”.