⚡ CDC와 Clock Gating 완벽 가이드

CDC와 Clock Gating 완벽 가이드: SoC 설계의 핵심 난제 정복하기

⚡ CDC와 Clock Gating 완벽 가이드

SoC 설계의 핵심 난제 — Metastability를 정복하고 전력을 최적화하는 방법

현대 SoC는 CPU(3GHz), Memory Controller(800MHz), Peripheral(100MHz) 등 서로 다른 속도로 뛰는 여러 개의 심장(Clock)을 가지고 있습니다. 이들 사이에서 데이터를 안전하게 전달하는 것이 CDC(Clock Domain Crossing)이고, 쉬는 시간에 심장을 멈춰 전력을 아끼는 것이 Clock Gating입니다. 이 글에서 두 기술의 모든 것을 다룹니다.

PART 1: Clock Domain Crossing (CDC)

🌊 1. CDC란 무엇인가?

Clock Domain Crossing(CDC)이란 한 클럭 도메인(Source)에서 생성된 신호가 위상(Phase)이나 주파수(Frequency)가 다른 또 다른 클럭 도메인(Destination)으로 전달되는 현상입니다.

📌 CDC가 발생하는 이유

• 서로 다른 PLL/Clock Source에서 생성된 클럭들
• 같은 소스지만 분주(Divide)되어 주파수가 다른 클럭
• 위상 관계를 알 수 없는 비동기(Asynchronous) 클럭
• 외부 인터페이스 (PCIe, USB, Ethernet 등)와의 연결

📊 CDC 발생 상황 ┌─────────────────┐ ┌─────────────────┐ │ Clock Domain A │ │ Clock Domain B │ │ (500MHz) │ │ (333MHz) │ │ │ │ │ │ ┌───┐ │ CDC │ ┌───┐ │ │ │ FF├──────────┼────────►├──────────┤ FF│ │ │ └───┘ │ Signal │ └───┘ │ │ ▲ │ │ ▲ │ │ │ │ │ │ │ │ CLK_A │ │ CLK_B │ └─────────────────┘ └─────────────────┘ → CLK_A와 CLK_B는 서로 독립적 (비동기) → Signal이 CLK_B 도메인으로 넘어갈 때 문제 발생!

💀 2. Metastability의 위험

CDC의 가장 무서운 적은 Metastability(메타스테이빌리티)입니다.

Metastability란?

Flip-Flop은 데이터가 클럭 Edge 전에 미리 도착해서(Setup Time), 일정 시간 유지되어야(Hold Time) 정상 동작합니다. 하지만 비동기 클럭 간에는 Edge 타이밍을 예측할 수 없습니다.

🚨 Metastability 발생 조건

Source 데이터가 변하는 바로 그 순간에 Destination 클럭의 Edge가 도착하면, Flip-Flop의 출력은 0도 1도 아닌 중간 전압 상태에서 불안정하게 진동합니다.

📊 Metastability 발생 타이밍 CLK_B ────┐ ┌────┐ ┌────┐ ┌──── │ │ │ │ │ │ └──┘ └──┘ └──┘ Capture Edge DATA ────────X────────────────── Data 변화 중! (Setup/Hold 위반) FF Output────────???───────────────── Metastable! (0도 1도 아닌 상태) → 출력이 언제 0/1로 안정화될지 예측 불가 → 뒷단 로직에 엉뚱한 값 전달 가능

Metastability의 결과

문제 설명 심각도
데이터 오염 불확실한 값이 뒷단 로직으로 전파 치명적
분기 오류 같은 신호를 다른 경로에서 다르게 해석 치명적
시스템 Hang FSM이 잘못된 상태로 진입, Deadlock 치명적
데이터 손실 Fast→Slow 도메인에서 데이터 누락 심각
간헐적 오류 재현 불가능한 랜덤 오동작 디버깅 난이도 극상

🔍 3. CDC 검출 및 검증

CDC 문제는 시뮬레이션에서 거의 발견되지 않습니다. 칩을 구워봐야 나타나는 경우가 많아, 전용 툴을 사용한 정적 분석이 필수입니다.

CDC 검증 플로우

RTL 코딩 CDC Lint CDC 정적분석 Formal CDC 합성/STA

주요 CDC 검증 툴

