From 3926d7bae115544dcdf11fa4435debd0cfdffa13 Mon Sep 17 00:00:00 2001 From: uvok Date: Mon, 29 Dec 2025 17:21:58 +0100 Subject: Fix fifo using memory, fix test bench --- fifo.tb.v | 6 ++--- fifo.v | 79 +++++++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/fifo.tb.v b/fifo.tb.v index 58fc084..3238eba 100644 --- a/fifo.tb.v +++ b/fifo.tb.v @@ -38,14 +38,14 @@ end always #10 clk_i = ~clk_i; initial begin - #10 + #15 - for (integer run = 0; run < 2; run++) begin + for (integer run = 1; run < 3; run++) begin write_i = 1; for (integer addr = 0; addr < 10; addr++) begin - data_i = addr + run; + data_i = (run << 4) | addr; #20 ; end diff --git a/fifo.v b/fifo.v index eaaa8a8..30b963e 100644 --- a/fifo.v +++ b/fifo.v @@ -1,5 +1,7 @@ `timescale 1us/1us +`include "my_mem.v" + module fifo #( parameter DATA_WIDTH = 8, parameter DATA_DEPTH = 1024 @@ -20,11 +22,36 @@ module fifo #( ); +localparam DATA_DEPTH_BITS = $clog2(DATA_DEPTH); + +// the -1 will make sure it fits +/* verilator lint_off WIDTHTRUNC */ +localparam [DATA_DEPTH_BITS-1:0] MAX_ADDRESS = (DATA_DEPTH - 1); + // need to "count" to number *including* depth reg [$clog2(DATA_DEPTH + 1)-1:0] r_count; -reg [(DATA_WIDTH-1) : 0] r_datastore [(DATA_DEPTH-1) : 0]; -reg [$clog2(DATA_DEPTH)-1:0] r_read_addr; -reg [$clog2(DATA_DEPTH)-1:0] r_write_addr; +reg [DATA_DEPTH_BITS-1:0] r_read_addr; +reg [DATA_DEPTH_BITS-1:0] r_write_addr; + +assign empty_o = r_count == 0; +assign full_o = r_count == DATA_DEPTH; + +wire int_wr_en = write_i && !full_o; +wire int_rd_en = read_i && !empty_o; + +my_mem #( + .DATA_WIDTH(DATA_WIDTH), + .DATA_DEPTH(DATA_DEPTH) +) fifo_mem ( + .clk_i(clk_i), + .write_en_i(int_wr_en), + .read_en_i(int_rd_en), + .r_read_addr(r_read_addr), + .r_write_addr(r_write_addr), + + .data_i(data_i), + .data_o(data_o) +); initial begin r_count = 0; @@ -33,38 +60,30 @@ initial begin end always @(posedge clk_i or negedge rst_i) begin - if (!rst_i) begin + if (!rst_i) r_count <= 0; - r_read_addr <= 0; - r_write_addr <= 0; - end else if (write_i && read_i) begin - r_count <= r_count + 1; - r_datastore[r_write_addr] <= data_i; + else if (write_i && read_i) // nothing to do - end else if (write_i && !full_o) begin + // count stays the same + ; + else if (write_i && !full_o) r_count <= r_count + 1; - r_datastore[r_write_addr] <= data_i; - end else if (read_i && !empty_o) begin + else if (read_i && !empty_o) r_count <= r_count - 1; - end - - if (!rst_i) begin - end else if (write_i && !full_o) begin - // the_verilator wrongly (???) assumes DATA_DEPTH-1 requires 1 more bit than it does? - if ({1'b0, r_write_addr} < (DATA_DEPTH - 1)) - r_write_addr <= r_write_addr + 1; - else - r_write_addr <= 0; - end else if (read_i && !empty_o) begin - // the_verilator wrongly (???) assumes DATA_DEPTH-1 requires 1 more bit than it does? - if ({1'b0, r_read_addr} < (DATA_DEPTH - 1)) - r_read_addr <= r_read_addr + 1; - else - r_read_addr <= 0; - end end -assign empty_o = r_count == 0; -assign full_o = r_count == DATA_DEPTH; +always @(posedge clk_i or negedge rst_i) begin + if (!rst_i) + r_read_addr <= 0; + else if (read_i && !empty_o) + r_read_addr <= (r_read_addr < MAX_ADDRESS) ? (r_read_addr + 1) : 0; +end + +always @(posedge clk_i or negedge rst_i) begin + if (!rst_i) + r_write_addr <= 0; + else if (write_i && !full_o) + r_write_addr <= (r_write_addr < MAX_ADDRESS) ? (r_write_addr + 1) : 0; +end endmodule -- cgit v1.2.3