关于同步以及异步FIFO的设计,5000字详解
目录
·写在前面
·正文
·同步FIFO回顾
·异步FIFO设计
·参考资料
写在前面
一开始是想既然是极简教程,就应该只给出FIFO的概念,没想到还是给出了同步以及异步FIFO的设计,要不然总感觉内容不完整,也好,自己设计的FIFO模块不用去担心因IP核跨平台不通用的缺陷!那我们开始吧。
正文
同步FIFO回顾
上一篇博客讲了同步FIFO的概念以及同步FIFO的设计问题,并给出了同步FIFO的Verilog代码以及VHDL代码,并经过了行为仿真测试。
$clog2()系统函数使用
这里简单提一下,同步FIFO的代码中用到了一个系统函数$clog2(),这个系统函数的使用方法很简单:
parameter DATA_WIDTH = 8;
parameter DATA_DEPTH = 8;
reg [DATA_WIDTH - 1 : 0] fifo_buffer[0 : DATA_DEPTH - 1];
reg [$clog2(DATA_DEPTH) - 1 : 0] wr_pointer = 0;
reg [$clog2(DATA_DEPTH) - 1 : 0] rd_pointer = 0;
例如我定义了FIFO缓冲区的深度为DATA_DEPTH = 8,那么其地址(指针)位宽是多少呢?这时候就可以使用系统函数$clog2()了,位宽可以表示为:
$clog2(DATA_DEPTH) // = 3;
指针就可以定义为:
reg [$clog2(DATA_DEPTH) - 1 : 0] wr_pointer = 0;
reg [$clog2(DATA_DEPTH) - 1 : 0] rd_pointer = 0;
综合属性控制资源使用
还有一点需要提的是,我们都知道在FPGA中FIFO的实现可以使用分布式资源或者BLOCK RAM,那么如何掌控呢?当使用FIFO缓冲空间较小时,我们选择使用Distributed RAM;当使用FIFO缓冲空间较大时,我们选择使用BLOCK RAM资源;这是一般的选择原则。我们可以通过在设计代码中加入约束条件来控制。
就上述同步FIFO而言,我们可以在缓冲区定义时候添加如下约束:
(*ram_style = "distributed"*) reg [DATA_WIDTH - 1 : 0] fifo_buffer[0 : DATA_DEPTH - 1];
或者:
(*ram_style = "block"*) reg [DATA_WIDTH - 1 : 0] fifo_buffer[0 : DATA_DEPTH - 1];
为了验证是否有用,我们在Vivado中进行验证如下:
当设计中使用BLOCK RAM约束:
(*ram_style = "block"*)reg [DATA_WIDTH - 1 : 0] fifo_buffer[0 : DATA_DEPTH - 1];
综合后的电路图如下,可见FIFO缓存区使用的资源为BLOCK RAM;
同时给出资源利用率报告:
可见存在BLOCK RAM,由于我仅仅综合了一个同步FIFO,因此这个Block RAM一定是FIFO缓冲区消耗的。
当使用Distributed RAM约束时:
(*ram_style = "distributed"*)reg