벤더 특징
SpyGlass CDC Synopsys 가장 널리 사용, 구조적 분석 강점
Questa CDC Siemens EDA Formal 검증 통합, 시뮬레이션 연계
Meridian CDC Cadence 대용량 설계, 자동 수정 제안
VC SpyGlass Synopsys 통합 Lint + CDC + DFT

검출되는 CDC 이슈 유형

⚠️ 주요 CDC Violation 유형

• No Synchronizer: 동기화 회로 없이 직접 연결
• Combo Logic in CDC: 동기화 전 조합 논리 존재
• Multi-bit CDC: 버스 신호를 개별 동기화
• Reconvergence: 동기화 후 다시 합쳐지는 신호
• FIFO Depth: 비동기 FIFO 깊이 부족

📝 4. SDC/SGDC로 예외 처리

모든 CDC 경로에 하드웨어 동기화가 필요한 것은 아닙니다. 특정 상황에서는 제약 조건(Constraints)으로 검사를 면제할 수 있습니다.

SDC (Synopsys Design Constraints)

📄 SDC: 비동기 클럭 그룹 설정
# 비동기 클럭 그룹 선언 # 서로 다른 그룹 간에는 타이밍 분석 제외 set_clock_groups -asynchronous \ -group [get_clocks clk_cpu] \ -group [get_clocks clk_peri] \ -group [get_clocks clk_ddr]
📄 SDC: False Path 설정
# 특정 CDC 경로를 타이밍 분석에서 제외 set_false_path \ -from [get_clocks clk_a] \ -to [get_clocks clk_b] # 양방향 모두 설정 set_false_path \ -from [get_clocks clk_b] \ -to [get_clocks clk_a]

SGDC (SpyGlass Design Constraints)

📄 SGDC: CDC 전용 제약
# SpyGlass CDC 툴 전용 제약 파일 # Quasi-static 신호 선언 (부팅 후 고정) cdc_false_path -from [get_pins u_config/mode_reg*/Q] # 특정 동기화 회로 인정 cdc_synchronizer -type custom \ -from u_sync/din \ -to u_sync/dout_sync2 # Gray Code FIFO 포인터 인정 cdc_false_path -through [get_nets *gray_ptr*]

예외 처리가 유효한 경우

상황 설명 처리 방법
Quasi-Static 부팅 시 한 번 설정, 동작 중 불변 cdc_false_path
Reset Signal 별도 Reset Synchronizer 존재 set_false_path
Test Mode 스캔 테스트 전용 신호 set_false_path
MUX Select 클럭 선택 후 안정화 시간 확보 set_max_delay
🚨 경고: 무분별한 False Path 금지!

Quasi-static이 아닌 동적 신호에 False Path를 설정하면 실제 CDC 문제가 숨겨집니다. 칩을 구워봐야 발견되는 최악의 버그가 됩니다!

🔧 5. 하드웨어 해결책 (H/W Solution)

실시간으로 변하는 데이터는 반드시 동기화 회로(Synchronizer)를 통해 CDC를 해결해야 합니다.

1-bit Signal: 2-FF Synchronizer

가장 기본적인 CDC 해결책입니다. Destination 클럭으로 동작하는 Flip-Flop 2개를 직렬 연결합니다.

📊 2-FF Synchronizer 구조 CLK_A Domain CLK_B Domain ┌───┐ ┌───┐ ┌───┐ D ──┤ FF├───────────────────┤FF1├────┤FF2├──► Q_sync └─┬─┘ └─┬─┘ └─┬─┘ │ │ │ CLK_A CLK_B CLK_B │ │ Meta Clean 가능 출력 → FF1에서 Metastability 발생 가능 → 1 클럭 동안 안정화 시간 확보 → FF2에는 깨끗한 0/1 전달

MTBF (Mean Time Between Failure)

동기화 회로의 신뢰도는 MTBF로 측정합니다.

📐 MTBF 계산 공식

MTBF = e(tr/τ) / (T0 × fclk × fdata)

tr: Resolution time (안정화 허용 시간) = 클럭 주기
τ: Metastability time constant (공정 의존)
T0: Metastability window (공정 의존)
fclk: 클럭 주파수
fdata: 데이터 변화 주파수

