본문 바로가기

UVM Error 메시지 출력해보기가 너무 어렵다. 실제 에러 내용을 출력하도록 예제 코드를 생성해 봤다.

uvm_report_cb::add 메소드는 uvm_report_catcher 타입의 객체를 콜백으로 요구합니다.

리포트 클래스 생성

  1. 클래스 생성: my_custom_reporteruvm_report_catcher를 상속받도록 클래스를 생성합니다. uvm_report_catcheruvm_report_object의 특수한 서브클래스로, 에러 메시지를 잡아내고 수정할 수 있는 메소드를 제공합니다.
  2. 콜백 등록 수정: uvm_report_cb::add 메소드 사용을 올바르게 수정하여 적합한 타입을 전달합니다.

클래스 정의 및 사용 예시

아래는 my_custom_reporteruvm_report_catcher에서 파생시키고, 적절하게 수정된 코드 예시입니다.

`include "uvm_macros.svh"
import uvm_pkg::*;

// uvm_report_catcher를 상속받는 my_custom_reporter 클래스 정의
class my_custom_reporter extends uvm_report_catcher {
    protected string messages[$];

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

    // 에러를 잡아내고 메시지를 저장하는 메서드
    virtual function action_e catch();
        if (get_severity() == UVM_ERROR) begin
            messages.push_back($sformatf("Error - ID: %s, Message: %s", get_id(), get_message()));
            return THROW; // 에러를 계속 전파
        end
        return THROW;
    endfunction

    // 저장된 에러 메시지 출력 메서드
    function void display_errors();
        foreach (messages[i])
            `uvm_info("DISPLAY_ERRORS", messages[i], UVM_NONE);
    endfunction
}

class my_test extends uvm_test {
    my_custom_reporter reporter;

    `uvm_component_utils(my_test)

    function new(string name = "my_test", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        reporter = new(); // 리포터 객체 생성
        uvm_callbacks#(uvm_report_object, uvm_report_catcher)::add(this, reporter); // 콜백 등록
    endfunction

    virtual task run_phase(uvm_phase phase);
        super.run_phase(phase);
        `uvm_error("MY_TEST_ERROR", "This is a simulated error for testing purposes.");
    endtask

    virtual function void report_phase(uvm_phase phase);
        super.report_phase(phase);
        reporter.display_errors(); // 에러 메시지 출력
    endfunction
}

module testbench;
    initial begin
        run_test("my_test");
    end
endmodule

이 변경은 my_custom_reporter 클래스가 uvm_report_catcher를 상속받도록 하여 uvm_callbacksadd 함수와 호환되도록 합니다. catch() 메서드는 리포트된 이벤트를 처리하고, 필요에 따라 수정하거나 로깅할 수 있습니다.

실제 에러는 다음과 같이 출력됩니다.

UVM_INFO ./rtl/my_test.sv(29) @ 795: uvm_test_top.env.agnt.seqr [DISPLAY_ERRORS] Error - ID: MY_ERROR_ID, Message: An intentional error occurred for demonstration purposes.
UVM_INFO ./rtl/my_test.sv(104) @ 795: uvm_test_top [my_test] Test is finishing, reporting status...
UVM_INFO ./rtl/my_test.sv(105) @ 795: uvm_test_top [my_test] Total errors: 1

B로그0간

개발 관련 글과 유용한 정보를 공유하는 공간입니다.