在逻辑设计领域,只涉及单个时钟域的设计并不多。尤其对于一些复杂的应用,FPGA往往需要和多个时钟域的信号进行通信。异步时钟域所涉及的两个时钟之间可能存在相位差,也可能没有任何频率关系,即通常所说的不同频不同相。

图1是一个跨时钟域的异步通信实例,发送域和接收域的时钟分别是clk_a和clk_b。这两个时钟频率不同,并且存在一定的相位差。对于接收时钟域而言,来自发送时钟域的信号data_a2b有可能在任何时刻变化。

图1 跨时钟域通信

对于上述的异步时钟域通信,设计者需要做特殊的处理以确保数据可靠的传输。由于两个异步时钟域的频率关系不确定,触发器之间的建立时间和保持时间要求也无法得到保证。如果出现建立时间或者保持时间违规,接收域将会采样到处于亚稳态数据,那么后果可想而知。

如何有效的进行跨时钟域的信号传输呢?最基本的思想是同步,在这个基础上设计者可以利用各种协议约定进行通信。单向控制信号检测方式(前面提到过的脉冲信号检测方法,这里为了和握手方式相区别,所以如此称呼)、握手协议的方式或者借助存储器的方式都是比较常用的处理手段。

本文将重点介绍握手方式进行异步时钟域的通信。

图2是一个基本的握手通信方式。所谓握手,意即通信双方使用了专用控制信号进行状态指示。这个控制信号既有发送域给接收域的,也有接收域给发送域的,有别于前面的单向控制信号检测方式。

图2 握手通信原理

使用握手协议方式处理跨时钟域数据传输,只需要对双方的握手信号(req和ack)分别使用脉冲检测方法进行同步。在具体实现中,假设req、ack、data总线在初始化时都处于无效状态,发送域先把数据放入总线,随后发送有效的req信号给接收域。接收域在检测到有效的req信号后锁存数据总线,然后回送一个有效的ack信号表示读取完成应答。发送域在检测到有效ack信号后撤销当前的req信号,接收域在检测到req撤销后也相应撤销ack信号,此时完成一次正常握手通信。此后,发送域可以继续开始下一次握手通信,如此循环。该方式能够使接收到的数据稳定可靠,有效的避免了亚稳态的出现,但控制信号握手检测会消耗通信双方较多的时间。以上所述的通信流程如图3所示。

图3 握手通信流程

下面通过一个简单的工程代码及其仿真测试进一步加深大家对基本握手协议的认识。

module handshack(

clk,rst_n,

req,datain,ack,dataout

);

input clk;      //50MHz系统时钟

input rst_n;    //低电平复位信号

input req;      //请求信号,高电平有效

input[7:0] datain;  //输入数据

output ack;     //应答信号,高电平有效

output[7:0] dataout;//输出数据,主要用于观察是否和输入一致

//--------------------------------------

//req上升沿检测

reg reqr1,reqr2,reqr3;

always @(posedge clk or negedge rst_n)

if(!rst_n) begin

reqr1 <= 1'b1;

reqr2 <= 1'b1;

reqr3 <= 1'b1;

end

else begin

reqr1 <= req;

reqr2 <= reqr1;

reqr3 <= reqr2;

end

//pos_req2比pos_req1延后一个时钟周期,确保数据被稳定锁存

wire pos_req1 = reqr1 & ~reqr2; //req上升沿标志位,高有效一个时钟周期

wire pos_req2 = reqr2 & ~reqr3; //req上升沿标志位,高有效一个时钟周期

//--------------------------------------

//数据锁存

reg[7:0] dataoutr;

always @(posedge clk or negedge rst_n)

if(!rst_n) dataoutr <= 8'h00;

else if(pos_req1) dataoutr <= datain;   //检测到req有效后锁存输入数据

assign dataout = dataoutr;

//--------------------------------------

//产生应答信号ack

reg ackr;

always @(posedge clk or negedge rst_n)

if(!rst_n) ackr <= 1'b0;

else if(pos_req2) ackr <= 1'b1;

else if(!req) ackr <= 1'b0;

assign ack = ackr;

endmodule