동기화 단계 일반적인 MTBF 적용 상황
2-FF 수백~수천 년 대부분의 상용 설계
3-FF 수백만 년 이상 고신뢰성 (항공, 의료)
4-FF 천문학적 수치 극한 신뢰성 요구

Reset Synchronizer

비동기 리셋 신호도 CDC 처리가 필요합니다. Assert는 비동기, Deassert는 동기 방식을 사용합니다.

📊 Reset Synchronizer (Async Assert, Sync Deassert) ┌───┐ ┌───┐ rst_n ─────────┬─────────────┤FF1├────┤FF2├──► rst_sync_n │ └─┬─┘ └─┬─┘ │ │ │ │ PREPRE │ └───────────────┴────────┘ │ CLK_B → rst_n=0: 즉시 FF1, FF2 출력 = 0 (비동기 Assert) → rst_n=1: CLK_B에 동기화되어 순차적으로 해제 (동기 Deassert)

🔄 6. Async FIFO와 Gray Code

Multi-bit 데이터를 넘길 때는 개별 2-FF 동기화가 절대 안 됩니다. 각 비트의 도착 시간이 달라 데이터가 깨집니다.

❌ 잘못된 방법

32-bit 버스를 각각 2-FF 동기화
→ 비트마다 Skew 발생
→ 데이터 오염 (Data Incoherency)

✅ 올바른 방법

Handshake Protocol
Async FIFO + Gray Code
DMUX Synchronizer

Async FIFO 구조

📊 Asynchronous FIFO 구조 Write Domain (CLK_W) Read Domain (CLK_R) wdata──┐ ┌──►rdata │ ┌─────────────────────┐ │ └────►│ │─────────┘ │ Dual-Port RAMwaddr───────►│ │◄─────────raddr └─────────────────────┘ ┌─────┐ ┌─────┐ │Write│ ┌───────────────────┐ │Read │ │Ptr │───►│ Gray Code 변환 │───CDC──►│Ptr │ │ │◄───│ + 2-FF Sync │◄───CDC───│Sync │ └─────┘ └───────────────────┘ └─────┘ │ │ wfull rempty → Write/Read 포인터만 CDC를 통해 동기화 → 데이터 자체는 RAM을 통해 안전하게 전달

Gray Code의 원리

Gray Code는 인접한 값 사이에 1비트만 변화하는 인코딩 방식입니다.

10진수 Binary Gray Code 변화 비트
0 000 000 -
1 001 001 1개
2 010 011 1개
3 011 010 1개
4 100 110 1개
5 101 111 1개
6 110 101 1개
7 111 100 1개
💡 Gray Code의 CDC 장점

• 한 번에 1비트만 변화 → Metastability가 발생해도 포인터가 최대 1만 틀림
• Binary에서 여러 비트가 동시에 변하면 → 포인터가 완전히 엉뚱한 값이 될 수 있음
• Gray Code 에러 → FIFO가 "약간 덜 찼다" 또는 "약간 덜 비었다"로 인식 (안전한 방향)

PART 2: Clock Gating

⚡ 7. Clock Gating의 원리

Clock Gating은 동작하지 않는 로직의 클럭을 차단하여 Dynamic Power를 절감하는 기술입니다.

왜 Clock Gating이 필요한가?

📐 동적 전력 소모 공식

Pdynamic = α × C × V2 × f

α: Switching activity (스위칭 확률)
C: Capacitance (부하 용량)
V: Supply voltage (공급 전압)
f: Clock frequency (클럭 주파수)

→ 클럭이 멈추면 f = 0 → 동적 전력 = 0!

SoC에서 클럭 네트워크가 전체 전력의 30~50%를 소비합니다. 유휴 상태에서 클럭을 차단하면 막대한 전력 절감이 가능합니다.

Clock Gating의 기본 개념

📊 Clock Gating 기본 개념 # Enable = 1: 클럭 전달 CLK ──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │ │ │ │ │ └──┘ └──┘ └──┘ └──┘ Enable ────────────────────────── (High) GCLK ──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │ │ │ │ │ └──┘ └──┘ └──┘ └──┘ # Enable = 0: 클럭 차단 CLK ──┐ ┌──┐ ┌──┐ ┌──┐ │ │ │ │ │ │ │ └──┘ └──┘ └──┘ └──┘ Enable __________________________ (Low) GCLK __________________________ (정지)

