지식 공유/UVM

[UVM 1.1d] 5-2. Register Model (Register Abstraction Layer)

긍수저 2024. 10. 15. 20:11
반응형

5-2. Register Model 구축 (Building a Register Model)

UVM의 Register Model은 하드웨어 설계에서 레지스터 맵을 추상화하여 검증 환경에서 관리하는 방법을 제공합니다. 이 모델은 레지스터와 필드의 객체를 생성하고, 이를 테스트벤치에서 사용할 수 있도록 조직화하는 데 중점을 둡니다.

Register Model을 구성하는 주요 컴포넌트:

  1. uvm_reg_block: 레지스터 모델에서 최상위 블록으로, 레지스터와 서브 블록을 포함하는 컨테이너 역할을 합니다.
  2. uvm_reg: 실제 레지스터를 나타내는 객체로, 레지스터 필드를 포함합니다.
  3. uvm_reg_field: 레지스터 내에서 특정 필드를 나타내며, 여러 필드가 모여 하나의 레지스터를 구성합니다.

Register Model 구축을 위한 주요 메서드

Register Model을 구축하기 위해서는 레지스터 블록, 레지스터, 필드를 생성하는 방법을 알아야 합니다. 아래는 이를 위한 주요 메서드입니다.

 

1. uvm_reg_block::create()

**uvm_reg_block**은 레지스터 모델의 최상위 블록을 생성하는 메서드입니다. 레지스터 모델 내에서 서브 블록이나 레지스터를 포함하는 컨테이너 역할을 하며, 계층 구조를 설정하는 데 필수적입니다.

예시 코드:

class my_reg_block extends uvm_reg_block;
  `uvm_object_utils(my_reg_block)

  function new(string name = "my_reg_block");
    super.new(name, UVM_NO_COVERAGE);
  endfunction

  // 레지스터 추가
  my_register reg1;
  my_register reg2;

  virtual function void build();
    this.default_map = create_map("default_map", 0, 4, UVM_LITTLE_ENDIAN, 1);
    
    reg1 = my_register::type_id::create("reg1", null, get_full_name());
    reg2 = my_register::type_id::create("reg2", null, get_full_name());

    reg1.configure(this);
    reg2.configure(this);

    // 레지스터 맵에 추가
    this.default_map.add_reg(reg1, 32'h0, "RW");
    this.default_map.add_reg(reg2, 32'h4, "RW");
  endfunction
endclass

 

2. uvm_reg::new()

각 레지스터는 uvm_reg 객체로 생성됩니다. uvm_reg는 필드를 포함하며, 이를 통해 레지스터의 특정 비트 범위를 정의할 수 있습니다. 필드의 크기, 읽기/쓰기 권한 등을 설정할 수 있습니다.

예시 코드:

class my_register extends uvm_reg;
  `uvm_object_utils(my_register)

  uvm_reg_field field;

  function new(string name = "my_register");
    super.new(name, 32, UVM_NO_COVERAGE);
  endfunction

  virtual function void build();
    field = uvm_reg_field::type_id::create("field", this);
    field.configure(this, 32, 0, "RW", 1, 0, 1, 1);
  endfunction
endclass

 

3. uvm_reg_field::configure()

레지스터 필드는 레지스터의 특정 비트를 정의합니다. uvm_reg_field 객체를 통해 레지스터의 필드를 설정하고, 해당 필드에 접근할 수 있습니다.

필드 구성 예시:

field.configure(this, 32, 0, "RW", 1, 0, 1, 1);
  • 32: 필드의 비트 크기
  • 0: 필드의 시작 위치
  • "RW": 읽기/쓰기 권한

5.5 Register Model을 환경에 통합하기 (Integrating the Register Model into an Environment)

Register Model을 구축한 후, 이를 UVM 환경에 통합하여 테스트벤치에서 사용할 수 있습니다. 이때, 레지스터 모델은 실제 설계와 상호작용하며, 검증 목표를 달성하기 위한 중요한 역할을 합니다.

1. Register Adapter

테스트 환경에서 Register Model을 사용할 때, **어댑터(adapter)**를 통해 레지스터 트랜잭션을 버스 트랜잭션으로 변환해야 합니다. 어댑터는 uvm_reg_adapter 클래스를 상속하여 정의할 수 있습니다.

예시 코드:

class my_reg_adapter extends uvm_reg_adapter;
  `uvm_object_utils(my_reg_adapter)

  virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
    my_bus_transaction trans;
    trans = my_bus_transaction::type_id::create("trans");
    trans.addr = rw.addr;
    trans.data = rw.data;
    return trans;
  endfunction
endclass

2. Environment 내 Register Model 설정

Register Model을 환경에 통합하는 과정에서는 uvm_env 클래스 내에서 레지스터 블록을 인스턴스화하고, 이를 통해 테스트 시나리오에서 사용할 수 있도록 설정합니다.

예시 코드:

class my_env extends uvm_env;
  my_reg_block reg_block;
  my_reg_adapter reg_adapter;

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

  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);

    reg_block = my_reg_block::type_id::create("reg_block", this);
    reg_block.build(); // 레지스터 모델 구축

    reg_adapter = my_reg_adapter::type_id::create("reg_adapter", this);
    reg_block.default_map.set_adapter(reg_adapter);
  endfunction
endclass

이 코드는 환경 내에서 레지스터 블록을 설정하고, 어댑터를 통해 레지스터 트랜잭션을 버스 트랜잭션으로 변환하여 사용합니다.


결론

5.4와 5.5에서는 UVM에서 Register Model을 구축하고, 이를 검증 환경에 통합하는 과정을 설명했습니다. 레지스터 블록, 레지스터, 필드를 생성하여 계층 구조를 구성한 후, 이를 어댑터를 통해 실제 하드웨어와 연결하는 방식으로 통합할 수 있습니다. 이를 통해 하드웨어 레지스터에 대한 복잡한 검증 작업을 보다 효율적으로 수행할 수 있습니다.

반응형