Skip to main content

Serial Receiver and Transmitter (UART) in Verilog | FPGA

Note: This was a post I wrote back in 2014 as I was teaching myself Verilog, but never got around to finishing the code for it and thus this post remained as a draft. I apologize that this is not in line with my other previous blog posts as it does not have a working code and is not demonstrated working in a video. But I am publishing this in hopes that someone researching this topic may find my introductory text on the topic useful.


UART stands for Universal Asynchronous Receiver and Transmitter. It is a system that is a capable of sending parallel data using a serial line. As the name indicates, the UART consists of a transmitter and a receiver. The transmitter accepts data in parallel and then by using a shift register send the data out bit by bit using predetermined parameters. Similarly the receiver accepts the data serially and then compiles the data using a shift register. Data is recognized by following a fixed format while transmitting and receiving, data sent consists of a start bit, data bits an optional parity bit and finally a stop bit. The transmission line will stay at 1 when it is idle, transmission starts when a 0 (start bit) is detected. This is followed by 8 data bits, followed by an optional parity bit. The parity bit is used for error detection, it can either be even parity or odd parity. The optional parity bit is followed by the stop bit(s) which marks the end of transmission for that word. The number of stop bits can be 1, 1.5 or 2.

The 'set parameters' that I mentioned earlier are important because no clock information is sent over the transmission line and smooth operations are ensured by these parameters, which are the baud rate (bits per second), the number of data bits (some systems use 6 or 7 data bits instead of the standard 8) and the number of stop bits. The commonly used baud rates are 2400, 4800, 9600 and 19,200.


 For example the above image shows data transfer that starts with the start bit, followed by 8 data bits, the optional parity bit and finally stop bit. Do note that the least significant bit (LSB) is always sent first.

As mentioned before no clock information is sent during data transmission and the receiver is still able to detect every bit. It achieves this by using an oversampling procedure. Oversampling procedure is to sample every incoming bits multiple times. For 1 stop bit the most common oversampling rate is 16, which means that each incoming bit is sampled 16 times. For 1.5 stop bits the over sampling rate will be 24 and for 2 stop bits the oversampling rate will be 36.  Understanding the oversampling procedure is essential to grasping the concept of serial communication.

Oversampling Procedure in Serial Communication


Since I will be using 1 stop bit the oversampling rate will be 16. I am going to use a couple counters to keep track of the sampling process. Now assume that the parameters we are using consists of 'x' data bits. The oversampling will proceed as follows:
  • As soon as the start bit is detected at the receiver, the sampling counter will start and count till 7 (half of 16). This ensures that the middle of the start bit is reached.
  • Now using another counter start counting till 15 (starting from 0, this makes it 16 counts). When 15 is reached we can be sure that the receiver has reached the middle of the first data bit. Move this bit to a shift register and restart this counter. Repeat this step until all data bits are accepted or repeat it 'x - 1' times.
  • Use the same counter procedure to accept the optional parity bit and the stop bit.
Because of this oversampling procedure the baud rate will be very low as compared to the clock rate. And that is why this method is not recommended for high data rate transmission.

Designing the Baud Rate Generator


The next step is to design the baud rate generator. As mentioned above the commonly used baud rates are 2400, 4800, 9600 and 19,200. Here I will be using the 19,200 baud rate. To design a counter for our designated baud rate is connected to the selected oversampling rate and since our over sampling rate is 16 ( 16 times the baud rate) we have 19,200 * 16 = 307,200. Now since I know the board I am using (BASYS2) has a 50 MHz clock, I can calculate the counter length needed for this by:

50M / 307,200 = 162.7 ~~ 163.

The width of the register that will count to 163 can be calculated by using the method explain here: To calculate an accurate time delay in verilog. So by using the log method I know that I need an 8 bit wide register to count up to 163.

Based on the nature of this design I will be using Finite State Machine with Data path (FSMD) to code this receiver. The finite states will follow the same procedure as explained above.

Comments

Popular posts from this blog

To Code a Stopwatch in Verilog

The stopwatch coded here will be able to keep time till 10 minutes. It will be a 4 digit stopwatch counting from 0:00:0 till 9:59:9. The right most digit will be incremented every 0.1 second, when it reaches 9 it will increment the middle two digits, which represent the second count. When it reaches 59 seconds it will increment the right most minute display. The stopwatch will be in the format M:SS:D. How to Create an Accurate Delay in Verilog: To make the stop watch an accurate device we need to be able to produce an accurate 0.1 second delay. I have already explained how to do this before in my decimal counter in verilog post. But since it is of great importance to the design will be explained in more detail here. Since we know that the BASYS2 (the one I am using, yours may be different) has a 50 MHz clock which means that the clock cycle is repeated 50M times in one second. So to create a 0.1 second delay we multiply the clock with the required time: 50MHz * 0.1 sec =

Seven Segment LED Multiplexing Circuit in Verilog

The seven segment LED circuit uses seven different and individual LED's to display a hexadecimal symbol. It has 7 wires to control the individual LED's one wire to control the decimal point and one enable wire. The demo board I am using here consists of four such 7-segment LED's(As do any other demo board). To reduce the number of wires a multiplexing circuit is used to control the display. Using the multiplexing circuit the number of wires required to light up all 4 displays are reduced from 32 to 12 (8 data bits and 4 enable bits). All bits here are active low, such that to enable them a '0' is required. For example the figure below shows how to display a 3 on the seven segment. The multiplexing circuit can take 4 inputs and have only one output. But the inputs should be displayed on the output fast enough to fool the viewer into thinking all outputs are enabled individually and simultaneously. This is achieved by having an enable signal that changes so fast t

Random Number Generator in Verilog | FPGA

In verilog a random number can be generated by using the $random keyword but that works only for simulation purposes and cannot be implemented. So when we need a random number for implementation i.e. in hardware it can be achieved using an LFSR (Liner Feedback Shift Register). An LFSR is simply a shift register with some of its bits (known as taps) XOR'd with themselves to create a feedback term. When implementing an LFSR it's width and it's repeatability must be kept under consideration .An N-bit LFSR will be able to generate (2**N) - 1 random bits before it starts repeating. For example a 30 bit LFSR will have 1073741823 random states before repeating, so for most practical purposes this can be considered true random. In an LFSR the MSB will always be the feedback point also the main thing to take care of while coding an LFSR is to know which bits are the taps (to be selected for XOR ). This is confusing as the taps are different for different size registers. For e