지노랩 /JinoLab
[UVM] 5.5.3 레지스터 파일 타입(Register File Type) ― uvm_reg_file 확장으로 다층 레지스터군(배열·서브파일 포함)을 모델링하기 본문
UVM(Universal Verification Methodology)/5. Register Layer Class 사용하기
[UVM] 5.5.3 레지스터 파일 타입(Register File Type) ― uvm_reg_file 확장으로 다층 레지스터군(배열·서브파일 포함)을 모델링하기
지노랩/JinoLab 2025. 5. 8. 09:15
1 | 개념 & 규칙
항목 규칙 비고
| 클래스 1 개 = 레지스터 파일 1 종류 | 같은 구성·오프셋 규칙을 갖는 파일은 하나의 타입 클래스로 표현 | |
| 상속 | class MY_RF_TYPE extends uvm_reg_file; | |
| utils 매크로 | \uvm_object_utils(MY_RF_TYPE)` | |
| 유일 이름 | 패키지 범위에서 중복되지 않도록 Generator가 관리 |
2 | 프로퍼티 선언 – 등록(register)·서브 파일(register file)
class MY_RF_TYPE extends uvm_reg_file;
// 2.1 포함 레지스터
rand CFG_REG_T R_CFG; // 단일
rand STATUS_REG_T R_STAT[4]; // 배열
// 2.2 포함 레지스터 파일
rand CH_RF_TYPE CH[2]; // 채널별 서브 파일
endclass
- 대문자 또는 접두어로 내부 심볼과 충돌 방지
- 모든 프로퍼티 rand — 랜덤화·제약 가능
3 | 생성자(new)
function new(string name="MY_RF_TYPE");
super.new(name); // uvm_reg_file 는 폭/커버리지 인자 필요 X
endfunction
4 | build() 메서드
virtual function void build();
uvm_reg_block blk = get_block(); // 상위 블록 핸들
// 4.1 레지스터 인스턴스화
R_CFG = CFG_REG_T::type_id::create(
$sformatf("%s.R_CFG", get_name()),
null, blk.get_full_name());
R_CFG.configure(blk, this); // parent 블록·파일 지정
R_CFG.build();
foreach (R_STAT[i]) begin
R_STAT[i] = STATUS_REG_T::type_id::create(
$sformatf("%s.R_STAT[%0d]", get_name(), i),
null, blk.get_full_name());
R_STAT[i].configure(blk, this);
R_STAT[i].build();
end
// 4.2 서브 레지스터 파일
foreach (CH[i]) begin
CH[i] = CH_RF_TYPE::type_id::create(
$sformatf("%s.CH[%0d]", get_name(), i),
null, blk.get_full_name());
CH[i].configure(blk, this);
CH[i].build();
end
endfunction
5 | map() 메서드 – 주소 맵에 배치
virtual function void map(uvm_reg_map mp, uvm_reg_addr_t off);
// 레지스터: add_reg(인스턴스, base+offset, access, unmapped?)
mp.add_reg(R_CFG, off + 'h00, "RW", 0);
foreach (R_STAT[i])
mp.add_reg(R_STAT[i], off + ('h10 + i*4), "RO", 0);
// 서브 파일: 재귀 호출
foreach (CH[i])
CH[i].map(mp, off + ('h100 + i*'h80));
endfunction
- off 파라미터로 상위 파일/블록 기준 오프셋 전달
- 필요하면 add_hdl_path() 로 back-door 경로도 설정
6 | set_offset() (선택) – 런타임 주소 재배치
virtual function void set_offset(uvm_reg_map mp, uvm_reg_addr_t off);
R_CFG. set_offset(mp, off + 'h00);
foreach (R_STAT[i])
R_STAT[i].set_offset(mp, off + ('h10 + i*4));
foreach (CH[i])
CH[i].set_offset(mp, off + ('h100 + i*'h80));
endfunction
- 다른 맵(예: APB↔AXI) 에서 동적 오프셋 변경이 필요할 때 사용
7 | 교차 제약 예 (레지스터 간)
constraint CFG_STAT_LOCK {
// 예: CFG.MODE 가 3일 때 STAT.EN 은 0
R_CFG.MODE.value == 3 -> R_STAT[0].EN.value == 0;
}
- 제약 블록을 별도 이름으로 두어 필요 시 껐다 켤 수 있게
실무 요약 체크리스트
단계 작업
| ① 클래스 선언 | extends uvm_reg_file + utils 매크로 |
| ② 프로퍼티 | 포함 레지스터/서브파일을 rand 로 선언 |
| ③ new() | super.new(name) 호출 |
| ④ build() | create → configure(blk,this) → build() 반복 |
| ⑤ map() | add_reg, 서브파일 map() 재귀 호출 |
| ⑥ (옵션) set_offset() | 동적 맵 수정 필요 시 구현 |
| ⑦ (옵션) 제약·커버리지 | 파일 내부 교차 제약, covergroup 추가 |
자동 Generator는 스펙에서 주소·크기·배열 정보를 읽어 위 절차를 코드로 출력하면 됩니다.
본 내용은
accellera에서 공개한
Universal Verification Methodology
(UVM) 1.2 User's Guide
를 바탕으로 작성된 글입니다.
'UVM(Universal Verification Methodology) > 5. Register Layer Class 사용하기' 카테고리의 다른 글
| [UVM] 5.5.5 블록 타입(Block Type) ― uvm_reg_block 상속으로 IP 블록 전체를 모델링하기 (0) | 2025.05.09 |
|---|---|
| [UVM] 5.5.4 메모리 타입(Memory Type) ― uvm_mem 확장으로 RAM·FIFO 등을 모델링하기 (0) | 2025.05.08 |
| [UVM] 5.5.2 레지스터 타입(Register Type) ― uvm_reg를 상속해 “하나의 레지스터 클래스”를 만드는 방법 (0) | 2025.05.07 |
| [UVM] 5.5.1 필드 타입(Field Type) ― 레지스터 필드를 객체로 “정의·제약·확장”하는 방법 (0) | 2025.05.07 |
| [UVM] 5.5 레지스터 모델 생성 — “Generator 작성자를 위한 실전 절차” (0) | 2025.05.06 |