Making a sequence with pre_body start from test class

Hi,

I have the following set of sequence classes and test class.


//Defining base sequence
class base_seq extends uvm_sequence;
   `uvm_object_utils(base_seq)
   `uvm_declare_p_sequencer(my_virtual_sequencer)

   axi_seq my_seq;

   function new(string name="base_seq");
      super.new(name);
   endfunction:new

   virtual task pre_body()
      my_seq = axi_seq::type_id::create("my_seq");
      axi_seq.start(p_sequencer.axi_seqr);       
   endtask: pre_body

endclass: base_seq

//Defining actual test sequence
class my_seq extends base_seq;
   `uvm_object_utils(my_seq)
   `uvm_declare_p_sequencer(my_virtual_sequencer)

   test_seq_item my_test_seq_item; //test_seq_item is of the type uvm_sequence_item

   function new(string name="my_seq");
      super.new(name);
   endfunction:new

   virtual task body();
      $display("Starting my_seq"); //Display 1

      `uvm_create_on(my_test_seq_item, p_sequencer.config_seqr)
      start_item(my_test_seq_item);
         my_test_seq_item.var1 = 1;
         my_test_seq_item.var2 = 2;
      finish_item(my_test_seq_item);

      $display("End of my_seq");  //Display 2

   endtask: body

endclass: my_seq

class my_test extends uvm_test;
   my_seq test_seq;

   `uvm_component_utils(my_test)
   function new(string name = "my_test", uvm_component parent=null);
      super.new(name,parent);
   endfunction : new

   virtual function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      test_seq = new();
   endfunction : build_phase

   virtual task run_phase(uvm_phase phase);
      //start test_seq of the class my_seq. I use start because i think that is the only way i can make the pre_body to execute
      test_seq.start(env_inst.vseqr); //vseqr is of of the type my_virtual_sequencer. 
   endtask: run_phase
endclass: my_test

As soon as i start the test_seq (of class my_seq) in my_test class, i see that pre_body of base_seq is executed and then i see the display statement (Display 1) in my_seq body. However the item my_test_seq_item (of class test_seq_item) is never started. I do not see any warnings or errors. The sequence my_seq seems to be stuck at the point after the display statement. I do not see Display 2.

Can any one figure out whats wrong here. Why is the sequence item in my_seq not getting started(executed)?

I do know a work around for this and this would have two steps.

  1. We could change the pre_body in the base_seq to body.
  2. Add the statement super.body() as the first line under body() of my_seq.

I really do not (read cannot) change the contents of body() task of my_seq. i.e i do not want to add a super.body().
I would like to know if we can somehow start axi_seq mentioned in base_seq before the body of my_seq and without changing the contents of the body() of my_seq. (Please read that i may be able to change anything outside of the body() of my_seq).

In reply to abdulhafiz.oa:

If you ar doing strange thinks you should not wonder when something happens.
(1) I try to understand why you are starting a sequence in the pre_body task. I do not see any reason for this.
(2) A sequencer is executing sequences and not seq_items, but the sequence is generating sequence items. Create s sequence instead of your item. This will work.

  1. I try to understand why you are starting a sequence in the pre_body task. I do not see any reason for this.
    Suppose you have a pre-existing sequence (which in my case is in my_seq as mentioned in the example) and later on you need to add a certain set of tasks which needs to be done prior to this pre-existing sequence. Can you please suggest me a way other than that described above. Please do understand that i have 1000s of such pre-existing sequences and it will be impossible for me to manually change each and every sequence that i have. With the method mentioned above in the example, all i need to do will be to extend my_seq from a base sequence class. This base sequence class will have the additional tasks in its pre_body(). I would also like to know if there is something that restricts me from starting a sequence in pre_body (Please point me to the reference if we have such a restriction).

  2. A sequencer is executing sequences and not seq_items, but the sequence is generating sequence items. Create s sequence instead of your item. This will work.
    A sequencer can execute a sequence item. There is no doubt on this. That is why in UVM we have set_sequencer method as part of uvm_sequence_item. The sequencer just requires a sequence item. It doesn’t matter whether the sequence generates this sequence item or you manually create it. All that should matter is the sequence_item should be compatible with the sequencer and it can push this sequence item to the driver. I do not agree that i should be restricted in manually creating the sequence items.

Regards
abdulhafiz.oa

In reply to abdulhafiz.oa:
Why you are starting the sequence in the base sequence?. Going this way you loose the ability to control the sequence execution. In the base you should model the behavior what this sequence is doing. And you should start it from your test. This is the recommended way.
Regarding the seq_item execution you are right. A sequencer can execute a seq_item. Befor calling start_item you should call create_item. See the UVM Ref Manual.

In reply to chr_sue:

In reply to abdulhafiz.oa:
Why you are starting the sequence in the base sequence?. Going this way you loose the ability to control the sequence execution. In the base you should model the behavior what this sequence is doing. And you should start it from your test. This is the recommended way.

I do not want any additional control the sequence. Its a fixed sequence. say, like a reset. I just want it to be executed once.
Regarding the seq_item execution you are right. A sequencer can execute a seq_item. Befor calling start_item you should call create_item. See the UVM Ref Manual.
Please refer the example. I have already used the code for creating the sequence item.
`uvm_create_on(my_test_seq_item, p_sequencer.config_seqr) (which is line 2 of body() method in my_seq)

Regards
abdulhafiz.oa

In reply to abdulhafiz.oa:

Having control over your sequences does not mean a modification of the sequence. It means you can start this sequence when it is necessary. And you should define in your test how your virtual sequence looks like and how the different sequences are started.
And again dealing with the generation of 1 seq_item is not the recommended way.

In reply to abdulhafiz.oa:

For point 1 you can use phasing, but what you’re trying to do is also valid.

For point 2, if you move your ‘display 2’ immediately after start_item(…), do you see it being called? start_item(…) will return once the sequencer you started the item on has called get_next_item(). If this doesn’t happen, it could be that you locked the sequencer from another sequence. I’m not sure why you see this only when starting your axi_seq from pre_body(). Maybe this is the sequence that does the locking.