一文讲透 FPGA CDC 多bit跨时钟域同步-hand-shanking机制

news/2024/11/16 16:20:03/文章来源:https://www.cnblogs.com/dy-stairmed/p/18549428

一、背景
数据的跨时钟域处理是FPGA开发过程中的常见问题,存在两种情况

    1. 慢时钟向快时钟同步:只需在快时钟域打两拍即可。其RTL如下:

    打拍同步的原理:大家在初学FPGA时,经常听过FPGA中对信号打拍可以有效得避免亚稳态,而且一般要打两拍,其数学本质是如果打一拍发生错误得概率是1/1000,那么打两拍发生错误得概率就是1/1000000,这从统计意义上已经无限接近0。
    从电路本身的角度上讲,如果一个信号的更新频率与当前时钟域内的信号更新频率不同步,那么其和当前时钟域内的信号做任何运算,都有可能导致结果出现毛刺或者不满足下级寄存器的建立或保持时间。因此,为了确保新引人的这个非本时钟域的信号不会对本时钟域造成毁灭性打击,必须对其进行同步化处理,而方法就是使用当前时钟地域的时钟对其进行采样。而进行两次打拍是让异步信号打两拍可以让异步过来的电平信号达到一个比较“健壮”的电平区间,二避免了由于建立时间、多级扇出导致的逻辑电平不稳定的情况。以下摘自《FPGA之道》:

