当前位置: 首页 > news >正文

fpga系列 HDL:跨时钟域同步 双触发器同步器

目录

      • 双触发器同步器(Two-Flip-Flop Synchronizer)示例代码:
      • 双触发器同步器的优缺点
        • 优点:
        • 缺点:
        • 适用场景:
    • 应用实例:同步来自spi_slave的单个使能信号
  • 跨时钟域的设计需要特别小心,以避免亚稳态问题。双触发器同步器(2-Flip-Flop Synchronizer)是一种简单且广泛应用的时钟域交叉(CDC)同步方法,用于将一个时钟域中的信号同步到另一个时钟域中。它通过使用两个触发器级联,确保信号在跨越不同时钟域时,(以指数平方级别)降低因为时钟的不匹配导致不稳定或亚稳态(metastability)发生的概率。

双触发器同步器(Two-Flip-Flop Synchronizer)示例代码:

module nocdc ( input wire clk_dst, // 目标时钟域时钟 input wire async_signal, // 来自源时钟域的异步信号 input wire rst_n, // 异步复位信号,低电平有效 output reg sync_signal, // 同步后的信号 output reg [7:0] counter // 计数器输出 ); reg sync_ff1, 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 <= async_signal; // 第一阶段采样异步信号 sync_ff2 <= sync_ff1; // 第二阶段消除亚稳态 end end assign sync_signal = sync_ff2; // 输出同步后的信号 // 使用同步后的信号更新计数器 always @(posedge clk_dst or negedge rst_n) begin if (!rst_n) begin counter <= 8'b0; end else if (sync_signal) begin counter <= counter + 1'b1; // 增加计数器 end end endmodule
  • 第一寄存器sync_ff1捕获来自源时钟域的信号,可能处于亚稳态。
  • 第二寄存器sync_ff2采样sync_ff1,将信号稳定到目标时钟域。

双触发器同步器的优缺点

优点:
  1. 简单高效:双触发器同步器结构简单,通常只需要两个 D 型触发器,因此在资源使用上非常高效。
  2. 低延迟:与其他更复杂的同步方法(如 FIFO)相比,双触发器同步器的延迟较低。
  3. 减少亚稳态的风险:通过两个触发器级联,可以有效降低亚稳态的发生概率,因为第二个触发器会提供额外的稳定化时间。
缺点:
  1. 仅适用于低频信号:双触发器同步器适用于频率差异较小的时钟域交叉。如果时钟域的频率差异过大,可能会导致信号丢失或同步失败。
  2. 无法处理高数据率:如果跨时钟域的数据速率较高,双触发器同步器可能无法有效同步所有数据。
  3. 可能的延迟:虽然延迟较小,但依然会引入一个时钟周期的延迟。
适用场景:
  • 双触发器同步器特别适合同步单比特控制信号低速数据,例如用于处理外部输入的控制信号、状态标志或较慢的时钟信号。
  • 在高数据率的应用中(如 SPI、I2C、UART 等接口),可能需要更复杂的同步方法,如 FIFO 缓存等。

应用实例:同步来自spi_slave的单个使能信号

  • 使能信号SPI_OPEN_LOOP为非同步信号:
  • scheduler的开环配置信号输入(SPI_OPEN_LOOP)来自spi_slave,scheduler实现如下:
// https://github.com/ChFrenkel/tinyODIN/blob/main/scheduler.v // 一个调度器(Scheduler)模块,且相较于原始的ODIN调度器移除了旋转FIFO相关功能 // "scheduler.v" - Scheduler module, rotating FIFOs removed from the original ODIN scheduler // // Project: tinyODIN - A low-cost digital spiking neuromorphic processor adapted from ODIN. // // Author: C. Frenkel, Delft University of Technology // Cite/paper: C. Frenkel, M. Lefebvre, J.-D. Legat and D. Bol, "A 0.086-mm² 12.7-pJ/SOP 64k-Synapse 256-Neuron Online-Learning // Digital Spiking Neuromorphic Processor in 28-nm CMOS," IEEE Transactions on Biomedical Circuits and Systems, // vol. 13, no. 1, pp. 145-158, 2019. module scheduler #( parameter N = 256, parameter M = 8 )( input wire CLK, input wire RSTN, input wire CTRL_SCHED_POP_N, input wire [3:0] CTRL_SCHED_VIRTS, input wire [7:0] CTRL_SCHED_ADDR, input wire CTRL_SCHED_EVENT_IN, input wire [M - 1:0] CTRL_NEURMEM_ADDR, input wire NEUR_EVENT_OUT, // 来自SPI配置寄存器的输入信号声明,此处接收SPI的开环配置信号,用于特定调度配置 input wire SPI_OPEN_LOOP, output wire SCHED_EMPTY, output wire SCHED_FULL, output wire [11:0] SCHED_DATA_OUT ); // 用于对SPI_OPEN_LOOP信号进行同步处理的寄存器声明(双同步寄存器) reg SPI_OPEN_LOOP_sync_int, SPI_OPEN_LOOP_sync; wire push_req_n; wire empty_main; wire full_main; wire [11:0] data_out_main; //---------------------------------------------------------------------------------- // SPI信号同步逻辑部分,采用同步屏障机制对SPI_OPEN_LOOP信号进行同步处理 // 确保该信号在时钟域内稳定可靠,避免亚稳态等问题,在复位(低电平有效)和时钟上升沿时进行操作 //---------------------------------------------------------------------------------- always @(posedge CLK, negedge RSTN) begin if(~RSTN) begin // 复位时将中间同步寄存器和最终同步寄存器都置为0 SPI_OPEN_LOOP_sync_int <= 1'b0; SPI_OPEN_LOOP_sync <= 1'b0; end else begin // 在正常时钟上升沿时,先将SPI_OPEN_LOOP信号同步到中间寄存器 SPI_OPEN_LOOP_sync_int <= SPI_OPEN_LOOP; // 再将中间寄存器的值同步到最终同步寄存器,形成两级同步 SPI_OPEN_LOOP_sync <= SPI_OPEN_LOOP_sync_int; end end fifo #( .width(12), .depth(128), .depth_addr(7) ) fifo_spike_0 ( .clk(CLK), .rst_n(RSTN), .push_req_n(full_main | push_req_n),// 推送请求 .pop_req_n(empty_main | CTRL_SCHED_POP_N),// 弹出请求 // 根据不同条件组合数据输入到FIFO,若有事件输入则组合虚拟相关信息和地址信息作为输入数据,否则用神经元地址信息作为输入 .data_in(CTRL_SCHED_EVENT_IN? {CTRL_SCHED_VIRTS,CTRL_SCHED_ADDR} : {4'b0,CTRL_NEURMEM_ADDR}), .empty(empty_main), .full(full_main), .data_out(data_out_main) ); // 推送请求控制逻辑,根据SPI_OPEN_LOOP_sync信号以及神经元事件输出等情况来决定是否允许推送数据 // 当SPI_OPEN_LOOP_sync为低电平且有神经元事件输出,或者有控制器的事件输入时,允许推送数据(push_req_n为低电平) assign push_req_n = ~((~SPI_OPEN_LOOP_sync & NEUR_EVENT_OUT) | CTRL_SCHED_EVENT_IN); assign SCHED_DATA_OUT = data_out_main; assign SCHED_EMPTY = empty_main; assign SCHED_FULL = full_main; endmodule

http://www.jsqmd.com/news/620518/

相关文章:

  • 告别‘玩具数据集’:手把手教你准备符合 RandLA-Net 要求的自定义点云数据(S3DIS 格式详解与转换脚本避坑)
  • AScript动态脚本语言:3大实战场景深度解析与iOS热更新解决方案
  • 供应商AI原生能力不达标,项目延期率飙升327%!——2023-2024国内217个AI项目复盘中的6类致命评估盲区
  • Cesium 适配 ArcGIS Server 非标准原点切片服务:以4490坐标系为例
  • 组织熵增 vs AI原生熵减:用香农-组织信息论量化研发效能衰减(SITS2026首次发布行业基准值)
  • 雪女-斗罗大陆-造相Z-Turbo实战:微信小程序开发中的AI对话集成
  • 从RGB-D图像到三维世界:深度相机点云生成的核心算法与坐标变换
  • TMSpeech:Windows平台离线语音转文字的终极解决方案
  • 完整Modbus协议栈:pymodbus核心组件详解
  • SQL批量删除旧日志数据_根据创建时间戳进行清理方案
  • 大数据-263 实时数仓-Canal 增量订阅与消费原理:MySQL Binlog 数据同步实践
  • 免费IP离线数据库完全指南:3种方法快速实现IP地址解析与地理位置查询
  • 格行随身WiFi“0元代理”登上热搜!官方邀请码888886,副业圈沸腾:流量分润能“躺赚”? - 格行官方招商总部
  • 写段代码教会你什么是HOOK技术?HOOK技术能干什么?然
  • nli-distilroberta-base构建智能Agent:实现多轮对话与复杂任务推理
  • 【技术解析】CRN:低成本相机与雷达如何协同实现高精度BEV 3D感知
  • 计算机毕业设计:Python天气数据爬虫可视化分析系统 Django框架 线性回归 数据分析 大数据 机器学习 大模型 气象数据(建议收藏)✅
  • 如何快速下载Google Drive共享文件:Python轻量级解决方案终极指南
  • 3个步骤掌握猫抓:让网页视频下载变得像呼吸一样简单
  • STM32光敏传感器实战:从环境检测到智能路灯(附完整代码)
  • 上海建筑房屋防水补漏TOP5品牌推荐榜:专业资质引领维修行业新标杆 - GrowthUME
  • 手把手教你用MySQL搭建苍穹外卖数据库(附完整sky.sql源码)
  • OpenClaw硬件要求解析:Qwen3.5-9B流畅运行配置
  • 网盘直链下载助手:八大平台真实地址一键获取,告别限速烦恼
  • 基于微信小程序实现智能社区服务管理系统【附项目源码+论文说明】
  • 从Matlab到FPGA:A律13折线PCM编码的Verilog实现与仿真
  • 【2026奇点技术白皮书首发】:全球仅23家通过AI原生研发成熟度三级认证企业的共性实践
  • 双足机器人走路不稳?试试用“轨道能量”这个核心概念来调参(Python仿真分析)
  • 手把手教你:在STM32F407上跑通PTPv2从机,实测与Linux ptp4l同步(附完整代码)
  • 实验室安全必备:5种危险有机试剂的淬灭操作指南(含实操视频)