🔒 8. ICG Cell의 필요성

단순히 assign gclk = clk & enable;로 구현하면 심각한 문제가 발생합니다.

Glitch 문제

📊 단순 AND Gate의 Glitch 문제 CLK ────┐ ┌──────┐ ┌── │ │ │ │ └──────┘ └──────┘ Enable ────────────────────────── (CLK High 중 변화!) GCLK ────┐ ┌┐ │ ││ └──────┘ Glitch! (수염 펄스) → 이 Glitch가 FF를 잘못 트리거! → Setup/Hold Violation 유발!
🚨 Glitch의 위험성

• Flip-Flop이 두 번 트리거될 수 있음
Setup/Hold Violation 발생
• 데이터 오염, 시스템 오동작
• 시뮬레이션에서 발견 어려움!

ICG (Integrated Clock Gating) Cell 구조

ICG는 Latch + AND Gate 조합으로 Glitch-free 동작을 보장합니다.

📊 ICG Cell 내부 구조 ┌─────────────────────────┐ │ ICG Cell │ │ │ Enable ────────────►│ ┌───────┐ │ │ │ Latch │ ┌─────┐ │ │ │ ├───►│ AND ├───┼──► GCLK CLK ───────────────►│ │ EN │ │ │ │ │ │ └───┬───┘ └──┬──┘ │ │ │ │ │ │ │ │ │ CLK────┘ │ │ │ │ │ └───────┼─────┘ │ (CLK Low일 때 │ │ Latch Open) │ │ └─────────────────────────┘ 동작 원리: 1. CLK = Low → Latch가 열려서 Enable 값 받아들임 2. CLK = High → Latch가 닫혀서 Enable 값 고정 (유지) 3. 결과: Enable이 CLK High 중에 변해도 GCLK에 영향 없음!

ICG Cell 타이밍

📊 ICG Cell Glitch-Free 동작 CLK ────┐ ┌──────┐ ┌──────┐ │ │ │ │ │ └──────┘ └──────┘ └── Enable ──────────────────────────────── Latch Latch Latch Open Closed Open (무시됨) (반영) Latch Q ───────────────────────────────── (안전하게 Low 전환) GCLK ────┐ ┌──────┐ ┌──────── │ │ │ │ └──────┘ └──────┘ 깨끗하게 차단! → CLK High 중 Enable 변화는 무시됨 → 다음 CLK Low에서 안전하게 반영 → Glitch 없는 깨끗한 클럭!

❌ 단순 AND Gate

assign gclk = clk & en;

• Glitch 발생 가능
• 타이밍 분석 어려움
• DFT 삽입 불가
• 툴이 최적화 못함

✅ ICG Cell 사용

Library의 표준 셀 사용

• Glitch-free 보장
• 정확한 타이밍 모델
• DFT (Scan) 지원
• 면적/전력 최적화

💻 9. 실전 RTL 코드

2-FF Synchronizer (Verilog)

📄 Verilog: 2-FF Synchronizer
// 2-FF Synchronizer for 1-bit CDC module sync_2ff ( input wire clk_dst, // Destination clock input wire rst_n, // Active-low reset input wire din, // Async input (from source domain) output wire dout_sync // Synchronized output ); // Metastability 방지를 위한 속성 // synthesis를 통해 이 레지스터들이 최적화되지 않도록 함 (* ASYNC_REG = "TRUE" *) reg sync_ff1; (* ASYNC_REG = "TRUE" *) reg sync_ff2; always @(posedge clk_dst or negedge rst_n) begin if (!rst_n) begin sync_ff1 <= 1'b0; sync_ff2 <= 1'b0; end else begin sync_ff1 <= din; // 1st stage (may go metastable) sync_ff2 <= sync_ff1; // 2nd stage (clean output) end end assign dout_sync = sync_ff2; endmodule

Reset Synchronizer (Verilog)

