vipinkmenon / mergeIP

Custom IP for merge operation for Xilinx FPGAs
https://youtu.be/cz0iKv53Vww
3 stars 0 forks source link

FSM doesn't work with the custom FIFO #1

Open msnagar opened 1 year ago

msnagar commented 1 year ago

Dear vipin, I test your code on the ZYNQ it is working fine with the generated FIFO. However, when I replace the FIFO with custom verilog code. It results always 0 output. I also tested the custom FIFO with AXI. It is working fine. FIFO code that I am using paste below.


timescale 1ns/1ps

module fifo #(parameter DATA_WIDTH = 32,             // width of each stored element
                        ADDRESS_WIDTH = 32,          // address width of the buffer
                        FIFO_SIZE = 32
             )
             (output reg [DATA_WIDTH-1:0] dataOut,   // output data
              output full,                           // signal for indicating FIFO is full
              output empty,                          // signal for indicating FIFO is empty
              output [ADDRESS_WIDTH:0] filled,       // number of memory locations filled
              input read,                            // read signal
              input write,                           // write signal
              input [DATA_WIDTH-1:0] dataIn,         // data to write
              input reset,                           // reset signal (Active-High)
              input enable,                          // enable signal
              input clk                              // clock pulse
             );

   reg [DATA_WIDTH-1:0] memory [0:FIFO_SIZE-1];              // main memory
    wire writeEnable, readEnable;                             // actual read/write signals, incorporating empty and full exceptions
    reg [ADDRESS_WIDTH:0] readPointer, writePointer;          // read and write pointers

    assign writeEnable = write & !full;
    assign readEnable = read & !empty;

    always @(posedge clk) begin
        if (reset) begin
            writePointer <= 0;
            readPointer <= 0;
        end
        else begin
            if (enable) begin
                if (readEnable) begin
                    dataOut <= memory[readPointer];
                    readPointer <= readPointer+1;
                end
                if (writeEnable) begin
                    memory[writePointer] <= dataIn;
                    writePointer <= writePointer+1;
                end
            end
            else begin
                writePointer <= writePointer;
                readPointer <= readPointer;
            end
        end
    end

    // assign outputs
    assign filled = writePointer - readPointer;
    assign full = (filled == {1'b1, {ADDRESS_WIDTH-1{1'b0}}});
    assign empty = (filled == 0);

endmodule
``` `
Heng-Zhou commented 1 year ago

In Vipin's project, the generated FIFO turns on the First Word Fall Through option, thus zero read latency. Your Verilog code is assuming this zero latency while reading. Due to the latency in FIFO circuit and you're using <=, however, the code can't capture the new data. This latency arises from transmission so it's not very large so you cannot see it in waveform diagram unless you zoom in very closely so it often gives an illusion that you can catch the new data at the current clock. As a side note, since delay statement (like #1) is not synthesizable, you can't simply use it to delay the assignment to catch the data in practical implementation; you have to wait until the next posedge of the clock even though the data will soon be available. The generated FIFO is active at rising edge of the clock and Vipin happened to do things at posedge, so this gives an illusion of one clock latency. That's how "Read Latency: 1" comes out when there is no FWFT feature in a FIFO, though the actual latency is not one-clock long. Maybe it is the case for your own FIFO which does not include FWFT. If so, you can either include FWFT feature in your FIFO design or read at the next clock if it is acceptable.

Below is my behavioral simulation. I let the rising edge to be at the middle of read enable signal, so you can see that the data is actually read out immediately after that moment. Also, as can be seen from the waveforms, the output data is zero before the first read, which is what's actually read, so your own FIFO always outputs 0.

image