VIVADO_FIFO IP核的使用
概述: FIFO本质上还是RAM,是一种先进先出的数据缓存器(先存入的数据先取出)。它与普通存储器的区别:没有外部读写地址线,只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1,不像其他存储器可以由地址线决定读取或写入某个指定的地址。
用途:
(1)跨时钟域多bit传输:读写可以由不同的时钟控制,使用异步FIFO可以在两个不同时钟系统之间快速方便的传输数据。
(2)数据匹配:对于不同宽度的数据接口可以使用FIFO,比如写入数据宽度为8bit,读取数据宽度为16bit,通过FIFO数据缓存器就可以达到数据匹配。
说明: IP核版本:FIFO Generator v13.2,配置环境vivado2018.2
文章目录
1.基本FIFO-IP核的配置
(1) .按照以下步骤
双击③处的FIFO Generator到步骤2。
注意:④处可以查看FIFO-IP核的版本,在官网可以下载到相应的说明文档。
官网:https://china.xilinx.com/
(2)进入FIFO配置页面:
看图:
最终的配置以及资源占用:
2.FIFO读写
找到创建的IP核,进行模块例化,模块的调用:
打开.veo文件就会看见IP核的端口,根据此端口在主模块中调用FIFO模块。以下为配置完IP核自动生成的端口内容。
fifo_generator_0 your_instance_name (
.clk(clk), // input wire clk
.rst(rst), // input wire rst
.din(din), // input wire [7 : 0] din
.wr_en(wr_en), // input wire wr_en
.rd_en(rd_en), // input wire rd_en
.dout(dout), // output wire [7 : 0] dout
.full(full), // output wire full
.empty(empty), // output wire empty
.prog_full(prog_full), // output wire prog_full
.prog_empty(prog_empty), // output wire prog_empty
.wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy
.rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy
);
(1)写FIFO
FIFO配置:
Interface Type:Native
Read Mode:Standard FIFO
Full Flags Reset Value:1
//写入宽度为8,深度为16. 读宽度为8,深度为16
module fifo(CLK_50M,RST_N);
input CLK_50M;
input RST_N;
//产生的计数数据用来写入FIFO
reg[7:0] WR_Cnt=8'd0;
//写入FIFO的数据
reg [7:0] W_Data=8'd0;
//链接FIFO_IP
wire FIFO_RData;
reg R_EN;//读使能
reg W_EN;//写使能
wire full;//FIFO满标志位
wire empty;//FIFO空标志位
//产生数据用来写入FIFO
always@(negedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
WR_Cnt <= 8'd0;
else
begin
if(WR_Cnt == 8'd31)
WR_Cnt <= 8'd0;
else
WR_Cnt <= WR_Cnt + 8'd1;
end
end
//产生读写使能
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
begin
W_EN <= 0;
R_EN <= 0;
end
else
begin
W_EN <= !full;//当非满的时候写使能
// R_EN <= !empty;//当非空的时候产生读使能(此处只写不读,屏蔽读使能)
end
end
//写入数据到FIFO
always@(posedge CLK_50M or negedge RST_N)
begin
if(!RST_N)
W_Data <= 8'd0;
else if(W_EN)//FIFO写
W_Data <= WR_Cnt;//将之前产生的周期性计数值,放置数据写入端口
end
//模块例化
fifo_generator_0 u1
(
.clk(CLK_50M),
.wr_en(W_EN),
.rd_en(R_EN),
.rst(~RST_N),
.din(W_Data),
.full(full), // output wire full
.empty(empty) // output wire empty
);
endmodule
仿真波形:
①:Full信号拉低,因为FIFO配置为Full Flags Reset Value:1,所以复位时Full信号是被高的复位结束后Full信号被拉低(其实经历了一定的周期才被拉低,请看⑤)。
②:wr_en(写使能)信号被置位,因为置位条件为:W_EN <= !full
,所以写使能信号在Full被拉低的下一个周期被置位。
③:在写使能置位的下一个上升沿FIFO写入第一个数据10。为什么在写使能的下一个上升沿写入,查看了FIFO手册(97页):
④:在写使能持续的最后一个周期写入最后一个数据25,写入的数据为(10-25)一共16个数据。数据宽度为(7:0)8bit宽度。
⑤:在FIFO复位结束后,经历了一定的周期Full信号才被拉低,查看FIFO手册(131页)
手册表明,当FIFO内核处于复位状态时,置位full和most_full标志以确保不发生写操作, FIFO退出复位状态并准备就绪后写入时,full和差不多_full标志置为无效; 这大约发生五个时钟异步复位无效后的周期。
(1)读FIFO
将上述代码的读使能信号取消屏蔽
R_EN <= !empty;//当非空的时候产生读使能
仿真波形:
①:在数据写入时FIFO就不是空的了,所以empty拉低。
②:在empty拉低的下一个周期写使能信号被置位,因为R_EN <= !empty
。
③:在读使能后第二个上升沿才读取读一个数据,查看FIFO手册(102页):
3.Standard FIFO对比First Word Fall Through
两种模式读写代码均采用以上代码,只是IP核配置的Read Mode分别为Standard FIFO与First Word Fall Through
(1)Standard FIFO
仿真波形:
读:
Standard FIFO模式下输出数据线是在rd_en使能后才有数据
(1)若勾选:Embedded Registers,(dout数据输出口会延迟一个时钟输出)
上图可以看到dout输出是在读使能信号rd_en置位后第3个上升沿开始才有数据。
查看FIFI手册(118页):
当使用Embedded Registers时,在读数据时输出端口会延迟一个时钟。
(2)若不勾选:Embedded Registers
仿真波形为
上图可以看到dout输出是在读使能信号rd_en置位后第2个上升沿开始有数据。查看手册(102页)
写:
选择Standard FIFO 我们定义的数据的深度为16,后面显示的Actual Write Depth(实际写深度也为16)。
仿真波形:写16个数据FIFO就达到满状态
(1)First Word Fall Through
读:
与Standard FIFO相比较First Word Fall Through第一个数据写入空的FIFO时,empty信号的变化增加了两个时钟周期的延迟。
查看手册(99页)
First Word Fall Through模式下在读使能之后的上升沿就可直接读取数据:
写:
选择First Word Fall Through我们定义的数据的深度为16,后面显示的Actual Write Depth(实际写深度却为18)。
仿真波形:FIFO写了18个数据FIFO才达到满状态
查看手册(99页)
FWFT模式下会增加两个有效深度。
4.配置时可查看读取延迟(Read Latency):
0延迟
1延迟
2延迟
5.异步复位至少持续3个时钟周期
查看手册(127页)
6.两次连续复位之间间隔至少确保6个时钟周期
查看手册(129页)
英语
不好
只能
勉强
做做
笔记
★★★如有错误,欢迎指导!!!