现在开始对上一篇博文介绍的异步FIFO进行功能验证,上一篇博文地址:http://blog.chinaaet.com/crazybird/p/5100000872 。对异步FIFO验证的平台如图1所示。
图1 异步FIFO验证平台
其中,clock为时钟生成器,asyn_fifo_if为产生异步FIFO读写命令的模块,asyn_fifo为异步FIFO设计模块。
验证顶层模块testbench的代码如下所示:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90/*******************************版权申明******************************** ** 电子技术应用网站, CrazyBird ** http://www.chinaaet.com, http://blog.chinaaet.com/crazybird ** **------------------------------文件信息-------------------------------- ** 文件名: clock.v ** 创建者: CrazyBird ** 创建日期: 2016-1-16 ** 版本号: v1.0 ** 功能描述: 时钟生成器 ** ***********************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module testbench; //****************************************************************** // 变量定义 //****************************************************************** wire wr_rst_n; wire wr_clk; wire wr_en; wire [7:0] wr_data; wire wr_full; wire [4:0] wr_cnt; wire rd_rst_n; wire rd_clk; wire rd_en; wire [7:0] rd_data; wire rd_empty; wire [4:0] rd_cnt; //****************************************************************** // 时钟生成器例化 //****************************************************************** clock #( .C_CLK_FREQ(100.0) ) u_clock_wr ( .clk ( wr_clk ) ); clock #( .C_CLK_FREQ(70.0) ) u_clock_rd ( .clk ( rd_clk ) ); //****************************************************************** // 异步FIFO读写指令产生模块例化 //****************************************************************** asyn_fifo_if #( .C_DATA_WIDTH(8) ) u_asyn_fifo_if ( .wr_rst_n ( wr_rst_n ), .wr_clk ( wr_clk ), .wr_en ( wr_en ), .wr_data ( wr_data ), .wr_full ( wr_full ), .rd_rst_n ( rd_rst_n ), .rd_clk ( rd_clk ), .rd_en ( rd_en ), .rd_empty ( rd_empty ) ); //****************************************************************** // 异步FIFO模块例化 //****************************************************************** asyn_fifo #( .C_DATA_WIDTH(8), .C_FIFO_DEPTH_WIDTH (4) ) u_asyn_fifo ( .wr_rst_n ( wr_rst_n ), .wr_clk ( wr_clk ), .wr_en ( wr_en ), .wr_data ( wr_data ), .wr_full ( wr_full ), .wr_cnt ( wr_cnt ), .rd_rst_n ( rd_rst_n ), .rd_clk ( rd_clk ), .rd_en ( rd_en ), .rd_data ( rd_data ), .rd_empty ( rd_empty ), .rd_cnt ( rd_cnt ) ); endmodule
时钟模块clock的代码实现如下所示(时钟的频率可设置):
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40/*******************************版权申明******************************** ** 电子技术应用网站, CrazyBird ** http://www.chinaaet.com, http://blog.chinaaet.com/crazybird ** **------------------------------文件信息-------------------------------- ** 文件名: clock.v ** 创建者: CrazyBird ** 创建日期: 2016-1-16 ** 版本号: v1.0 ** 功能描述: 时钟生成器 ** ***********************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module clock( clk ); //****************************************************************** // 参数定义 //****************************************************************** parameter C_CLK_FREQ = 100.0; //MHz localparam C_CLK_CYCLE = 1000.0 / C_CLK_FREQ; //****************************************************************** // 端口定义 //****************************************************************** output reg clk; //****************************************************************** // 时钟生成 //****************************************************************** initial begin clk = 0; forever #(C_CLK_CYCLE/2) clk = ~clk; end endmodule
本次测试的步骤如下所示:
(1)只写异步FIFO
(2)只读异步FIFO
(3)同时读写异步FIFO
测试步骤的代码在asyn_fifo_if模块中,如下所示:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131/*******************************版权申明******************************** ** 电子技术应用网站, CrazyBird ** http://www.chinaaet.com, http://blog.chinaaet.com/crazybird ** **------------------------------文件信息-------------------------------- ** 文件名: asyn_fifo_if.v ** 创建者: CrazyBird ** 创建日期: 2016-1-16 ** 版本号: v1.0 ** 功能描述: 产生异步FIFO的读写命令 ** ***********************************************************************/ // synopsys translate_off `timescale 1 ns / 1 ps // synopsys translate_on module asyn_fifo_if( wr_rst_n, wr_clk, wr_en, wr_data, wr_full, rd_rst_n, rd_clk, rd_en, rd_empty ); //****************************************************************** // 参数定义 //****************************************************************** parameter C_DATA_WIDTH = 8; //****************************************************************** // 端口定义 //****************************************************************** output reg wr_rst_n; input wr_clk; output reg wr_en; output reg [C_DATA_WIDTH-1:0] wr_data; input wr_full; output reg rd_rst_n; input rd_clk; output reg rd_en; input rd_empty; //****************************************************************** // 内部变量定义 //****************************************************************** reg normal_wr; reg normal_rd; //****************************************************************** // 变量初始化 //****************************************************************** initial begin wr_rst_n = 1'b0; rd_rst_n = 1'b0; normal_wr = 1'b0; normal_rd = 1'b0; #492; wr_rst_n = 1'b1; rd_rst_n = 1'b1; #100; //只写FIFO normal_wr = 1'b1; repeat(20) @(negedge wr_clk); normal_wr = 1'b0; //只读FIFO normal_rd = 1'b1; repeat(20) @(negedge rd_clk); normal_rd = 1'b0; //同时读写FIFO normal_wr = 1'b1; normal_rd = 1'b1; repeat(100) @(negedge wr_clk); normal_wr = 1'b0; normal_rd = 1'b0; repeat(20) @(negedge rd_clk); $stop; end //****************************************************************** // 写FIFO信号的产生 //****************************************************************** always @(negedge wr_clk or negedge wr_rst_n) begin if(wr_rst_n == 1'b0) begin wr_en <= 1'b0; wr_data <= {(C_DATA_WIDTH){1'b0}}; end else if(normal_wr == 1'b1) begin if(wr_full == 1'b0) begin wr_en <= 1'b1; wr_data <= {$random%((1 << C_DATA_WIDTH)-1)}; end else begin wr_en <= 1'b0; wr_data <= {(C_DATA_WIDTH){1'b0}}; end end else begin wr_en <= 1'b0; wr_data <= {(C_DATA_WIDTH){1'b0}}; end end //****************************************************************** // 读FIFO信号的产生 //****************************************************************** always @(negedge wr_clk or negedge wr_rst_n) begin if(wr_rst_n == 1'b0) rd_en <= 1'b0; else if(normal_rd == 1'b1) begin if(rd_empty == 1'b0) rd_en <= 1'b1; else rd_en <= 1'b0; end else rd_en <= 1'b0; end endmodule
modelsim仿真结果如图2~4所示(具体情况可自行分析)。
图2 只写异步FIFO
图3 只读异步FIFO
图4 同时读写异步FIFO
至此,异步FIFO的设计和验证都完成了。现在预告下一篇博文:参数化的优先级编码器设计。哈哈,不要以为很简单哦。记住,是“参数化”,即输入信号的位宽可设置。大家也可以先想想如何实现。也许,灵感一来很快就想出来了,否则,半个小时、1个小时、甚至很多。
转载:http://blog.chinaaet.com/crazybird/p/5100000874
最后
以上就是迅速电话最近收集整理的关于基于FPGA的异步FIFO验证的全部内容,更多相关基于FPGA内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复