一.典型方法

典型方法即双锁存器法,第一个锁存器可能出现亚稳态,但是第二个锁存器出现亚稳态的几率已经降到非常小,双锁存器虽然不能完全根除亚稳态的出现(事实上所有电路都无法根除,只能尽可能降低亚稳态的出现),但是基本能够在很大程度上减小这种几率。最后的一个D触发器和逻辑电路组成的是一个采沿(上升沿,修改一下就能采集下降沿)电路,即当第二个锁存器的输出中出现1个上升沿,那么最后的逻辑输出就会产生1个clock的高电平脉冲

二.结绳法

1.结绳法1:利用数据的边沿作时钟(例子中上升沿)。(可以将脉冲无限延长,直到可以采集到数据,然后复位,要考虑产生数据的频率)。

实例1

说明:这种结绳法的原理是,数据作为Din_clkA,即当数据有上升沿(0->1)时,寄存器1的输出将会稳定在高电平,此时等待clkB采样,当clkB完成采样后,寄存器4会输出高电平,若此时Din_clkA为高电平,那么即可完成复位,开始下一次采样等待。

这里需要注意的是当数据来临(即上升沿)时,clkB域需要等待3个clkB才会在寄存器4输出并完成输入端的复位,所以Din如果变化较快

即持续时间短于3个clkB,也就是clkA频率大于clkB的1/3,那么这时Din的变化将无法被采样到,因为clkB域需要3个clkB才能

完成采样,并且此时Din必须是低电平才能复位,并且复位后的0也要延迟3个clkB才能到达输出端.

因此说,在慢时钟采样快时钟的时候,结绳法适合采样数据较少(即脉冲间隔较大)的控制信号。即脉冲间隔Ta>3Tb;即等待3个clkB时钟后,完成复位,才允许下一个输入脉冲。

实例2

说明:与实例1的区别是,这种复位更迅速,不需要等到clkA为低电平,即可完成复位。复位后,经过3个clkB,寄存器2~4相继复位

2结绳法2:利用数据作为异步复位,置位信号。(适合将不足时钟宽度的脉冲扩展1周期)

实例1:输入高脉冲(clka域),输出高脉冲(clkb域)

说明:当clkB因为太慢,没有采到din_clkA时,din_clkA的高电平脉冲会异步置位,即寄存器1从clkA的上升沿开始到clkB的下一个上升沿之间输出为高,寄存器2采样到高电平,并持续1个clkB,高电平持续时间为1个clkB多一点;

当clkB足够快,其上升沿采到了din_clkA时,置位作用从clkA的上升沿开始,跨越了clkB的上升沿,那么输出高电平持续了2个clkB还多一点,因为寄存器1持续了1个周期多一点。

实例2:输入高脉冲(clka域),输出低脉冲(clkb域)

说明:同上

实例3:输入低脉冲(clka域),输出低脉冲(clkb域)

说明:同上

实例4:输入低脉冲(clka域),输出高脉冲(clkb域)

说明:同上

3结绳法3:输入作为数据输入,同样也是检测高有效后,输出一直为高,异步时钟域可以采集到数据后再复位。
因为没有将输入作为时钟,或者作为异步set,reset,所以这类方便比较常用。

参考代码:

//================================================================================
// Created by : Ltd.com
// Filename : sync_clk1_clk2.v
// Author : Python_Wang
// Created On : 2009-02-27 22:47
// Last Modified : 2009-02-28 09:09
// Description :
//
//
//================================================================================
module sync_clk1_clk2(
clk1 ,
rst_n1 ,
clk2 ,
rst_n2 ,
data_clk1_i ,
data_clk2_o
);
input clk1 ;
input rst_n1 ;
input clk2 ;
input rst_n2 ;
input data_clk1_i ;
output data_clk2_o ; reg data_clk1_q1 ;
reg data_clk1_q2 ; reg data_clk2_q1 ;
reg data_clk2_q2 ;
reg data_clk2_q3 ;
reg data_clk2_q4 ;
reg data_clk2_q5 ; wire data_clk1 ; assign data_clk1 = data_clk1_i | ( !data_clk2_q5 & data_clk1_q1) ; always@(posedge clk1 or negedge rst_n1)
begin
if(!rst_n1) begin
data_clk1_q1 <= #1 'b0;
data_clk1_q2 <= #1 'b0;
end
else begin
data_clk1_q1 <= #1 data_clk1 ;
data_clk1_q2 <= #1 data_clk1_q1;
end
end always@(posedge clk2 or negedge rst_n2)
begin
if(!rst_n2) begin
data_clk2_q1 <= #1 'b0;
data_clk2_q2 <= #1 'b0;
data_clk2_q3 <= #1 'b0;
end
else begin
data_clk2_q1 <= #1 data_clk1_q1;
data_clk2_q2 <= #1 data_clk2_q1;
data_clk2_q3 <= #1 data_clk2_q2;
end
end always@(posedge clk1 or negedge rst_n1)
begin
if(!rst_n1) begin
data_clk2_q4 <= #1 'b0;
data_clk2_q5 <= #1 'b0;
end
else begin
data_clk2_q4 <= #1 data_clk2_q2;
data_clk2_q5 <= #1 data_clk2_q4;
end
end assign data_clk2_o = data_clk2_q2 & ~data_clk2_q3 ; endmodule