该实例的verilog代码模拟了握手通信的接收域,其仿真波形如图4所示。在发送域请求信号(req)有效的若干个时钟周期后,先是数据(datain)被有效锁存了(dataout),然后接收域的应答信号(ack)也处于有效状态,此后发送域撤销请求信号,接收域也跟着撤销了应答信号,由此完成一次通信。

图4 握手通信仿真波形

基于FPGA的跨时钟域信号处理——专用握手信号的更多相关文章

  1. FPGA跨时钟域处理方法

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

  2. FPGA基础学习(3) -- 跨时钟域处理方法

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

  3. FPGA中亚稳态相关问题及跨时钟域处理

    前言 触发器输入端口的数据在时间窗口内发生变化,会导致时序违例.触发器的输出在一段时间内徘徊在一个中间电平,既不是0也不是1.这段时间称为决断时间(resolution time).经过resolut ...

  4. 跨时钟域设计【一】——Slow to fast clock domain

    跨时钟域设计是FPGA设计中经常遇到的问题,特别是对Trigger信号进行同步设计,往往需要把慢时钟域的Trigger信号同步到快时钟域下,下面是我工作中用到的慢时钟域到快时钟域的Verilog HD ...

  5. 异步FIFO跨时钟域亚稳态如何解决?

    跨时钟域的问题:前一篇已经提到要通过比较读写指针来判断产生读空和写满信号,但是读指针是属于读时钟域的,写指针是属于写时钟域的,而异步FIFO的读写时钟域不同,是异步的,要是将读时钟域的读指针与写时钟域 ...

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

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

  7. 跨时钟域设计【二】——Fast to slow clock domain

    跨时钟域设计中,对快时钟域的Trigger信号同步到慢时钟域,可以采用上面的电路实现,Verilog HDL设计如下:   // Trigger signal sync, Fast clock dom ...

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

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

  9. 【iCore、iCore2、iBoard例程】【异步FIFO跨时钟域通信(通过ARM 读FPGA FIFO)】

    欢迎访问电子工程师学堂,以便了解更多内容:http://www.eeschool.org 一.本实验基于iCore2 完成,通过简单改动,即可用在 iCore 核心板.iBoard 电子学堂上. iC ...

随机推荐

  1. Android持久化保存cookie

    在解析网页信息的时候,需要登录后才能访问,所以使用httpclient模拟登录,然后把cookie保存下来,以供下一次访问使用,这时就需要持久化cookie中的内容. 在之前先科普一下基础知识: 什么 ...

  2. BZOJ:3441 乌鸦喝水

    bzoj:3441 乌鸦喝水 题目传送门 Description 一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水. 他准备从第1个水缸飞到第n个水缸,共m次.在飞过一个水缸的过程 ...

  3. 蓝桥杯--算法提高 排列数 (简单dfs)

    算法提高 排列数   时间限制:1.0s   内存限制:256.0MB      问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入 ...

  4. query.setFirstResult解析

    转自:https://blog.csdn.net/thinkingcao/article/details/78053622

  5. 5.listview(QStringList QStringListModel)

    UI mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include < ...

  6. 个人对于React的Diff算法的一点疑问(待更新)

    本人对于Diff算法也并未做深入研究,只是大概的看过一些博文了解了些原理,但依然有了如下疑问 : 对于vdom所表示的对象中,若在该oldObj和newObj之间,发现一个元素节点所表示的子对象不见了 ...

  7. 详解循环神经网络(Recurrent Neural Network)

    本文结构: 模型 训练算法 基于 RNN 的语言模型例子 代码实现 1. 模型 和全连接网络的区别 更细致到向量级的连接图 为什么循环神经网络可以往前看任意多个输入值 循环神经网络种类繁多,今天只看最 ...

  8. adb屏幕截屏

    import subprocess #执行结果使用管道输出,对于参数是字符串,需要指定shell=Trueprocess = subprocess.Popen('adb shell screencap ...

  9. input的radio根据value和name反向显示

    1.获取radio的值,是根据name设置一组单选框. 例如: <div id="sexBox"> <input type="radio" i ...

  10. vue实现分页器(仿element)

    1.起因 今日看完element中分页器的源码实现,比较简单,遂自己按着理解实现了一个简单的分页器,记录下来,以便日后温习. 2.实现难点 分页器的实现难点主要是什么时候显示分页器的省略, 我的思路是 ...