diff options
| author | uvok | 2025-12-29 17:21:58 +0100 |
|---|---|---|
| committer | uvok | 2025-12-29 17:21:58 +0100 |
| commit | 3926d7bae115544dcdf11fa4435debd0cfdffa13 (patch) | |
| tree | c7e74917add8e5abb0169a87d1e095c1dacfc355 /fifo.v | |
| parent | 0a4f9bf2fee4e5ebff9b797349e3a477a7013fdf (diff) | |
Fix fifo using memory, fix test bench
Diffstat (limited to 'fifo.v')
| -rw-r--r-- | fifo.v | 79 |
1 files changed, 49 insertions, 30 deletions
@@ -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 |