“为什么要采样两次呢?
采样一次,已经完成了非本时钟域信号的同步操作,那么为什么还要采用两级采样法呢?虽然从逻辑上来看,两级采样法就跟移位寄存器一样,并不能改变信号的逻辑值,而且还会增加信号传递进来的延迟,但是这绝对不是画蛇添足,而是非常必要的,原因如下:请大家思考一下,进行第一级采样的那个寄存器,其建立和保持时间是不否能够得到满足?显然在有些情况下,其建立和保持时间是无法得到满足的,因为它和当前时钟域时钟信号的变化并不同步,因此总会碰到问题。例如,当asynsignal从0变化到1时,如果在过这前后时间内,clk共经历了3个上升沿,那么unsafesignal的输出可能是001,也可能是011,其中,第二次采样由于建立或者保持时间不满足,所以无法确定其是0还是1,不过值得欧慰的是,无论是001,还是011,都至少正确捕捉到了原始信号的变化。也许你会觉得,异步逻辑本身就不可能在时间上被精确地捕捉到,既然能够正确捕捉到信号的变化,那不就够了么?没错,从逻辑上来说是够了,但是从驱动能力上来说,也许不够。大家都知道,FPGA内部的工作电压一般为1.5V,也就是说,理想情况下,逻辑1对应电压1.5V,逻辑0对应电压0V。但是现实是残酷的,逻辑1不可能精确地是1.5V,逻辑0也不可能是精确地0V,事实上,也许业界公认0.5V以上就可以判定为逻辑1,反之则可以被判定为逻辑0,这也是为什么数字信信号比模拟信号更能抗干扰的原因。所以,如果现在问你,FPGA内部有两个触发器的输出都是逻辑1,那么它俩的物理电压相等吗?答案显然是不一定。为什么触发器能够给出正确地输出结果的前提是输入信号要满足其建立、保持时间要求?其实原因很简单,就是要给数字电路以充足的时间来进行充电或者放电操作,从而让其输出的逻辑1更接近于1.5V,逻辑0更接近于0V;反之,如果一个逻辑电平1、0对应的物理电平更接近于1.5V或者0V,那么它就更容易在规定时间内对其后级触发器进行充分的充电或放电控制,从而使其后级触发器的输出也更加"强壮"。那么现在,我们在回过头来审视unsafesignal的物理电压,由于输出unsafesignalf的触发器,很可能出现建立或保持时间要求不满足的情况,因此,在这种情况下,它的充、放电操作都很不充分,输出的逻辑1或者逻辑0的物理电压都不会太好。例如,如果unsafesignalj为逻辑1,那么其物理电压很可能为0.6V,如果当前时钟域中有很多地方都用到了unsafesignal,那么0.6V电压的扇出能力显然会比较差,因此等传递到后续各个用到unsafe signal的地方,物理电压可能就变为0.4V、0.5V、0.55V等等,那么这时 unsafe signal就会被不同的触发器认成不同的逻辑电平,于是错误便诞生了。为了避免这种情况的发生,我们对unsafesignal再次进行采样。由于unsafesignal和safesignal是同步的,因此对于输出safesignal的触发器来说,建立时间已经远远超出了其建立时间要求,因此,即使0.6V的电压对其充电比较慢,但由于充电时间足够,充电电流也有保障,所以也能让safesignal达到一个比较健壮的物理电压,例如1.4V。接下来,我们再将safesignal连接到各个需要使用它的地方,其扇出能力就不会再有任何问题了。”

  1. 2.快时钟域向慢时钟域同步
    第一种简单的方式是在快慢时钟域间添加一个FIFO,这样就可以避免时钟不同步的问题。
    第二种方式是hand shanking机制,简单来说就是一种握手机制,其时序图可以用下图表示:

    在数据有效后,主机发起同步请求req,直至检测到从机的ACK信号后,req拉低,标志一次同步结束。而req信号在从机进行采样同步,并经过两拍后,从机对主机的DATA信号进行采样同步,完成从快时钟域到慢时钟域的数据同步。
    代码如下:
  `// ************************ ***************************************// Copyright (C) xx Coporation 
// File name: hand_shanking.v  
// Author: Dongyang  
// Date: 2024-11/16 
// Version: 1.0  
// Abstract: CDC multi bit sync,use hand shanking to sync data
//***************************************************************** `
`timescale 1 ns/1 ns
module  hand_shanking_module# (parameter integer DATA_WIDTH = 8)
(input                            i_clk_f          ,     //input                            i_sys_rst_n      ,     //外部异步复位信号input       [DATA_WIDTH-1 : 0]   i_src_data       ,     //外部输入信号,input                            i_src_data_valid ,     //数据有效标志input                            i_clk_s          ,output                           o_des_ack        ,     //应答完成信号,取上升沿后可作为i_clk_s 的o_des_data 的valid 信号output  reg [DATA_WIDTH-1 : 0]   o_des_data            //在i_clk_s 时钟域同步后的信号
);//******************** siganl define  ***********************reg                         r_src_req             ;reg                         r_src_ack_sync1       ;reg                         r_src_ack_sync2       ;reg                         r_des_req_sync1       ;reg                         r_des_req_sync2       ;reg                         r_des_ack             ; //************** combination  logic *************************
assign        o_des_ack = r_des_ack;
// step 1 , generate r_src_req 
always @(posedge i_clk_f or negedge i_sys_rst_n) beginif (~i_sys_rst_n) beginr_src_req <= 1'b0;endelse beginif (i_src_data_valid) begin                  //once datavalid , generate r_src_reqr_src_req <= 1'b1;endelse if (r_src_ack_sync2) begin             // when i_clk_s domain ack successfully,r_src_req resetr_src_req <= 1'b0;endend
end//step 2 and 3, under i_clk_s domain, sync r_src_req from i_clk_f domain,generate ack ok siganl
always @(posedge i_clk_s or negedge i_sys_rst_n) beginif (~i_sys_rst_n) beginr_des_req_sync1 <= 1'b0;r_des_req_sync2 <= 1'b0;r_des_ack       <= 1'b0;endelse beginr_des_req_sync1 <= r_src_req ;r_des_req_sync2 <= r_des_req_sync1;r_des_ack       <= r_des_req_sync2;end
end
//step 3, once r_des_req_sync2 set, sync o_des_data
always @(posedge i_clk_s or negedge i_sys_rst_n) beginif (~i_sys_rst_n) begino_des_data <= 'b0;endelse beginif(r_des_req_sync2) begino_des_data <= i_src_data;endend
end//step 4 ,sync r_des_ack to i_clk_f domain
always@(posedge i_clk_f or negedge i_sys_rst_n) beginif(~i_sys_rst_n) beginr_src_ack_sync1 <= 1'b0;r_src_ack_sync2 <= 1'b0;endelse beginr_src_ack_sync1 <= r_des_ack;r_src_ack_sync2 <= r_src_ack_sync1;end
endendmodule

TestBench:

`timescale 1 ns/1 ns
module tb_hand_shanking();parameter integer DATA_WIDTH =  8;reg                         clk_f      = 'b0;
reg                         clk_s      = 'b0;
reg                         sys_rst_n  = 'b0;
reg   [DATA_WIDTH- 1 : 0 ]  src_data   = 'b0;
reg                         data_valid = 'b0;always # 10   clk_f = ~ clk_f;
always # 30   clk_s = ~ clk_s;initial beginclk_f      = 'b0;clk_s      = 'b0;sys_rst_n  = 'b0;src_data   = 'b0;data_valid = 'b0;#50sys_rst_n <= 1'b1;#100src_data <= 8'h5A;data_valid <= 1'b1;#20data_valid <= 1'b0;#500src_data <= 8'h6A;data_valid <= 1'b1;#20data_valid <= 1'b0;endhand_shanking_module  
#(.DATA_WIDTH(DATA_WIDTH)
)U_hand_shanking_module_0 
(.i_clk_f             (clk_f),.i_sys_rst_n         (sys_rst_n),.i_src_data          (src_data),.i_src_data_valid    (data_valid),.i_clk_s             (clk_s),.o_des_ack           (),.o_des_data          ());endmodule

