I'm learning verilog and in the process trying to implement some simple logic circuits (and as everybody, a simple SOC)
I implemented a simple UART, and it worked well during simulation and the test-benches, but after synthesis in an actual FPGA (an ice40, using Yosys), I run into problems in about 2% of the received characters.
D2 is the RX data, D3 is the TX data (should be an echo of the received data), D0 is the sampling pulses of the UART, D1 is a "uart receiving" signal.
The problem was that the UART was ending before the current byte has ended.
After a lot of testing, I realized that when the High to Low transition at the start bit was at a time near enough to the internal FPGA clock, the initial state in verilog was not set to the correct value.
The verilog code was:
always @(posedge clk) begin // Main RX processing if (!rx_active) begin if (!rx) begin rx_shift <= 0; rx_state <= 19; end end
I changed the code to:
always @(posedge clk) begin // Latches RX signal, prevents glitches rx_latch <= rx; // Main RX processing if (!rx_active) begin if (!rx_latch) begin rx_shift <= 0; rx_state <= 19; end end
After that change, the UART worked always ok, this means that the combinatorial logic generating the state transition was setting only some of the bits in rx_state, as probably the clock signal did not reached all FF at the same time.
My questions are:
- Is this expected behavior in Verilog?
- How I can test if this race conditions are possible in my code?