지노랩 /JinoLab

[UVM] 3.10 시나리오 생성 활성화 (Enabling Scenario Creation) 본문

UVM(Universal Verification Methodology)/3. 재사용 가능한 검증 컴포넌트 개발(Developing Reusabl

[UVM] 3.10 시나리오 생성 활성화 (Enabling Scenario Creation)

지노랩/JinoLab 2025. 3. 18. 12:17

 

1. 개요

검증 환경을 구축한 후, 사용자는 다양한 테스트 시나리오를 생성하여 특정 DUT(Design Under Test)를 검증해야 함.
그러나 검증 환경 개발자는 DUT의 프로토콜을 가장 잘 이해하고 있으므로, 테스트 작성이 용이하도록 여러 가지 지원 기능을 제공해야 함.

이를 위해 검증 환경 개발자는 다음과 같은 작업을 수행해야 함:

  1. 데이터 항목(data item) 클래스에 "제어 변수(knobs)"를 추가하여 테스트 제어를 단순화.
  2. 재사용 가능한 다양한 시퀀스(sequences) 라이브러리를 제공.

이러한 지원을 통해 검증 환경 사용자는:

  • 새로운 트랜잭션을 생성하는 새로운 시퀀스를 정의할 수 있음.
  • 기존 시퀀스를 호출하여 새로운 시퀀스를 정의할 수 있음.
  • 기본 데이터 항목의 제어 변수(knobs)를 조정하여 드라이버 및 환경의 동작을 변경할 수 있음.
  • 새로운 동작 및 시퀀스를 활성화(enable)하여 DUT의 다양한 동작을 검증할 수 있음.

2. 시퀀스 라이브러리의 역할

UVM에서 시퀀스(sequence)는 트랜잭션(transaction)을 생성하는 객체이며,
이러한 시퀀스를 재사용 가능한 라이브러리로 구성하면 효율적인 검증 환경을 구축할 수 있음.

시퀀스의 주요 역할:

  • DUT의 프로토콜을 반영하는 트랜잭션 생성.
  • 무작위(random) 시뮬레이션을 통해 다양한 입력 조건을 생성.
  • 특정 조건을 만족하는 트랜잭션을 반복적으로 실행.
  • 하위 시퀀스를 호출하여 복합적인 테스트 시나리오 생성.

3. UVM 시퀀스의 기본 구조

UVM에서 모든 사용자 정의 시퀀스는 uvm_sequence 클래스를 상속받아 정의함.
다음은 간단한 시퀀스의 예제 코드임:

class my_sequence extends uvm_sequence#(my_transaction);
    `uvm_object_utils(my_sequence)

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

    virtual task body();
        my_transaction tr;
        repeat(10) begin
            tr = my_transaction::type_id::create("tr");
            start_item(tr);
            assert(tr.randomize()); // 랜덤값 생성
            finish_item(tr);
        end
    endtask
endclass
  • uvm_sequence#(my_transaction): my_transaction 타입의 트랜잭션을 생성하는 시퀀스를 정의.
  • start_item(tr): 드라이버가 처리할 트랜잭션을 생성 시작.
  • assert(tr.randomize()): 랜덤한 트랜잭션 값 생성.
  • finish_item(tr): 트랜잭션을 종료하고 드라이버로 전송.

4. 시퀀스 라이브러리의 구성

UVM 환경에서는 재사용 가능한 시퀀스 라이브러리를 구성하는 것이 중요함.
이 라이브러리는 여러 개의 시퀀스를 포함하며, 사용자가 필요에 따라 시퀀스를 선택하여 사용할 수 있음.

(1) 기본 시퀀스 (Basic Sequence)

단순한 랜덤 트랜잭션을 생성하는 기본적인 시퀀스.

class basic_sequence extends uvm_sequence#(my_transaction);
    `uvm_object_utils(basic_sequence)

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

    virtual task body();
        my_transaction tr;
        repeat(5) begin
            tr = my_transaction::type_id::create("tr");
            start_item(tr);
            assert(tr.randomize());
            finish_item(tr);
        end
    endtask
endclass

(2) 특정 패턴 시퀀스 (Patterned Sequence)

특정한 패턴의 트랜잭션을 생성하는 시퀀스.

class pattern_sequence extends uvm_sequence#(my_transaction);
    `uvm_object_utils(pattern_sequence)

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

    virtual task body();
        my_transaction tr;
        for (int i = 0; i < 10; i++) begin
            tr = my_transaction::type_id::create("tr");
            start_item(tr);
            tr.addr = i * 4; // 주소 값을 특정 패턴으로 설정
            tr.data = i * 10; // 데이터 값도 특정 패턴으로 설정
            finish_item(tr);
        end
    endtask
endclass

(3) 복합 시퀀스 (Mixed Sequence)

다른 시퀀스를 호출하여 복합적인 시나리오를 실행하는 시퀀스.

class mixed_sequence extends uvm_sequence#(my_transaction);
    `uvm_object_utils(mixed_sequence)

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

    virtual task body();
        basic_sequence b_seq = basic_sequence::type_id::create("b_seq");
        pattern_sequence p_seq = pattern_sequence::type_id::create("p_seq");

        `uvm_info("MIXED_SEQ", "Starting Basic Sequence", UVM_LOW)
        b_seq.start(m_sequencer);

        `uvm_info("MIXED_SEQ", "Starting Pattern Sequence", UVM_LOW)
        p_seq.start(m_sequencer);
    endtask
endclass
  • basic_sequence와 pattern_sequence를 실행하여 다양한 패턴을 조합.
  • b_seq.start(m_sequencer): 기본 시퀀스 실행.
  • p_seq.start(m_sequencer): 패턴 시퀀스 실행.

5. 시퀀스를 사용하여 환경 제어

시퀀스를 사용하여 검증 환경의 동작을 제어할 수 있음.

(1) 시퀀서에 시퀀스 적용

다음과 같이 시퀀스를 실행할 수 있음:

initial begin
    basic_sequence seq = basic_sequence::type_id::create("seq");
    seq.start(my_sequencer);
end
  • seq.start(my_sequencer): my_sequencer에서 basic_sequence 실행.

(2) 시퀀서의 기본 시퀀스 설정

initial begin
    uvm_config_db#(uvm_object_wrapper)::set(null, "uvm_test_top.my_env.my_agent.my_sequencer.run_phase",
                                             "default_sequence", basic_sequence::get_type());
