2026. 4. 10. 20:02ㆍUVM
UVM 리포팅 시스템이란?
UVM은 `uvm_info, `uvm_warning, `uvm_error, `uvm_fatal 네 가지 매크로로 메시지를 출력하는 통합 리포팅 시스템을 제공합니다. 단순 $display와 달리 심각도(severity), 식별자(ID), 상세 수준(verbosity)을 함께 관리할 수 있어 대규모 테스트벤치에서 필수입니다.
4가지 심각도 매크로
// 형식: `uvm_("", "", )
`uvm_info("DRV", "트랜잭션 전송 시작", UVM_LOW)
`uvm_info("DRV", "addr = 0x100", UVM_MEDIUM)
`uvm_info("DRV", "내부 상태 덤프", UVM_HIGH)
`uvm_warning("SCB", "예상과 다른 데이터 수신") // 계속 진행
`uvm_error("SCB", "scoreboard 미스매치 발생") // 에러 카운트 +1
`uvm_fatal("CFG", "필수 인터페이스 연결 안됨") // 즉시 시뮬 중단
Verbosity 레벨
Verbosity는 메시지의 상세 수준입니다. 런타임에 설정된 레벨보다 높은 verbosity의 메시지는 출력되지 않습니다. 기본값은 UVM_MEDIUM입니다.
// 낮을수록 항상 출력, 높을수록 필터링됨
UVM_NONE = 0 // 항상 출력
UVM_LOW = 100 // 중요 정보
UVM_MEDIUM = 200 // 기본값 (default 출력 임계치)
UVM_HIGH = 300 // 디버그용 상세 정보
UVM_FULL = 400 // 매우 상세 (개발 중에만 사용)
UVM_DEBUG = 500 // 최대 상세
Verbosity 실시간 변경
// 커맨드라인으로 변경
// +UVM_VERBOSITY=UVM_HIGH
// 코드에서 변경 (특정 컴포넌트에만 적용)
env.agent.driver.set_report_verbosity_level(UVM_HIGH);
// 전체 레벨 변경
uvm_top.set_report_verbosity_level_hier(UVM_HIGH);
$sformatf로 동적 메시지 출력
task run_phase(uvm_phase phase);
my_item tr;
forever begin
seq_item_port.get_next_item(tr);
`uvm_info("DRV",
$sformatf("Driving: addr=0x%0h data=0x%0h wr=%0b",
tr.addr, tr.data, tr.write),
UVM_LOW)
// ... 드라이빙
seq_item_port.item_done();
end
endtask
에러/경고 제어 — set_report_*
특정 ID의 메시지 행동을 변경하거나 억제할 수 있습니다.
// 특정 ID의 UVM_ERROR를 UVM_WARNING으로 격하
set_report_severity_id_override(UVM_ERROR, "SCB", UVM_WARNING);
// 특정 ID 메시지 완전히 억제
set_report_id_action(UVM_INFO, "NOISY_ID", UVM_NO_ACTION);
// 특정 ID 로그 파일로 출력
set_report_id_file("DRV", log_file_handle);
set_report_id_action("DRV", UVM_LOG | UVM_DISPLAY);
uvm_report_server — 전역 통계 관리
uvm_report_server는 시뮬레이션 전체의 에러/경고 카운트를 관리합니다. 시뮬레이션 종료 시 자동으로 요약 리포트를 출력합니다.
// 에러 카운트 직접 확인
function void check_phase(uvm_phase phase);
uvm_report_server rs = uvm_report_server::get_server();
int err_cnt = rs.get_severity_count(UVM_ERROR);
if (err_cnt > 0)
`uvm_fatal("TEST", $sformatf("Test FAILED: %0d errors", err_cnt))
else
`uvm_info("TEST", "Test PASSED", UVM_NONE)
endfunction
// 시뮬레이션 끝 자동 요약 예시:
// --- UVM Report Summary ---
// UVM_INFO : 1523
// UVM_WARNING: 2
// UVM_ERROR : 0
// UVM_FATAL : 0
uvm_field_* 매크로 — do_print / do_copy / do_compare 자동화
uvm_object 기반 클래스(주로 sequence_item, transaction)에서 uvm_object_utils_begin / uvm_object_utils_end 블록 안에 uvm_field_* 매크로를 선언하면, print / copy / compare / pack / unpack 동작이 자동으로 구현됩니다. 별도 함수 작성 없이 item.print(), item.compare(other)를 바로 쓸 수 있습니다.
class my_seq_item extends uvm_sequence_item;
rand bit [7:0] addr;
rand bit [31:0] data;
rand bit wr_en;
string tag;
`uvm_object_utils_begin(my_seq_item)
`uvm_field_int (addr, UVM_ALL_ON)
`uvm_field_int (data, UVM_ALL_ON)
`uvm_field_int (wr_en, UVM_ALL_ON)
`uvm_field_string(tag, UVM_ALL_ON)
`uvm_object_utils_end
function new(string name = "my_seq_item");
super.new(name);
endfunction
endclass
uvm_field_* 매크로 종류
| 매크로 | 대상 타입 | 설명 |
|---|---|---|
`uvm_field_int(F, FLAG) |
int, bit, logic 등 정수형 | 정수형 필드 등록 |
`uvm_field_string(F, FLAG) |
string | 문자열 필드 등록 |
`uvm_field_object(F, FLAG) |
uvm_object 파생 클래스 | 객체 필드 등록 (deep copy 지원) |
`uvm_field_array_int(F, FLAG) |
배열 (int[]) | 정수 배열 등록 |
`uvm_field_queue_int(F, FLAG) |
큐 (int $queue) | 정수 큐 등록 |
`uvm_field_enum(T, F, FLAG) |
enum 타입 | enum 필드 등록 (T는 enum 타입명) |
FLAG 주요 값
| FLAG | 의미 |
|---|---|
UVM_ALL_ON |
print, copy, compare, pack/unpack 모두 활성화 (기본 권장) |
UVM_NOPRINT |
print 제외 |
UVM_NOCOPY |
copy 제외 |
UVM_NOCOMPARE |
compare 제외 (Scoreboard에서 비교 대상 제외 시 유용) |
UVM_DEFAULT |
UVM_ALL_ON과 동일 |
// 활용 예
my_seq_item a = my_seq_item::type_id::create("a");
my_seq_item b = my_seq_item::type_id::create("b");
a.print(); // uvm_field_*가 선언된 모든 필드 출력
b.copy(a); // a의 모든 필드를 b에 deep copy
a.compare(b); // 필드 단위로 비교, 다르면 에러 메시지 출력
// Scoreboard에서 예측값 vs 실제값 비교 시 자주 활용됨
💡 주의: uvm_field_* 매크로는 편리하지만 런타임 오버헤드가 있습니다. 대규모 시뮬레이션에서 성능이 중요하다면 do_print(), do_copy(), do_compare()를 직접 오버라이드하는 방식도 고려할 수 있습니다.