仿真:

4.结绳法3:利用握手协议:(可以将脉冲无限延长,直到可以采集到数据,然后复位,要考虑产生数据的频率)。

Pulse2Toggle                             Synchronization                    Toggle2Pluse

Toggle2Pluse                             Synchronization                      Pluse2Toggle

说明:        结绳模块(Pluse2Toggle): 负责延长待采样信号

同步模块(Synchronization):负责双触发器锁存

解绳模块(Toggle2Pluse):  负责将长信号转换成脉冲信号

参考代码:

//================================================================================
// Created by : Ltd.com
// Filename : handover.v
// Author : Python_Wang
// Created On : 2009-02-19 19:31
// Last Modified : 2009-02-20 08:38
// Description :
//
//
//================================================================================
module handover(
rst_n ,
ClkA ,
Req_ClkA ,
Ack_ClkA ,
ClkB ,
Dvld_ClkB
);
input rst_n ;
input ClkA ;
input Req_ClkA ;
input ClkB ;
output Ack_ClkA ;
output Dvld_ClkB ;
reg Dvalid_ClkB ;
reg Q_Dvalid_ClkB ; reg Dvalid_ClkA ;
always@(posedge ClkA)
begin
if(!rst_n) begin
Dvalid_ClkA <= #1 1'b0;
end
else if(Req_ClkA) begin
Dvalid_ClkA <= #1 ~Dvalid_ClkA ;
end
end reg Q1_ClkB ;
reg Q2_ClkB ;
reg Q3_ClkB ;
always@(posedge ClkB)
begin
if(!rst_n) begin
Q1_ClkB <= #1 'b0;
Q2_ClkB <= #1 'b0;
Q3_ClkB <= #1 'b0;
end
else begin
Q1_ClkB <= #1 Dvalid_ClkA ;
Q2_ClkB <= #1 Q1_ClkB ;
Q3_ClkB <= #1 Q2_ClkB ;
end
end wire Req_ClkB = Q2_ClkB ^ Q3_ClkB ; always@(posedge ClkB)
begin
if(!rst_n) begin
Dvalid_ClkB <= #1 'b0;
Q_Dvalid_ClkB <= #1 1'b0;
end
else if(Req_ClkB) begin
Dvalid_ClkB <= #1 ~Dvalid_ClkB ;
Q_Dvalid_ClkB <= #1 Dvalid_ClkB ;
end
end always@(posedge ClkB)
begin
if(!rst_n) begin
Q_Dvalid_ClkB <= #1 1'b0;
end
else begin
Q_Dvalid_ClkB <= #1 Dvalid_ClkB ;
end
end reg Q1_ClkA ;
reg Q2_ClkA ;
reg Q3_ClkA ;
always@(posedge ClkA)
begin
if(!rst_n) begin
Q1_ClkA <= #1 'b0 ;
Q2_ClkA <= #1 'b0 ;
Q3_ClkA <= #1 'b0 ;
end
else begin
Q1_ClkA <= #1 Dvalid_ClkB ;
Q2_ClkA <= #1 Q1_ClkA ;
Q3_ClkA <= #1 Q2_ClkA ;
end
end assign Ack_ClkA = Q2_ClkA ^ Q3_ClkA ;
assign Dvld_ClkB = Dvalid_ClkB & ~Q_Dvalid_ClkB; endmodule

仿真:

另外对于为了提高速度和准确度的握手操作中,可以将设置一定的握手模块(n>2(clk1+clk2)/Trd),流水操作

结绳就是将单脉冲延长,以方便采集到数据。

结绳的方法归结为2类:

1.利用脉冲的边沿做时钟;

2.利用脉冲的电平(部分场合要求最小脉冲宽度)做选择器或者异步复位,置位。

另外的关键点就是什么时候结绳结束(采集到了数据就要让对方回到初始状态),

这里的操作也有2种方法:

1.利用采集到的脉冲做异步复位,置位。

2.利用采集到的脉冲再次结绳采集做握手响应信号。

处理的时候应该选择对应的方法。

