diff options
| author | uvok | 2026-01-09 15:18:23 +0100 |
|---|---|---|
| committer | uvok | 2026-01-09 15:18:23 +0100 |
| commit | 6c83fd8730e55de8b1daaac1deb111d3d9bd408e (patch) | |
| tree | 33a3dbc4fd87011b657b193224c3f39c5de6b766 /playground/fifo.v | |
| parent | 678cb2d2d752bbac7625ba9b287762b3acabf116 (diff) | |
move stuff around
Diffstat (limited to 'playground/fifo.v')
| -rw-r--r-- | playground/fifo.v | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/playground/fifo.v b/playground/fifo.v new file mode 100644 index 0000000..bcc2d3f --- /dev/null +++ b/playground/fifo.v @@ -0,0 +1,90 @@ +`timescale 1us/1us + +`include "my_mem.v" + +module fifo #( + parameter DATA_WIDTH = 8, + parameter DATA_DEPTH = 1024 +) ( + input rst_i, + input clk_i, + + input write_i, + input read_i, + + output empty_o, + output full_o, + + //output data_valid_o, + + input [(DATA_WIDTH-1) : 0] data_i, + output reg [(DATA_WIDTH-1) : 0] data_o + +); + +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); +/* verilator lint_on WIDTHTRUNC */ + +// need to "count" to number *including* depth +reg [$clog2(DATA_DEPTH + 1)-1:0] r_count; +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; + r_read_addr = 0; + r_write_addr = 0; +end + +always @(posedge clk_i or negedge rst_i) begin + if (!rst_i) + r_count <= 0; + else if (write_i && read_i) + // nothing to do + // count stays the same + ; + else if (write_i && !full_o) + r_count <= r_count + 1; + else if (read_i && !empty_o) + r_count <= r_count - 1; +end + +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 |
