지노랩 /JinoLab

[UVM] 3.9 환경(Environment) 생성 본문

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

[UVM] 3.9 환경(Environment) 생성

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

3.9 환경(Environment) 생성

1. 개요

UVM에서 **Environment(환경)**는 여러 개의 에이전트(Agent), 스코어보드(Scoreboard), 커버리지 수집기(Coverage Collector) 등을 포함하는 상위 계층의 검증 컴포넌트임.
즉, 개별적인 트랜잭션 레벨 컴포넌트들을 조합하여 전체적인 검증 환경을 구성하는 역할을 함.

환경을 올바르게 설계하면 재사용성(reusability)이 높아지고, 다양한 테스트 시나리오에 쉽게 적용 가능.


2. 환경(Environment) 설계 원칙

  1. 검증 컴포넌트들을 계층적으로 구성
    • 환경 내에서 하위 컴포넌트(에이전트, 스코어보드, 커버리지 수집기 등)를 생성.
  2. 컴포넌트 간 인터페이스 연결(TLM 포트 이용)
    • 에이전트의 분석 포트(Analysis Port)를 스코어보드와 커버리지 수집기에 연결.
  3. 설정(Configuration)을 이용한 유연한 환경 조절
    • 에이전트의 개수, 역할(마스터/슬레이브) 등을 설정값으로 관리하여 다양한 검증 요구사항을 충족.

3. 환경(Environment) 클래스 예제

아래는 **simple_env**라는 기본적인 환경 클래스를 정의한 예제 코드.

class simple_env extends uvm_env;
    `uvm_component_utils(simple_env)

    // 환경 내부에 포함될 컴포넌트
    simple_agent agent;
    uvm_scoreboard scoreboard;

    // 생성자
    function new(string name = "simple_env", uvm_component parent);
        super.new(name, parent);
    endfunction

    // build_phase(): 하위 컴포넌트 생성
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        agent = simple_agent::type_id::create("agent", this);
        scoreboard = uvm_scoreboard::type_id::create("scoreboard", this);
    endfunction

    // connect_phase(): 하위 컴포넌트 연결
    virtual function void connect_phase(uvm_phase phase);
        agent.monitor.item_collected_port.connect(scoreboard.analysis_export);
    endfunction
endclass

4. 코드 설명

라인 코드 설명

1 class simple_env extends uvm_env; uvm_env를 상속하여 환경 클래스 정의
2 `uvm_component_utils(simple_env) UVM Factory에 등록하여 객체를 동적으로 생성 가능
5-6 simple_agent agent; uvm_scoreboard scoreboard; 환경 내부에 포함될 에이전트와 스코어보드 선언
9-11 function new(...) 생성자 정의
14-18 build_phase() 환경 내부의 하위 컴포넌트(에이전트, 스코어보드) 생성
21-23 connect_phase() 에이전트의 모니터에서 수집된 데이터를 스코어보드로 전달

5. connect_phase()에서의 TLM 연결

위 코드에서 connect_phase()에서는 TLM Analysis Port를 이용하여 트랜잭션 데이터를 스코어보드로 전달.

agent.monitor.item_collected_port.connect(scoreboard.analysis_export);
  • agent.monitor.item_collected_port
    에이전트 내 모니터에서 트랜잭션을 수집하는 분석 포트
  • scoreboard.analysis_export
    수집된 트랜잭션을 받아서 비교 및 검증을 수행하는 분석 익스포트(Analysis Export)

이와 같은 연결 방식을 사용하면 트랜잭션 데이터를 여러 개의 분석 컴포넌트(스코어보드, 커버리지 수집기 등)로 쉽게 전송할 수 있음.


6. 환경 클래스의 역할

  • 에이전트(Agent)와 스코어보드(Scoreboard)를 포함하는 상위 계층의 검증 환경 제공
  • 컴포넌트 간의 인터페이스를 연결하여 데이터를 주고받을 수 있도록 구성
  • 설정을 이용하여 검증 환경을 동적으로 변경 가능
    • 예를 들어, 환경 내에 여러 개의 에이전트를 포함할 수도 있음.

3.9.1 환경(Environment) 클래스

1. 개요

