Query Regarding Sequence Layering Management

In reply to vadivelan014:

The way you’ve written your higher_default_sequence:

class higher_default_sequence extends uvm_sequence #(higher_packet); 
 `uvm_sequence_utils(higher_default_sequence, higher_sequencer); 
.....

 higher_sequence1 h_seq1;
 higher_sequence2 h_seq2;
 higher_sequence3 h_seq3;
 higher_sequence4 h_seq4;

 task body();
 `uvm_do(h_seq1);
 `uvm_do(h_seq2);
 `uvm_do(h_seq3);
 `uvm_do(h_seq4);
 endtask
 endclass

shows the four sequences running serially (that is, h_seq2 starts after h_seq1 completes, etc.). If that’s all you want to do, then I think you may be overthinking things a bit. It appears that each of your h_seq sequences generates a single h_pkt that the lower_sequences (actually translator sequences, as defined in the Cookbook) use to generate a corresponding lower_packet. Since each h_pkt includes the enable logic for either L1 or L2, it makes no sense to have the two lower_sequences each trying to get from the higher_sequence simultaneously, since it screws up the handshake as you’ve seen.
Instead, you would be better off actually treating higher_default_sequence as a virtual sequence:

class higher_default_sequence extends uvm_sequence #(higher_packet); 
 `uvm_object_utils(higher_default_sequence, higher_sequencer); 
.....
 lower_sequencer1 Lsqr1;
 lower_sequencer2 Lsqr2;

 higher_sequence1 h_seq1;
 higher_sequence2 h_seq2;
 higher_sequence3 h_seq3;
 higher_sequence4 h_seq4;

 task body();
   h_seq1.start(Lsqr1, this);
   h_seq2.start(Lsqr2, this);
   h_seq3.start(Lsqr1, this);
   h_seq4.start(Lsqr2, this);
 endtask
 endclass

Please see the UVM Cookbook for more details on virtual sequences. Notice that we’re not using a virtual sequence**r**, which is unnecessary since you can put the lower_sequencer pointers directly in the virtual sequence.
You’d have to change the definitions of h_seq[1,2,3,4] since they are now running on the lower_sequencers. These now become what we call “worker sequences” (see the Cookbook) which will call the lower_sequence with the appropriate values.
By starting the four sequences one-at-a-time on the lower_sequencers, you should avoid the handshake problem. The downstream layering low sqr1 ↔ low sqr 1a ↔ low sqr 1b ↔ driver ↔ DUT should remain unchanged.
Remember, the key to layering is to make each layer appear that it’s just a sequence/sequencer/driver connection. Since you can’t connect a single sequence to multiple drivers, you can’t have multiple translator sequences talking to the same sequence either.

Other comments on your code:
You’ll notice that I replace uvm_sequence_utils with uvm_object_utils. The sequence utils has been deprecated, as has uvm_update_sequence_lib_and_item. If you really think you need to use a sequence library, please see the [Cookbook](https://verificationacademy.com/cookbook/sequences/sequencelibrary) to learn how to do it, but I don't think you do. You'll also notice that I replaced the uvm_do macros with sequence.start(). The uvm_do macros are evil and we recommend against using them. In your original approach, you would replace the uvm_do macro with

h_seq1.start(m_sequencer, this);

if you really wanted to start h_seq1 on the higher_sequencer. Using my approach, you would have had to change uvm_do to uvm_do_on (I think - I can never keep those macros straight).

Hope this helps.