一.典型方法

典型方法即双锁存器法,第一个锁存器可能出现亚稳态,但是第二个锁存器出现亚稳态的几率已经降到非常小,双锁存器虽然不能完全根除亚稳态的出现(事实上所有电路都无法根除,只能尽可能降低亚稳态的出现),但是基本能够在很大程度上减小这种几率。最后的一个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. jquery图片播放插件Fancybox(灯箱)

    效果预览Demo源码下载 Fancybox的特点如下: 可以支持图片.html文本.flash动画.iframe以及ajax的支持 可以自定义播放器的CSS样式 可以以组的形式进行播放 如果将鼠标滚动 ...

  2. Using the Task Parallel Library (TPL) for Events

    Using the Task Parallel Library (TPL) for Events The parallel tasks library was introduced with the ...

  3. POJ -- 3842

    An Industrial Spy   Description Industrial spying is very common for modern research labs. I am such ...

  4. NPOI读取Excel案例

    3.4用NPOI操作EXCEL--从Excel中抽取文本 我们知道,搜索引擎最擅长处理的就是文本,而Excel中的内容并不是以文本方式存储的.那么如果想要搜索引擎爬虫能够抓取到Excel中的内容是比较 ...

  5. [POJ1969]Count on Canton

    NOIP1999普及组 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9333   Accepted: 5469 Descr ...

  6. linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)

    1. Based on linux2.6.32,  only for mem(SDR) 2. 有兴趣请先参考阅读: 电源管理方案APM和ACPI比较.doc Linux系统的休眠与唤醒简介.doc 3 ...

  7. 完美atoi,哈哈

    /* atoi算法,要求完美版 有两种,一种是用longlong,一种是真用int “” " " “-” “+” “ -23” “ +23” “12a" "ab ...

  8. 动态规划:最长上升子序列(LIS)

    转载请注明原文地址:http://www.cnblogs.com/GodA/p/5180560.html 学习动态规划问题(DP问题)中,其中有一个知识点叫最长上升子序列(longest  incre ...

  9. jsp <c:forEach> 判断第一条 或 最后一条记录

    <c:forEach>标签具有以下一些属性: var:迭代参数的名称.在迭代体中可以使用的变量的名称,用来表示每一个迭代变量.类型为String. items:要进行迭代的集合.对于它所支 ...

  10. 如何生成Dump文件

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何生成Dump文件.