Jump to content

How virtual sequence start?


Recommended Posts

Hi all,
I have ran into the problem about virual sequence's starting
Here are the codes:
 
class my_env extends uvm_env;
 ...
 master_vsequence v_seq[];
 ...
function void build_phase(uvm_phase phase);
  ...
  v_seq  = new[host_num];
  for (int i = 0; i < host_num; i++) begin
   v_seq[i] = master_vsequence::type_id::create($sformatf("v_seq[%0d]", i), this);
  ...
 endfunction: build_phase
 ...

 task run_phase(uvm_phase phase);
  //fork 
  // update_vif_enables()
  //join 
  $display("Starting virtual sequence!!!")
  fork  
   for (int i = 0; i < host_num; i++) begin
    v_seq[i].starting_phase = phase;
    slv_seq[i].starting_phase = phase;
    v_seq[i].start(subenv[i].v_sqr);
    slv_seq[i].start(subenv[i].slv_agt.slv_sqr);
   end  
  join  
 endtask : run_phase

 ...
endclass: my_env


class my_subenv extends uvm_env

function void build_phase(uvm_phase phase)
  
  inst_name = $sformatf("v_sqr%0d", id);
  v_sqr = vsequencer::type_id::create(inst_name, this);
  //uvm_config_db#(uvm_object_wrapper)::set(this, {inst_name, ".run_phase"}, "default_sequence", master_vsequence::type_id::get());
  ...
endfunction: build_phase
 ...

 function void connect_phase(uvm_phase phase)
  string inst_name;
  super.connect_phase(phase);
  inst_name = $sformatf("v_sqr%0d", id);
  uvm_config_db#(config_sequencer)::set(this, inst_name, "cfg_sqr", this.cfg_agt.cfg_sqr);
  uvm_config_db#(string_sequencer)::set(this, inst_name, "str_sqr", this.str_agt.str_sqr);
 endfunction : connect_phase
 ...
endclass : my_subenv

class master_vsequence extends uvm_sequence;
  ...
  function new(string name = "master_vsequence");
   ...
   cfg_seq = config_sequence::type_id::create("cfg_seq",,get_full_name());
   str_seq = string_sequence::type_id::create("str_seq",,get_full_name());
   ...
  endfunction

  virtual task body();
   `uvm_do_on(cfg_seq, p_sequencer.cfg_sqr)
   `uvm_do_on(str_seq, p_sequencer.str_sqr)
   //cfg_seq.start(p_sequencer.cfg_sqr)
   //str_seq.start(p_sequencer.str_sqr)
  endtask: body
  
  `uvm_declare_p_sequencer(vsequencer)
endclass : master_vsequence

class vsequencer extends uvm_sequencer;
  // subsequenc
 config_sequencer cfg_sqr;
 string_sequencer str_sqr;

 function void build_phase(uvm_phase phase)
  string inst_name;
  super.build_phase(phase);
  // instantiates sequencers and config;
  inst_name = $sformatf("vcfg_sqr%0d", ID);
  cfg_sqr = config_sequencer::type_id::create(inst_name, this);
  void'(uvm_config_db#(config_sequencer)::get(this, "", inst_name, cfg_sqr));
  inst_name = $sformatf("vstr_sqr%0d", ID);
  str_sqr =string_sequencer::type_id::create(inst_name, this);
  void'(uvm_config_db#(string_sequencer)::get(this, "", inst_name, str_sqr));
 endfunction : build_phase
endclass: vsequence

 

When I run these codes, It prints"Starting virtual sequence!!!" on screen, then stucks. Seems like the virtual sequence doesn't start. Is there any problem about starting virtual sequence as above? By the way, the config_sequence will start successly if I don't use virtual sequence and string_seuquece.
Link to comment
Share on other sites

 
When I run these codes, It prints"Starting virtual sequence!!!" on screen, then stucks. Seems like the virtual sequence doesn't start. Is there any problem about starting virtual sequence as above? By the way, the config_sequence will start successly if I don't use virtual sequence and string_seuquece.

 

I find that it stucks at line 295 in uvm_sequence_base.svh when excuting v_seq.start(subenv.v_sqr); Does anybody run into the same problem? Please share the solution.

By the way, here is the relevant source code of uvm_sequence_base.svh.

 

  virtual task start (uvm_sequencer_base sequencer,
                      uvm_sequence_base parent_sequence = null,
                      int this_priority = -1,
                      bit call_pre_post = 1);

    set_item_context(parent_sequence, sequencer);

    if (!(m_sequence_state inside {CREATED,STOPPED,FINISHED})) begin
      uvm_report_fatal("SEQ_NOT_DONE", 
         {"Sequence ", get_full_name(), " already started"},UVM_NONE);
    end

    if (m_parent_sequence != null) begin
       m_parent_sequence.children_array[this] = 1;
    end

    if (this_priority < -1) begin
      uvm_report_fatal("SEQPRI", $sformatf("Sequence %s start has illegal priority: %0d",
                                           get_full_name(),
                                           this_priority), UVM_NONE);
    end
    if (this_priority < 0) begin
       if (parent_sequence == null) this_priority = 100;
       else this_priority = parent_sequence.get_priority();
    end

    // Check that the response queue is empty from earlier runs
    clear_response_queue();

    m_priority           = this_priority;

    if (m_sequencer != null) begin
        if (m_parent_sequence == null) begin
          m_tr_handle = m_sequencer.begin_tr(this, get_name());
        end else begin
          m_tr_handle = m_sequencer.begin_child_tr(this, m_parent_sequence.m_tr_handle, 
                                                   get_root_sequence_name());
        end
    end

    // Ensure that the sequence_id is intialized in case this sequence has been stopped previously
    set_sequence_id(-1);
    // Remove all sqr_seq_ids
    m_sqr_seq_ids.delete();

    // Register the sequence with the sequencer if defined.
    if (m_sequencer != null) begin
      void'(m_sequencer.m_register_sequence(this));
    end

    // Change the state to PRE_START, do this before the fork so that
    // the "if (!(m_sequence_state inside {...}" works
    m_sequence_state = PRE_START;
    fork // line 295
      begin
        m_sequence_process = process::self();

        // absorb delta to ensure PRE_START was seen
        #0;
        pre_start();

        if (call_pre_post == 1) begin
          m_sequence_state = PRE_BODY;
          #0;
          pre_body();
        end

        if (parent_sequence != null) begin
          parent_sequence.pre_do(0);    // task
          parent_sequence.mid_do(this); // function
        end

        m_sequence_state = BODY;
        #0;
        body();

        m_sequence_state = ENDED;
        #0;

        if (parent_sequence != null) begin
          parent_sequence.post_do(this);
        end

        if (call_pre_post == 1) begin
          m_sequence_state = POST_BODY;
          #0;
          post_body();
        end

        m_sequence_state = POST_START;
        #0;
        post_start();

        m_sequence_state = FINISHED;
        #0;

      end
    join

    if (m_sequencer != null) begin      
      m_sequencer.end_tr(this);
    end
        
    // Clean up any sequencer queues after exiting; if we
    // were forcibly stoped, this step has already taken place
    if (m_sequence_state != STOPPED) begin
      if (m_sequencer != null)
        m_sequencer.m_sequence_exiting(this);
    end

    #0; // allow stopped and finish waiters to resume

    if ((m_parent_sequence != null) && (m_parent_sequence.children_array.exists(this))) begin
       m_parent_sequence.children_array.delete(this);
    end
  endtask
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...