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
Go to full version