Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Community Forums
- :
- Forums
- :
- About Our Community
- :
- General Technical Discussion
- :
- UART Speed problems

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted

roeldejong

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2013 03:11 AM

7,653 Views

Registered:
03-12-2013

Good morning,

I am busy realizing a communication between 2 FPGA boards ( For testing purpose we use the Spartan 3E Starter kits 2x ). I use 2x Profibus RS-485 tranceivers ( SN65HVD1176 ) ( 40 Mbps max )

These work perfect with the UART project i have at the moment.

The only problem i counter now is that above a bitrate of +- 600000 it will not receive correctly, On the scope the signal still looks ok to me. The frequency is also correct.

I attached the UART vhd file which i used, i also have a link with the uart project. UART link

In the project there is also the calculation to go from the default 50mhz frequecy of the board to go to a frequency to we can manage 115200 baud for example. I tested o many frequencies, this all works perfect except above 600k somewhere.

So my question is, does anyone know of wat to help me find why this doesnt work above that frequency ( for me ? ).

I can provide images of the signal on the scope, earliest tomorrow. I will post these in this topic.

ps. I Changed the loopback so it doesnt resend what it receives everytime. I just check if the receive character is an "N' for example and it notifies me when the received character is NOT a 'N'. From the other board i keep sending the N characters.

If i need to provide more information, just ask and i will post it.

1 Solution

Accepted Solutions

Highlighted

gszakacs

Professor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2013 06:58 AM - edited 03-12-2013 06:59 AM

10,116 Views

Registered:
08-14-2007

Just looking at these two constants I can see one issue:

constant c_tx_divider_val : integer := CLOCK_FREQUENCY / BAUD_RATE;

constant c_rx_divider_val : integer := CLOCK_FREQUENCY / (BAUD_RATE * 16);

At 50 MHz, the rx divider will only be 5 (nominal 5.208333...) while the tx divider will

be 83 (nominal 83.333...). 5 times 16 is 80, so the difference is more than the 1%

normally required to maintain a good link (3.75%). If you need to use high baud

rates and don't have a clock that is a neat binary multiple of the baud rate, the best

way is to build the receive baud divider into the receiver rather than using a fixed

oversampling rate of 16x. For example in this case you could use the same divider

of 83 for both transmit and receive. Then when you sample the input (at the 50 MHz

input clock frequency) you look for the falling edge that signals a start bit and at

that point reset the **receive** baud divider. Then bit sampling occurs when the recieve baud

divider counter equals 83/2 (83 shifted right one) or 41.

Another way to do this is to use something like DDS to create a jittery 16x clock

at the exact required frequency (on average).

In any case you need to be sure that both tx and rx use the same divide numbers.

If you want to stick with the 16x rx sampling, then use a divide by 16 on the rx

clock for the transmitter rather than a separate divider.

-- Gabor

4 Replies

Highlighted

gszakacs

Professor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2013 06:58 AM - edited 03-12-2013 06:59 AM

10,117 Views

Registered:
08-14-2007

Just looking at these two constants I can see one issue:

constant c_tx_divider_val : integer := CLOCK_FREQUENCY / BAUD_RATE;

constant c_rx_divider_val : integer := CLOCK_FREQUENCY / (BAUD_RATE * 16);

At 50 MHz, the rx divider will only be 5 (nominal 5.208333...) while the tx divider will

be 83 (nominal 83.333...). 5 times 16 is 80, so the difference is more than the 1%

normally required to maintain a good link (3.75%). If you need to use high baud

rates and don't have a clock that is a neat binary multiple of the baud rate, the best

way is to build the receive baud divider into the receiver rather than using a fixed

oversampling rate of 16x. For example in this case you could use the same divider

of 83 for both transmit and receive. Then when you sample the input (at the 50 MHz

input clock frequency) you look for the falling edge that signals a start bit and at

that point reset the **receive** baud divider. Then bit sampling occurs when the recieve baud

divider counter equals 83/2 (83 shifted right one) or 41.

Another way to do this is to use something like DDS to create a jittery 16x clock

