Hi semidesign, It is usually not a good idea to drive the full and empty output logic combinationally and assigned to the final output. When there is a push and the current wptr is MAX-1, then it will go to MAX value. You can check this condition and pass it through a flop. The output of the flop is full. Same for empty. This way the final full and empty signals come from flops which greatly reduces output delay.
Here is the complete code - " `timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // // Create Date: 19.08.2024 23:34:43 // Design Name: Asynchronous FIFO // Module Name: top // Project Name: // Target Devices: // Tool Versions: // Description: // This module implements an Asynchronous FIFO with separate read and write clocks. // It includes logic to handle data synchronization across different clock domains // using Gray code pointers to avoid metastability and synchronization errors. // // Dependencies: None // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module top ( input wr_clk, // Write clock input rd_clk, // Read clock input rst, // Asynchronous reset input wr_en, // Write enable signal input rd_en, // Read enable signal input [7:0] write_data, // Data input for writing to FIFO output reg [7:0] read_data, // Data output for reading from FIFO output wire empty, // Flag to indicate FIFO is empty output wire full // Flag to indicate FIFO is full );
parameter fifo_depth = 8; // FIFO depth is 8, so address pointer will be 3 bits wide parameter add_size = 4; // Address size set to 4 bits to handle full/empty condition
// Define the read and write pointers with 4 bits each reg [3:0] wptr, rptr; wire [3:0] wptr_gray, rptr_gray;
// FIFO buffer memory of 8 entries, each 8 bits wide reg [7:0] mem [7:0];
// Write data into FIFO buffer // This block is triggered by the write clock and checks for write enable and FIFO full conditions always @(posedge wr_clk) begin if (rst) begin // Reset write pointer to zero wptr > 1);
// Synchronize the write pointer to the read clock domain // This prevents metastability when comparing pointers across different clock domains always @(posedge rd_clk) begin if (rst) begin // Reset synchronization flip-flops wptr_gray_ff1
Here the full condition logic does not match with the one in the video. It should be - wptr_gray[2] != rptr_gray_sync[2] . Above they are checking for equal which is done for binary comparison not gray.
Hi semidesign, It is usually not a good idea to drive the full and empty output logic combinationally and assigned to the final output. When there is a push and the current wptr is MAX-1, then it will go to MAX value. You can check this condition and pass it through a flop. The output of the flop is full. Same for empty. This way the final full and empty signals come from flops which greatly reduces output delay.
Here is the complete code -
"
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// Create Date: 19.08.2024 23:34:43
// Design Name: Asynchronous FIFO
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// This module implements an Asynchronous FIFO with separate read and write clocks.
// It includes logic to handle data synchronization across different clock domains
// using Gray code pointers to avoid metastability and synchronization errors.
//
// Dependencies: None
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module top (
input wr_clk, // Write clock
input rd_clk, // Read clock
input rst, // Asynchronous reset
input wr_en, // Write enable signal
input rd_en, // Read enable signal
input [7:0] write_data, // Data input for writing to FIFO
output reg [7:0] read_data, // Data output for reading from FIFO
output wire empty, // Flag to indicate FIFO is empty
output wire full // Flag to indicate FIFO is full
);
parameter fifo_depth = 8; // FIFO depth is 8, so address pointer will be 3 bits wide
parameter add_size = 4; // Address size set to 4 bits to handle full/empty condition
// Define the read and write pointers with 4 bits each
reg [3:0] wptr, rptr;
wire [3:0] wptr_gray, rptr_gray;
// FIFO buffer memory of 8 entries, each 8 bits wide
reg [7:0] mem [7:0];
// Synchronized write and read pointers (Gray code)
reg [3:0] wptr_gray_sync;
reg [3:0] wptr_gray_ff1, wptr_gray_ff2;
reg [3:0] rptr_gray_sync;
reg [3:0] rptr_gray_ff1, rptr_gray_ff2;
// Write data into FIFO buffer
// This block is triggered by the write clock and checks for write enable and FIFO full conditions
always @(posedge wr_clk) begin
if (rst) begin
// Reset write pointer to zero
wptr > 1);
// Synchronize the write pointer to the read clock domain
// This prevents metastability when comparing pointers across different clock domains
always @(posedge rd_clk) begin
if (rst) begin
// Reset synchronization flip-flops
wptr_gray_ff1
need testbench
Here the full condition logic does not match with the one in the video. It should be - wptr_gray[2] != rptr_gray_sync[2] . Above they are checking for equal which is done for binary comparison not gray.
Sir Testbench for this code ?
Full state explaination
I'm unable to understand....
explanation is awesome, please provide the copy of code in EDA playground
Hi what is the name of faculty ?
Pls share your query
Fifo Full state explaination plss@@SemiDesign