Author Topic: 2 Word, first word fall through (FWFT) FIFO, FIFO style elastic buffer for speed  (Read 2452 times)

0 Members and 1 Guest are viewing this topic.

Offline BrianHGTopic starter

  • Super Contributor
  • ***
  • Posts: 8085
  • Country: ca
Another beginner super-simple System Verilog project.

This module was specifically designed to both FIFO and increase you compiled FMAX speed results when bridging 2 separate source and destination modules in your design.

Shifting data in has a single clock cycle until the data output & status flags are valid.

Great for linking multiple sections of your overall design where some of those sections occasionally take more than 1 clock cycle for some functions.

It's single register output plus that register input only selects between the source data and the 1 extra buffer word data means proper strategic usage of this FIFO will also improve FMAX in many designs.

See attached simulation which illustrates functionality.

Code:

Code: [Select]

// *****************************************************************
// *** FIFO_2word_FWFT.sv V1.0, August 15, 2020
// ***
// *** This 1 word FIFO with first word feed through (FWFT)
// *** This was designed to be backwards compatible with the
// *** FIFO_3word_0_latency.sv with the 'zero latency' disabled.
// *** written by Brian Guralnick.
// ***
// *** See the included 'FIFO_2word_FWFT.png' simulation for functionality.
// ***
// *** Using System Verilog code which only uses synchronous logic.
// *** Well commented for educational purposes.
// *****************************************************************

module FIFO_2word_FWFT (

input  logic clk,                 // CLK input
input  logic reset,               // reset FIFO

input  logic shift_in,            // load a word into the FIFO.
input  logic shift_out,           // shift data out of the FIFO.
input  logic [bits-1:0] data_in,  // data word input.

output logic fifo_not_empty,      // High when data_out has valid data.
output logic fifo_full,           // High when the FIFO's 1 word elastic memory is
                                  // filled and there isn't a 'shift_out'

output logic [bits-1:0] data_out  // FIFO data word output
);

//*************************************************************************************************************************************
parameter  int bits = 8 ;                // sets the width of the fifo
//*************************************************************************************************************************************

logic  [bits-1:0]  source;        // The result from a mux which selects between the data_in and memory register.
logic              source_ready;  // This goes high when there is a shift_in, or when the memory_filled is high.
logic  [bits-1:0]  memory;
logic              memory_filled;
logic              source_sel_memory;
logic              data_out_ready;

always_comb begin
source            = memory_filled ? memory : data_in  ; // A Mux which selects the source of the next value for the 'data_out' register.
source_ready      = memory_filled ? 1'b1   : shift_in ; // A Mux which selects the source of the next value for the 'data_out_ready' register.

fifo_not_empty    = data_out_ready                    ; // the data_out register has data ready to be recieved.
fifo_full         = memory_filled && !shift_out       ; // if the memory is filled and currently there is no shift_out
                                                        // in progress, report that the FIFO is full.
end // always_comb

always_ff @(posedge clk) begin
if (reset) begin
    memory           <= 0;             // clear the FIFO memory register
    memory_filled    <= 0;             // clear the FIFO memory_filled flag
    data_out         <= {bits{1'bz}};  // clear the data_out register, when simulationg, show that the data out hs no valid data
    data_out_ready   <= 0;             // clear the data_our ready register
    end else begin

             if (shift_out || !data_out_ready) begin          // Shift out when told to, or if the data_out_ready is not ready,
                                                              // keep on feeding this register until the first valid word comes in (FWFT)
                                               data_out       <= source_ready ? source : {bits{1'bz}} ; // If no words left coming from the source, show that there is no valid data.
                                               data_out_ready <= source_ready;
                                               end

             if (shift_in && data_out_ready)   begin
                                               memory         <= data_in;
                                               memory_filled  <= source_ready && (!shift_out || memory_filled);

                     end else if (shift_out)   memory_filled  <= 0;            // A shift_out without a (shift_in && data_out_ready)
                                                                               // empties the memory_filled flag.

  end // !reset
end // always_ff
endmodule


« Last Edit: August 17, 2020, 02:17:49 am by BrianHG »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf