Wednesday, July 21, 2021

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