07-31-2017 11:58 AM
i am writing to find out if you have any videos or could point me to the best resources for learning to use a UART with a Spartan 6 (SP 605 ) FPGA to receive sensor data. I don't have a lot of time and need to streamline my learning process. Would appreciate any advise on best way to approach learning how to use the UART.
07-31-2017 07:36 PM
Do you have the need to implement a uart tx and rx block yourself? Will all of your design be in logic, or can you afford to drop down a soft processor such as MicroBlaze ( or even picoblaze )?
If you are just reading UART data from a sensor, implementing a block to read out the 8 bits at a time and present it to a FIFO for read out is pretty straight forward. Here is a good list of resource on how the protocol ( usually ) works.
The short answer is this:
0) Generate a clock, or a clock enable, that is 16x your baud rate ( so if you were running at 9600, generate a clock at 153600 Hz ).
1) Look for a falling edge ( logic high to logic low ), this is the "start bit".
2) Count 8 clock cycles, and sample the value ( it should be low ). This effectively puts you at the "center" of the bit.
3) Count 16 more clock cycles, and samples. Do this 8 more times. Each sample should be in the center of the 8 bits in the payload.
4) Count 16 more clock cycles, and sample. This is the stop bit and should be high.
Each sample can be put into a shift register, and then on the stop bit the shift register value can be loaded into a register for read out, or into a FIFO to cross clock domains.
07-31-2017 08:07 PM
Generate a clock, or a clock enable, that is 16x your baud rate ( so if you were running at 9600, generate a clock at 153600 Hz ).
While this is the "traditional" way of doing a UART implementation (and I have even done it this way), it has been pointed out that this really isn't necessary.
What @timduffy describes is fundamentally correct, but having a pre-divider to generate the baud x 16 clock and then using this to count of 8 and 16 clock cycles for the 1/2 bit period and one full bit period isn't really required. You can just use a counter to count clock cycles directly. So, for example if you are doing 9600 baud and your system clock is 100MHz, then a bit period is 10417 clock periods. To wait a half clock period, just have a counter that counts 5,208 clock periods, and for the full bit period use a counter that counts 10417. This ends up being more precise, is simpler in terms of coding, and is so negligibly larger in a modern FPGA that it doesn't matter.
07-31-2017 08:11 PM
08-01-2017 12:36 AM
@avrumw This eliminates the need for any clock-crossing since you can run your counter from whatever clock the rest of the design uses.
@foremanj The challenge here is that building a 16x clock for a UART can actually be a bit of a challenge at the higher baud rates. Say you've got a 50MHz FPGA clock and a 921600bps UART (seems to be increasingly common now that nobody actually cares about making their UART work with an ancient PC that can only drive 115200bps). Then the 16x clock would have to be at 14.7456MHz, and getting that from a 50MHz clock isn't pretty. The closest clean divider is 1/3, but that has an error over 13%. Over the 10 bits that a UART sends you'd be out by more than a whole bit by the end.
In contrast, doing a direct reading of the 921600bps UART from a 50MHz clock gives you a 1/54 divider, with 0.4% error, and 4% error over a whole 10-bit transfer.
It might well be irrelevant in this case (plenty of equipment still uses 9600bps UARTs) but for someone who doesn't know what they're doing it can create some difficult-to-trace problems.