at the exact required frequency (on average).

In any case you need to be sure that both tx and rx use the same divide numbers.

If you want to stick with the 16x rx sampling, then use a divide by 16 on the rx

clock for the transmitter rather than a separate divider.

-- Gabor

Highlighted
##

Jump to solution

roeldejong

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-13-2013 03:27 AM

7,616 Views

Registered:
03-12-2013

Re: UART Speed problems

Hello Gabor,

I stopped with the 16x oversampling now. I went to 5 ( Which is the minimal if im correct ? ). Already getting higher speeds after calculating good values which are within the 1% range.

It must have been the problem then the difference in the value was more then 1%.

I am going to test more with this now. Thank you for your clear answer.

//Roel

Highlighted
##

Jump to solution

roeldejong

Visitor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-13-2013 04:44 AM

7,608 Views

Registered:
03-12-2013

Re: UART Speed problems

I still have another question about this, Now i changed to 5x oversampling.

I tried a baudrate of 1.000.000 whcih gives the following values.

50.000.000 / 1.000.000 = 50

50.000.000 / ( 1.000.000 * 5 ) = 10

Which looks to me no problem, since: 10 * 5 = 50

Now this gives the same problem as before, on the scope the signal looks ok. and a lower baudrate gives noproblem.

My maximum without a problem is now around 800kbaud.

Now the strangest thing.

I also used a value which i first used with 8x oversampling 781250 now with the 5x oversmpling.

50.000.000 / 781.250 = 64

50.000.000 / ( 781.250 * 5 ) = 12 ( 12,8 in the integer value )

So we have an error of 64- ( 12*5 ) = 4. Where the maximum can be 1% = 0,64.

So the error is to big, but the communication works without any error.

Antough with 5x multisampling my maximum speed can be high then it was before with the 16x, which seems logical ?

Anyone can help me out on this.

//Roel

Highlighted
##

Jump to solution

gszakacs

Professor

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-13-2013 06:52 AM

7,591 Views

Registered:
08-14-2007

Re: UART Speed problems

@roeldejong wrote:

Hello Gabor,

I stopped with the 16x oversampling now. I went to 5 ( Which is the minimal if im correct ? ). Already getting higher speeds after calculating good values which are within the 1% range.

It must have been the problem then the difference in the value was more then 1%.

I am going to test more with this now. Thank you for your clear answer.

//Roel

Some older UART chips used an oversampling of 4x. In an FPGA there is no real need to

follow this approach. As I said in my earlier post, using the receive baud divider as the

sampling factor gives the best performance at higher baud rates unless your clock is

a neat multiple of the desired baud rate.

If you are controlling the baud at both ends of the link, the important thing is to be consistent

such that a transmitter's baud rate is within a small percentage of the receiver's baud

rate. Your method of generating a separate rate for transmit and receive sections is

not well suited to this. If you can set the baud for both ends of the link, and have the

same code running at both ends based on the same input clock frequency, then you

are better off using the 5x baud clock to run both transmitter and receiver. If you are

communicating with another device that has standard set baud rates, then you need more

absolute accuracy and should consider the approaches I mentioned earlier.

The 1% factor I noted is commonly used because it should work if a transmitter is 1% high

and a receiver 1% low from the agreed standard rate. Measuring a relative difference you

then can go to about 2% and still work.

There are other factors that can limit the tolerance to baud rate differences. One is the

oversampling rate, which limits how close to the center of the start bit the sampling starts.

Remember that you are starting from near mid-bit, and any frequency difference will

walk the sampling point towards one end or the other of the bit interval. In the case you

noted where the difference seemed too far to work, but the link worked, you may have had

the luck of starting from nearer to the edge of the bit time that the frequency walks you

away from. In other words the error in center bit sampling was in the opposite direction

of the frequency error.

Another issue at high rates is the link physical transmission media. For example many

RS422 transceivers have asymmetric propagation delay. When the low to high prop

delay is very different from the high to low prop delay, the effective bit sampling window

gets smaller. This means you need more accuracy in sampling than you would just

assume from the baud rate.

-- Gabor