end
  • default_sequence 설정을 통해 기본적으로 실행할 시퀀스를 지정할 수 있음.

6. 정리

  • 검증 환경의 사용자가 쉽게 테스트 시나리오를 작성할 수 있도록 지원해야 함.
  • 데이터 항목 클래스에 "제어 변수(knobs)"를 추가하여 제어 가능성을 높임.
  • 재사용 가능한 다양한 시퀀스를 제공하여 테스트 효율성을 향상.
  • 단순한 랜덤 트랜잭션, 특정 패턴 트랜잭션, 복합 트랜잭션을 생성하는 다양한 시퀀스를 활용.
  • 시퀀서를 통해 환경을 제어하고, 기본 실행 시퀀스를 설정할 수 있음.

7. 다음 단계

  • 검증 환경을 더욱 유연하게 만들기 위해 시퀀스와 시퀀서 간의 상호작용을 깊이 이해할 필요가 있음.
  • 실제 테스트 사례에 맞게 시퀀스를 수정하여 테스트 시나리오의 현실성을 높여야 함.
  • UVM Factory와 Configuration Database를 활용하여 더욱 유연한 검증 환경을 구성할 수 있음.

즉, 다양한 시퀀스를 설계하고 활용하여, 보다 체계적이고 효과적인 검증 환경을 구축하는 것이 중요함.

 

 

 

 


 

본 내용은
accellera에서 공개한
Universal Verification Methodology
(UVM) 1.2 User's Guide
를 바탕으로 작성된 글입니다.