module FIFO (CLK_I, RST_I, DAT_I, DAT_O, QUEUE_I, DEQUEUE_I, EMPTY_O, FULL_O); // entries = 2**QUEUE_SIZE parameter QUEUE_SIZE = 2; parameter DATA_WIDTH = 32; // If true, queue and dequeue can be simultaneous // on empty and full queues. Otherwise data must // pass through the queue first, costing one cycle. parameter WRITE_THROUGH = 0; input CLK_I, RST_I, QUEUE_I, DEQUEUE_I; input [DATA_WIDTH-1:0] DAT_I; output [DATA_WIDTH-1:0] DAT_O; output EMPTY_O, FULL_O; reg [QUEUE_SIZE-1:0] HEAD = 0; reg [QUEUE_SIZE-1:0] TAIL = 0; wire [QUEUE_SIZE-1:0] NEXT_HEAD = HEAD + 1; generate if (WRITE_THROUGH == 0) begin : force_queue assign EMPTY_O = (HEAD == TAIL); assign FULL_O = (NEXT_HEAD == TAIL); end else begin : write_through assign EMPTY_O = (HEAD == TAIL) & ~QUEUE_I; assign FULL_O = (NEXT_HEAD == TAIL) & ~DEQUEUE_I; end endgenerate always @(posedge CLK_I) begin if (RST_I) begin HEAD <= 0; TAIL <= 0; end else begin if (QUEUE_I & ~FULL_O) HEAD <= HEAD + 1; if (DEQUEUE_I & ~EMPTY_O) TAIL <= TAIL + 1; end end // synthesis attribute ram_style of QUEUE is distributed; reg [DATA_WIDTH-1:0] QUEUE[0:(1<