[UVM] uvm_component vs uvm_object 완전 정리 | 차이점, 생성자, 팩토리 매크로

2026. 4. 10. 20:02UVM

반응형

두 클래스의 핵심 차이

UVM의 모든 클래스는 uvm_component 아니면 uvm_object에서 파생됩니다. 한 줄로 요약하면, 컴포넌트는 테스트벤치 구조(계층)를 이루는 영구적 존재이고, 오브젝트는 데이터를 담아 이동하는 일회성 존재입니다.


uvm_component

uvm_componentbuild_phase에서 생성되고 시뮬레이션이 끝날 때까지 살아 있습니다. 부모(parent) 인자를 받아 계층 트리를 구성하며, UVM Phase(build → connect → run → ...)가 자동으로 실행됩니다.

// 대표적인 uvm_component 파생 클래스
uvm_test
uvm_env
uvm_agent
uvm_driver
uvm_monitor
uvm_scoreboard
uvm_sequencer
class my_driver extends uvm_driver #(my_item);
  `uvm_component_utils(my_driver)  // 팩토리 등록

  // 생성자: 반드시 parent 인자 포함
  function new(string name, uvm_component parent);
    super.new(name, parent);
  endfunction

  // Phase 자동 실행
  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
  endfunction

  task run_phase(uvm_phase phase);
    // 드라이빙 로직
  endtask
endclass

uvm_object

uvm_object는 부모 없이 생성되고, Phase가 없으며, 사용 후 GC됩니다. 트랜잭션, 시퀀스, 설정 객체처럼 데이터를 담아 전달하는 목적에 사용됩니다.

// 대표적인 uvm_object 파생 클래스
uvm_sequence_item   // 트랜잭션
uvm_sequence        // 시퀀스
uvm_reg             // RAL 레지스터
uvm_reg_block       // RAL 블록
uvm_config_db 설정 객체 등
class my_item extends uvm_sequence_item;
  `uvm_object_utils(my_item)   // 팩토리 등록

  rand logic [31:0] addr;
  rand logic [31:0] data;
  rand bit          write;

  // 생성자: parent 없음
  function new(string name = "my_item");
    super.new(name);
  endfunction

  // uvm_object의 유용한 내장 메서드
  function string convert2string();
    return $sformatf("addr=0x%h data=0x%h wr=%0b", addr, data, write);
  endfunction
endclass

결정적 차이점 비교

가장 자주 헷갈리는 포인트 다섯 가지입니다.

//                   uvm_component          uvm_object
// 생성자 인자        (name, parent)         (name)
// 팩토리 매크로      uvm_component_utils    uvm_object_utils
// Phase 실행         O (자동)               X
// 계층 구조          O (tree)               X
// 수명              시뮬레이션 전체         생성~참조 소멸
// 주요 용도          구조 (드라이버 등)     데이터 (트랜잭션 등)

가장 흔한 실수 3가지

실수 1: component를 object 생성자로 만들기

// WRONG: parent 없이 component 생성
class my_driver extends uvm_driver;
  function new(string name = "my_driver"); // parent 누락!
    super.new(name, null); // null parent → 계층 깨짐
  endfunction
endclass

// CORRECT
function new(string name, uvm_component parent);
  super.new(name, parent);
endfunction

실수 2: 잘못된 팩토리 매크로 사용

// WRONG: component에 object_utils 사용
class my_env extends uvm_env;
  `uvm_object_utils(my_env)  // Phase 등록 누락 → run_phase 미실행!
endclass

// CORRECT
`uvm_component_utils(my_env)

실수 3: object를 build_phase 밖에서 component처럼 생성

// uvm_sequence_item은 type_id::create("name") 으로 생성
// parent 인자 없음
my_item req = my_item::type_id::create("req");

// uvm_component는 반드시 build_phase 내에서 parent 지정
my_driver drv = my_driver::type_id::create("drv", this);