设计背景:
First Input First Output的缩写,先入先出队列,这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。FIFO是队列机制中最简单的,每个接口上都存在FIFO队列,表面上看FIFO队列并没有提供什么QoS(Quality of Service,服务质量)保证,甚至很多人认为FIFO严格意义上不算做一种队列技术,实则不然,FIFO是其它队列的基础,FIFO也会影响到衡量QoS的关键指标:报文的丢弃、延时、抖动。既然只有一个队列,自然不需要考虑如何对报文进行复杂的流量分类,也不用考虑下一个报文怎么拿、拿多少的问题,而且因为按顺序取报文,FIFO无需对报文重新排序。简化了这些实现其实也就提高了对报文时延的保证。
设计原理:
本次的设计主要通过调用FIFO的IP核来设置一个简单的单口FIFO,也就是说读写时钟为相同的时钟。其设置流程如下所示也如rom,ram,设置一样的打开步骤
如下如选择FIFO,然后写入生成的FIFO文件名,my_fifo,下一步
设置合适的数据位宽和深度,之后下一步
出现了空满标志位,full,emty,我们去掉数据个数标志usedw.下一步
之后不停的下一步,出现下面的界面选择生成的文件,然后就完成简单的FIFO设计
设计架构图:
设计代码:
顶层模块:
0 module top (clk,rst_n,q); //输入输出端口
1 input clk;
2 input rst_n;
3 output [7:0]q;
4 wire wrreq; //写使能信号
5 wire rdreq; //读使能信号
6 wire empty; //空标志位
7 wire full; //满标志位
8 wire [7:0] data;
9
10 fifo_control fifo_control ( //FIFO控制器的例化
11 .clk(clk),
12 .rst_n(rst_n),
13 .full(full),
14 .empty(empty),
15 .wrreg(wrreq),
16 .rdreg(rdreq),
17 .data(data)
18 );
19 my_fifo my_fifo ( //生成IP核的例化
20 .clock ( clk ),
21 .data ( data ),
22 .rdreq ( rdreq ),
23 .wrreq ( wrreq ),
24 .empty ( empty ),
25 .full ( full),
26 .q ( q )
27 );
28
29 endmodule
设计模块
0 module fifo_control ( //端口列表
1 input clk,
2 input rst_n,
3 input full, //满标志
4 input empty, //空标志
5 output reg wrreg, //写使能
6 output reg rdreg, //读使能
7 output reg [7:0] data
8 );
9 reg state;
10 always @(posedge clk or negedge rst_n)
11 if (!rst_n)
12 begin
13 data<=0;
14 wrreg<=0; //写使能关闭
15 rdreg<=0; //读使能关闭
16 state <= 0;
17 end
18 else
19 begin
20 case (state)
21 0: if(empty) //判断是否为空,为空写
22 begin
23 wrreg<=1;
24 data <= data + 1;
25 end
26 else if (full) //判断否写满,为满不写
27 begin
28 state <= 1;
29 wrreg<=0;
30 rdreg<=1;
31 data<=0;
32 end
33 else
34 begin
35 wrreg<=1;
36 data <= data + 1;
37 end
38
39 1:begin
40 if (empty) //判断是否读空,读空关闭读使能
41 begin
42 rdreg<=0;
43 state <= 0;
44 end
45 end
46 endcase
47 end
48
49 endmodule
测试模块
0 `timescale 1ns/1ps
1 module fifo_tb;
2
3 reg clk;
4 reg rst_n;
5 wire [7:0] q;
6 initial begin
7 clk = 0;
8 rst_n = 0;
9
10 #200 rst_n=1;
11
12 end
13 always #10 clk=~clk;
14 top top(
15 .clk(clk),
16 .rst_n(rst_n),
17 .q(q)
18 );
19
20 endmodule
仿真图:
从仿真空可以看到。我们写入的数据是1--255--0,读出的数据也是从1开始读再到0。
这样就完成了一个简单的FIFO,如果要生成双口的结局跨时钟问题可以在设置时,下面页面选择
来进行设置
全部0条评论
快来发表一下你的评论吧 !