Verilog HDL Examples - FIFO Design - Synchronous FIFOs
Synchronous FIFO Design :
Lets have a look at below block diagram of Synchronous FIFO. Further we will have a look at its Verilog HDL implementation.
For synchronous FIFO design (a FIFO where writes to, and reads from the FIFO buffer are conducted in the same clock domain), one implementation counts the number of writes to, and reads from the FIFO buffer to increment (on FIFO write but no read), decrement (on FIFO read but no write) or hold (no writes and reads, or simultaneous write and read operation) the current fill value of the FIFO buffer. The FIFO is full when the FIFO counter reaches a predetermined full value and the FIFO is empty when the FIFO counter is zero.
Lets assume a FIFO with 8 words depth.
//Generation of Empty and Full Conditions
---------------------------------------------------------------------------------------------------
Module fifo(
input [7:0] data_in,
input clk,
input rst , rd, wr,
output empty, full ,
output reg [3:0] fifo_cnt,
output reg[7:0] data_out);
reg [7:0] fifo_ram[0:7];
reg [2:0] rd_ptr, wr_ptr;
assign empty = (fifo_cnt == 0);
assign full = (fifo_cnt == 8);
------------------------------------------------------------------------------------------------------
// fifo_ram writing & reading
------------------------------------------------------------------------------------------------------
always @(posedge clk) begin : WRITE
if(wr && !full)
fifo_ram[wr_ptr] = data_in;
else if (wr && rd)
fifo_ram[wr_ptr] = data_in;
end
always @(posedge clk) begin : READ
if(rd && !empty)
data_out = fifo_ram[rd_ptr];
else if (rd && wr)
data_out = fifo_ram[rd_ptr];
end
--------------------------------------------------------------------------------------------------------
//Pointer Generation
--------------------------------------------------------------------------------------------------------
always @ (posedge clk) begin : POINTER
if (rst) begin
wr_ptr <= 0;
rd_ptr <= 0;
end
else if begin
wr_ptr <= ((wr && !full) || (wr && rd)) ? wr_ptr + 1 : wr_ptr;
rd_ptr <= ((rd && !empty) || (rd && wr)) ? rd_ptr +1 : rd_ptr;
end
end
---------------------------------------------------------------------------------------------------------
//Counter Logic Generation
---------------------------------------------------------------------------------------------------------
always @ (posedge clk) begin : COUNTER
if (rst)
fifo_cnt <= 0;
else begin
case ((wr, rd))
2'b00 : fifo_cnt <= fifo_cnt;
2'b01 : fifo_cnt <= (fifo_cnt == 0) ? 0 : fifo_cnt - 1;
2'b10 : fifo_cnt <= (fifo_cnt == 8) ? 8 : fifo_cnt + 1;
2'b11 : fifo_cnt <= fifo_cnt;
default : fifo_cnt <= fifo_cnt;
endcase
end
end
-------------------------------------------------------------------------------------------------------
Timing Diagram : (FIFO Depth = 4)
Happy Learning !!!
0 Comments:
Post a Comment