Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输

Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输

    • 一、Xilinx FIFO IP核介绍
    • 二、UPP
    • 仿真效果
    • 总结

一、Xilinx FIFO IP核介绍

1.Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输_第1张图片
因为采用异步FIFO,因此我们必须采用独立的读写时钟,同时为了节省LUTs资源,选用Block RAM
2.Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输_第2张图片模式的话我比较喜欢使用标准FIFO,明德扬老师喜欢用First-word fall through,这个区别是 FWFT模式是数据先出现在输出总线上,再使能读信号,为了低延迟,只有7系列和 virtex 5系列支持 ,我目前使用的spartan6系列并不支持,英文翻译再下面:
Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输_第3张图片接下来是位宽的设置,因为我的输入为32位的IQ两路信号,因此我的输入位宽为64,输出位宽由UPP输出数据位宽决定,8位传输。最大512的存储空间,本来想设置为读写分时,后面决定阉割版的读写分时没什么意思,此处的空间其实可以将512改成2,但是我懒得改了~
我的写时钟频率为500KHz,读时钟频率为5MHz,差距在10倍,因为将64位数据拆成8位进行发送需要8次才能发送完毕,为了保证不会写满FIFO,因此我选了一个差距为10位的读时钟。
Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输_第4张图片接下来就是一些控制信号,为了方便大家随便加上。我的读数据速度为
5Mhz乘8=40Mbits ,写速度为64*500khz=32Mbits,因此读的快,写的慢。
Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输_第5张图片同步复位,注意这里的复位,是导致我上次失败的原因,查阅手册也可以看到,复位仅仅是复位FIFO内部的读写地址,并不会清空内部数据。
在这里插入图片描述另外两个概念,可编程的满标志上下限和满标志的空上下限一会介绍~

此处我需要介绍一下网上流传的几个概念“读满”写空“虚空”“虚满”
首先需要明确一点是满、空该如何判断,
如果是自己写FIFO,其实就是一个双口RAM,是存在地址的,我们调用了FIFO核,核将地址省略了,但是地址的作用就是用来判断空和满,但是应该如何判断呢?
判断空-------将写地址打两拍到读时钟域
判断满-------将读地址打两拍到写时钟域
为什么要这样呢,不同时钟域的数据进行数据传输和比对时,很有可能会引起亚稳态导致判断失败,因此必须要打两拍。
什么叫虚空。什么叫虚满
判断空,将写时钟打两拍在读时钟域进行判断,那么在打两拍的过程中,写时钟可能又写了几个数据进入FIFO,那么我们判断的空就不是真的空,他叫虚空~,满是一个道理,但是这个并不影响FIFO,只会漏掉指针而已,判断虚空FIFO不再读,一会写地址更新过来肯定会继续读的,判断虚满,读地址更新过来还会继续写的,不存在数据的遗漏或者FIFO的空满。那么为了准确判断或者我们可以自己控制空满上下限就有个前面的可编程满标志上下限和空标志上下限,但是这个我也不好把控,而且我的FIFO里面的数据很少,我就全部设置为不编制,让FIFO自己判断空还是满 ,以上大概就是对FIFO的介绍~不对的地方还请大家批评指正。

二、UPP

Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输_第6张图片UPP通用并口大概就是这样,Start代表第一个数据,enable使能开始数据传输

仿真效果

写时钟域
在这里插入图片描述rdy_nege为写时钟,可以看到,rst复位以后,经过三个时钟周期后数据才能写入到FIFO中,但不知道为什么写计数不会增加,当我把读域的代码注释掉以后又会增加,这是目前的问题。
读时钟域
在这里插入图片描述读时钟域比较复杂,因为我设置的
assign rd_en=~empty;
而FIFO核自己肯定将empty同步到了读时钟域,即empty与读时钟clk_1250k肯定是同步的,那么即为同时拉高,但其实触发器存在输出延迟Tco,同时我使用assign组合逻辑导致rd_en的上升沿肯定晚于读时钟的上升沿,因此我们可以看到,通过读计数8-1的过程,8持续了两个周期,因此第一个读周期的时候rd-en为0,并不能成功读取,同理当rd-data_count为1时为最后一个数据的输出。此时虽然rd_en拉低了,但是DFF扔成功输出FIFO最后一个值,所以FIFO输出的数据的计数为87654321,正好8个数。
为了保证DSP端能够成功读取到输出数据,我将读时钟clk_1250k翻转,并将读使能通过读时钟进行重新采样,延迟一个时钟周期,UPP通信时序如下
在这里插入图片描述保证数据的中心时钟进行变化,同时start信号只计数一个时钟周期,DSP端成功接收数据~

总结

FIFO最难的地方还是读了数据以后送到后级,采用
assign rd_en=~empty是可以的,明德扬老师也是这么做的,可以保证不会读空。但是读使能的第一个时钟是不会读出来数据的,如果做时序后仿,使能信号应该在第一个时钟的后面。

你可能感兴趣的:(Xilinx 异步FIFO核实现FPGA与DSP通过UPP(通用并口)进行数据传输)