Write a synchronous FIFO code.
Notice: You can start with this question where you are required to design it first using logic gates and sequential elements.
Answer
module fifo #(parameter FIFO_DEPTH=16 , FIFO_WIDTH=8) (
input clk, // Clock
input reset, // Reset
// Write Port
input write_en, // Write enable
input [FIFO_WIDTH-1:0] data_in, // FIFO Input Data
output empty, // FIFO empty indication
// Read Port
input read_en, // Read enable
output full, // FIFO full indication
output reg [FIFO_WIDTH-1:0] data_out // FIFO Output Data
);
parameter PTR_DEPTH = $clog2(FIFO_DEPTH);
reg [FIFO_WIDTH-1:0] mem_array [0:FIFO_DEPTH-1];
reg [PTR_DEPTH-1:0] fifo_counter;
reg [PTR_DEPTH-1:0] next_fifo_counter;
wire [1:0] sel;
integer i;
assign sel = {write_en, read_en};
assign full = (fifo_counter == FIFO_DEPTH - 1);
assign empty = (fifo_counter == 0);
always @* begin
if(reset)
next_fifo_counter = 0;
else begin
case(sel)
2'b01 : next_fifo_counter = fifo_counter - 1;
2'b10 : next_fifo_counter = fifo_counter + 1;
default : next_fifo_counter = fifo_counter;
endcase
end
end
always @ (posedge clk) fifo_counter <= next_fifo_counter;
always @ (posedge clk) begin
if(write_en) begin
mem_array[0] <= data_in;
for (i = 0; i < FIFO_DEPTH-1; i = i + 1) begin
mem_array[i+1] <= mem_array[i];
end
end
end
always @ (posedge clk) begin
if(reset)
data_out <= 0;
else if(read_en) begin
data_out <= mem_array[fifo_counter-1];
end
end
endmodule
Next Question>>>