📄 Verilog: Reset Synchronizer (Async Assert, Sync Deassert)
// Reset Synchronizer // Async Assert (즉시 리셋), Sync Deassert (동기 해제) module reset_sync ( input wire clk, input wire rst_async_n, // Async reset input output wire rst_sync_n // Sync reset output ); (* ASYNC_REG = "TRUE" *) reg rst_ff1; (* ASYNC_REG = "TRUE" *) reg rst_ff2; always @(posedge clk or negedge rst_async_n) begin if (!rst_async_n) begin // Async Assert: 즉시 리셋 rst_ff1 <= 1'b0; rst_ff2 <= 1'b0; end else begin // Sync Deassert: 클럭에 동기화되어 해제 rst_ff1 <= 1'b1; rst_ff2 <= rst_ff1; end end assign rst_sync_n = rst_ff2; endmodule

Gray Code 변환 (Verilog)

📄 Verilog: Binary ↔ Gray Code 변환
// Binary to Gray Code 변환 function [3:0] bin2gray; input [3:0] bin; begin bin2gray = bin ^ (bin >> 1); end endfunction // Gray Code to Binary 변환 function [3:0] gray2bin; input [3:0] gray; reg [3:0] bin; integer i; begin bin[3] = gray[3]; for (i = 2; i >= 0; i = i - 1) begin bin[i] = bin[i+1] ^ gray[i]; end gray2bin = bin; end endfunction // 사용 예시 wire [3:0] wptr_gray = bin2gray(wptr_bin); wire [3:0] rptr_bin = gray2bin(rptr_gray_sync);

Clock Gating (합성 툴 인식용)

📄 Verilog: Clock Gating 패턴 (합성 툴이 ICG로 변환)
// 방법 1: 합성 툴이 자동 인식하는 패턴 // Design Compiler의 compile_ultra -gate_clock 옵션 사용 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin data_reg <= 32'b0; end else if (enable) begin // ← 이 패턴이 CG로 변환됨 data_reg <= data_in; end end // 방법 2: 명시적 ICG 인스턴스화 (큰 블록 단위) // Library에서 제공하는 ICG 셀 사용 CKLNQD1 u_icg ( // 예: TSMC Library ICG Cell .CP (clk), // Clock input .E (enable), // Enable input .TE (scan_en), // Test enable (DFT) .Q (gclk) // Gated clock output );

🧙‍♂️ 10. 베테랑의 실전 팁

✅ CDC 베테랑의 철칙

1. CDC 툴 Warning을 무시하지 마라
시뮬레이션에서는 안 나타나고 칩을 구워야 발견되는 버그입니다.

2. Multi-bit 신호를 개별 2-FF로 넘기지 마라
반드시 Async FIFO, Handshake, 또는 DMUX Synchronizer를 사용하세요.

3. Gray Code 포인터는 필수
Async FIFO의 포인터는 반드시 Gray Code로 변환 후 동기화하세요.

4. False Path 설정은 신중하게
정말 Quasi-static인지 100% 확신이 있을 때만 사용하세요.

5. Reset Synchronizer를 잊지 마라
비동기 리셋도 CDC입니다. Async Assert, Sync Deassert 패턴을 사용하세요.

✅ Clock Gating 베테랑의 철칙

1. 단순 AND Gate로 클럭을 자르지 마라
반드시 Library의 ICG Cell을 사용하세요. Glitch가 칩을 죽입니다.

2. 합성 툴 옵션을 활용하라
compile_ultra -gate_clock으로 자동 CG 삽입을 활용하세요.

3. 큰 블록은 수동 ICG로
Auto-gating은 FF 단위입니다. 블록 단위 제어는 직접 ICG를 넣으세요.

4. DFT를 고려하라
ICG의 Test Enable(TE) 핀을 Scan Enable과 연결하세요.

📌 핵심 요약

CDC (Clock Domain Crossing)

문제: Metastability로 인한 데이터 오염, 시스템 Hang
검출: SpyGlass CDC, Questa CDC 등 전용 툴 사용
1-bit 해결: 2-FF Synchronizer
Multi-bit 해결: Async FIFO + Gray Code

Clock Gating

목적: Dynamic Power 절감
문제: 단순 AND Gate → Glitch 발생
해결: ICG Cell (Latch + AND) 사용
원리: CLK Low에서만 Enable 변화 반영

댓글

이 블로그의 인기 게시물

📚 SDC 마스터 클래스 시리즈 | Chapter 1

📚 SDC 마스터 클래스 시리즈 | Chapter 2

📚 SDC 마스터 클래스 시리즈 | Chapter 3