FPGA-ip核学习笔记:FIFO

FPGA-ip核学习笔记:FIFO


根据达芬奇pro的指导书写的一些学习笔记,方便后续查阅复习。

FIFO

FIFO 的英文全称是 First In First Out,即先进先出。FPGA 使用的 FIFO 一般指的是对数据的存储具有先
进先出特性的一个缓存器,常被用于数据的缓存,或者高速异步数据的交互也即所谓的跨时钟域信号传递。

RAM和ROM可以在外部设定地址线,选择需要读写的位置,但是FIFO只能采取顺序写入数据的方式。

FIFO的时钟

FIFO分为同步和异步两种,由读写时钟是否相同来区分。

如果为同步FIFO则读写都是用wr_clk时钟,异步则采用wr_clk和rd_clk两个不同的时钟。
在这里插入图片描述
FIFO宽度:FIFO 一次读写操作的数据位 N;
FIFO 的深度:FIFO 可以存储多少个宽度为 N 位的数据。
空,满,将空,将满标志。
读时钟:读 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
写时钟:写 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
将空,将满标志分别对于空,满标志提前一个时钟拉高。

同步 FIFO 常用于同步时钟的数据缓存,异步 FIFO 常用于跨时钟域的数据信号的传递,例如时钟域 A 下的数据 data1 传递给异步时钟域 B,当 data1 为连续变化信号时,如果直接传递给时钟域 B 则可能会导致收非所送的情况,即在采集过程中会出现包括亚稳态问题在内的一系列问题,使用异步 FIFO 能够将不同时钟域中的数据同步到所需的时钟域中。

FIFO写入模块代码解析

	module fifo_wr(
2	 input clk , // 时钟信号
3	 input rst_n , // 复位信号
4
5	 input almost_empty, // FIFO 将空信号
6	 input almost_full , // FIFO 将满信号
7 	output reg fifo_wr_en , // FIFO 写使能
8 	output reg [7:0] fifo_wr_data // 写入 FIFO 的数据
9 );
10
11 //reg define
12	 reg [1:0] state ; //动作状态
13 	reg almost_empty_d0 ; //almost_empty 延迟一拍
14 	reg almost_empty_syn ; //almost_empty 延迟两拍
15 	reg [3:0] dly_cnt ; //延迟计数器
16 //*****************************************************
17 //** main code
18 //*****************************************************
19
20 //因为 almost_empty 信号是属于 FIFO 读时钟域的
21 //所以要将其同步到写时钟域中
22 always@( posedge clk ) begin
23	 if( !rst_n ) begin //一旦复位,所有的将空类信号全部归零
24 		almost_empty_d0 <= 1'b0 ;
25		 almost_empty_syn <= 1'b0 ;
26 end
27 	else begin //没有复位的情况下,延时信号前移。
28		 almost_empty_d0 <= almost_empty ;
29 		almost_empty_syn <= almost_empty_d0 ;
30 end
31 end
32
33 //向 FIFO 中写入数据
34 	always @(posedge clk ) begin
35 		if(!rst_n) begin //复位信号开启
36 			fifo_wr_en <= 1'b0;
37 			fifo_wr_data <= 8'd0;
38			 state <= 2'd0;
39 			dly_cnt <= 4'd0;
40 end
41 else begin
42	 case(state)
43	 2'd0: begin
44 		if(almost_empty_syn) begin //如果检测到 FIFO 将被读空(下一拍就会空)
45		 state <= 2'd1; //就进入延时状态
46		 end
47 else
48 		state <= state;
49 end
50		 2'd1: begin  //如果检测到FIFO内数据为空,先延时10拍,等待状态更新,然后开始写。
51			 if(dly_cnt == 4'd10) begin //延时 10 拍
52 			//原因是 FIFO IP 核内部状态信号的更新存在延时
53			 //延迟 10 拍以等待状态信号更新完毕
54 			dly_cnt <= 4'd0;
55 			state <= 2'd2; //开始写操作
56 			fifo_wr_en <= 1'b1; //打开写使能
57 end
58 else
59 		dly_cnt <= dly_cnt + 4'd1;
60 end
61 		2'd2: begin //如果马上写满,关闭写使能,回到状态一,否则持续写。
62 			if(almost_full) begin //等待 FIFO 将被写满(下一拍就会满)
63 			fifo_wr_en <= 1'b0; //关闭写使能
64 			fifo_wr_data <= 8'd0;
65			 state <= 2'd0; //回到第一个状态
66 end
67 else begin //如果 FIFO 没有被写满
68		 fifo_wr_en <= 1'b1; //则持续打开写使能
69 		fifo_wr_data <= fifo_wr_data + 1'd1; //且写数据值持续累加
70 end
71 end
72 		default : state <= 2'd0;
73 endcase
74 end
75 end
76
77 endmodule

fifo_wr 模块的核心部分是一个不断进行状态循环的小状态机,如果检测到 FIFO 为空,则先延时 10
拍,这里注意,由于 FIFO 的内部信号的更新比实际的数据读/写操作有所延时,所以延时 10 拍的目的是等
待 FIFO 的空/满状态信号、数据计数信号等信号的更新完毕之后再进行 FIFO 写操作,如果写满,则回到状
态 0,即等待 FIFO 被读空,以进行下一轮的写操作。

三个状态-依据FIFO先进先出的特点。
1、是否要读空,读空进入延时状态
2、延时状态:延时十拍等待状态更新,并开始写操作,打开写使能
3、是否要写满。写满则回到第一个状态,未写满则继续进行写操作。

同理在FIFO的读模块依据上面的代码既可以编写。整个代码包含三部分:顶层模块( FIFO IP 核、写 FIFO 模块、读 FIFO 模块进行例化),读模块,写模块。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值