仿真波形:
https://img2024.cnblogs.com/blog/3539410/202411/3539410-20241116161229825-134001601.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834652.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KBPC3510-ASEMI整流桥KBPC3510参数、封装、尺寸

KBPC3510-ASEMI整流桥KBPC3510参数、封装、尺寸编辑:ll KBPC3510-ASEMI整流桥KBPC3510参数、封装、尺寸 型号:KBPC3510 品牌:ASEMI 封装:KBPC-4 正向电流:35A 反向电压:1000V 引脚数量:4 芯片个数:4 芯片尺寸:50MIL 漏电流:>10ua 恢复时间:>2000ns 浪涌电流:…

IDEA中操作表

Navicat中创建的表,同时也可以在IDEA中打开。 IDEA中侧边可以创建架构 可以选择相应排序规则以及创建新的表,但不如navicat方便

使用while循环分别对两个vector进行赋值,该怎么做

问题 在写程序的时候遇到了这样一个问题,见代码 #include <iostream> #include <vector>using namespace std;bool isequal(vector<int> vshort, vector<int> vlong) {for (int index = 0; index != vshort.size(); index++)if (vshort[index] != vlo…

合并具有文本框的Word文档:VBA代码批量操作

本文介绍基于VBA语言,对大量含有图片、文本框与表格的Word文档加以批量自动合并,并在每一次合并时添加分页符的方法~本文介绍基于VBA语言,对大量含有图片、文本框与表格的Word文档加以批量自动合并,并在每一次合并时添加分页符的方法。在我们之前的文章中,介绍过基于Pytho…

streamstring类介绍

std::stringstream 是 C++ 标准库中提供的一个类,定义在头文件 <sstream> 中。它是基于字符串的流(stream),允许像操作输入流(std::cin)或输出流(std::cout)那样,操作字符串内容。 std::stringstream 是 std::iostream 的派生类,支持同时进行字符串解析(输入)…

爬虫

程序示例: import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegexDemo6 {public static void main(String[] args) {/** 有如下文本, 请按照要求爬取数据. * Java 自从 95 年问世以来, 经历了很多版本, 目前企业中用的最多的是 Java8 和 Java11,…

将数值转换为字符串的函数

在 C++ 中,itoa 和 sprintf 是用于将数值转换为字符串的经典函数。然而,它们有一定的局限性或者安全性问题,现代 C++ 更倾向于使用标准库的解决方案,如 std::to_string 和 std::stringstream,来代替这些函数。 1. itoa 的替代 itoa 是一种将整数转换为字符串的函数,但它不…

20222406 2024-2025-1 《网络与系统攻防技术》实验五实验报告

20222406 2024-2025-1 《网络与系统攻防技术》实验五实验报告 1.实验内容对网站进行 DNS 域名查询,包括注册人、IP 地址等信息,还通过相关命令查询 IP 地址注册人及地理位置。尝试获取 QQ 好友 IP 地址并查询其地理位置。使用 nmap 对靶机环境扫描,获取靶机 IP 活跃状态、开…

delphi 新版内存表 FDMemTable

c++builder XE 官方demo最全60多个 http://community.embarcadero.com/blogs?view=entry&id=8761FireDAC.Comp.Client用好FDMemTable代替之前的ClientDataSet,以前ClientDataSet内存表转换太繁琐了步骤。TClientDataSet *cds = new TClientDataSet(this); DataSetProvid…

理想雪 - 翠鸟协会

写在前面3844 字 | 小说 | 热爱 | 思考 | 表达 | 坚定 | 证明 | 坚守《理想雪》系列故事均为架空世界观,所有人名、地名等与现实世界无任何关联。该系列只且仅只为了说明,小说作者在该情境下会诞生的想法和采取的行动,以及背后的世界观、价值观和人生观。因此将具有强烈的个…

专题课:综合案例5

评委打分解答: 1.首先肯定要键盘录入6个评委的分数6个评委的分数,即6个变量,我们肯定用数组更加方便,因为后面求和求最大值之类的,用数组都更简单 遍历数组,我们每键盘打出一个元素就将其放入数组中 . 2.然后定义求和变量,将6个分数求和3.for循环搭配if筛选求最大、最小…

# 20222403 2024-2025-1 《网络与系统攻防技术》实验六实验报告

1.实验内容 本实践目标是掌握metasploit的用法。 指导书参考Rapid7官网的指导教程。 https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/ 下载官方靶机Metasploitable2,完成下面实验内容。 (1)前期渗透 ①主机发现(可用Aux中的arp_sweep,search一…