SemiMatrix / TOPICS / CLOCK DOMAIN CROSSING (CDC) & LINT
DIGITAL DESIGN & STATIC VERIFICATION

Clock Domain Crossing (CDC)
Metastability Physics, Async FIFOs & SpyGlass Signoff

Synopsys SpyGlass CDC Metastability MTBF Formula Gray-Code Async FIFO Cadence JasperGold CDC

ในระบบบนชิป (System-on-Chip: SoC) ยุคใหม่ แต่ละโมดูลย่อย (CPU, GPU, NPU, PCIe, LPDDR) ทำงานด้วยความถี่และเฟสของสัญญาณนาฬิกาที่ไม่ประสานกัน (Asynchronous Clocks) การส่งผ่านข้อมูลข้ามโดเมนสัญญาณนาฬิกา (CDC) หากไม่ได้รับการออกแบบอย่างถูกต้อง จะทำให้เกิดสภาวะกึ่งเสถียร Metastability และทำให้ระบบล่มแบบสุ่ม (Random Crash) ซึ่งเป็นบั๊กฮาร์ดแวร์ที่ตรวจจับได้ยากที่สุด

📍 CAREER ROADMAP CONTEXT
STAGE 02 — RTL DESIGN & STATIC VERIFICATION: CDC & Lint Signoff
ออกแบบ Synchronizers, Gray Code Dual-Clock FIFO, Handshake Controllers, และรัน Static CDC Verification ด้วย Synopsys SpyGlass CDC / Cadence JasperGold CDC ก่อนเข้าสู่ขั้นตอน Synthesis
Industry Tools: Synopsys SpyGlass CDC, Cadence JasperGold CDC, Siemens Questa CDC, Real Intent Meridian CDC
Related: RTL Architecture & SystemVerilog · STA & False Paths · UVM Verification · HDL & Logic Sandbox
Role: RTL Design Engineer / ASIC Verification Engineer / SoC Integration Lead

01 ปัญหาพื้นฐานของการส่งสัญญาณข้าม Clock Domains

เมื่อสัญญาณข้อมูล $D$ ที่ถูกส่งมาจากสัญญาณนาฬิกาต้นทาง ($CLK_A$) เดินทางมาถึง Flip-Flop ปลายทางที่ทำงานด้วยสัญญาณนาฬิกา ($CLK_B$) เนื่องจากเฟสของสัญญาณทั้งสองไม่เกี่ยวข้องกัน สัญญาณ $D$ มีโอกาสสูงมากที่จะเปลี่ยนสถานะในจังหวะ Setup/Hold Aperture Window ของ Flip-Flop ปลายทาง ส่งผลให้วงจรป้อนกลับแบบขนานภายใน Flip-Flop ไม่สามารถตัดสินใจระดับแรงดันไฟฟ้าเป็น '0' หรือ '1' ได้ในทันที

02 ฟิสิกส์ Metastability และสมการ Mean Time Between Failures ($MTBF$)

เมื่อ Flip-Flop ตกอยู่ในสภาวะ Metastability แรงดันไฟฟ้าเอาต์พุตจะค้างอยู่ที่จุดสมดุลกึ่งเสถียร ($V_{\text{meta}} \approx V_{dd}/2$) และจะค่อยๆ คลายตัว (Decay) เข้าสู่สถานะตรรกะที่เสถียรตามสมการเอ็กซ์โพเนนเชียล:

MEAN TIME BETWEEN FAILURES (MTBF) FORMULA
\text{MTBF} = \frac{1}{P_{\text{failure}}} = \frac{\exp\left(\frac{t_{\text{resolve}}}{\tau}\right)}{f_{\text{clk, dst}} \cdot f_{\text{data, src}} \cdot T_w}
เมื่อ $f_{\text{clk, dst}}$ คือความถี่สัญญาณนาฬิกาปลายทาง, $f_{\text{data, src}}$ คือความถี่การเปลี่ยนข้อมูลของต้นทาง, $T_w$ คือ Setup/Hold Window ของ Flip-Flop, $\tau$ คือค่าคงที่เวลาการฟื้นตัว (Regenerative Time Constant ของเทคโนโลยี $\approx 5-15\text{ ps}$ ใน 3nm), และ $t_{\text{resolve}}$ คือเวลาที่ให้ Flip-Flop คลายตัว (สำหรับ 2-FF Synchronizer $t_{\text{resolve}} = T_{\text{clk}} - T_{\text{setup}} - T_{\text{ck2q}}$)

