reset phase跳转如下:

  1) 在top层中进行reset

top.sv中
module top();
  event dyn_rst_event;
  initial begin
    rst_n =1'b0;
    #80ns;
    rst_n =1'b1;
    if($test$plusargs("reset"))begin 
      repeat(1200) @(posedge clk);
      rst_n =1'b0;
      ->dyn_rst_event;
      repeat(1200) @(posedge clk);
      rst_n =1'b1;      
    end
  end
endmodule

  2) 在main_phase中进行检测,检测到reset=0后进行phase跳转;

class base_test extends uvm_test;

  virtual task main_phase(uvm_phase phase);
    super.main_phase(phase);
    wait(top.rst_n == 1);
    #10ns;
    wait(top.rst_n == 0);
    phase.jump(uvm_reset_phase::get());
  edntask

endclass

  当检测到复位了即rst_n = 0时就跳转,一般正常情况下rst_n always 1.

  3) 在seqr中进行seqr.stop_sequence.

    跳转完了后在seqr中stop掉正在running 的sequence,防止出现fork join_none的进程一直在跑.

    注意:如果想要正常终止axi相关的seq,seqr.stop_sequence还是会报错,可以在vseq中直接disable掉进程,这样不会出错.

class v_sequencer extends uvm_sequencer
  xx_sequencer my_seqr;

  task reset_phase(uvm_phase phase);
    super.reset_phase(phase);
    my_seqr.stop_sequences();
  endtask

endclass

  4) 在reset_phase中进行queue的清理

   由于reset是随时发生的,这个时候还有比对的数据,需要清空,防止解复位后比对错误, task中需要raise和drop objection.

class my_scoreboard extends uvm_scoreboard;
  
  virtual task reset_phase(uvm_phase phase);
    super.reset_phase(phase);
    phase.raise_objection(this);
    clear_all_data();
    phase.drop_objection(this);
  endtask

endclass

5) 在body中进行reset后重启seq任务

class base_rst_seq extends uvm_sequence;
  virtual task body();
    if(glb_cfg.dyn_rst == 1'b0) begin
      fork
        begin: to_start_seq_test
          to_start_seq();
        end
        begin
          @(top.dyn_rst_event);
          glb_cfg.dyn_rst = 1'b1;
          disable to_start_seq_test;
        end
      join
    end
    else begin
      to_start_seq();
    end
  endtask
endclass

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