4. FIFO写操作握手:写请求与写确认、写指针更新机制、写满条件判断

写操作握手,说白了就是数据怎么安全地送进FIFO里。我刚开始做FIFO设计时,总觉得写操作很简单——不就是把数据写进去嘛。结果第一次仿真就出了大问题,数据写丢了,还覆盖了旧数据。嗯,从那以后我再也不敢小看这个握手过程了。

4.1 写请求与写确认:谁说了算?

写操作的核心,是写使能(wr_en)和写确认(wr_ack)的配合。我个人习惯把写使能看作“敲门”,写确认看作“开门”。

  • 写使能(wr_en):外部模块告诉FIFO:“我要写数据了!”
  • 写确认(wr_ack):FIFO回应:“收到,数据已存入。”

你想想看,如果没有写确认,外部模块怎么知道数据真的写进去了?我在项目中遇到过这样的情况:外部模块连续发写请求,但FIFO其实已经满了,结果数据全丢了。所以,写确认信号必须和写指针更新同步。

核心原则:写使能有效且FIFO未满时,数据才被真正写入。写确认在下一个时钟周期拉高。

4.2 写指针更新机制:数据该放哪儿?

写指针(wr_ptr)就是FIFO的“收件员”,它告诉数据该放在哪个地址。每次成功写入一个数据,写指针就加1。

我记得有一次调试,发现写指针跳过了某个地址,数据直接写到了错误的位置。查了半天,原来是写指针更新条件写错了。这里我给大家一个避坑指南:

我曾经踩过的坑:写指针更新不能只看wr_en,还要检查FIFO是否满。如果FIFO满了还更新指针,数据就会覆盖还没读走的内容。

写指针更新的标准写法:

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        wr_ptr <= 0;
    else if (wr_en && !full)
        wr_ptr <= wr_ptr + 1;
end

这里有个细节:wr_en && !full 这个条件,缺一不可。我见过有人只写wr_en,结果FIFO满了还在写,数据全乱套了。

4.3 写满条件判断:什么时候该停?

写满(full)判断,是FIFO设计中最容易出错的地方之一。为什么?因为判断条件不是简单的“写指针追上读指针”。

我给大家画个图,你就明白了:

Addr 0 Addr 1 Addr 2 Addr 3 Addr 4 Addr 5 wr_ptr rd_ptr 满状态:wr_ptr 追上 rd_ptr(但多绕了一圈)

看到了吗?写满的判断,不是简单的 wr_ptr == rd_ptr。因为空状态也是这个条件。那怎么区分?

我的经验:用格雷码(Gray Code)或者加一个额外的标志位。我个人偏爱加一个 full_flag 寄存器,在写操作时判断是否即将满。

写满判断的标准写法:

assign full = (wr_ptr_next == rd_ptr) && wr_en;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        full_reg <= 0;
    else if (wr_en && (wr_ptr_next == rd_ptr))
        full_reg <= 1;
    else if (rd_en)
        full_reg <= 0;
end

这里有个关键点:wr_ptr_next 是写指针的下一个值。如果下一个值等于读指针,说明再写一次就满了。这叫“提前判断”,能避免溢出。

4.4 写操作握手完整流程

把上面三个部分串起来,写操作的完整流程是这样的:

  1. 外部模块拉高 wr_en,同时把数据放到 wr_data 总线上
  2. FIFO检查 full 信号:如果未满,接收数据,更新写指针
  3. 下一个时钟周期,拉高 wr_ack,告诉外部模块“数据已收”
  4. 如果FIFO满了,wr_ack 保持低电平,数据被忽略

重要提醒:写确认信号不能和写使能同时有效。我见过有人把这两个信号连在一起,结果每个时钟周期都写两次数据,FIFO直接爆炸。

4.5 常见问题与避坑

问题 原因 解决方案
数据写丢 写使能有效时FIFO已满 检查full信号后再写
写指针乱跳 更新条件没加满判断 wr_en && !full
满状态误判 wr_ptr == rd_ptr 无法区分空/满 加额外标志位或用格雷码
写确认延迟 组合逻辑路径太长 用寄存器打一拍

嗯,写操作握手这部分,说白了就是三个字:稳、准、狠。稳——数据不能丢;准——指针不能偏;狠——满了一定要停。我在项目中吃过亏,所以特别强调这些细节。你设计的时候,多想想边界情况,基本就不会出大问题。

小技巧:仿真时故意让写操作连续不停,看看FIFO满了之后数据会不会丢失。这是检验写操作握手是否正确的“试金石”。

可可精品资料库