在进行FPGA开发的时候,经常会用到,几个模块之间的链接与嵌套这个时候就需要保证数据准确无误的传输,那么我们就需要加上握手信号来控制信号的传输。特别是在通信中的同步,会经常的用到这些握手信号,握手协议的原则是:当Valid 和 Ready信号同时高有效时,数据在时钟的上升沿传输。在新版本的Xilinx的FPGA中好多IP核都是基于此种握手协议来传输的。特别是在学到AXI的时候,不至于太吃力。类比于生活中的接力赛跑运动员之间的接力棒传递,有利于更好的理解握手协议。
端口名称解释:
clk : 输入端口,上升沿有效。
data_in:输入信号,输入数据。
datain_val:输入信号,表明该模块的上流有有效的数据发送过来,高电平有效。
datain_rdy:输出信号,表明该模块已经准备好接受来自上流模块的数据。高电平有效。
data_out :输出信号,输出的是数据。
dataout_val;输出信号,表明该模块有有效数据要输出。
dataout_rdy:输出信号,表明该模块有做好了数据输出的准备。
转化为几个模块的链接形式更容易理解:
那么先从最基本的开就是两个模块之间的数据传输:
从图中可以看出:当发送端的有效发送数据到来的时候,也就是VALID拉高的时候data开始输出有效的数据,在上图中虽然发送端的数据有效发出但是接收端并没有准备好接受第一帧数据,所以上图中,接受端只会有效的接收到第二帧和第三帧数据(word2和word3)。
如图所示,只有红色虚线标注的两个时钟上升沿,接收端才能接收到有效的数据。
握手信号的三种类型:
第一种是Valid-before-Ready,就是说valid信号是在Ready信号之前有效,这种通道一般作为数据的输出端的设计。在收到下游模块的READY信号之后,才开始传输数据。第三种是Ready-Before-Valid信号一般作为接收端的模块,这样的设计在数据来临之前,通道就已经做好了接收数据的准备,可以保持通道的最大吞吐量。因为READY信号产生,这个通道保持刷新等待数据。通道作为接收端的使用。
Valid-Ready协议'Stalemate'情况:
Stalemate可以理解为“锁住”。假设我们不遵守上面两种接收端和输出端的设计规则。输出端用Ready-Before-Valid而接受端使用Valid-before-Ready,就会出现输出端等待接受端给出的Ready来输出数据,但是接收端也在等待输出端给出Valid信号来接受数据。两者都在等待却没有一方先给,所以这个时候这个通道就是无效的,被“锁住”了。
例子:
可以实现数据的流入和数据的流出,这样一个双端口握手协议通道传输。对于Valid和Ready信号的原理类似于FIFO的读写和空满信号,就好像FIFO外边包了一层。也就是在FIFO的端口信号上加上如下图的方向器。可以实现一个简单的握手协议。
在此图的基础上升级一下:其中FIFO相当于中间数据的一个缓存。
端口的代码实现:
1 assign valid_o = ~fifo_empty; 2 assign ready_o = ~fifo_full; 3 assign wr_en = ready_o & valid_i; 4 assign rd_en = ready_i & valid_o;
先到这里吧,下一次用这种方法做个实例看看效果,也注意一下细节,各位多多指教。