关于FPGA异步时钟采样--结绳法的点点滴滴的更多相关文章

  1. FPGA异步时钟设计中的同步策略

    1 引言    基于FPGA的数字系统设计中大都推荐采用同步时序的设计,也就是单时钟系统.但是实际的工程中,纯粹单时钟系统设计的情况很少,特别是设计模块与外围芯片的通信中,跨时钟域的情况经常不可避免. ...

  2. FPGA 异步时钟处理方

    1 假设FPGA设计,包括不同的频率的时钟,它会发出涉及异步时钟. 我们需要一些方法来使时钟同步,从而保证FPGA可靠性设计. 2 在建立和保持时间所构成的有效时间窗体内,数据输入到触发器进行转换. ...

  3. FPGA异步时钟系统中信号处理之单比特信号

    有些东西当你习以为常而不去深思熟虑的时候,致命的错误就会因此埋下!      FPGA开发中难免会遇到跨时钟域处理的问题,而对于单比特信号,我会不假思索的回答:打两拍不久解决了吗?但是事实时,这佯作的 ...

  4. cdc跨时钟域处理-结绳握手法

    参考文档 https://blog.csdn.net/u011412586/article/details/10009761 前言 对于信号需要跨时钟域处理而言,最重要的就是确保数据能稳定的传送到采样 ...

  5. FPGA跨时钟域处理方法

    文章主要是基于学习后的总结. 1. 时钟域 假如设计中所有的触发器都使用一个全局网络,比如FPGA的主时钟输入,那么我们说这个设计只有一个时钟域.假如设计有两个输入时钟,如图1所示,一个时钟给接口1使 ...

  6. Xilinx FPGA全局时钟和全局时钟资源的使用方法

    对FPGA的全局时钟了解不多,遂转载一篇文档: http://xilinx.eetop.cn/?action-viewnews-itemid-42 目前,大型设计一般推荐使用同步时序电路.同步时序电路 ...

  7. FPGA跨时钟域握手信号的结构

    FPGA跨时钟数据传输,是我们经常遇到的问题的,下面给出一种跨时钟握手操作的电路结构.先上图 先对与其他人的结构,这个结构最大的特点是使用 req 从低到高或者高到低的变化 来表示DIN数据有效并开始 ...

  8. PAT 乙级 1070 结绳(25) C++版

    1070. 结绳(25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定一段一段的绳子,你需要把它们串成一条 ...

  9. PAT 1070 结绳(25)(代码)

    1070 结绳(25 分) 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子,可以再次对折去跟另一段绳子串连.每 ...

随机推荐

  1. POJ 2002 Squares 解题报告(哈希 开放寻址 & 链式)

    经典好题. 题意是要我们找出所有的正方形.1000点,只有枚举咯. 如图,如果我们知道了正方形A,B的坐标,便可以推测出C,D两点的坐标.反之,遍历所有点作为A,B点,看C,D点是否存在.存在的话正方 ...

  2. jquery插件cloud-zoom(放大镜)

    效果预览:http://www.helloweba.com/demo/cloud-zoom/ 源代码下载:http://pan.baidu.com/s/1eQnadXo Cloud Zoom是一个图像 ...

  3. Android开发视频学习(2)

    S02E05_Android当中的线程 Worker Thread不允许操作UI,只能在Main Thread操作UI S02E06_Handler(一) Handler,Looper,Message ...

  4. Error:Could not open initscript class cache for initialization script 'C:\Users\Avishek\AppData\Local\Temp\asLocalRepo14.gradle' (C:\Users\Avishek.gradle\caches\2.2.1\scripts\asLocalRepo14_dkwbdtenxxg

    Error:Could not open initscript class cache for initialization script 见鬼 Android Studio打开项目时遇到这个问题 昨 ...

  5. C# 线程更新UI

    最方便的用法: private void ViewMsg(string msg)        { /* control.Invoke(new SetControlTextDelegate((ct,  ...

  6. HDU 4746 Mophues 莫比乌斯反演

    分析: http://blog.csdn.net/acdreamers/article/details/12871643 分析参见这一篇 http://wenku.baidu.com/view/fbe ...

  7. [转]"由于这台计算机没有远程桌面客户端访问许可证,远程会话被中断"的解决方案

    先使用如下命令登录到服务器: mstsc /v:{服务器IP} /admin 然后再使用下列方法之一即可. 方法一: 1.单击“开始→运行”,输入“gpedit.msc”打开组策略编辑器窗口,依次定位 ...

  8. BOM(浏览器对象模型)的一些内置对象总结

    1.window对象 BOM的核心对象是window,它表示浏览器的一个实例,它也是ECMAScript规定的Globle对象,也就是说网页中任何一个对象都是在window这个对象里面的.如果有用到框 ...

  9. Azure 虚拟机常见问题-下

    虚拟机上的默认用户名和密码是什么? Azure 提供的映像没有预先配置用户名和密码.使用这些映像中的其中一个创建虚拟机时,你需要提供用户名和密码,用于登录到虚拟机. 提示 如果忘记了用户名或密码且安装 ...

  10. python seq

    missing parentheses in call to print  ==> python高版本 print("") name 'raw_input' is not d ...