跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言算法

FPGA 跨时钟域 CDC 处理的三种实用工程方案

FPGA 跨时钟域(CDC)处理是解决多时钟系统信号同步的关键技术。主要包含三种方案:单比特信号采用两级寄存器同步消除亚稳态;多比特信号使用握手机制,通过 valid 和 ack 信号确保数据完整性;批量高速数据传输推荐使用异步 FIFO,利用格雷码编码指针避免采样错误。工程中需遵循设计原则,如复位信号同步、避免直接打拍等,并正确处理工具生成的 CDC 警告以确保系统稳定性。

赛博朋克发布于 2026/4/7更新于 2026/7/2443 浏览

FPGA 跨时钟域(CDC)处理方案

1. 什么是跨时钟域(CDC)

跨时钟域是指信号从一个时钟域传输到另一个时钟域。主要特征包括:

  • 核心场景:信号从源时钟域(如 clk_a)传到目标时钟域(如 clk_b)。
  • 触发条件:两个时钟频率不同,或相位无关。
  • 潜在风险:若未做处理直接打拍,会出现亚稳态,导致数据错误或系统死机。

在多时钟系统中,必须进行 CDC 处理,这是 FPGA 开发的基本要求。

2. 方案一:单比特信号同步(两级寄存器)

适用场景:按键输入、使能信号、标志位、单 bit 控制信号(如中断请求、数据有效标志)。

代码示例:

module sync_2d(
    input  wire      clk_dst, // 目标时钟
    input  wire      rst_n,   // 全局复位,低电平有效
    input  wire      din,     // 异步输入信号
    output wire      dout     // 同步后输出
);

reg q1, q2;

// 时序逻辑,目标时钟上升沿触发
always @(posedge clk_dst or negedge rst_n) begin
    if (!rst_n) begin
        q1 <= 1'b0;
        q2 <= 1'b0;
    end else begin
        q1 <= din; // 第一级同步
        q2 <= q1;  // 第二级同步
    end
end

assign dout = q2;

endmodule

注意事项:

  • 两级寄存器足以抵御大部分亚稳态,无需多打拍。
  • 禁止只打一拍,否则亚稳态未稳定即输出。
  • 模板通用,适配不同频率的目标时钟。

3. 方案二:多比特信号握手机制

适用场景:数据总线、地址信号、多 bit 控制信号。

核心思路:

  1. 发送方准备好数据并发送 valid 信号。
  2. 将 valid 信号通过两级同步器同步到接收方时钟域。
  3. 接收方检测到 valid 后锁存数据,并发送 ack 应答。
  4. 将 ack 信号同步回发送方,确认接收完成。

注意:多 bit 信号禁止直接打拍,会导致位间延迟不一致引发数据错乱。

代码示例:

module cdc_handshake (
    // 发送方 (clk_a)
    input  wire       clk_a,
    input  wire       rst_n,
    input  wire [15:0] data_a,
    input  wire       data_vld_a,
    
    // 接收方 (clk_b)
    input  wire       clk_b,
    output reg [15:0] data_b,
    output reg        data_vld_b
);

reg valid_a_sync1, valid_a_sync2;
reg ack_b, ack_b_sync1, ack_b_sync2;
reg data_lock;

// 第一步:valid_a 同步到 clk_b 域
always @(posedge clk_b or negedge rst_n) begin
    if (!rst_n) begin
        valid_a_sync1 <= 1'b0;
        valid_a_sync2 <= 1'b0;
    end else begin
        valid_a_sync1 <= data_vld_a;
        valid_a_sync2 <= valid_a_sync1;
    end
end

// 第二步:接收方逻辑(锁存 + 应答)
always @(posedge clk_b or negedge rst_n) begin
    if (!rst_n) begin
        data_b <= 16'd0;
        data_vld_b <= 1'b0;
        ack_b <= 1'b0;
        data_lock <= 1'b0;
    end else begin
        case (valid_a_sync2)
            1'b1: begin
                if (!data_lock) begin
                    data_b <= data_a;
                    data_vld_b <= 1'b1;
                    data_lock <= 1'b1;
                    ack_b <= 1'b1;
                end else begin
                    data_vld_b <= 1'b0;
                end
            end
            1'b0: begin
                data_vld_b <= 1'b0;
                ack_b <= 1'b0;
                data_lock <= 1'b0;
            end
        endcase
    end
end

