Xilinx FIFO Generate IP核(3):读模式详解--标准FIFO vs FWFT模式

1 引言

      在Xilinx FIFO Generator IP核中,读模式的选择直接影响数据流的控制逻辑和系统性能。标准FIFO和首字直通(First Word Fall Through,FWFT)是两种主要的读模式,它们有着本质的区别。

2 基本概念对比

2.1 标准FIFO模式

  • 数据输出时机:需要在rd_en有效后,数据才出现在输出端口

  • 控制逻辑:需要先判断empty信号,再发出读使能

  • 延迟特性:至少1个时钟周期的读取延迟

2.2 FWFT模式(首字直通)

  • 数据输出时机:数据在写入后自动出现在输出端口(只要FIFO非空)

  • 控制逻辑:数据就绪后立即可用,通过rd_en确认消费

  • 延迟特性:零延迟读取,数据立即可用

3 详细工作机制解析

3.1 标准FIFO模式时序

关键点:

        1. 周期2:rd_en=1,但数据A还没有出现在输出

        2. 周期3:数据A出现在dout(延迟1周期)

        3. 周期4:数据B出现在dout(连续读取)

标准FIFO的读取流程:

  1. 检查empty信号为低(FIFO非空)

  2. 拉高rd_en信号

  3. 等待一个时钟周期

  4. 数据出现在dout

3.2 FWFT模式时序

关键点:

        1. 周期1:数据A自动出现在dout,无需rd_en

        2. 周期3:rd_en=1确认消费数据A

        3. 周期3:数据B立即出现在dout

        4. 零延迟读取!

FWFT模式的读取流程:

  1. 数据写入FIFO后自动出现在dout

  2. 检查empty信号为低(数据可用)

  3. 在需要时拉高rd_en确认数据消费

  4. 下一个数据立即出现在dout(如果FIFO中还有数据)

4 内部架构差异

4.1 标准FIFO内部结构

module standard_fifo_internal (
    input wire clk,
    input wire [7:0] din,
    input wire wr_en,
    input wire rd_en,
    output reg [7:0] dout,
    output wire empty
);
    
    // 存储阵列
    reg [7:0] memory [0:15];
    reg [3:0] wr_ptr = 0;
    reg [3:0] rd_ptr = 0;
    
    // 输出寄存器
    reg [7:0] dout_reg;
    
    always @(posedge clk) begin
        // 写入逻辑
        if (wr_en && !full) begin
            memory[wr_ptr] <= din;
            wr_ptr <= wr_ptr + 1;
        end
        
        // 读取逻辑 - 关键区别!
        if (rd_en && !empty) begin
            dout_reg <= memory[rd_ptr];  // 数据从存储读到输出寄存器
            rd_ptr <= rd_ptr + 1;
        end
        
        dout <= dout_reg;  // 输出寄存器驱动dout
    end
    
    assign empty = (wr_ptr == rd_ptr);
    
endmodule

4.2 FWFT模式内部结构

module fwft_fifo_internal (
    input wire clk,
    input wire [7:0] din,
    input wire wr_en,
    input wire rd_en,
    output reg [7:0] dout,
    output wire empty
);
    
    // 存储阵列
    reg [7:0] memory [0:15];
    reg [3:0] wr_ptr = 0;
    reg [3:0] rd_ptr = 0;
    
    // FWFT专用:预取寄存器
    reg [7:0] prefecth_reg;
    reg prefecth_valid = 0;
    
    always @(posedge clk) begin
        // 写入逻辑
        if (wr_en && !full) begin
            memory[wr_ptr] <= din;
            wr_ptr <= wr_ptr + 1;
            
            // FWFT特性:如果输出寄存器为空,立即填充
            if (!prefecth_valid) begin
                prefecth_reg <= din;
                prefecth_valid <= 1;
            end
        end
        
        // 读取逻辑 - FWFT关键机制!
        if (rd_en && prefecth_valid) begin
            // 消费当前预取数据
            dout <= prefecth_reg;
            prefecth_valid <= 0;
            
            // 立即预取下一个数据(如果存在)
            if (!empty) begin
                prefecth_reg <= memory[rd_ptr];
                rd_ptr <= rd_ptr + 1;
                prefecth_valid <= 1;
            end
        end else if (prefecth_valid) begin
            // 保持数据在输出,直到被读取
            dout <= prefecth_reg;
        end
    end
    
    // FWFT的空标志基于预取寄存器
    assign empty = !prefecth_valid;
    