หากออกแบบโดยไม่มี Synchronizer ค่า $MTBF$ อาจอยู่ที่เพียงไม่กี่วินาที แต่การเพิ่ม Flip-Flop ตัวที่สอง (2-FF Sync) จะเพิ่มค่า $t_{\text{resolve}}$ ขึ้นอีก 1 คาบเวลา ส่งผลให้ค่า $MTBF$ พุ่งสูงขึ้นเป็น หลายหมื่นล้านปี ($> 10^{10}\text{ Years}$) ซึ่งเพียงพอต่อความน่าเชื่อถือระดับอุตสาหกรรม

03 วงจรซิงโครไนซ์สัญญาณควบคุม 1 บิต (1-Bit Control Synchronizers)

ขึ้นอยู่กับทิศทางความเร็วของสัญญาณนาฬิกา:

1. 2-FF / 3-FF Synchronizer

ใช้สำหรับสัญญาณระดับช้า (Level Signals) เช่น Enable, Reset, Power-Good สัญญาณต้องคงที่ยาวนานกว่า $1.5 \times T_{\text{dst}}$ เสมอ ในโหนดความถี่สูง (> 2 GHz) แนะนำให้ใช้ 3-FF เพื่อความปลอดภัยสูงสุด

2. Fast-to-Slow Pulse Synchronizer

เมื่อส่งพัลส์สั้น 1 คาบจากโดเมนเร็วสู่โดเมนช้า สัญญาณจะหลุดรอดการจับ ต้องใช้วงจร Toggle Flop ในการเปลี่ยนพัลส์เป็นระดับสถานะ แล้วส่งผ่าน 2-FF และใช้วงจรตรวจจับขอบ (Edge Detector) กู้พัลส์คืนที่ปลายทาง

04 สถาปัตยกรรม Asynchronous FIFO & Gray Code

สำหรับการส่งข้อมูลหลายบิต (Multi-bit Data Bus) ห้ามมิให้นำบัสแต่ละเส้นไปผ่าน 2-FF แยกกันโดยเด็ดขาด เพราะเวลาหน่วงที่ต่างกันเพียงเล็กน้อยของแต่ละเส้นลวด (Bus Skew) จะทำให้ข้อมูลปลายทางกลายเป็นค่ามั่ว (Data Incoherency)

Asynchronous FIFO เป็นโซลูชันมาตรฐานสากล:

GRAY CODE CONVERSION FORMULAS
\text{Gray}[N-1:0] = \text{Binary}[N-1:0] \oplus (\text{Binary}[N-1:0] \gg 1)
Gray Code มีคุณสมบัติเด่นคือ เมื่อค่าพอยน์เตอร์เพิ่มขึ้น 1 ลำดับ จะมีบิตเปลี่ยนสถานะเพียง 1 บิตเสมอ ($\text{Hamming Distance} = 1$) ทำให้แม้สัญญาณนาฬิกาปลายทางจะสุ่มอ่านค่าในจังหวะที่มี Metastability ค่าที่อ่านได้จะมีเพียงค่าก่อนหน้าหรือค่าปัจจุบันเท่านั้น ไม่มีทางอ่านได้ค่ากระโดดข้ามขั้น
1
Dual-Port SRAM Array
เก็บข้อมูล Payload จริง โดยขาเขียนควบคุมโดย $CLK_{\text{write}}$ และขาอ่านควบคุมโดย $CLK_{\text{read}}$
2
Pointer Synchronization via 2-FF
แปลง Write Pointer ($W_{\text{ptr}}$) และ Read Pointer ($R_{\text{ptr}}$) เป็น Gray Code แล้วส่งข้ามโดเมนผ่าน 2-FF Synchronizers
3
Full & Empty Flag Generation
สร้างสัญญาณ FIFO Empty ในโดเมนอ่าน ($R_{\text{gray}} == W_{\text{gray, sync}}$) และสร้างสัญญาณ FIFO Full ในโดเมนเขียน ($W_{\text{gray}}[N:N-1] == \sim R_{\text{gray, sync}}[N:N-1]$ และบิตที่เหลือเท่ากัน)

