지노랩 /JinoLab

[UVM] 5.9.1 트랜잭션 어댑터(Transaction Adapter) 본문

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

[UVM] 5.9.1 트랜잭션 어댑터(Transaction Adapter)

지노랩/JinoLab 2025. 5. 18. 09:00

 

1 | 왜 어댑터가 필요할까?

  • 레지스터 모델 내부는 표준 구조체 uvm_reg_bus_op 로 모든 버스 RW를 표현
  • typedef struct { uvm_access_e kind; // UVM_READ / UVM_WRITE bit [ADDR_W-1:0] addr; bit [DATA_W-1:0] data; uvm_status_e status; } uvm_reg_bus_op;
  • 실제 버스(UVC)는 프로토콜-전용 sequence_item(예: apb_rw, axi_rw)에 맞춰 동작

uvm_reg_adapter 를 상속한 어댑터 클래스가 두 형식을 상호 변환해 준다.


2 | 어댑터 클래스 작성 핵심

class reg2apb_adapter extends uvm_reg_adapter;
  `uvm_object_utils(reg2apb_adapter)

  function new(string name="reg2apb_adapter");
    super.new(name);

    // (선택) 버스 특성 표기
    supports_byte_enables = 0;   // APB = false
    provides_responses    = 1;   // read 결과가 별도 response 로 옴
  endfunction

  // ────────────── Reg → Bus ──────────────
  virtual function uvm_sequence_item
            reg2bus(const ref uvm_reg_bus_op rw);
    apb_rw tx = apb_rw::type_id::create("apb_rw");
    tx.kind = (rw.kind == UVM_READ) ? apb_rw::READ
                                    : apb_rw::WRITE;
    tx.addr = rw.addr;
    tx.data = rw.data;
    return tx;
  endfunction

  // ────────────── Bus → Reg ──────────────
  virtual function void bus2reg(uvm_sequence_item bus_item,
                                ref uvm_reg_bus_op rw);
    apb_rw tx;
    if (!$cast(tx, bus_item))
      `uvm_fatal("NOT_APB_TYPE", "bus_item 타입이 apb_rw 아님");
    rw.kind   = (tx.kind == apb_rw::READ) ? UVM_READ : UVM_WRITE;
    rw.addr   = tx.addr;
    rw.data   = tx.data;
    rw.status = UVM_IS_OK;       // 에러 처리 필요 시 수정
  endfunction
endclass

속성 의미

supports_byte_enables 프로토콜이 바이트-이네이블 지원 여부 (AXI = 1, APB = 0)
provides_responses 드라이버가 read 결과·에러를 별도 response 아이템으로 돌려주는지 (AXI, AHB OK)

3 | 환경에서 어댑터 연결 (root block만)

class block_env extends uvm_env;
  block_reg_model regmodel;
  apb_agent       apb;

  virtual function void connect_phase(uvm_phase phase);
    // 루트 모델인지 확인
    if (regmodel.get_parent() == null) begin

      // (1) 어댑터 생성
      reg2apb_adapter adp = reg2apb_adapter::type_id::create
                               ("reg2apb", this);

      // (2) RAL ↔ Sequencer 연결
      regmodel.default_map.set_sequencer(apb.sequencer, adp);

      // (3) Explicit mode일 경우 predictor 연결 등 추가
    end
  endfunction
endclass
  • Implicit prediction: 위 코드만으로도 OK
  • Explicit / Passive 모드라면 uvm_reg_predictor + 모니터 analysis 포트 연결을 추가

4 | 실무 팁

팁 이유

어댑터는 버스 UVC 라이브러리(package) 안에 포함하기 어떤 디자인-별 RAL이 와도 재사용 가능
여러 맵(APB, AHB…) 사용 시 맵마다 xxx_adapter 를 만들어 set_sequencer() 호출
byte enable 지원 버스라면 어댑터 내부에서 rw.byte_en 필드를 tx에 매핑해야 함
Read response 분리 버스(AXI) 드라이버가 response 채널에서 반환 → provides_responses=1 + bus2reg() 에서 resp 아이템 캐스팅


 

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