summaryrefslogtreecommitdiff
path: root/fifo.v
diff options
context:
space:
mode:
authoruvok2025-12-29 17:21:58 +0100
committeruvok2025-12-29 17:21:58 +0100
commit3926d7bae115544dcdf11fa4435debd0cfdffa13 (patch)
treec7e74917add8e5abb0169a87d1e095c1dacfc355 /fifo.v
parent0a4f9bf2fee4e5ebff9b797349e3a477a7013fdf (diff)
Fix fifo using memory, fix test bench
Diffstat (limited to 'fifo.v')
-rw-r--r--fifo.v79
1 files changed, 49 insertions, 30 deletions
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