Electronics > FPGA

Efinix FPGA design sometimes a signal is not set high...

(1/1)

Boscoe:
Hi all, this one really has me scratching my head. I almost didn't know how to describe it.

I have an FPGA design with an FT245 async module all simulated and verified however when loaded onto the FPGA and run I get too much data RXd on the USB - too many bytes are recieved and the amount is constantly random.

Looking into my module (below) with the Efinix debugger I can see one of the signals does not go high even though the state machine state variable does change in the exact same logic block. Again, this is intermittent! Sometimes the
--- Code: ---str_read_o
--- End code ---
signal is set high and sometimes it's not. As can be seen in the image, the state increments from 0 to 1 where the
--- Code: ---str_read_o
--- End code ---
signal should also be set high but sometimes it isn't, it doesn't go high around 10% of the time. The image is a screenshot of the on board debugger synthed in the FPGA design.

The timing fully passes, the mipi_pix_clk is a 100MHz clock and the tools say the Fmax is ~209Mhz. All setup and hold timings also pass.

Does anyone know what may be going on here?

Thanks!


--- Code: ---module ft245_async_tx
    (input wire clk_i, nrst_i,

     // Input data stream
     input wire [7 : 0] str_data_i,
     input wire str_rdy_i,
     output reg str_read_o = 1'b0,

     // FT245 async interface
     output wire [7 : 0] ft_data_o,
     output reg ft_rd_o = 1'b1, ft_wr_o = 1'b1,
     input wire ft_txe_i);

  // Output is always the FIFO input
  assign ft_data_o = str_data_i;

  // State machine variable
  reg [7 : 0] state = 8'h0;

  always @(posedge clk_i or negedge nrst_i) begin

    // Reset
    if (nrst_i == 1'b0) begin

      str_read_o <= 1'b0;

      ft_rd_o <= 1'b1;
      ft_wr_o <= 1'b1;

      state <= 8'h0;
    end

    // Run
    else begin

      case (state)
        0: begin

          // If the FT device is ready and data is available in the FIFO
          if ((ft_txe_i == 1'b0) && (str_rdy_i == 1'b1)) begin

            // Read some data out the FIFO
            str_read_o <= 1'b1;

            // Advance the state machine
            state <= 8'h1;
          end
        end

        1: begin

          // Reset the read flag
          str_read_o <= 1'b0;

          // Advance the state machine
          state <= 8'h2;
        end

        2, 3, 4: begin

          // Wait for the min hold time (30ns)
          if (state == 8'h4) begin

            // Reset the WR signal
            ft_wr_o <= 1'b1;

            // Go back to the beginning
            state <= 8'h0;
          end

          else begin

            // Increment the state to eventually leave
            state <= state + 8'h1;

            // Drop the WR to indicate to the FT device to read the data
            ft_wr_o <= 1'b0;
          end
        end

        default: begin
          // Go back to the beginning
          state <= 8'h0;
        end
      endcase
    end
  end
endmodule
--- End code ---

davep238:
Perhaps some dumb questions/observations but...
1) As far as I can tell "state" only has values between 0 and 4, so why is it 8-bits? In VHDL, I would use an enumerated type. Are enumerated types available in Verilog, or is that only in SystemVerilog?
2) "str_read_o" is only assigned in "state 0" and "state 1". I expect that a latch will be created.
3) To me, it would less confusing if "state 2,3,4" was broken up into a separate "state 2,3" and a separate "state 4". In a sense, you already do that with "if (state == 8'h4)..."

SiliconWizard:
I haven't looked into details of your code (and I know VHDL better than Verilog), but are you sure you don't read async signals from the FTDI chip without resynchronizing them first? (That would be the TXE signal here)

Boscoe:
Thank you both for the replies. The TXE signal is not registered but I don't see the issue with this as it's sampled on the same clock. I ended up rewriting this with a couple of if statements and it worked no problem:


--- Code: ---      // If the FT device is ready and data is available in the FIFO
      if ((ft_txe_i == 1'b0) && (str_rdy_i == 1'b1) && (state == 8'b0)) begin

        // Read some data out the FIFO
        str_read_o <= 1'b1;
      end

      if (str_read_o == 1'b1) begin

        str_read_o <= 1'b0;

        state <= 8'h3;
      end

      if (state != 8'b0) begin

        ft_wr_o <= 1'b0;

        state <= state - 8'b1;
      end

      else begin

        ft_wr_o <= 1'b1;
      end
--- End code ---

Navigation

[0] Message Index

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod