同步 FIFO

/*---------深度16,位宽8bit同步fifo-----------*/
module Syn_fifo (
    input       clk,
    input       rst_n,
    input       wr_en,
    input       rd_en,
    input [7:0] din,    //fifo 位宽

    output reg [7:0] dout,
    output      full,empty

);

reg [3:0] wr_ptr;
reg [3:0] rd_ptr;
reg [3:0] cnt;

reg [7:0] mem[0:15];

assign full = (cnt == 4'd15);
assign empty = (cnt == 4'd0);
/*---------cnt;else 中含同时读写--------*/
always@(posedge clk or negedge rst_n)
    if (!rst_n)
        cnt <= 4'd0;
    else if (!full && wr_en) 
        cnt <= cnt + 4'd1;
    else if (!empty && rd_en)
        cnt <= cnt - 4'd1;
    else 
        cnt <= cnt;
/*-------------读数据----------------*/
always@(posedge clk or negedge rst_n)
    if (!rst_n)
        dout <= 8'd0;
    else if (rd_en && !empty)
        dout <= mem[rd_ptr]

/*-------------写数据--------------*/
always@(posedge clk)
    if (wr_en && !full)
        mem[wr_ptr] <=din;

/*-----------更新读写指针-------------*/
always@(posedge clk or negedge rst_n)
    if (!rst_n)
        wr_ptr <= 4'b0;
    else if(!full && wr_en)
        wr_ptr <=wr_ptr + 4'd1;
    else 
        wr_ptr <=wr_ptr;
      
always@(posedge clk or negedge rst_n)
    if (!rst_n)
        rd_ptr <= 4'd0;
    else if(!empty && rd_en)
        rd_ptr <=rd_ptr - 4'd1;
    else 
        rd_ptr <=rd_ptr;

endmodule
同步 FIFO(First In First Out)是一种先进先出的数据缓存结构,其读写操作共享同一个时钟域。这种设计简化了控制逻辑和状态标志的生成,使其适用于单一时钟域内的数据缓冲需求。 ### 实现原理 同步 FIFO 的核心由一个存储单元(通常是一个二维数组)、读指针、写指针以及空满标志组成。具体实现中: - **存储单元**:用于存储数据,深度和宽度可配置。 - **读指针**:指向下一个要读取的数据位置。 - **写指针**:指向下一个要写入的位置。 - **空标志**:当读指针与写指针相等时,表示 FIFO 为空。 - **满标志**:当写指针追上读指针一圈后,表示 FIFO 已满。 在每次时钟上升沿触发时,根据读使能(`read_en`)和写使能(`write_en`)信号的状态决定是否执行读写操作。如果 FIFO 非空并且 `read_en` 有效,则从 FIFO 中读取数据;如果 FIFO 未满并且 `write_en` 有效,则将数据写入 FIFO。 以下是一个简化的 Verilog 实现示例: ```verilog module sync_fifo #(parameter DATA_WIDTH = 8, DEPTH = 16) ( input clk, input rst_n, input write_en, input [DATA_WIDTH-1:0] data_in, input read_en, output reg [DATA_WIDTH-1:0] data_out, output full, output empty ); reg [DATA_WIDTH-1:0] mem [0:DEPTH-1]; reg [$clog2(DEPTH)-1:0] wr_ptr, rd_ptr; wire [DATA_WIDTH-1:0] next_data_out; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin wr_ptr <= 0; rd_ptr <= 0; data_out <= 0; end else begin if (write_en && !full) begin mem[wr_ptr] <= data_in; wr_ptr <= wr_ptr + 1; end if (read_en && !empty) begin data_out <= mem[rd_ptr]; rd_ptr <= rd_ptr + 1; end end end assign full = (wr_ptr == rd_ptr) ? ((wr_ptr == DEPTH - 1) ? 1'b1 : 1'b0) : 1'b0; assign empty = (wr_ptr == rd_ptr) ? 1'b1 : 1'b0; endmodule ``` 上述代码中,`full` 和 `empty` 标志通过比较 `wr_ptr` 和 `rd_ptr` 来确定 FIFO 状态[^3]。 ### 应用场景 同步 FIFO 常用于需要在同一时钟域内进行数据缓冲的应用,例如: - **流水线处理**:在数字信号处理或图像处理中,作为阶段间的数据缓冲区。 - **数据速率匹配**:当生产数据的速度与消费数据的速度不一致时,用来平衡两者之间的差异。 - **突发数据传输**:允许接收方以自己的节奏处理来自发送方的突发性数据流。 - **硬件接口通信**:如 UART、SPI 或 I²C 接口中的数据收发缓冲。 由于同步 FIFO 的简单性和较低的资源消耗,它非常适合于那些不需要跨时钟域传输数据的设计场景[^4]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值