// 第三步:ack_b 同步回 clk_a 域
always @(posedge clk_a or negedge rst_n) begin
    if (!rst_n) begin
        ack_b_sync1 <= 1'b0;
        ack_b_sync2 <= 1'b0;
    end else begin
        ack_b_sync1 <= ack_b;
        ack_b_sync2 <= ack_b_sync1;
    end
end

endmodule

4. 方案三:异步 FIFO

适用场景:高速数据传输、批量数据处理(图像、串口、以太网等)。

核心要点:

  • 读写指针使用格雷码编码,避免跨时钟域时多 bit 同时变化导致采样错误。
  • 工程通常直接调用 IP 核(如 Vivado FIFO Generator),而非手写。

Vivado 配置步骤:

  1. 打开 IP Catalog,搜索 "FIFO",选择 "FIFO Generator"。
  2. Basic:命名 IP 核,勾选 Native。
  3. FIFO Type:选择 "Independent Clocks Block RAM"(异步 FIFO)。
  4. Write Interface:设置写时钟频率、数据位宽。
  5. Read Interface:设置读时钟频率、数据位宽(需与写一致)。
  6. FIFO Depth:根据数据量设置深度。
  7. Flags:勾选 Full Flag 和 Empty Flag。
  8. Data Counts:可选勾选计数功能以便调试。
  9. Summary:核对参数后 Generate。

IP 核调用示例:

module async_fifo_top (
    input  wire       clk_a, // 写时钟
    input  wire       clk_b, // 读时钟
    input  wire       rst_n, // 全局复位
    input  wire [15:0] wr_data,
    input  wire       wr_en,
    input  wire       rd_en,
    output wire [15:0] rd_data,
    output wire       full,
    output wire       empty
);

async_fifo async_fifo_inst (
    .rst (~rst_n),
    .wr_clk (clk_a),
    .rd_clk (clk_b),
    .din (wr_data),
    .wr_en (wr_en),
    .rd_en (rd_en),
    .dout (rd_data),
    .full (full),
    .empty (empty)
);

endmodule

调用说明:

  • 注意 IP 核默认复位高电平有效,需适配全局低电平复位。
  • 端口名称必须与 IP 核生成的一致。
  • wr_en 仅在写时钟域控制,rd_en 仅在读时钟域控制。

5. CDC 设计原则

  1. 单 bit 信号统一用两级寄存器同步。
  2. 多 bit 信号禁止直接打拍,使用握手或异步 FIFO。
  3. 跨时钟域信号保持一个周期以上有效时间。
  4. 复位信号也需做跨时钟域同步。
  5. 重视开发工具报告的 CDC 警告,排查潜在风险。

目录

  1. FPGA 跨时钟域(CDC)处理方案
  2. 1. 什么是跨时钟域(CDC)
  3. 2. 方案一:单比特信号同步(两级寄存器)
  4. 3. 方案二:多比特信号握手机制
  5. 4. 方案三:异步 FIFO
  6. 5. CDC 设计原则
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 智能家居接入 Google Home 与 Assistant 集成指南
  • 华为 AI 岗位机考真题及编程题解析
  • 思源黑体 NotoSansSC-Regular.otf 字体介绍与特点
  • C++ vector 容器底层原理与模拟实现
  • 网络安全行业人才缺口与薪资前景分析
  • 强化学习 SAC 算法原理与 PyTorch 实现
  • Flutter inAppWebviewCookieManager 在鸿蒙系统的适配与安全实践
  • faster-whisper 语音转文字模型选型与对比决策指南
  • Gitee+PicGo 搭建 Markdown 笔记图床方案
  • 鸿蒙电商购物全栈项目——购物车优化与支付集成
  • 在线考试系统全流程开发实践:从数据库设计到前端交互
  • 人工智能对上位机系统的全面重塑与影响分析
  • Vitis 实战:从零将 AI 模型部署到 FPGA
  • 从零开始构建简单 RAG 应用指南
  • SpringBoot 新版本特性演进:2.1 至 3.1 核心变更
  • Golang 主流 Web 框架深度解析:GitHub 星标 TOP8 选型指南
  • 从零部署 OpenClaw:接入 QQ 的全流程踩坑记录
  • Visual Studio 中 GitHub Copilot 隐私设置:控制代码数据共享边界
  • MATLAB 实现基于多目标粒子群算法(MOPSO)的无人机三维路径规划
  • VSCode Copilot 接入智谱 GLM-5.1 与自定义大模型方案

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online