// address generator/counter module addr_gen #( parameter MAX_DATA=256 ) ( input en, clk, rst, output reg [AWIDTH-1:0] addr ); localparam AWIDTH = $clog2(MAX_DATA); initial addr <= 0; // async reset // increment address when enabled always @(posedge clk or posedge rst) if (rst) addr <= 0; else if (en) begin if (addr == MAX_DATA-1) addr <= 0; else addr <= addr + 1; end endmodule //addr_gen // Define our top level fifo entity module fifo #( parameter MAX_DATA=256 ) ( input wen, ren, clk, rst, input [7:0] wdata, output reg [7:0] rdata, output reg [AWIDTH:0] count ); localparam AWIDTH = $clog2(MAX_DATA); // fifo storage // sync read before write wire [AWIDTH-1:0] waddr, raddr; reg [7:0] data [MAX_DATA-1:0]; always @(posedge clk) begin if (wen) data[waddr] <= wdata; rdata <= data[raddr]; end // storage // addr_gen for both write and read addresses addr_gen #(.MAX_DATA(MAX_DATA)) fifo_writer ( .en (wen), .clk (clk), .rst (rst), .addr (waddr) ); addr_gen #(.MAX_DATA(MAX_DATA)) fifo_reader ( .en (ren), .clk (clk), .rst (rst), .addr (raddr) ); // status signals initial count <= 0; always @(posedge clk or posedge rst) begin if (rst) count <= 0; else if (wen && !ren) count <= count + 1; else if (ren && !wen) count <= count - 1; end endmodule