vivado ip核 FIFO的配置与调用

本文介绍了 FIFO 常见的作用,通过一步步配置,再到例程和 testbench 实现一个 FIFO IP 核的调用 。


xilinx 的 FIFO generator core 支持 Native interface FIFOs, AXI Memory Mapped interface FIFOs 和 AXI4-Stream interface FIFOs。

AXI Memory Mapped 和 AXI4-Stream interface FIFOs 是由 Native interface FIFO 衍生出来的。

目录

FIFO 的用处

FIFO 各端口含义

FIFO 的配置及仿真结果

FIFO 的调用、代码


FIFO 的用处

Native interface FIFOs 可用于数据宽度转换、跨时钟域处理。

数据宽度转换:例如从8位宽的数据变换到 16 位宽的数据,即输入 8 位宽数据,输出补成 16 位宽。

跨时钟域处理:例如数据采集时钟为 20 MHz,而数据处理时钟为 100 MHz,则可通过 FIFO 将数据从 20 MHz 转换到 100 MHz。

FIFO 各端口含义

输入端口:
  wr_clk       写时钟
  rd_clk        读时钟
  din             输入数据
  wr_en        写使能
  rd_en         读使能

输出端口:
  dout           输出数据
  full             满标记
  wr_ack      写应答
  empty        空标记
  valid          输出有效标记
  rd_data_count               读计数
  wr_data_count              写计数
  almost_full                    快满标记
  overflow                        写溢出标记
  almost_empty               快空标记
  underflow                      读溢出标记

具体使用FIFO 的配置中会说明。

FIFO 的配置及仿真结果

配置

 

④ 具体选哪种资源看情况,下表列出对比

⑤ standard mode 和 First Word Fall Through的仿真对比见仿真部分

⑥ 当我们选 write depth 为16时,后面接着一句 actual write depth : 15,意味着实际上的写深度为15,这在仿真结果也可以看到。

配置好后点生成 IP 核。

仿真

standard modeFirst Word Fall Through

图1 Standard mode,第一个数据是 1,只有当 rd_en 为高电平时,dout 才从 1 开始依次输出数据 ,valid 也是在 rd_en 为高电平后一个时钟拉高
 
图2 First Word Fall Through,第一个数据为 1,rd_en还未拉高时 dout 就输出 1,valid 也拉高,直到 rd_en 为高电平时才继续读取数据

 

⑦ 可选信号及可配置标记位 

wr_ack :wr_en 为高电平,立即写入 din 的第一个数据,这点可以从dout的第一个数据开出。在 wr_en 拉高后的下一个写时钟上升沿,wr_ack 拉高,表明上一周期写入成功。

almost full 、full、overflow :写入 15个数据后 full 拉高,在第14个数据时 almost full 拉高,若写满后 wr_en 仍为高电平(继续写入),则 overflow 拉高,表示溢出。改代码使写满后wr_en为低电平,则 overflow 始终为低电平,见下两图对比 。

此 FIFO 设置深度时设为 16,实际上,从仿真结果看,仅写入15个数据就满了。

将可配置满标记阈值设为 10,由仿真结果,当 wr_data_count 数到10时,prog_full 拉高,实际上,wr_data_count 有两个时钟周期的延迟,因此,此时写入的是第12个数据

almost empty、 empty 、underflow:rd_en 为高电平时,并没有立即开始读出,这点与写入不同,直到下一个读时钟周期,dout 才输出读的第一个数据,同时 valid 拉高,读到第14个数据,empty 拉高,表示读空了,第13个数据时 almost empty 拉高,若读空后rd_en仍为高电平(继续读出),则 underflow 电平拉高,表示溢出。类似于 overflow ,当读空时 rd_en 为低电平,则underflow始终为低电平。

此 FIFO 设置深度时设为 16,写入了 15 个数据,实际上,从仿真结果看,仅读出 14 个数据就空了。

将可配置空标记阈值设为 5,由仿真结果,当 rd_data_count 为5时,prog_empty 拉高。

 

FIFO 的调用、代码

在 sources 里的 IP sources ,打开.veo文件,划到最后,可以看到 FIFO 的例化,直接复制使用即可。

在代码中定义端口并例化 FIFO

module t1(
	input wire rst,
	input wire wr_clk,
	input wire rd_clk,
	input wire [4 : 0] din,
	input wire wr_en,
	input wire rd_en,
	output wire [4 : 0] dout,
	output wire full,
	output wire wr_ack,
	output wire empty,
	output wire valid,
	output wire [3 : 0] rd_data_count,
	output wire [3 : 0] wr_data_count,
	output wire almost_full,
	output wire overflow,
	output wire almost_empty,
	output wire underflow
	);

fifo_generator_0 fifo_inst2 (
  .rst(rst),                      // input wire rst
  .wr_clk(wr_clk),                // input wire wr_clk
  .rd_clk(rd_clk),                // input wire rd_clk
  .din(din),                      // input wire [4 : 0] din
  .wr_en(wr_en),                  // input wire wr_en
  .rd_en(rd_en),                  // input wire rd_en
  .dout(dout),                    // output wire [4 : 0] dout
  .full(full),                    // output wire full
  .wr_ack(wr_ack),                // output wire wr_ack
  .empty(empty),                  // output wire empty
  .valid(valid),                  // output wire valid
  .rd_data_count(rd_data_count),  // output wire [3 : 0] rd_data_count
  .wr_data_count(wr_data_count),  // output wire [3 : 0] wr_data_count
  .almost_full(almost_full),      // output wire almost_full
  .overflow(overflow),            // output wire overflow
  .almost_empty(almost_empty),    // output wire almost_empty
  .underflow(underflow)           // output wire underflow

  // .wr_rst_busy(wr_rst_busy),      // output wire wr_rst_busy
  // .rd_rst_busy(rd_rst_busy)      // output wire rd_rst_busy
);
endmodule

写测试文件

`timescale 1ns/1ps
module test_tb();
reg                 rst;
reg                 wr_clk;
reg                 rd_clk;
reg      [4 : 0]    din;
wire                 wr_en;
wire                 rd_en;
wire     [4 : 0]    dout;
wire                full;
wire                wr_ack;
wire                empty;
wire                valid;
wire     [3 : 0]    rd_data_count;
wire     [3 : 0]    wr_data_count;
wire                almost_full;
wire                overflow;
wire                almost_empty;
wire                underflow;


//读时钟
initial rd_clk = 1;
always#5 rd_clk = ~rd_clk;

//写时钟
initial wr_clk = 1;
always#25 wr_clk = ~wr_clk;

//读使能、写使能
assign wr_en = ((~rd_en) && (~full));
assign rd_en = ((~wr_en) && (~empty));

//写数据 
always @ ( posedge wr_clk ) begin
    if ( rst )
        din <= 5'd1;
    else if ( wr_en )
        din <= din + 1'b1;
end

initial begin
    rst = 1;
    #11;
    rst = 0;

end

//例化
t1 t1_inst(
    .rst            ( rst           ),
    .wr_clk         ( wr_clk        ),
    .rd_clk         ( rd_clk        ),
    .din            ( din           ),
    .wr_en          ( wr_en         ),
    .rd_en          ( rd_en         ),
    .dout           ( dout          ),
    .full           ( full          ),
    .wr_ack         ( wr_ack        ),
    .empty          ( empty         ),
    .valid          ( valid         ),
    .rd_data_count  ( rd_data_count ),
    .wr_data_count  ( wr_data_count ),
    .almost_full    (almost_full    ),   
    .overflow       (overflow       ),   
    .almost_empty   (almost_empty   ),       
    .underflow      (underflow      )    
    );
endmodule

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值