AXI4 UVM (5) — 네 파일의 관계

Seungyun Lee·2026년 7월 30일

AXI4_UVM_FULL

목록 보기
8/16

시리즈 마무리: 아이템 · 인터페이스 · 드라이버 · 모니터가 어떻게 맞물리나


네 파일의 관계

                    axi4_seq_item (아이템)
              "AXI 버스트 하나"의 공통 표현
         ┌──────────────────────────────────────┐
         │ Sequence가 randomize → Driver가 구동  │
         │ Monitor가 재조립 → Scoreboard가 비교  │
         └──────────────────────────────────────┘
                          ▲   ▲
          같은 객체 타입을 │   │ 공유
                          │   │
┌────────────────────────────────────────────────────────┐
│                     axi4_if.sv                          │
│   master_cb (드라이브)      monitor_cb (샘플)           │
│   #1step / #1               #1step only                 │
└──────────┬────────────────────────┬────────────────────┘
           │ vif.master_cb          │ vif.monitor_cb
    ┌──────▼──────┐          ┌──────▼─────┐
    │ axi4_driver │          │axi4_monitor│
    │             │          │            │
    │ 큐: 보낼 것 │          │ 큐: 본 것  │
    │ aw_q,w_q,   │          │ aw_q,      │
    │ ar_q        │          │ w_done_q,  │
    │             │          │ ar_q       │
    │ pop → 구동  │          │ [0]참조→채움│
    │ item_done() │          │ ap.write() │
    │  즉시!      │          │            │
    └──────┬──────┘          └─────┬──────┘
           │                        │
           │   axi4_seq_item        ▼
           └───────┬─────────→ Scoreboard
                              (do_compare로 판정)
flowchart LR
    ITEM["axi4_seq_item<br/>(아이템)<br/>버스트 1개 표현"]

    SEQ["Sequence"] -->|randomize| ITEM
    ITEM -->|beat_addr 공유| REF["Reference Model"]
    ITEM --> DRV["axi4_driver"]
    IF["axi4_if<br/>(clocking block)"] -.master_cb.-> DRV
    IF -.monitor_cb.-> MON["axi4_monitor"]
    DRV -->|핀 구동| BUS["AXI 버스"]
    BUS -->|핀 관찰| MON
    MON -->|재조립한 아이템| SB["Scoreboard"]
    REF -->|예측한 아이템| SB
    SB -->|do_compare| RESULT["pass / fail"]

역할 대비표

axi4_seq_itemaxi4_ifaxi4_driveraxi4_monitor
역할버스트 1개 표현 + 합법성 규칙신호 + 타이밍 규칙 정의큐 → 버스 (구동)버스 → 큐 (관찰)
핵심 자산constraint, beat_addr()master_cb, monitor_cb6개 스레드5개 스레드
Clocking Block둘 다 제공master_cb 사용monitor_cb 사용
큐/데이터동적 배열 data[], strb[]pop_front() 후 구동[0] 참조하며 채움
핵심 트릭post_randomize 마스킹#1step race 방지item_done() 즉시[0]을 pop 없이 참조
검증 관여비교 기준 제공 (do_compare)없음없음 (구동만)발행만 (판정은 SB)

파라미터 일관성

아이템:     AXI_DATA_WIDTH, AXI_ADDR_WIDTH, AXI_STRB_WIDTH (패키지)
인터페이스: DATA_WIDTH=32, ADDR_WIDTH=16, STRB_WIDTH=4

이 둘이 다르면:
  seq_item.data는 64비트인데 vif.wdata는 32비트
  → 상위 비트 잘림 → 조용한 데이터 손실!

해결: package의 파라미터를 인터페이스 default로 사용해 단일 소스화

네 파일이 함께 만드는 이슈

아이템 규칙: WRAP은 len {1,3,7,15}, 4KB 경계 준수 (constraint)
드라이버:    beat_addr()로 WRAP 주소 계산해 구동
      +
드라이버 이슈: W가 AW보다 먼저 나갈 수 있음 (채널 독립)
      +
모니터 가정: AW를 먼저 봤다고 가정 (aw_q[0]에 채움)
      ↓
특정 backpressure 패턴에서 모니터가 W beat를 놓침!

→ 둘 중 하나를 고쳐야 함
   (드라이버: AW 핸드셰이크 후 w_q push / 모니터: W 버퍼링)

부록: 레쥬메 표현 예시

Item (seq_item):

Encoded AXI4 protocol legality (4KB boundary, size/address alignment, WRAP beat-count
rules) directly into SystemVerilog constraints, and implemented burst-accurate address
prediction shared by driver and reference model — exposing a DUT bug where WRAP bursts
incremented linearly.

Interface:

Designed a parameterized AXI4 SystemVerilog interface with separate driver/monitor
clocking blocks (sample/drive skews) and direction-enforcing modports, eliminating
clock-edge race conditions at compile time.

Driver:

Built a pipelined AXI4 master driver with per-channel threads and configurable
outstanding depth, instrumented with peak-concurrency counters that quantitatively
prove multi-outstanding traffic reached the DUT — the same driver degrades to
strictly serialized behavior against single-outstanding slaves without code changes.

Monitor:

Architected an outstanding-aware, channel-parallel AXI4 monitor using per-phase FIFO
correlation, preventing transaction loss under multi-outstanding traffic.


인터뷰 대비 예상 질문

  1. 왜 clocking block을 두 개 만들었나?
    마스터는 드라이브+샘플이 섞여있고 모니터는 순수 샘플만 해야 하는데,
    하나의 CB로는 두 역할의 방향을 동시에 표현할 수 없어서.

  2. blocking 드라이버와 pipelined 드라이버의 차이는?
    item_done()을 언제 부르냐. 즉시 부르면 시퀀스가 버스보다 앞서 달려
    Outstanding이 생김.

  3. wr_peak 카운터는 왜 필요한가?
    Outstanding 미지원 슬레이브는 이 값을 1 이상 못 올림.
    따라서 이 카운터가 "파이프라인이 실제로 동작했다"는 증거.

  4. 모니터가 aw_q[0]을 pop하지 않고 참조만 하는 이유는?
    Handle 복사로 큐 안 객체를 직접 채우기 위해. WLAST에서야 pop.

  5. W가 AW보다 먼저 나가면 무슨 일이 생기나?
    AXI상 합법이지만 이 모니터는 AW를 먼저 봤다고 가정 → beat 유실 가능.

  6. 시퀀스가 seq_item을 재사용하면 왜 위험한가?
    파이프라인 드라이버는 큐에 Handle을 저장 → 원본 재랜덤화 시 큐 내용도 변경.
    Deep copy 또는 매번 create로 방지.

  7. do_compare에서 == 대신 ===를 쓰는 이유는?
    ==는 2-state라 X/Z가 있으면 결과가 X(불확실). ===는 4-state로 X까지 정확히
    비교 → DUT가 X를 뱉는 버그를 명확히 불일치로 잡음.

  8. WRAP 버스트를 어떻게 검증했나?
    beat_addr()가 정확한 WRAP window 계산을 하고, DUT는 WRAP을 INCR처럼 선형
    증가시키는 버그가 있어 스코어보드에서 미스매치로 포착됨.

profile
Design Verification engineer

0개의 댓글