手撕IP核系列——Xilinx FIFO IP核-同步FIFO

本文转载自:十年老鸟的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 文件即可直接仿真

最新文章

最新文章