FIFO Interface

Questions and discussions about the Xillybus IP core and drivers

FIFO Interface

Postby Guest »

Can someone take a look at my code as I am having trouble interfacing my logic with an input and output FIFO.

The works as follows:

Xillybus --> FIFO In --> Core --> FIFO Out --> Xillybus

I do not want my core to work on data when there isn't any valid data being presented as it would ruin the computation and I need it to not compute data when there isn't anywhere to put it, i.e. FIFO full, as sequence of output data matters. Currently the Core module just registers data and passes it through.

Currently it keeps locking up without getting data out.


Code: Select all
   

    (* ASYNC_REG="TRUE" *) reg
        core_in_open_cross,
        core_in_open;
       
    (* ASYNC_REG="TRUE" *) reg     
        core_out_open_cross,
        core_out_open;
       
    (* ASYNC_REG="TRUE" *) reg
        has_been_full_cross,
        has_been_full;
       
    reg
        core_out_has_been_full,
        core_out_has_been_nonfull;

    wire
        reset,
        core_clk;
   
    wire [31:0]
        core_in_data,
        core_out_data;
   
    wire
        core_in_empty,
        core_out_full;

   
    // Clock crossing logic: bus_clk -> core_clk --- CPU to FPGA signal

    always @(posedge core_clk) begin
        core_in_open_cross <= user_w_write_32_open;
        core_in_open <= core_in_open_cross;
       
        core_out_open_cross <= user_r_read_32_open;
        core_out_open <= core_out_open_cross;
           
        if (!core_out_full)
            core_out_has_been_nonfull <= 1;
        else if (!core_out_open)
            core_out_has_been_nonfull <= 0;

        // core_out_has_been_full remembers that FIFO has been full
        // core_out_has_been_nonfull prevents core_out_has_been_full to respond
        //        to the initial full condition every FIFO displays on reset
       
        if (core_out_full && core_out_has_been_nonfull)
            core_out_has_been_full <= 1;
        else if (!core_out_open)
            core_out_has_been_full <= 0;
   
    end
       
    // Clock crossing logic: core_clk -> bus_clk --- FPGA to CPU signal
    always @(posedge bus_clk) begin
        has_been_full_cross <= core_out_has_been_full;
        has_been_full <= has_been_full_cross;
    end

    // Used to reset FIFOs and Core
    assign reset = !user_w_write_32_open && !user_r_read_32_open;

    assign user_r_read_32_eof = 0;
   
    assign core_in_en = core_in_open && !core_in_empty;
    assign core_out_en = core_out_open && !core_out_full && !core_out_has_been_full;
    assign core_en = core_in_en && core_out_en; // Only enable core
   
    fifo_32 fifo_core_in(
        .rst(!user_w_write_32_open),
        .wr_clk(bus_clk),
        .rd_clk(core_clk),
        .din(user_w_write_32_data),
        .wr_en(user_w_write_32_wren),
        .rd_en(core_in_en),
        .dout(core_in_data),
        .full(user_w_write_32_full),
        .empty(core_in_empty)
        );
       
    fifo_32 fifo_core_out(
        .rst(!user_r_read_32_open),
        .wr_clk(core_clk),
        .rd_clk(bus_clk),
        .din(core_out_data),
        .wr_en(core_out_en),
        .rd_en(user_r_read_32_rden),
        .dout(user_r_read_32_data),
        .full(core_out_full),
        .empty(user_r_read_32_empty)
        );
       
    core dut(
        .clk(core_clk),
        .reset(reset),
        .enable(core_en),
        .din(core_in_data),
        .dout(core_out_data)
        );

// Core module

module core(
   input
      clk,
      reset,
      enable,
   
   input [31:0]
      din,
      
   output [31:0]
      dout
   );
   
   
   reg [31:0] data;
   
   assign dout = data;
   
   initial begin
      data = 0;
   end
   
   always @(posedge clk) begin
      if (reset) begin
         data <= 0;
      end else begin
        if (enable) begin
         data <= din;
        end
      end
   end
   
endmodule

Guest
 

Re: FIFO Interface

Postby support »

Hello,

I don't understand why you've involved all that extra logic. It seems like it's inspired by the example for data acquisition and/or playback applications, which doesn't seem to be your case.

You correctly chose dual-clock FIFOs for crossing clock domains. These two FIFOs have empty and full ports, which you can use to control core_en. If fifo_core_in is a FWFT FIFO, it may turn out as easy as

assign core_en = !core_in_empty && !core_out_full;

All this "has been empty" and "has been full" logic doesn't belong here -- it's not an error to stall the processing momentarily in your case. This logic makes sense such a stall is a malfunction, in particular when data is acquired from an external source in realtime.

Regards,
Eli
support
 
Posts: 802
Joined:


Return to Xillybus

cron