5 Essential Question

Seungyun Lee·2026년 5월 20일

UVM

목록 보기
11/11

Index

  1. CDC coherency
  2. AXI Deadlock
  3. Implicit vs Explicit Prediction
  4. Vacuous Assertions
  5. Constraint Bipolarity

Basic word

Metastability

Metastability in VLSI is a phenomenon where a flip-flop enters an unstable intermediate voltage state (neither stable '0' nor '1') due to setup or hold time violations

2FF Synchronizer

We use a 2-flop synchronizer to safely pass a 1-bit control signal across asynchronous clock domains.
If the input violates setup or hold time, the first flip-flop might enter a metastable state.
However, the one-clock-cycle delay between the two flops provides enough 'Resolution Time' for the signal to settle to a stable 0 or 1, which drastically improves the system's MTBF

Resolution Time: 2개의 플립플롭이 만들어내는 해결책 (시간 벌기)
MTBF: 신뢰성을 증명하는 결과 지표 (Mean Time Between Failures)


1. CDC Coherency

A. What is CDC Coherency?

CDC Coherency means ensuring that all bits of a multi-bit signal arrive and are sampled together when crossing clock domains

B. The Problem: Why Simple Synchronizers Fail

If we use simple synchronizers on a data bus, routing skew will cause 'Data Tearing,' meaning the receiving domain might sample invalid garbage values

  • Routing Skew: Inside the chip, the physical wires for each bit have slightly different lengths. Some bits travel faster, and some travel slower.

  • Asynchronous Sampling: Because clk_A and clk_B are not synchronized, clk_B might sample the data exactly while it is changing.

The Phantom State (Example):
If the data transitions from 4'b0000 to 4'b1111, clk_B might sample it right in the middle. Because of routing skew, it might read 4'b0011—a garbage value (phantom state) that was never actually sent. This causes critical system failures.

C. Industry Solutions (How to fix it)

To maintain coherency, we never synchronize the data directly. Instead, we use Asynchronous FIFOs, Gray code pointers, or Data-path handshakes.

Gray Code Encoding

Data is encoded so that only one bit changes at a time (e.g., 00 -> 01 -> 11). Because only a single bit is transitioning, you will never sample a garbage value. This is strictly used for Asynchronous FIFO Pointers.

Data-path Synchronization (Handshake)

Do not put synchronizers on the data bus itself. Instead, hold the multi-bit data steady so it is physically stable. Then, pass a single 1-bit Valid (or Enable) signal through a 2-flop synchronizer. The destination domain only reads the data when the Valid signal is safely received.

Asynchronous FIFO

For heavy, continuous traffic (like an AXI data payload), handshake is too slow. We use an Asynchronous FIFO, which safely transfers data using Dual-port RAM and Gray-coded read/write pointers.


2. AXI Deadlock

A. The Definition

An AXI deadlock is a critical bug where bus traffic permanently freezes due to a circular dependency(순환 의존성)

Basically, they wait for each other.
Master waits for READY, Slave waits for VALID. The bus just hangs with both signals stuck at zero

B. The Causes

  1. Usually, it's a protocol violation. The Master's VALID should never wait for the READY signal.

  2. On a larger SoC scale, it’s a structural issue. For example, a FIFO overflow freezes the interconnect

C. How to Catch It

To catch them in UVM environment, I need to implement SystemVerilog Assertions (SVA) to monitor handshake rules and build Watchdog Timers in the Monitor to detect transaction timeouts."


3. Implicit vs Explicit Prediction

when the RAL mirror goes stale

A. The Stale Mirror

A stale mirror happens when the UVM RAL database goes out of sync with the actual hardware registers.

RAL Mirror란 무엇인가?

UVM RAL 모델은 내부에 칩의 모든 레지스터 값을 복사해 둔 가상의 메모리 공간을 가집니다. 이를 Mirror (거울)라고 부릅니다.
검증 환경은 시뮬레이션 속도를 높이기 위해, 매번 AXI 버스를 타고 물리적 하드웨어(DUT)의 값을 읽어오는 대신 이 가상의 Mirror 값을 확인(get())하여 로직을 처리합니다.

문제 발생 (The Stale Mirror):

이 Mirror 값과 실제 DUT 하드웨어의 값이 달라지는 순간, 우리는 이것을 "Mirror goes stale(미러 값이 썩었다/유효하지 않다)"라고 표현합니다. 이때부터 테스트벤치는 엉뚱한 값을 바탕으로 채점을 하게 되어 시뮬레이션 전체가 망가집니다.

