지노랩 /JinoLab

[UVM] 5.5.5 블록 타입(Block Type) ― uvm_reg_block 상속으로 IP 블록 전체를 모델링하기 본문

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

[UVM] 5.5.5 블록 타입(Block Type) ― uvm_reg_block 상속으로 IP 블록 전체를 모델링하기

지노랩/JinoLab 2025. 5. 9. 09:21

 

1 | 블록 타입의 역할

계층 클래스 설명

Block uvm_reg_block IP / 서브시스템 하나를 캡슐화. 여러 레지스터·레지스터 파일·메모리·서브-블록주소 맵 보유
RegFile uvm_reg_file 블록 안 하위 레지스터 그룹
Register uvm_reg 필드(비트) 집합
Memory uvm_mem 대용량 RAM·FIFO

2 | 기본 골격 & 필수 규칙

class MY_IP_BLK extends uvm_reg_block;
  `uvm_object_utils(MY_IP_BLK)

  // 2-1. 주소 맵
  uvm_reg_map    APB;
  uvm_reg_map    AXI;

  // 2-2. 포함 요소
  rand CTRL_REG_T       R_CTRL;
  rand STATUS_RF_TYPE   RF_STAT;
       BUF256x32_MEM    MEM_BUF;
  rand SUBSYS_BLK       SUB;     // 서브-블록
endclass
  • 대문자 이름 또는 접두어로 내부 심볼과 충돌 방지
  • 레지스터/레지스터 파일/서브-블록은 rand 속성, 메모리는 보통 non-rand

3 | 생성자(new)

function new(string name="MY_IP_BLK");
  super.new(.name(name),
            .has_coverage(UVM_NO_COVERAGE));  // 필요 시 변경
endfunction

4 | build() 메서드 핵심 순서

virtual function void build();

  //------------------------------------------------------------------
  // 4-1. 주소 맵 생성
  APB = create_map(.name("APB"), .base_addr('h0),
                   .n_bytes(4), .endian(UVM_LITTLE_ENDIAN));
  AXI = create_map("AXI", 'h8000, 4, UVM_LITTLE_ENDIAN);
  default_map = APB;      // 필수 지정
  //------------------------------------------------------------------

  //------------------------------------------------------------------
  // 4-2. 레지스터 / 레지스터 파일 / 메모리 / 서브-블록 인스턴스
  R_CTRL = CTRL_REG_T     ::type_id::create("R_CTRL",  null, get_full_name());
  R_CTRL.configure(this);          R_CTRL.build();
  APB.add_reg(R_CTRL, 'h00, "RW", 0);

  RF_STAT = STATUS_RF_TYPE::type_id::create("RF_STAT", null, get_full_name());
  RF_STAT.configure(this);         RF_STAT.build();
  RF_STAT.map(APB, 'h100);

  MEM_BUF = BUF256x32_MEM ::type_id::create("MEM_BUF", null, get_full_name());
  MEM_BUF.configure(this);
  APB.add_mem(MEM_BUF, 'h400, "RW", 0);

  SUB = SUBSYS_BLK::type_id::create("SUB", null, get_full_name());
  SUB.configure(this);             SUB.build();
  // 서브-블록의 default_map 을 상위 맵에 삽입
  APB.add_submap(SUB.default_map, 'h800);
  //------------------------------------------------------------------
endfunction

포인트

  • create_map → 한 블록에 여러 주소 맵 지원 가능
  • 인스턴스화 순서: create → configure(블록 부모=this) → build()
  • 주소 배치: 레지스터/메모리 add_*, 레지스터 파일 map, 서브-블록 add_submap

5 | (선택) set_offset() — 런타임 오프셋 재배치

virtual function void set_offset(uvm_reg_map mp, uvm_reg_addr_t off);
  R_CTRL .set_offset(mp, off + 'h00);
  RF_STAT.set_offset(mp, off + 'h100);
  MEM_BUF.set_offset(mp, off + 'h400);
  SUB    .set_offset(mp, off + 'h800);
endfunction

6 | 블록-레벨 커버리지(옵션)

covergroup cg_vals;
  cp_mode : coverpoint R_CTRL.MODE.value;
  cp_stat : coverpoint RF_STAT.ST0.FLAGS.value;
  cross cp_mode, cp_stat;
endgroup

function new(string name="MY_IP_BLK");
  super.new(name, build_coverage(UVM_CVR_FIELD_VALS));
  if (has_coverage(UVM_CVR_FIELD_VALS))
    cg_vals = new();
endfunction

virtual function void sample_values();
  super.sample_values();
  if (get_coverage(UVM_CVR_FIELD_VALS))
    cg_vals.sample();
endfunction

7 | 실무 체크리스트 (Generator Writer)

단계 해야 할 일

주소 맵 정의 최소 1개, default_map 필드에 지정
객체 create/configure/build get_full_name() 컨텍스트, parent block – this
맵 추가 add_reg / add_mem / add_submap & 레지스터 파일 map()
HDL 경로(back-door) 필요 시 add_hdl_path[_slice]()
⑤ (옵션) 커버리지 등록 build_coverage() → has_coverage() 체크 후 covergroup 생성
제약 블록 내 필드 cross 제약은 별도 constraint 블록에 배치


 

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