Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Verilog FIFO Generator and read_enable. Asynchronos

How do you use the read enable to properly output a signal on a pin? I am using a ZyBo board and used a the FIFO Generator Wizard. I need an asynchronous, continuous writing to a FIFO and reading from the FIFO. This is why I need a write_enable signal and read_enable signal. However, I cannot read from the FIFO. I check to make sure the FIFO isn't empty and that read_enable is asserted. I read from the FIFO by serializing a 32bit word onto a data pin. (It alternates from serializing onto pin I and pin Q). How can I make sure I am reading from the FIFO and outputting the serialized data onto a pin? The following is my code:


    // Wires and registers related to data capturing 
    wire        capture_clk;
    reg   capture_data;
    wire        capture_en;
    reg    slowdown;
    wire        capture_full;
    reg            capture_open;
    reg            capture_open_cross;
    reg            capture_has_been_full;
    reg            capture_has_been_nonfull;
    reg            has_been_full_cross;
    reg            has_been_full;
    
    // Data capture section
    // ====================
    always @(posedge capture_clk)
      begin
    if (capture_en)
      capture_data <= user_w_write_32_data; // Data source being read from a file
    
    // The slowdown register limits the data pace to 1/32 the bus_clk
    // when capture_clk = bus_clk. This is necessary, because the
    // core in the evaluation kit is configured for simplicity, and
    // not for performance. Sustained data rates of 200 MB/sec are
    // easily reached with performance-oriented setting.
    // The slowdown register has no function in a real-life application.
    slowdown <= slowdown + 1;
    // capture_has_been_full remembers that the FIFO has been full
    // until the file is closed. capture_has_been_nonfull prevents
    // capture_has_been_full to respond to the initial full condition
    // every FIFO displays on reset.
    if (!capture_full)
      capture_has_been_nonfull <= 1;
    else if (!capture_open)
      capture_has_been_nonfull <= 0;
    
    if (capture_full && capture_has_been_nonfull)
      capture_has_been_full <= 1;
    else if (!capture_open)
      capture_has_been_full <= 0;
    
      end
    // The dependency on slowdown is only for bogus data
    assign capture_en = capture_open && !capture_full && 
                 !capture_has_been_full &&
                 (slowdown == 0);
        
    // Clock crossing logic: bus_clk -> capture_clk
    always @(posedge capture_clk)
      begin
    capture_open_cross <= user_r_read_32_open;
    capture_open <= capture_open_cross;
      end
    // Clock crossing logic: capture_clk -> bus_clk
    always @(posedge bus_clk)
      begin
    has_been_full_cross <= capture_has_been_full;
    has_been_full <= has_been_full_cross;
      end
    
    // The user_r_read_32_eof signal is required to go from '0' to '1' only on
    // a clock cycle following an asserted read enable, according to Xillybus'
    // core API. This is assured, since it's a logical AND between
    // user_r_read_32_empty and has_been_full. has_been_full goes high when the
    // FIFO is full, so it's guaranteed that user_r_read_32_empty is low when
    // that happens. On the other hand, user_r_read_32_empty is a FIFO's empty
    // signal, which naturally meets the requirement.
    
    assign user_r_read_32_eof = user_r_read_32_empty && has_been_full;
    assign user_w_write_32_full = 0;
    
    // The data capture clock here is bus_clk for simplicity, but clock domain
    // crossing is done properly, so capture_clk can be an independent clock
    // without any other changes.
    
    assign capture_clk = bus_clk;
    
    async_fifo_32x512 fifo_32 //FIFO created using Xilinx FIFO Generator Wizard
      (
        .rst(!user_r_read_32_open),
        .wr_clk(capture_clk),
        .rd_clk(bus_clk),
        .din(capture_data),
        .wr_en(capture_en),
        .rd_en(user_r_read_32_rden),
          .dout(user_r_read_32_data),
        .full(capture_full),
        .empty(user_r_read_32_empty)
        );
                
        reg Q_en = 1'b0; //starting value is 0 because first 32bit is I
        reg  data_outI = 32'd0;
        reg  data_outQ = 32'd0;
        reg I = 1'b0;
        reg Q = 1'b0;
        reg counter_32_shift = 6'b000000;
        reg temp = 1'b0;
                
        always @(posedge bus_clk) begin
            if(user_r_read_32_empty == 1'b0 && user_r_read_32_rden == 1'b1)begin //if something in FIFO
                if(Q_en == 1'b0) begin //output onto pin I
                    if(counter_32_shift == 6'b000000) begin
                        data_outI <= user_r_read_32_data;
                    end else if(counter_32_shift != 5'd32) begin
                        I <= data_outI;
                        data_outI <= (data_outI >> 1);
                        Q <= data_outQ;
                        data_outQ <= (data_outQ >> 1);
                        counter_32_shift <= counter_32_shift + 1'b1;
                    end else begin //counter_32_shift == 32
                        I <= data_outI;
                        data_outI <= (data_outI >> 1);
                        Q <= data_outQ;
                        data_outQ <= (data_outQ >> 1);
                        counter_32_shift <= 6'd0;
                        Q_en <= ~Q_en;
                    end
                end else if(Q_en == 1'b1) begin //Output onto pin Q
                    if(counter_32_shift == 6'd0) begin
                        data_outQ <= user_r_read_32_data;
                    end else if(counter_32_shift != 6'd32) begin
                        I <= data_outI;
                        data_outI <= (data_outI >> 1);
                        Q <= data_outQ;
                        data_outQ <= (data_outQ >> 1);
                        counter_32_shift <= counter_32_shift + 1'b1;
                    end else begin //counter_32_shift == 32
                        I = data_outI;
                        data_outI <= (data_outI >> 1);
                        Q = data_outQ;
                        data_outQ <= (data_outQ >> 1);
                        counter_32_shift <= 6'd0;
                        Q_en <= ~Q_en;
                    end
                end// end Q_en compare
            end //end check if FIFO empty
        end //end always

Thanks in advance for all the help
No RepliesBe the first to reply