endmodule

5 实际应用场景对比

5.1 标准FIFO适用场景

module standard_fifo_applications;
    // 场景1:需要精确流量控制的数据流水线
    module image_processing_pipeline (
        input wire clk,
        input wire [23:0] pixel_in,
        input wire pixel_valid,
        output wire [23:0] pixel_out,
        output wire processing_ready
    );
        
        // 使用标准FIFO进行精确的流水线控制
        fifo_generator_0 line_buffer (
            .clk(clk),
            .din(pixel_in),
            .wr_en(pixel_valid),
            .dout(pixel_out),
            .rd_en(processing_ready && !empty),
            .empty(empty)
        );
        
        // 处理模块只有在真正需要数据时才读取
        assign processing_ready = !busy;  // 基于处理状态控制读取
    endmodule
    
    // 场景2:与外部设备接口,需要严格的握手协议
    module uart_tx_controller (
        input wire clk,
        input wire [7:0] tx_data,
        input wire tx_valid,
        output reg tx_busy
    );
        
        wire fifo_empty;
        reg rd_en = 0;
        
        fifo_generator_0 tx_fifo (
            .clk(clk),
            .din(tx_data),
            .wr_en(tx_valid),
            .dout(uart_data),
            .rd_en(rd_en),
            .empty(fifo_empty)
        );
        
        // 状态机控制读取时机
        always @(posedge clk) begin
            case(state)
                IDLE: if (!fifo_empty) begin
                    rd_en <= 1;
                    state <= SEND_START;
                end
                SEND_START: begin
                    rd_en <= 0;
                    // 启动UART发送
                end
            endcase
        end
    endmodule
endmodule

5.2 FWFT模式适用场景

