diff --git a/lib/fifo/sync/fifo_sync.sv b/lib/fifo/sync/fifo_sync.sv index 33cad34..ae388a1 100644 --- a/lib/fifo/sync/fifo_sync.sv +++ b/lib/fifo/sync/fifo_sync.sv @@ -14,7 +14,8 @@ module fifo_sync #( output wire [DATA_WIDTH-1:0] dout, output wire empty, output wire full, - output wire [$clog2(DEPTH):0] data_count + output wire [$clog2(DEPTH):0] fill_level, + output reg err ); localparam ADDR_WIDTH = $clog2(DEPTH); @@ -37,15 +38,23 @@ module fifo_sync #( always @(posedge clk or negedge rst_n) begin if (!rst_n) begin rd_ptr <= 0; - end else if (rd_en && !empty) begin - rd_ptr <= rd_ptr + 1'b1; + err <= 1'b0; + end else begin + if (rd_en && empty) begin + err <= 1'b1; + end else begin + err <= 1'b0; + end + if (rd_en && !empty) begin + rd_ptr <= rd_ptr + 1'b1; + end end end // 数据计数 - assign data_count = wr_ptr - rd_ptr; + assign fill_level = wr_ptr - rd_ptr; assign empty = (wr_ptr == rd_ptr); - assign full = (data_count == DEPTH); + assign full = (fill_level == DEPTH); generate if (USE_RAM) begin : USE_RAM_BLOCK diff --git a/tb/fifo/sync/fifo_sync_tb.sv b/tb/fifo/sync/fifo_sync_tb.sv index 5c31292..600cbbb 100644 --- a/tb/fifo/sync/fifo_sync_tb.sv +++ b/tb/fifo/sync/fifo_sync_tb.sv @@ -15,7 +15,8 @@ module fifo_sync_tb; wire [DATA_WIDTH-1:0] dout; wire empty; wire full; - wire [$clog2(DEPTH):0] data_count; + wire [$clog2(DEPTH):0] fill_level; + wire err; // 实例化DUT fifo_sync #( @@ -32,7 +33,8 @@ module fifo_sync_tb; .dout(dout), .empty(empty), .full(full), - .data_count(data_count) + .fill_level(fill_level), + .err(err) ); // 时钟生成 @@ -81,6 +83,14 @@ module fifo_sync_tb; if (!empty) $display("[TB][ERROR] FIFO未空!"); else $display("[TB][INFO] FIFO已空!"); + // 尝试在empty时读,触发err + @(negedge clk); + rd_en = 1; + @(negedge clk); + rd_en = 0; + if (err) $display("[TB][INFO] 读空FIFO触发err信号"); + else $display("[TB][ERROR] 读空FIFO未触发err!"); + // 交错写读 for (int i = 0; i < 8; i++) begin @(negedge clk); @@ -100,9 +110,11 @@ module fifo_sync_tb; // 监控输出 always @(posedge clk) begin if (wr_en && !full) - $display("[TB][WRITE] @%0t: din=%0d, wr_ptr=%0d", $time, din, dut.wr_ptr); + $display("[TB][WRITE] @%0t: din=%0d, wr_ptr=%0d, fill_level=%0d", $time, din, dut.wr_ptr, fill_level); if (rd_en && !empty) - $display("[TB][READ ] @%0t: dout=%0d, rd_ptr=%0d", $time, dout, dut.rd_ptr); + $display("[TB][READ ] @%0t: dout=%0d, rd_ptr=%0d, fill_level=%0d", $time, dout, dut.rd_ptr, fill_level); + if (err) + $display("[TB][ERR ] @%0t: 读空FIFO!", $time); end endmodule