이 Mirror 값을 DUT와 똑같이 최신 상태로 갱신해 주는 작업이 바로 Prediction(예측)입니다.

B. Implicit vs. Explicit

In the industry, we never use Implicit Prediction because it blindly assumes a write was successful.
Instead, we strictly use Explicit Prediction. It uses the AXI Monitor and a Predictor to update the mirror only after verifying the physical bus transaction.

Implicit Prediction

UVM이 기본적으로 제공하는 가장 단순한 동기화 방식입니다.

동작 방식: 테스트벤치(Sequence)에서 reg.write(data) 명령을 내리는 바로 그 순간, UVM은 "내가 데이터를 썼으니까 하드웨어에도 당연히 그 값이 써졌겠지?"라고 스스로 가정하고 즉시 Mirror 값을 업데이트해 버립니다.

치명적인 단점 (현업에서 금지하는 이유):
만약 AXI 버스 중간에서 에러가 발생해서 하드웨어에 값이 제대로 써지지 않았다면 어떻게 될까요? 하드웨어는 이전 값을 유지하고 있는데, RAL Mirror는 이미 새 값으로 업데이트되어 버립니다. (Stale 상태 발생)
또한, 다른 마스터(예: 칩 내부의 다른 CPU)가 해당 레지스터를 건드리는 경우, UVM은 이를 전혀 눈치채지 못합니다.

Explicit Prediction (명시적 예측)

The Industry Standard
현업에서는 Implicit Prediction을 기능적으로 꺼버리고(set_auto_predict(0)), 무조건 Explicit Prediction을 아키텍처에 구현합니다.

동작 방식: Sequence가 reg.write()를 호출하더라도 Mirror 값은 절대 바뀌지 않습니다. 대신, 버스를 물리적으로 감시하는 Monitor가 활약합니다. Monitor가 AXI 버스에서 데이터가 정상적으로 전송되는 것을 확인(Valid/Ready Handshake)한 뒤, 그 내역을 uvm_reg_predictor라는 통역사 컴포넌트에게 보냅니다. 통역사가 이 내역을 분석하여 비로소 Mirror 값을 갱신합니다.

장점: 물리적 버스 트래픽을 100% 반영하므로, AXI 에러가 나거나 다른 마스터가 버스를 통해 값을 바꿀 때도 Mirror가 정확하게 동기화됩니다. "Trust but verify (믿지만 확인하라)" 철학입니다.

C. The Exception

"However, even Explicit Prediction cannot catch internal hardware changes, like a FIFO status register updating itself. For those, we must force a read or use backdoor access to update the mirror."
(하지만 Explicit Prediction조차도 FIFO 상태 레지스터가 스스로 업데이트되는 것 같은 내부 하드웨어 변화는 잡아낼 수 없습니다. 이런 경우엔 강제로 Read를 하거나 Backdoor 접근을 써서 미러를 갱신해야 합니다.)


SVA(SystemVerilog Assertions)에서 이 두 연산자는 전제 조건(A)이 만족되었을 때, 결과(B)를 언제부터 검사할 것인가(Timing)를 결정하는 단 하나의 물리적인 차이점만 가집니다.

|-> (Overlapping Implication / 겹치는 연산자)
전제 조건(A)이 참(True)이 된 바로 그 동일한 클럭 사이클(Same cycle)부터 결과(B)를 검사합니다.

|=> (Non-overlapping Implication / 겹치지 않는 연산자)
전제 조건(A)이 참이 되면, 그 클럭은 건너뛰고 다음 클럭 사이클(Next cycle)부터 결과(B)를 검사합니다.

A |=> B 는 A |-> ##1 B 와 100% 동일합니다.
A |-> ##1 B 해석: A가 발생한 그 순간(|->)을 기준으로 검사를 시작하되, 1클럭 지연(##1) 후에 B를 확인하라.

4.Vacuous Assertions

why a passing SVA might be hiding a bug

A. The Definition

"A vacuous pass happens when the antecedent of an implication operator is never triggered during the simulation."

(Vacuous(공허한) pass는 조건부 연산자의 전제 조건(ˌan(t)əˈsēd(ə)nt)이 시뮬레이션 동안 단 한 번도 트리거되지 않을 때 발생합니다.)

B. The Danger (왜 버그를 숨기는가)

