`include "ethmac_defines.v" `include "timescale.v" module eth_fifo (data_in, data_out, clk, reset, write, read, clear, almost_full, full, almost_empty, empty, cnt); parameter DATA_WIDTH = 32; parameter DEPTH = 8; parameter CNT_WIDTH = 4; input clk; input reset; input write; input read; input clear; input [DATA_WIDTH-1:0] data_in; output [DATA_WIDTH-1:0] data_out; output almost_full; output full; output almost_empty; output empty; output [CNT_WIDTH-1:0] cnt; `ifdef ETH_FIFO_XILINX `else `ifdef ETH_ALTERA_ALTSYNCRAM `else reg [DATA_WIDTH-1:0] fifo [0:DEPTH-1]; reg [DATA_WIDTH-1:0] data_out; `endif `endif reg [CNT_WIDTH-1:0] cnt; reg [CNT_WIDTH-2:0] read_pointer; reg [CNT_WIDTH-2:0] write_pointer; always @ (posedge clk or posedge reset) begin if(reset) cnt <= 0; else if(clear) cnt <= { {(CNT_WIDTH-1){1'b0}}, read^write}; else if(read ^ write) if(read) cnt <= cnt - 1; else cnt <= cnt + 1; end always @ (posedge clk or posedge reset) begin if(reset) read_pointer <= 0; else if(clear) read_pointer <= { {(CNT_WIDTH-2){1'b0}}, read}; else if(read & ~empty) read_pointer <= read_pointer + 1'b1; end always @ (posedge clk or posedge reset) begin if(reset) write_pointer <= 0; else if(clear) write_pointer <= { {(CNT_WIDTH-2){1'b0}}, write}; else if(write & ~full) write_pointer <= write_pointer + 1'b1; end assign empty = ~(|cnt); assign almost_empty = cnt == 1; assign full = cnt == DEPTH; assign almost_full = &cnt[CNT_WIDTH-2:0]; `ifdef ETH_FIFO_XILINX xilinx_dist_ram_16x32 fifo ( .data_out(data_out), .we(write & ~full), .data_in(data_in), .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer), .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer), .wclk(clk) ); `else // !ETH_FIFO_XILINX `ifdef ETH_ALTERA_ALTSYNCRAM altera_dpram_16x32 altera_dpram_16x32_inst ( .data (data_in), .wren (write & ~full), .wraddress (clear ? {CNT_WIDTH-1{1'b0}} : write_pointer), .rdaddress (clear ? {CNT_WIDTH-1{1'b0}} : read_pointer ), .clock (clk), .q (data_out) ); //exemplar attribute altera_dpram_16x32_inst NOOPT TRUE `else // !ETH_ALTERA_ALTSYNCRAM always @ (posedge clk) begin if(write & clear) fifo[0] <= data_in; else if(write & ~full) fifo[write_pointer] <= data_in; end always @ (posedge clk) begin if(clear) data_out <= fifo[0]; else data_out <= fifo[read_pointer]; end `endif // !ETH_ALTERA_ALTSYNCRAM `endif // !ETH_FIFO_XILINX endmodule