UVM 환경(Environment) 클래스는 재사용 가능한 검증 컴포넌트들의 최상위 컨테이너 역할을 하며,
검증 환경을 구성하는 에이전트(Agent), 스코어보드(Scoreboard), 커버리지 수집기(Coverage Collector) 등의 서브 컴포넌트를 인스턴스화하고 설정하는 역할을 담당함.

환경 클래스는 다양한 검증 시나리오에서 재사용성을 극대화하는 요소로,
테스트벤치에서 인스턴스화되어 검증 대상(DUT)에 맞춰 동적으로 설정 가능.


2. 환경 클래스의 주요 역할

  • 하위 컴포넌트(에이전트, 스코어보드 등) 생성 및 연결
  • 설정(Configuration) 기능을 활용하여 다양한 테스트 환경에 맞게 조정
  • TLM 포트를 이용한 데이터 흐름 관리
  • 동적으로 확장 가능한 구조 제공 (예: 마스터/슬레이브 개수 조절)

3. 환경 클래스 예제

다음은 AHB 버스 검증을 위한 ahb_env 환경 클래스 예제.

class ahb_env extends uvm_env;
    // 마스터 개수 설정 변수
    int num_masters;

    // AHB 마스터 에이전트 배열
    ahb_master_agent masters[];

    // UVM 자동화 매크로 등록
    `uvm_component_utils_begin(ahb_env)
        `uvm_field_int(num_masters, UVM_ALL_ON)
    `uvm_component_utils_end

    // 생성자 정의
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction : new

    // build_phase(): 하위 컴포넌트 생성
    virtual function void build_phase(uvm_phase phase);
        string inst_name;
        super.build_phase(phase);

        // 마스터 개수 설정 확인
        if(num_masters == 0)
            `uvm_fatal("NONUM", "'num_masters' 값이 설정되지 않았습니다.");

        // 마스터 에이전트 배열 크기 설정
        masters = new[num_masters];

        // 마스터 에이전트 인스턴스 생성
        for(int i = 0; i < num_masters; i++) begin
            $sformat(inst_name, "masters[%0d]", i);
            masters[i] = ahb_master_agent::type_id::create(inst_name, this);
        end

        // 슬레이브 및 기타 하위 컴포넌트 추가 가능
    endfunction : build_phase

endclass : ahb_env

4. 코드 설명

 

