OpenCores
Issue List
Baud Rate off by 1? #8
Closed agprimatic opened this issue almost 14 years ago
agprimatic commented almost 14 years ago

It looks like the baud rate generator counts from 0 to DIVIDER. To match a real 16750, I think it should count from 0 to DIVIDER-1. The example is with a 1.8432 MHz clock and a baud rate of 115200, DIVIDER should be 1, and the 16x clock should be 1.8432 MHz.

agprimatic commented almost 14 years ago

Type your text here

agprimatic commented almost 14 years ago

Type your text here

hasw commented almost 14 years ago

I've checked the simulation with the following settings:

CLK period = 30 ns BAUDCE period = 30 ns * 18 = 540 ns (1.851851 MHz)

With DIVIDER set to 1 it generates a baudrate*16 period of 540 ns. This leads to a baudrate of 115740 BAUD.

The error is 0.469% as the BAUDCE input error is the same. So the divider count should be fine.

Regards, Sebastian

agprimatic commented almost 14 years ago

I'm not sure where the 18 comes from in the above calculation.

The simplest example I could come up with is when the clock is 1.8432 MHz and the desired baud rate is 115200. According to the 16750 datasheet, the divisor should be set at 1.

With the current code at line 58 in uart_baudgen.vhd if (iCounter = unsigned(DIVIDER)) then

this will make iBaudtick16x a square wave at 921.6 kHz (iCounter counts from 0 to 1), which is half of what it should be.

I believe the line should read: if (iCounter = unsigned(DIVIDER)-1) then

I think this also uncovers another bug in that the BAUDOUTN will not function correctly if iBaudtick16x is always 1, since it depends on iBaudtick16x being equal to 0 for it to transition. And, if the divisor is set to 1 with a fixed uart_baudgen.vhd, iBaudtick16x will always be 1.

agprimatic commented almost 14 years ago

I'm not sure where the 18 comes from in the above calculation.

The simplest example I could come up with is when the clock is 1.8432 MHz and the desired baud rate is 115200. According to the 16750 datasheet, the divisor should be set at 1.

With the current code at line 58 in uart_baudgen.vhd if (iCounter = unsigned(DIVIDER)) then

this will make iBaudtick16x a square wave at 921.6 kHz (iCounter counts from 0 to 1), which is half of what it should be.

I believe the line should read: if (iCounter = unsigned(DIVIDER)-1) then

I think this also uncovers another bug in that the BAUDOUTN will not function correctly if iBaudtick16x is always 1, since it depends on iBaudtick16x being equal to 0 for it to transition. And, if the divisor is set to 1 with a fixed uart_baudgen.vhd, iBaudtick16x will always be 1.

hasw commented almost 14 years ago

If you look at the testbench: 33 MHz / 18 is the closest you can get to 1.8432 MHz with a base clock of 33 MHz.

The most important thing is missing: How have you connected the clock pins? If you mean 1.8432 MHz clock is this connected to BAUDCE or CLK? How is BAUDCE connected? Always 1 won't work (as you have already discoverd), then you have to modify the sources.

Changing the code to "if (iCounter = unsigned(DIVIDER)-1) then" will break the testbench. 33 MHz CLK and BAUDCE at ~1.84 MHz will then not work anymore.

The testbench shows the core usage example. CLK >> BAUDCE. For other cases multiple code places have to be rewritten.

Regards, Sebastian

Nicky57 commented about 13 years ago

I have implemented this core on Xilinx Spartan 3an, with 50Mhz clock input (replaced the 40Mhz input clock by 50Mhz, and adapted the baud rate divisor in software).

I confirm that the core don't work at 115,2kbauds (over speed work well). But at this baud rate, I have synchronization problem when I transfert file.

If I modify the baugen vhdl to: "if (iCounter = unsigned(DIVIDER)-1) then " ...

Then all works well now.

I think the counter must count from 0 to DIVIDER-1.

hasw closed this over 5 years ago
phantomrsw commented about 2 years ago

Hi guys! It seems I've run into the same problem. When writing to divisor 1 , which corresponds to the maximum baud , reception does not work, but transmission works. I found out that when divisor=1, the iBaudtick16x signal is always in state 1. I tried to rewrite the uart_baudgen module so that when divisor=1, the CLC signal was connected to BAUDTICK and this output had a frequency of 16x baud. But this did not help me, and the transfer does not work either. You will have to rewrite several source modules. Has anyone already done this? How did you solve this problem?


Assignee
No one
Labels
Bug