지노랩 /JinoLab

[UVM] 5.7.3 에일리어스 레지스터( Aliased Registers ) 본문

UVM(Universal Verification Methodology)/5. Register Layer Class 사용하기

[UVM] 5.7.3 에일리어스 레지스터( Aliased Registers )

지노랩/JinoLab 2025. 5. 15. 11:48

 

1 | 개념 - “에일리어스” vs. “공유(Shared)”

구분 설명 예시

Aliased 하나의 주소 맵에 두 개 이상의 주소가 똑같은 레지스터를 가리킴 0x0100 : RW, 0x0200 : RO
Shared 서로 다른 맵(AXI, APB 등)에서 같은 레지스터 접근 AXI 0x1000, APB 0x2000

2 | UVM에서 모델링해야 할 점

  1. 주소별로 서로 다른 접근 속성(필드 Access Policy) 를 표현해야 한다.
  2. 각 주소마다 고유한 uvm_reg 인스턴스가 필요하다.
  3. 두 인스턴스의 미러 값은 항상 동일해야 한다.

3 | 필드 Access 가 다른 예 – 코드 흐름

// ── (1) RW 속성으로 접근할 주소 0x0100
class my_reg_Ra extends uvm_reg;
  rand uvm_reg_field F1;
  virtual function void build();
    F1 = uvm_reg_field::type_id::create("F1");
    F1.configure(this, 8, 0, "RW", 0, 8'h0, 1,1,1);
  endfunction
  `uvm_object_utils(my_reg_Ra)
endclass

// ── (2) RO 속성으로 접근할 주소 0x0200
class my_reg_Rb extends uvm_reg;
  uvm_reg_field F1;
  virtual function void build();
    F1 = uvm_reg_field::type_id::create("F1");
    F1.configure(this, 8, 0, "RO", 0, 8'h0, 1,0,1);
  endfunction
  `uvm_object_utils(my_reg_Rb)
endclass

4 | 에일리어싱 연동 클래스(콜백 사용)

// Ra 로 쓰면 Rb 미러도 즉시 동일 값으로 예측
class write_also_to_F extends uvm_reg_cbs;
  uvm_reg_field m_tgt;
  function new(uvm_reg_field tgt); m_tgt = tgt; endfunction

  virtual function void post_predict(uvm_reg_field fld,
                                     uvm_reg_data_t val,
                                     uvm_predict_e  kind,
                                     uvm_path_e     path,
                                     uvm_reg_map    map);
    if (kind == UVM_PREDICT_WRITE)
      void'(m_tgt.predict(val, -1, UVM_PREDICT_WRITE, path, map));
  endfunction
endclass
// 두 레지스터를 묶는 alias 컨테이너
class alias_RaRb extends uvm_object;
  protected my_reg_Ra m_Ra;
  protected my_reg_Rb m_Rb;
  `uvm_object_utils(alias_RaRb)

  function void configure(my_reg_Ra Ra, my_reg_Rb Rb);
    m_Ra = Ra; m_Rb = Rb;
    write_also_to_F cb = new(Rb.F1);      // Ra→Rb 동기
    uvm_reg_field_cb::add(Ra.F1, cb);
  endfunction
endclass

5 | 블록 build() 예

class my_blk extends uvm_reg_block;
  rand my_reg_Ra Ra;
  rand my_reg_Rb Rb;

  virtual function void build();
    default_map = create_map("", 0, 4, UVM_BIG_ENDIAN);

    // ① 인스턴스 생성/구성
    Ra = my_reg_Ra::type_id::create("Ra", , get_full_name());
    Ra.configure(this, null);  Ra.build();
    Rb = my_reg_Rb::type_id::create("Rb", , get_full_name());
    Rb.configure(this, null);  Rb.build();

    // ② 주소 매핑
    default_map.add_reg(Ra, 'h0100);
    default_map.add_reg(Rb, 'h0200);

    // ③ 에일리어스 연결
    alias_RaRb al = alias_RaRb::type_id::create("RaRb");
    al.configure(Ra, Rb);
  endfunction
endclass

6 | 요약 팁

체크리스트 이유

주소별 동작이 다르면 레지스터 타입도 별도로 만든다. Access Policy 충돌 방지
콜백(post_predict 등)을 이용해두 인스턴스 미러를 동기화한다. 예측 불일치 방지
에일리어스 관리용 클래스를 uvm_object로 두고 configure()에서 링크 재사용·팩터리 가능
테스트벤치에서 어떤 주소로 접근할지 명확히 하기 위해, 인스턴스 이름을 Ra,Rb 처럼 구분 가독성 향상

공식 UVM에는 일반화된 에일리어스 클래스가 없으므로 – 설계별 필요에 맞춰 위와 같은 방식으로 직접 작성해야 합니다.

 

 


 

본 내용은
accellera에서 공개한
Universal Verification Methodology
(UVM) 1.2 User's Guide
를 바탕으로 작성된 글입니다.