Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

step-17 and above - UART speed differs from Verilog encoded baudrate #3

Closed
fm4dd opened this issue Sep 8, 2023 · 5 comments
Closed

Comments

@fm4dd
Copy link
Owner

fm4dd commented Sep 8, 2023

The target UART speed is configured inside the SOC module as 1.000.000 baud. However the real output rate on the UART USB adapter is well below the target value. This is the baud rate setting in SOC.v:

   corescore_emitter_uart #(
      .clk_freq_hz(`CPU_FREQ*1000000),
      .baud_rate(1000000)                           
   ) UART(
      .i_clk(clk),
      .i_rst(!resetn),
      .i_data(mem_wdata[7:0]),  
      .i_valid(uart_valid),
      .o_ready(uart_ready),
      .o_uart_tx(TXD)                                
   );

On the output, Sigrok PulseView measured a baudrate of 833.333 instead:

I am using Digilent's PMOD-USBUART plugged into port PMOD-B, and connected a protocol analyzer like this:

The UART speed, that is supposed to stay fixed at 1Mbaud, changes along with changing the FPGA CPU frequency setting CPU_FREQ. I recorded the following values:

Verilog corescore_emitter_uart() baud_rate setting 1000000 (original):

CPU_FREQ measured baud_rate
5 MHz n/a (program fails execution)
10 MHz 833.333
20 MHz 909.090
30 MHz 952.380
40 MHz n/a (program fails execution)

Trying to raise the Verilog corescore_emitter_uart() baud_rate setting to 1100000:

CPU_FREQ measured baud_rate
5 MHz n/a (program fails execution)
10 MHz 909.090
20 MHz 1.000.000
30 MHz 1.052.631
40 MHz n/a (program fails execution)
@fm4dd
Copy link
Owner Author

fm4dd commented Sep 9, 2023

A check of the same code on a Lattice IceBreaker FPGA board shows very similar timing deviations:

CPU_FREQ measured baud_rate
16 MHz n/a (program fails execution)
20 MHz 909.090
30 MHz 952.380
40 MHz 952.380
50 MHz n/a (program fails execution)

It seems to be caused by design.

Further attempts on Gatemate perfomance optimizations under yosys synthesis (-retime and -luttree) or place and route (timing mode -tm 1 or 2) brought only marginal changes, if any.

Interim conclusion is to try these bitrates for serial communication: 833.333, 909.090, 952.380, 1.000.000

If the serial synchronization mismatch is not far off, the terminal already shows garbled character strings such as this: ��o�į������o�l����p�O�����

From observation, the serial protocol can withstand the bitrate to be "off" by a few percent, giving a (small) window of operation. A good Google search string for it is "baud rate deviation tolerance"

@Elektronikus
Copy link

I think, in the emitter_uart.v is an error
localparam START_VALUE = clk_freq_hz/baud_rate; localparam WIDTH = $clog2(START_VALUE);
should be:
localparam START_VALUE = (clk_freq_hz/baud_rate) - 2; localparam WIDTH = $clog2(START_VALUE+2);
Than the terminal works with 1000000

@fm4dd
Copy link
Owner Author

fm4dd commented Sep 29, 2024

This sounds great, Thank You! Let me try this as soon as I get the chance.

@fm4dd
Copy link
Owner Author

fm4dd commented Oct 6, 2024

This is awesome. I could confirm the fix today by re-testing step-17. Now the baudrate matches the expected 1.000.000 value:
20241006 LA trace for baudrate fix to issue-3

Closing issue #3 as resolved.

@fm4dd fm4dd closed this as completed Oct 6, 2024
fm4dd added a commit that referenced this issue Oct 6, 2024
@fm4dd
Copy link
Owner Author

fm4dd commented Oct 7, 2024

Oscilloscope timing view of step-17:
20241006 OSC trace for baudrate fix to issue-3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants