本文转载自:十年老鸟的CSDN博客
注:本文由作者授权转发,如需转载请联系作者本人
关键信号说明
同步FIFO中的一些关键信号说明
实际上,我们需要做的就是将上面几个信号的时序做到与IP核的一模一样也就成功了,当然,还有输出数据和data_count的时序也要一样
IP核设置
设置宽度为16,深度为64的FIFO。
配置卡片1:
配置卡片2:
注意,这里output register考虑进去,因为这个地方可以优化时序
卡片3
卡片4:
配置总结:
设计细节
my_fifo:第一版
my_fifo1:第二版,最终用这个
module my_fifo1#(
parameter WIDTH = 16,
parameter DEPTH = 64,
parameter ADDR_WIDTH = clogb2(DEPTH),
parameter PROG_EMPTY_ASSERT = 2,
parameter PROG_EMPTY_DESERT = 3,
parameter PROG_FULL_ASSERT = 62,
parameter PROG_FULL_DESERT = 61,
parameter EMBEDDED_REGISTER = 1
)(
input sys_clk,
input sys_rst,
input [WIDTH-1:0]din,
input wr_en,
input rd_en,
output reg [WIDTH-1:0]dout,
output reg full,
output reg empty,
output reg prog_full,
output reg prog_empty,
output reg almost_full,
output reg almost_empty,
output reg [ADDR_WIDTH-1:0]data_count
);
WIDTH/ DEPTH
PROG_EMPTY_ASSERT/ PROG_EMPTY_DESERT
PROG_FULL_ASSERT/ PROG_FULL_DESERT
EMBEDDED_REGISTER
这些设置是和IP核能够对应上的
仿真验证
所有输出端口进行一对一的对比
reg flag1 = 0;
reg flag2 = 0;
reg flag3 = 0;
reg flag4 = 0;
reg flag5 = 0;
reg flag6 = 0;
reg flag7 = 0;
reg flag8 = 0;
always @(posedge i_clk)
begin
flag1 <= fifo_dou == fifo_dou1;
flag2 <= fifo_full == fifo_full1;
flag3 <= fifo_empty == fifo_empty1;
flag4 <= prog_full == prog_full1;
flag5 <= prog_empty == prog_empty1;
flag6 <= fifo_count == fifo_count1;
flag7 <= almost_empty == almost_empty1;
flag8 <= almost_full == almost_full1;
end
//测试1:连续写入和读出测试full 和 prog_full 和 almost_full 和 empty 和 prog_empty 和 almost_empty
/*
always @(posedge i_clk)
r_cnt <= r_cnt + 1;
assign i_wr_en = r_cnt[15:0] > 15 && r_cnt[15:0] < 150;
assign i_din = r_cnt;
assign rd_en = r_cnt[15:0] > 300 && r_cnt[15:0] < 450;
*/
//测试2:间隔写入和读出测试full 和 prog_full 和 almost_full 和 empty 和 prog_empty 和 almost_empty
/*
always @(posedge i_clk)
r_cnt <= r_cnt + 1;
assign i_wr_en = r_cnt[15:0] < 3000 && r_cnt[3:0] == 15 ;
assign i_din = r_cnt;
assign rd_en = r_cnt[15:0] > 3000 && r_cnt[3:0] == 15;
*/
//测试3:同时写入和读出测试full 和 prog_full 和 almost_full 和 empty 和 prog_empty 和 almost_empty
always @(posedge i_clk)
r_cnt <= r_cnt + 1;
assign i_wr_en = r_cnt[15:0] > 2880 && r_cnt[3:0] == 14 ; //15/14
assign i_din = r_cnt;
assign rd_en = r_cnt[15:0] > 3000 && r_cnt[3:0] == 15;
仿真结果
8个flag输出至始至终是一样的,说明手写RTL和IP核输出时序是完全一致的
最后说明:
资源备份:百度网盘-Xilinx设计-Xilinx同步FIFO
执行srcs中tb_sync_fifo.tcl 文件即可直接仿真