OPPRU 2025. 2. 23. 13:19

 

※ vseqr.sv
class vseqr_c extends uvm_sequencer;
  `uvm_component_utils(vseqr_c)
  
  pipe_sequencer_c    pipe_seqr;
  
  virtual interface pipe_if    vif;
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction      

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    `uvm_info(get_type_name(), $sformatf("build_phase() starts.."), UVM_LOW)
    
    //Get interface from uvm_config_db
    if (!uvm_config_db#(virtual pipe_if)::get(this, "", "vif", vif)) begin
      `uvm_fatal(get_type_name(), {"virtual interface must be set for: ", get_full_name(), ".vif"})
    end    
    
  endfunction
  
  virtual function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);     
  endfunction
    
endclass

 

 virtual sequencer 는 검증 환경에서 사용하는 여러 sequencer 들을 모아놓은 component 로 top sequencer 라고도 한다. test sequence 에서 transaction item 은 driver 를 지나기 전 sequencer 를 통해 전달해야 하는데, 직접적으로 sequencer 를 pin-to-pin 으로 연결하여 전달할 수가 없다.

 개인적인 생각으로는 uvc 안 에서는 interface 를 virtual 로 가져와서 사용한 것처럼 driver 내 sequencer 를 바로 사용할 수 없으니 virtual sequencer 를 따로 만든 것으로, 사용하는 의도가 비슷하여 이름을 지은 것으로 생각된다.

 하지만 진짜 virtual sequencer 의 강점은 sequencer 연결이 아니라 virtual interface 역시 가져와서 sequence 에서 사용할 수 있다는 점이다. ⑾ test sequence 에서 더 자세히 설명하겠지만 sequence 에서 virtual sequencer 를 uvm_decare_p_sequencer 의 uvm api 를 사용하여 p_sequencer 로 선언할 수 있고 p_sequencer 를 통해 interface 의 신호들을 run_phase() 동안에 직접 컨트롤하거나 모니터링을 할 수 있다. 다시 돌아와서 결론은 virtual sequencer 를 p_sequencer 로 선언하고 sequence 내 transaction item 을 pointing 한 sequencer 로 지정하면 driver 를 통해 DUT 로 전송이 가능해진다.