Efinix FPGA design sometimes a signal is not set high... - Page 1
Forum section: electronics / general

author: Boscoe
author_rank: Frequent Contributor
timestamp: January 02, 2025, 09:21:55 am
content: 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 theCode:str_read_osignal is set high and sometimes it's not. As can be seen in the image, the state increments from 0 to 1 where theCode:str_read_osignal 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 streaminput wire [7 : 0] str_data_i,input wire str_rdy_i,output reg str_read_o = 1'b0,// FT245 async interfaceoutput 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 inputassign ft_data_o = str_data_i;// State machine variablereg [7 : 0] state = 8'h0;always @(posedge clk_i or negedge nrst_i) begin// Resetif (nrst_i == 1'b0) beginstr_read_o <= 1'b0;ft_rd_o <= 1'b1;ft_wr_o <= 1'b1;state <= 8'h0;end// Runelse begincase (state)0: begin// If the FT device is ready and data is available in the FIFOif ((ft_txe_i == 1'b0) && (str_rdy_i == 1'b1)) begin// Read some data out the FIFOstr_read_o <= 1'b1;// Advance the state machinestate <= 8'h1;endend1: begin// Reset the read flagstr_read_o <= 1'b0;// Advance the state machinestate <= 8'h2;end2, 3, 4: begin// Wait for the min hold time (30ns)if (state == 8'h4) begin// Reset the WR signalft_wr_o <= 1'b1;// Go back to the beginningstate <= 8'h0;endelse begin// Increment the state to eventually leavestate <= state + 8'h1;// Drop the WR to indicate to the FT device to read the dataft_wr_o <= 1'b0;endenddefault: begin// Go back to the beginningstate <= 8'h0;endendcaseendendendmodule

author: davep238
author_rank: Contributor
timestamp: January 08, 2025, 04:54:43 pm
content: 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)..."

author: SiliconWizard
author_rank: Super Contributor
timestamp: January 08, 2025, 10:38:03 pm
content: 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)

author: Boscoe
author_rank: Frequent Contributor
timestamp: January 11, 2025, 01:43:25 pm
content: 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 FIFOif ((ft_txe_i == 1'b0) && (str_rdy_i == 1'b1) && (state == 8'b0)) begin// Read some data out the FIFOstr_read_o <= 1'b1;endif (str_read_o == 1'b1) beginstr_read_o <= 1'b0;state <= 8'h3;endif (state != 8'b0) beginft_wr_o <= 1'b0;state <= state - 8'b1;endelse beginft_wr_o <= 1'b1;end