05 ข้อผิดพลาดเชิงโครงสร้างที่พบบ่อย (Structural CDC Flaws)

ข้อผิดพลาด (CDC Violation) สาเหตุทางกายภาพ ผลกระทบและแนวทางแก้ไข
Re-convergence of Synchronized Signals สัญญาณควบคุม 2 เส้นผ่าน Sync แยกกัน แล้วนำมารวมกันใน Logic Gate เดียวกัน ความล่าช้า 1-2 คาบที่สุ่มไม่เท่ากันทำให้เกิด Invalid States → ต้องรวม FSM ให้ส่งสัญญาณเดียว
Glitch on Asynchronous Mux Control สัญญาณควบคุม Mux มาจากโดเมนอื่นโดยไม่มีการซิงโครไนซ์ที่ปราศจาก Glitch สัญญาณสวิตช์ระหว่างวิ่ง ทำให้เกิด Pulse Glitch ขนาดจิ๋ว → ใช้ Glitch-Free Mux Cell
Pulse Width Violation พัลส์จากโดเมนเร็วแคบกว่า $1.5 \times T_{\text{clk, dst}}$ Flip-Flop ปลายทางมองไม่เห็นสัญญาณเลย → ใช้ Pulse Stretcher / Handshake

06 กฎการตรวจเช็ค Synopsys SpyGlass CDC & Linting

ในกระบวนการ Verification วิศวกรจะกำหนดกฎในไฟล์ SGDC (SpyGlass Design Constraints):

  • cdc_setup_check — ตรวจจับสัญญาณ Unsynchronized Crossing ทั้งหมดใน RTL
  • Ac_conv01 / Ac_conv02 — ตรวจจับปัญหา Re-convergence ของสัญญาณที่ผ่าน Sync
  • Clock-Reset Coherency — รับประกันว่า Asynchronous Reset ถูก De-assert ประสานกับ Clock เสมอ (Reset Synchronizer)

07 โค้ดต้นแบบ SystemVerilog 2-FF Synchronizer

ตัวอย่างโค้ด SystemVerilog พร้อม Synthesis Attribute ป้องกันไม่ให้คอมไพเลอร์ Optimize หรือจับ Flip-Flop รวมกัน:

module sync_2ff #(
  parameter int WIDTH = 1
)(
  input logic clk_dst,
  input logic rst_n_dst,
  input logic [WIDTH-1:0] async_data_in,
  output logic [WIDTH-1:0] sync_data_out
);

  // Synthesis attributes to prevent register merging & keep physical proximity
  (* async_reg = "true", dont_touch = "true" *)
  logic [WIDTH-1:0] stage1_reg;
  (* async_reg = "true", dont_touch = "true" *)
  logic [WIDTH-1:0] stage2_reg;

  always_ff @(posedge clk_dst or negedge rst_n_dst) begin
    if (!rst_n_dst) begin
      stage1_reg <= '0;
      stage2_reg <= '0;
    end else begin
      stage1_reg <= async_data_in;
      stage2_reg <= stage1_reg;
    end
  end

  assign sync_data_out = stage2_reg;
endmodule

08 ปฏิบัติการจำลองบน HDL & Logic Sandbox Lab

คุณสามารถเขียนโค้ด SystemVerilog ทดลองการส่งสัญญาณข้ามสัญญาณนาฬิกา และสร้างเวฟฟอร์มจำลองได้โดยตรงในเบราว์เซอร์:

HDL & Digital Logic Sandbox

เขียนโค้ด Synchronizer, ทดสอบ Logic Gates, รันจำลอง Timing Waveforms ในเครื่องมือ Sandbox ของเรา

เปิดห้องแล็บ HDL Sandbox →