07_UVM Object Compare : automation macro와 do_compare 활용

UVM Object Compare : automation macro와 do_compare 활용
UVM Object Compare

UVM 객체 비교 완벽 가이드: automation macro와 do_compare 활용

UVM (Universal Verification Methodology) 환경에서 객체의 동일성을 확인하는 것은 검증의 중요한 부분입니다. uvm_object 클래스는 객체 비교를 위한 compare 메소드를 제공하며, UVM 자동화 매크로를 활용하면 이 기능을 별도의 코드 작성 없이 자동으로 사용할 수 있습니다. 이전 게시물에서는 copy, do_copy 및 자동화 매크로를 이용한 print 기능에 대해 다루었습니다. 이번 글에서는 UVM 자동화 매크로를 이용한 객체 비교 방법과 do_compare의 내부 동작 방식에 대해 자세히 알아보겠습니다. SystemVerilog 기본 지식을 바탕으로 UVM의 강력한 객체 비교 기능을 익혀보세요.

UVM 자동화 매크로를 이용한 객체 비교

UVM 자동화 매크로는 copy, print 뿐만 아니라 compare 기능까지 자동으로 구현할 수 있도록 지원합니다. 아래 예제에서는 Packet 클래스와 Object 클래스를 정의하고, 각 클래스의 멤버 변수들을 자동화 매크로를 사용하여 등록합니다. 특히 `uvm_field_int 매크로를 사용하여 등록된 m_addr 변수는 print, copy, compare와 같은 기본 기능에 자동으로 포함됩니다. Object 클래스 내부에는 다른 데이터 타입의 변수들과 Packet 타입의 객체가 포함되어 있으며, 이들 또한 적절한 매크로 (예: `uvm_field_enum)를 통해 등록됩니다.

typedef enum {FALSE, TRUE} e_bool;
class Packet extends uvm_object;
  rand bit[15:0] 	m_addr;

  virtual function string convert2string();
    string contents;
    contents = $sformatf("m_addr=0x%0h", m_addr);
  endfunction

  `uvm_object_utils_begin(Packet)
  	`uvm_field_int(m_addr, UVM_DEFAULT)
  `uvm_object_utils_end

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

class Object extends uvm_object;
  rand e_bool 				m_bool;
  rand bit[3:0] 			m_mode;
  string 					m_name;
  rand Packet 				m_pkt;

  function new(string name = "Object");
    super.new(name);
    m_name = name;
    m_pkt = Packet::type_id::create("m_pkt");
    m_pkt.randomize();
  endfunction

  `uvm_object_utils_begin(Object)
  	`uvm_field_enum(e_bool, m_bool, UVM_DEFAULT)
  	`uvm_field_int (m_mode, 		UVM_DEFAULT)
  	`uvm_field_string(m_name, 		UVM_DEFAULT)
  	`uvm_field_object(m_pkt, 		UVM_DEFAULT)
  `uvm_object_utils_end
endclass

compare 메소드 활용

다음은 두 개의 Object 타입 객체를 생성하고 랜덤하게 값을 할당한 후, compare 메소드를 사용하여 두 객체가 동일한지 비교하는 예제입니다. 초기 비교 후에는 각 멤버 변수를 하나씩 복사하면서 비교 결과를 확인하여 compare 메소드의 동작 방식을 이해할 수 있도록 합니다.

class base_test extends uvm_test;
  `uvm_component_utils(base_test)
  function new(string name = "base_test", uvm_component parent=null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
  	// Create two objects, randomize them and print the contents
    Object obj1 = Object::type_id::create("obj1");
    Object obj2 = Object::type_id::create("obj2");
    obj1.randomize();
    obj1.print();
    obj2.randomize();
    obj2.print();

    _compare(obj1, obj2);

      `uvm_info("TEST", "Copy m_bool", UVM_LOW)
    obj2.m_bool = obj1.m_bool;
        `uvm_info("TEST", $sformatf("Obj2.print: %s", obj2.convert2string()), UVM_LOW)
    _compare(obj1, obj2);

      `uvm_info("TEST", "Copy m_mode", UVM_LOW)
    obj2.m_mode = obj1.m_mode;
        `uvm_info("TEST", $sformatf("Obj2.print: %s", obj2.convert2string()), UVM_LOW)
    _compare(obj1, obj2);

      `uvm_info("TEST", "Copy m_name", UVM_LOW)
    obj2.m_name = obj1.m_name;
        `uvm_info("TEST", $sformatf("Obj2.print: %s", obj2.convert2string()), UVM_LOW)
    _compare(obj1, obj2);

      `uvm_info("TEST", "Copy m_pkt.m_addr", UVM_LOW)
    obj2.m_pkt.m_addr = obj1.m_pkt.m_addr;
    	`uvm_info("TEST", $sformatf("Obj2.print: %s", obj2.convert2string()), UVM_LOW)
    _compare(obj1, obj2);
  endfunction

  function void _compare(Object obj1, Object obj2);
    if (obj2.compare(obj1))
      `uvm_info("TEST", "obj1 and obj2 are same", UVM_LOW)
    else
      `uvm_info("TEST", "obj1 and obj2 are different", UVM_LOW)
  endfunction
endclass

module tb;
	initial begin
		run_test("base_test");
	end
endmodule

build_phase 함수 내에서 두 개의 Object 객체 (obj1, obj2)를 생성하고 각각 랜덤화한 후 출력합니다. _compare 태스크는 두 객체를 인자로 받아 compare 메소드를 호출하여 비교 결과를 로깅합니다. 초기에는 랜덤화된 값이 다르므로 "obj1 and obj2 are different" 메시지가 출력될 것입니다. 그 후, 각 멤버 변수 (m_bool, m_mode, m_name, m_pkt.m_addr)를 obj1에서 obj2로 하나씩 복사할 때마다 compare 메소드를 호출하여 비교 결과를 확인합니다. 최종적으로 모든 멤버 변수가 복사되면 "obj1 and obj2 are same" 메시지가 출력되는 것을 확인할 수 있습니다.

결론

UVM 자동화 매크로와 compare 메소드를 함께 사용하면 객체의 모든 등록된 필드를 자동으로 비교하여 검증 환경에서 객체의 동일성을 효율적으로 확인할 수 있습니다. 특히 복잡한 데이터 구조를 가진 객체의 비교 로직을 직접 구현할 필요 없이 UVM 프레임워크의 기능을 활용함으로써 개발 시간을 단축하고 코드의 신뢰성을 높일 수 있습니다. SystemVerilog와 UVM을 처음 배우는 엔지니어라면 자동화 매크로를 적극적으로 활용하여 객체 비교 기능을 익히는 것이 중요합니다.

다음 이전

POST ADS 2