73 lines
1.5 KiB
Verilog
73 lines
1.5 KiB
Verilog
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<<QUEUE_SIZE)-1];
|
|
|
|
always @(posedge CLK_I)
|
|
begin
|
|
if (QUEUE_I & ~FULL_O)
|
|
QUEUE[HEAD] <= DAT_I;
|
|
end
|
|
|
|
generate
|
|
if (WRITE_THROUGH == 0)
|
|
begin : force_queue_out
|
|
assign DAT_O = QUEUE[TAIL];
|
|
end
|
|
else
|
|
begin : write_through_out
|
|
assign DAT_O = (HEAD == TAIL) ? DAT_I : QUEUE[TAIL];
|
|
end
|
|
endgenerate
|
|
|
|
endmodule
|