module fwft_fifo_applications;
    // 场景1:需要最小延迟的数据处理
    module low_latency_processing (
        input wire clk,
        input wire [31:0] sensor_data,
        input wire data_valid,
        output wire [31:0] processed_data
    );
        
        // 使用FWFT实现零延迟处理
        fifo_generator_1 sensor_fifo (
            .clk(clk),
            .din(sensor_data),
            .wr_en(data_valid),
            .dout(raw_data),  // 数据立即可用!
            .rd_en(1'b1),     // 持续读取可用数据
            .empty()          // 通常不需要检查empty
        );
        
        // 处理模块立即处理到达的数据
        assign processed_data = process_function(raw_data);
    endmodule
    
    // 场景2:DSP算法流水线
    module dsp_pipeline (
        input wire clk,
        input wire [15:0] adc_data,
        output wire [15:0] filter_output
    );
        
        wire [15:0] stage1_out, stage2_out;
        
        // 第一级:FIR滤波
        fir_filter stage1 (
            .clk(clk),
            .data_in(adc_data),
            .data_out(stage1_out)
        );
        
        // FWFT FIFO作为流水线寄存器
        fifo_generator_1 pipe_reg1 (
            .clk(clk),
            .din(stage1_out),
            .wr_en(1'b1),
            .dout(stage2_in),  // 立即传递给下一级
            .rd_en(1'b1)       // 持续流动
        );
        
        // 第二级处理立即开始
        iir_filter stage2 (
            .clk(clk),
            .data_in(stage2_in),
            .data_out(filter_output)
        );
    endmodule
    
    // 场景3:AXI Stream接口兼容
    module axi_stream_bridge (
        input wire aclk,
        input wire [63:0] s_axis_tdata,
        input wire s_axis_tvalid,
        output wire s_axis_tready
    );
        
        // FWFT模式天然适合AXI Stream
        fifo_generator_1 stream_fifo (
            .clk(aclk),
            .din(s_axis_tdata),
            .wr_en(s_axis_tvalid && s_axis_tready),
            .dout(m_axis_tdata),
            .rd_en(m_axis_tready && !empty),
            .full(s_axis_tready),  // 反相作为tready
            .empty(empty)
        );
        
        assign m_axis_tvalid = !empty;
    endmodule
endmodule

6 性能与资源对比

6.1 时序性能分析

标准FIFO时序特性:

- 读取延迟:1个时钟周期

- 最大吞吐量:每个时钟周期1个数据

- 控制复杂度:中等(需要管理empty和rd_en)

FWFT时序特性:

- 读取延迟:0个时钟周期

- 最大吞吐量:每个时钟周期1个数据

- 控制复杂度:低(数据立即可用)

实际测试场景:

在100MHz时钟下,深度1024的FIFO:

标准FIFO:填充到读取的延迟 = 1 + N cycles

FWFT FIFO:填充到读取的延迟 = N cycles(节省1个周期)

6.2 资源使用对比

典型结果:

标准FIFO: LUTs≈50, FFs≈80, BRAMs=1

FWFT FIFO: LUTs≈60, FFs≈100, BRAMs=1 (稍多控制逻辑)

7 设计技巧与最佳实践

7.1 标准FIFO设计技巧

module standard_fifo_design_tips;
    // 技巧1:正确的空标志检查
    always @(posedge clk) begin
        if (!fifo_empty) begin
            rd_en <= 1;
        end else begin
            rd_en <= 0;
        end
    end
    
    // 技巧2:避免在empty变化边界读取
    // 错误做法:可能导致漏读或重复读取
    // 正确做法:使用registered empty信号
    
    // 技巧3:与valid信号配合使用
    assign data_valid = rd_en && !fifo_empty;
endmodule

7.2 FWFT设计技巧

module fwft_fifo_design_tips;
    // 技巧1:简化控制逻辑
    // 数据立即可用,可以直接连接处理逻辑
    assign processor_input = fwft_dout;
    assign fwft_rd_en = processor_ready;
    
    // 技巧2:流水线优化
    // FWFT天然适合流水线设计
    always @(posedge clk) begin
        if (!fwft_empty) begin
            // 立即处理数据,无需等待
            stage1_output <= process_stage1(fwft_dout);
            fwft_rd_en <= 1;  // 确认消费
        end
    end
    
    // 技巧3:背压控制
    // 当处理模块忙时,停止读取
    assign fwft_rd_en = !fwft_empty && !processor_busy;
endmodule

8 总结与选择指南

8.1 核心差异总结

特性标准FIFOFWFT模式
读取延迟1个时钟周期0个时钟周期
数据可用性需要rd_en后出现写入后自动出现
控制逻辑需要管理empty和rd_en时序简化控制,数据就绪即用
资源消耗较少稍多(预取逻辑)
适用场景精确流量控制、外部接口低延迟处理、流水线设计

8.2 选择建议

选择标准FIFO当:

  • 需要精确的流量控制

  • 与外部设备接口,需要严格握手协议

  • 读取时序需要与特定状态机精确配合

  • 资源优化是首要考虑

选择FWFT模式当:

  • 需要最小化处理延迟

  • 设计数据流处理的流水线

  • 与AXI Stream等流协议接口

  • 简化控制逻辑是优先考虑

8.3 实践建议

  1. 新设计推荐FWFT:现代FPGA设计通常受益于低延迟特性

  2. 兼容性考虑:如果替换现有设计,注意时序差异

  3. 性能验证:在实际目标频率下测试两种模式的时序收敛

  4. 资源评估:在资源紧张的设计中评估额外的控制逻辑开销

      通过深入理解这两种读模式的差异,您可以根据具体应用需求做出最合适的选择,优化设计的性能和资源利用率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA_小田老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值