라인  코드  설명
1 class ahb_env extends uvm_env; uvm_env를 상속하여 환경 클래스 정의
3-4 int num_masters; ahb_master_agent masters[]; 마스터 개수 및 마스터 에이전트 배열 선언
6-9 `uvm_component_utils 매크로 UVM Factory 등록 및 설정 값 자동 관리
11-14 function new(...) 생성자 정의
17-20 if(num_masters == 0) ... 마스터 개수가 설정되지 않으면 오류 발생
22 masters = new[num_masters]; 마스터 에이전트 배열 생성
24-27 for(int i = 0; i < num_masters; i++) ... create()를 사용해 동적으로 마스터 에이전트 생성

5. build_phase()에서의 하위 컴포넌트 생성

  • build_phase()에서 num_masters 값에 따라 마스터 에이전트를 동적으로 생성.
  • 마스터 개수가 0이면 오류(fatal error) 발생하도록 설계.
  • type_id::create()를 이용하여 마스터 에이전트 객체를 동적으로 생성.
    masters[i] = ahb_master_agent::type_id::create(inst_name, this);
    
  • 이 방식은 환경을 재사용할 때 매우 유용함 → 마스터 개수만 변경하면 검증 환경을 쉽게 확장 가능.

6. 환경 클래스의 재사용성

  • num_masters 값을 설정함으로써 마스터 개수를 유연하게 변경 가능.
  • type_id::create()를 사용하여 에이전트나 서브 컴포넌트를 쉽게 교체 가능.
    • 예를 들어, 특정 테스트에서 다른 종류의 에이전트를 사용하고 싶다면, Factory Override를 통해 변경 가능.
  • 에이전트 외에도 슬레이브, 스코어보드, 커버리지 모듈 등을 추가하여 더욱 확장 가능.

3.9.2 build_phase 호출 (Invoking build_phase)

1. 개요

과거 UVM 버전에서는 build, connect, run 등의 여러 흐름 제어 작업을 수동으로 호출하는 것이 가능했음.
즉, build_phase() 같은 메서드를 직접 호출하는 방식으로 검증 환경을 구성하는 것이 일반적이었음.

그러나 최신 UVM 버전에서는 이러한 수동 호출 방식이 더 이상 허용되지 않으며(deprecated), 오류로 간주됨.
이제 UVM 클래스 라이브러리가 자동으로 모든 phase 작업을 실행하므로, 사용자가 직접 호출할 필요가 없음.


2. 주요 내용

  • 최신 UVM에서는 build_phase() 등의 각종 phase 작업이 자동으로 실행됨.
  • 이전 방식: 사용자가 build(), connect(), run() 등의 메서드를 직접 호출.
  • 현재 방식: build_phase(), connect_phase(), run_phase() 등의 UVM Phase 메서드는 자동으로 실행되며, 직접 호출하면 오류 발생.
  • 자식 컴포넌트 간 연결 작업은 부모 컴포넌트의 connect_phase()에서 수행해야 함.

3. build_phase()의 자동 실행

UVM은 build_phase()를 자동으로 실행하므로 사용자가 직접 호출할 필요가 없음.
예를 들어, 다음과 같은 방식으로 build_phase()를 명시적으로 호출하면 오류가 발생할 수 있음.

// 잘못된 예제 (Deprecated 방식)
class my_env extends uvm_env;
    my_agent agent;

    function new(string name, uvm_component parent);
        super.new(name, parent);
        build_phase(null); // 직접 호출하면 오류 발생
    endfunction
endclass

위와 같은 방식은 최신 UVM에서는 더 이상 허용되지 않으며, 대신 build_phase()가 자동으로 실행됨.


4. 올바른 사용 방법

UVM에서는 하위 컴포넌트 인스턴스화를 build_phase()에서 수행해야 하며, connect_phase()에서 컴포넌트 간 연결을 수행해야 함.

class my_env extends uvm_env;
    my_agent agent;

    // UVM 매크로 등록
    `uvm_component_utils(my_env)

    // 생성자
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction : new

    // 올바른 `build_phase()` 사용 방법
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        agent = my_agent::type_id::create("agent", this);
    endfunction : build_phase
endclass

위 코드에서 build_phase()는 UVM 프레임워크에 의해 자동으로 실행되므로, 사용자가 직접 호출할 필요 없음.


5. connect_phase()에서의 연결 수행

자식 컴포넌트 간의 연결은 connect_phase()에서 수행해야 함.

class my_env extends uvm_env;
    my_agent agent;
    my_scoreboard sb;

    // UVM 매크로 등록
    `uvm_component_utils(my_env)

    // 생성자
    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction : new

    // `build_phase()`에서 인스턴스 생성
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        agent = my_agent::type_id::create("agent", this);
        sb = my_scoreboard::type_id::create("sb", this);
    endfunction : build_phase

    // `connect_phase()`에서 컴포넌트 연결
    virtual function void connect_phase(uvm_phase phase);
        agent.analysis_port.connect(sb.analysis_export);
    endfunction : connect_phase
endclass
  • build_phase()에서 create()를 사용해 하위 컴포넌트를 생성.
  • connect_phase()에서 컴포넌트 간의 TLM 포트 연결 수행.

6. build_phase() 관련 주요 가이드라인

잘못된 방식 (Deprecated)  올바른 방식 (UVM 1.2 이상)
build_phase()를 직접 호출 UVM이 자동으로 실행
connect() 호출을 build_phase()에서 수행 connect_phase()에서 연결 수행
build(), run() 등의 수동 호출 build_phase(), run_phase() 등의 자동 실행 활용

7. 정리

  • UVM 1.2 이상에서는 build_phase()와 같은 Phase 메서드를 수동으로 호출하면 안 됨.
  • UVM 라이브러리가 자동으로 Phase를 실행하므로 사용자는 build_phase()를 정의만 하면 됨.
  • build_phase()에서는 컴포넌트를 생성하고, connect_phase()에서 연결 작업을 수행해야 함.
  • 기존의 build(), connect(), run() 등의 직접 호출 방식은 오류로 간주됨.

즉, UVM에서는 Phase를 직접 실행하지 않고, UVM 프레임워크가 자동으로 처리하도록 설계하는 것이 중요함.

 

 


 

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