首先介绍 SCFIFO
的使用。如图 1
所示,在搜索栏中搜索“
fifo
(大小写均可)”就会显示和 FIFO
相关的所有
IP
核,这里我们选择
Installed Plug-Ins
目录下的 Memory Compiler 文件夹下的“
FIFO
”。
语言选择 Verilog HDL。然后就是选择
IP
核存放的路径,这里我们将
SCFIFO IP
核放在工程目录的ipcore_dir 文件夹下。然后是给
IP
核命名,为了能够清晰表达
FIFO
的大小和位宽,这里我们将其命名为“scfifo
”
。以上选择无误后点击“Next
”。
![](https://i-blog.csdnimg.cn/blog_migrate/08125c6b53e45f281b76f5e3239da28c.png)
图 1
下面我们开始进行 FIFO
参数的配置,其中:
框 1
为
FIFO
数据位宽的选择,可以根据需求选择,这里我们使用默认的
8bit
。
框 2
为
FIFO
深度的选择,所谓深度其实就是个数的选择,即设置
FIFO
可以存储多少个 8
位宽的数据,这里最小为
4
个,且都是
2
的
n
次方个,我们选择
FIFO
的深度为256。
框 3
为
FIFO
读写时钟的配置,选择“
Yes
” 读写为同一个时钟,即
SCFIFO
;选择“No
” 读写为不同时钟,即
DCFIFO
,这里我们选择 “
Yes
”。如图 2
所示,配置完成后点击“
Next
”。
![](https://i-blog.csdnimg.cn/blog_migrate/ad5c354625008216981d63c3275941fb.png)
图 2
图 3
为
FIFO
输入输出管脚的选择界面。其中红框中的三个输出信号默认是有效的,分别为:
full:写满标志位,有效表示
FIFO
已经存储满了,此时应该通过该信号控制写请求信号(也称为写使能信号),禁止再往 FIFO
中写入数据,防止数据溢出丢失。当写入数据量达到 FIFO
设置的最大空间时,时钟上升沿写入最后一个数据同时
full
拉高;读取数据时随时钟上升沿触发同时拉低。
empty:读空标志位,有效表示
FIFO
中已经没有数据了,此时应该通过该信号控制读请求信号(也称为读使能信号),禁止 FIFO
继续再读出数据,否则读出的将是无效数据。与 full
相反,写入数据同时拉低;读到最后一个数据同时拉高。
usedw:显示当前
FIFO
中已存数据个数,与写入数据的个数是同步的,即写第一个数据时就置 1
,空或满时值为
0
(满是因为寄存器溢出)。
剩下的信号可以选择添加也可以选择不添加,这里我们只做简单的介绍不进行添加。
almost full:几乎满标志信号,我们可以控制
FIFO
快要被写满的时候和
full
信号的作用一样。
almost empty:几乎空标志信号,我们可以控制
FIFO
快要被读空的时候和
empty
信号的作用一样。
Asynchronous clear:异步复位信号,用于清空
FIFO
。
Synchronous clear:同步复位信号,用于清空
FIFO
。
此页面我们保持默认即可,然后点击“Next
”。
![](https://i-blog.csdnimg.cn/blog_migrate/a642ebbad43371e890997b60f80128bf.png)
图 3
图 4
为设置
FIFO
属性和使用资源的界面,其中:
框 1
需要重点注意,上面的是普通同步
FIFO
模式,当前读请求有效的下一拍数据才出来;而下面的则是先出数据 FIFO
模式,读请求来到之前第一个数据就已经先出来了,使得当前的读请求有效时立刻输出数据,而不会像普通模式那样当前读请求有效后下一拍才会输出数据。这里我们选择默认的普通模式。
框 2
为指定实现
FIFO
使用的存储块类型和
FIFO
的存储深度,具体可选值与使用的 FPGA 芯片有关,默认为
Auto
,我们一般使用默认值就可以了。
设置完毕后点击“Next”。
图 4
图 5
为
FIFO
速度(性能)选择和是禁用保护电路,其中:
框 1
为性能设置,选择“
Yes(best speed)
”将获得最大的速度(性能),但是需要牺牲更多的资源(面积);选择“No(smallest area)
”将使用更少的资源(面积)但是速度(性能)可能不是最快的。这里我们没有特殊要求,默认即可。
框 2
为选择是否禁止上溢检测和下溢检测的保护电路(上溢检测保护电路主要是用在 FIFO
存储满时禁止继续写数据;下溢检测保护电路主要是用于
FIFO
被读空时,禁止继续读数据)。如果需要则保持默认,如果不需要可以选择禁用下面的两个选项来提高 FIFO 速度(性能),这里我们没有特殊需求所以保持默认即可。
框 3
为选项使用逻辑单元实现
FIFO
存储器。这里使用默认设置,即用存储块实现 FIFO。
设置完毕后点击“Next
”。
图 5
如图 6
所示,该界面没有什么要配置的参数,但显示了我们在仿真
SCFIFO IP
核时所需要的 Altera
仿真库,这里提示了我们单独使用第三方仿真工具时需要添加名为 “altera_mf
” 的库。这里保持默认,直接点击“
Next
”。
![](https://i-blog.csdnimg.cn/blog_migrate/36d6e61c222f2a3e241601c0e8e7c14c.png)
图 6
如图 7
所示,该界面显示的是配置好
SCFIFO IP
核后我们要输出的文件,其中“scfifo.v
”是默认输出的,不可以取消。此外我们再将“
scfifo_inst.v
”这个实例化模板文件添加上,方便我们实例化时使用,其余的文件都可以不勾选。
到此为止我们的 SCFIFO IP
核的配置就全部完成了,再检查下我们的配置,如果有问题可以点击“Back
”返回之前的配置界面进行修改,如果确认无误后可以点击“
Finish
” 退出配置界面,如果后面在仿真时发现 SCFIFO IP
核的配置有问题也可以再进行修改。
![](https://i-blog.csdnimg.cn/blog_migrate/911daf13dadccc0824f2f14f15cb9d48.png)
图 7
下面进行SCFIFO IP核的调用
SCFIFO IP 核配置完成后我们对它进行调用,通过仿真来观察
full
、
empty
、
usedw
这
三个信号的变化。为了让大家能够清晰的看到
SCFIFO IP
核信号的变化,
RTL
代码的顶层只有端口列表和 SCFIFO IP
核的实例化,其中:
RTL 代码顶层的输入信号有:
50MHz
的系统时钟
sys_clk
、输入
256
个
8bit
的数据 pi_data(值为十进制
0~255
)和伴随该输入数据有效的标志信号
pi_flag
、
FIFO
的写请求信号 rdreq
。这些输入信号需要在
Testbench
中产生激励。
RTL 代码顶层的输出信号有:从
FIFO
中读取的数据
po_data
、
FIFO
空标志信号empty、
FIFO
满标志信号
full
、指示
FIFO
中存在数据个数的信号
usedw
。这些信号也是我们需要通过仿真 SCFIFO IP
核主要观察的信号,这些信号通过
Testbench
中给输入信号激励后产生输出。
`timescale 1ns/1ns
module scfifo_256_8
(
input wire sys_clk , //系统时钟50Mhz
input wire [7:0] pi_data , //输入顶层模块的数据
//要写入到FIFO中的数据
input wire pi_flag , //输入数据有效标志信号
//也作为FIFO的写请求信号
input wire rdreq , //FIFO读请求信号
output wire [7:0] po_data , //FIFO读出的数据
output wire empty , //FIFO空标志信号,高有效
output wire full , //FIFO满标志信号,高有效
output wire [7:0] usedw //FIFO中存在的数据个数
);
scfifo_256x8 scfifo_256x8_inst(
.clock (sys_clk ), //input clock
.data (pi_data ), //input [7:0] data
.rdreq (rdreq ), //input rdreq
.wrreq (pi_flag ), //input wrreq
.empty (empty ), //output empty
.full (full ), //output full
.q (po_data ), //output [7:0] q
.usedw (usedw ) //output [7:0] usedw
);
endmodule