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

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

FPGA 跨时钟域(CDC)处理的三种工程方案。针对单比特信号,采用两级寄存器同步消除亚稳态;针对多比特信号,使用握手机制确保数据完整性;针对批量高速数据,推荐调用 Vivado 异步 FIFO IP 核并利用格雷码同步指针。文章强调了 CDC 铁律,包括单 bit 同步规范、多 bit 禁止直接打拍、复位同步及工具警告排查,为 FPGA 开发提供稳定可靠的实践指导。

星河入梦发布于 2026/4/6更新于 2026/7/2245 浏览

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

1. 什么是跨时钟域 CDC?

核心场景:信号从一个时钟域(比如 clk_a)传到另一个时钟域(比如 clk_b); 触发条件:两个时钟的频率不同,或者相位无关(没有固定的时间关系); 直接后果:如果不做处理,直接打拍会出现亚稳态,进而导致数据错误,严重的还会让整个系统死机。

注意:只要是多时钟系统,就必须做 CDC 处理,这是企业级 FPGA 开发的基本要求。

2. 方案 1:单比特信号 —— 两级寄存器同步

适用场景:按键输入、使能信号、标志位、单 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

关键要点:

  • 两级寄存器足够抵御大部分亚稳态,工程里单 bit 信号统一用这个方案。
  • 绝对不要只打一拍!只打一拍风险极大。
  • 替换 clk_dst 即可适配不同频率。

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

适用场景:数据总线、地址信号、多 bit 控制信号。 核心思路:发送方准备数据并发送 valid,接收方同步 valid 后锁存数据并回传 ack。

module cdc_handshake(
    input  wire            clk_a,
    input  wire            rst_n,
    input  wire [15:0]     data_a,
    input  wire            data_vld_a,
    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

// 第二步:接收方逻辑(锁存数据 + 产生应答 ack_b)
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

代码要点补充:

  • 数据位宽:修改成 8bit、32bit 只需调整位宽和复位值。
  • 时钟适配:clk_a 和 clk_b 可任意频率。
  • 核心逻辑:通过'valid 同步→数据锁存→ack 同步'的闭环,确保多 bit 数据稳定跨时钟域。

4. 方案 3:异步 FIFO

适用场景:高速数据传输、批量数据处理,比如图像数据、串口数据、以太网数据。 核心要点:读写指针必须用格雷码编码后,再跨时钟域同步。

Vivado 异步 FIFO IP 核详细配置步骤

  1. 打开 Vivado 软件,进入项目,点击左侧'IP Catalog',搜索'FIFO Generator'。
  2. Basic:命名 async_fifo,勾选 Native。
  3. FIFO Type:选择 Independent Clocks Block RAM。
  4. Write Interface:配置写时钟频率、位宽。
  5. Read Interface:配置读时钟频率、位宽。
  6. FIFO Depth:配置深度。
  7. Flags:勾选 Full Flag 和 Empty Flag。
  8. Data Counts:可选。
  9. Summary:生成 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 核默认复位为高电平有效,示例中用'~rst_n'适配全局低电平复位。
  • 端口对应:例化端口名称必须和 IP 核生成的端口完全一致。
  • 使能控制:wr_en 仅在写时钟域控制,rd_en 仅在读时钟域控制。

5. 工程中必须记住的 CDC 铁律

  • 单 bit 信号:统一用两级寄存器同步。
  • 多 bit 信号:禁止直接打拍,必须用握手机制或异步 FIFO。
  • 跨时钟域的信号,尽量保持一个周期以上的有效时间。
  • 复位信号也要做跨时钟域同步。
  • 开发工具报的 CDC 警告,不要随便忽略。

目录

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

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

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

更多推荐文章

查看全部
  • Clawdbot 源码部署实战:从环境搭建到 WebChat 验证
  • OpenClaw 中文发行版部署指南:npm/Docker/脚本三种方式
  • Ghostty + Yazi + Lazygit 构建现代化终端开发工作流
  • JavaScript 金额计算精度丢失与分摊方案
  • 算法实战:位运算解决两数之和、唯一数字与缺失数字
  • DeepSeek 20 个实用建议:普通人如何高效使用大模型
  • Spring AI Alibaba 智能 Agent 开发实战
  • stable-diffusion-videos 音乐视频制作教程:实现 AI 视频与音乐节奏同步
  • ArkTS 语法助手技能安装指南与 AI 编程配置
  • web APIS Day1
  • Stable Diffusion 入门:AI 绘画原理与本地部署指南
  • Windows 11 环境下通过命令行升级 Python 版本的方法
  • OpenClaw 对接 QQ 机器人实战指南:本地与云端部署方案
  • 无人机视角山区泥石流和滑坡图像识别数据集
  • Neo4j 图数据库核心概念与在线控制台实战
  • KaiwuDB 3.1.0 在 Ubuntu 22.04 部署实战:TLS 配置与性能测试
  • 本地部署 Ollama:模型管理与 Open-WebUI 交互指南
  • AIGC 时代下 R 语言在数据科学中的应用实践
  • 内容创作模式全解:UGC、PGC、PUGC、OGC、MGC、BGC 与 AIGC
  • 大模型应用开发实战基础

相关免费在线工具

  • 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

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online