"It is dangerous because it gives a false sense of security. The assertion reports zero errors, but in reality, the hardware logic was never actually tested because the stimulus was missing."

(이것은 가짜 안도감을 주기 때문에 위험합니다. Assertion은 에러가 없다고 보고하지만, 실제로는 자극(Stimulus)이 누락되어 하드웨어 로직이 아예 테스트조차 되지 않은 것입니다.)

C. The Solution

"To prevent this, I always pair my assertions with a cover property on the antecedent. We must verify the coverage report to ensure the scenario actually happened, rather than just trusting the assertion pass log."

(이를 막기 위해, 저는 항상 전제 조건에 대해 cover property를 쌍으로 작성합니다. 단순히 Assertion 성공 로그를 믿는 대신, 커버리지 리포트를 확인해서 해당 시나리오가 실제로 발생했는지 반드시 증명해야 합니다.)


5. Constraint Bipolarity

사실 현업 및 공식 스펙 문서에서는 Bipolarity(양극성)라는 단어보다는 Bidirectional Nature(양방향성)라는 용어를 훨씬 더 많이 사용합니다. 일반적인 C/C++ 소프트웨어 엔지니어들이 검증(DV)으로 넘어올 때 가장 많이 겪는 혼란이자 함정입니다.

C언어나 파이썬 같은 절차적 프로그래밍에 익숙한 사람들은 아래의 SystemVerilog 제약 조건(Constraint) 코드를 볼 때, 위에서 아래로 흐르는 순차적인 로직으로 착각합니다.

class my_packet;
  rand bit a; // 1-bit (0 or 1)
  rand bit b; // 1-bit (0 or 1)
  
  constraint c_logic {
    (a == 1) -> (b == 1);
  }
endclass

Constraint Bipolarity (양방향성)의 진짜 의미
SystemVerilog의 제약 조건은 왼쪽에서 오른쪽으로만 흐르지 않고, 오른쪽에서 왼쪽으로도(역방향으로도) 영향을 미칩니다. 이것이 바로 양방향성(Bipolarity/Bidirectional)입니다.

수식 (a == 1) -> (b == 1)은 명제 논리학의 대우(Contrapositive)에 의해 (b == 0) -> (a == 0)과 완벽하게 동일합니다.

즉, 제약 조건 해결기(Solver)는 a를 먼저 정하고 b를 정하는 것이 아닙니다. b를 먼저 0으로 뽑아버리고, 그 결과에 맞춰 강제로 a를 0으로 만들어버릴 수도 있습니다.

현업의 해결책:
이 역방향 간섭을 끊고 내가 원하는 대로 확률을 조절하기 위해 사용하는 키워드가 바로 solve ... before ... 입니다.

constraint c_order {
  solve a before b; 
  (a == 1) -> (b == 1);
}

동작 원리: "확률 공간을 계산할 때, b의 상태를 보지 말고 일단 무조건 a부터 50:50의 독립적인 확률로 뽑아라(Solve). 그 다음에 그 결과에 맞춰 b를 뽑아라."

주의할 점: 이 키워드는 변수에 값이 대입되는 '시간적 순서'를 바꾸는 것이 아닙니다. 오직 '확률의 분포(Probability Distribution)'를 강제하기 위해 사용됩니다.

A. Bidirectional Nature (양방향성의 정의)

"Unlike procedural code, SystemVerilog constraints are bidirectional. Variables on the right side of an expression can influence the variables on the left side."

(절차적 코드와 달리 SystemVerilog 제약 조건은 양방향입니다. 수식의 오른쪽에 있는 변수가 왼쪽에 있는 변수에 영향을 미칠 수 있습니다.)

B. The Problem (확률 왜곡)

"Because the solver evaluates all valid combinations simultaneously, the probability distribution of one variable can be skewed by the constraints of another."

(Solver가 모든 유효한 조합을 동시에 평가하기 때문에, 한 변수의 확률 분포가 다른 변수의 제약 조건에 의해 왜곡될 수 있습니다.)

C. The Solution (해결책)

"To fix this, we use the solve before construct. It does not change the valid state space, but it forces the solver to determine the probability of the first variable independently, fixing the skewed distribution."

(이를 해결하기 위해 solve before 구문을 사용합니다. 이는 유효한 상태 공간을 바꾸지는 않지만, Solver가 첫 번째 변수의 확률을 독립적으로 결정하도록 강제하여 왜곡된 분포를 바로잡습니다.)

profile
Design Verification engineer

0개의 댓글