4.1 UART Transmitter Design Guide PDF
4.1 UART Transmitter Design Guide PDF
This document is here to help guide you through the design of the UART transmitter. If you are
having any troubles be sure to read through each section as you are designing your UART
transmitter. Also be sure that you read the comments in the VHDL design file as these are there
to help you design and understand the design.
Constants
This section discusses the constants used in the UART transmitter design. The UART transmitter
contains 3 constants:
1. max_clk_count, which is the number of clock cycles it takes to achieve 1-bit time for the
desired baud rate.
o Example: We have a 50 MHz input clock and we would like to achieve a baud
rate of 19200, what would the max_clk_count be?
o A: Take the clock rate 50MHz and divide it by the desired baud rate à 50,000,000
/ 19200 = 2604. This would give us a bit time of 52µS (2604 / 50,000,000). Let’s
check our answer, 1/19200 = 52 µS, therefore by taking the clock rate / baud rate
gives us our clock count.
2. max_clk_count_delay, is the number of clock cycles required to achieve a delay of 52
µS. This number was arbitrarily chosen.
3. max_bits, is the total number of bits in our UART data packet. We are transmitting 1
start bit, 8 data bits and 1 stop bit.
Signals
The UART transmitter design uses several signals to successfully implement the design. All the
signals you will need to implement the design are listed in the tUART.vhd file, you may add
more signals if you feel they are necessary but if you follow the lectures, comments in the code,
and this design guide you shouldn’t need to add any more signals.
State Machine
This section discusses the transmitter state machine and what needs to be accomplished
in order to design it correctly. Figure 1 is the transmitter state machine diagram we are trying to
implement.
Figure 1 - Transmitter State Machine Diagram
The state machine contains two processes, state_proc and nxt_state_proc, where
state_proc assigns the signal ‘state’ to the value of the signal ‘nxt_state’. The nxt_state_proc
evaluates multiple signals and determines what value to assign to the ‘nxt_state’ signal. Below
each state is listed and described:
init state
o The init state is the initial state in this state machine and is the state we go to when
we assert the reset signal. In this state we want to do the following things:
Set the transmit_done signal high, indicating we are no longer
transmitting.
Check if the start_trans signal is high, if it is set the nxt_state signal to the
load, otherwise stay in the init state.
Check if the delay_clock_done signal is high, if yes set the delay_clock
signal low, otherwise set the delay_clock signal high.
load state
o The load state is where we set the load_data signal high and set the nxt_state
signal to shift.
shift state
o The shift state is the state we are in when we are shifting (transmitting) the data
packet. We want to check if the done_shifting signal is high, if it is we want to set
the nxt_state signal to init and set the delay_clock signal high. If the done_shifting
signal is not high, we want to stay in the shift state
Processes
This section discusses each process in detail. If you get stuck or need guidance on how to write
the VHDL code for each process, this document can be used to help you.
begin_trans_proc
This process shall be designed to detect the rising edge of the start signal. Using Figure 2
as a reference, where the portion of a circuit has been enclosed to represent a process and a
portion has been enclosed to represent a concurrent statement.
count_bits_proc
Count the number of bits that have been shifted. If number_bits signal is equal to the
constant max_bits then we want to set the done_shifting signal high and set the
number_bits signal to zero.
Load data into the data_reg signal. When loading data into the data_reg we must be sure
to include the start and stop bits. Below is the format we want the data located in
the data_reg to be:
Shift the data located in the data_reg. Since we are transmitting data little endian we
want to implement a shift register that shifts data to the right. An example of shifting the
data in the data_reg can be found below:
We want to shift data every time the shift_data signal is high. We also want to increment the
number_bits signal to keep track of how many times we have shifted data. Make sure that you
are replacing the empty data_reg values with ‘1’ otherwise if you put zero’s we could cause an
accidental start condition.
clock_count_proc
This process shall be designed to count the number of clock cycles so that the UART
transmitter transmits at the specific baud rate. This only occurs when we are in the shift state. We
want this process to be evaluated every clock cycle, therefore we need the input signal clk placed
in the processes sensitivity list.
clock_delay_proc
This process is design to create a delay so that when the data transmission has been
completed there is a small delay before the tx_ready output signal goes high indicating we are
ready to transmit another data packet. This is here simply as a pre-caution to prevent us from
potentially “over feeding” ourselves. Also if you were interfacing an FPPGA with a
microcontroller, the microcontroller may not be able to keep up with the FPGA you design a
delay in the transmission so the microcontroller has time to act on the received message before
receiving another message.
tx_ready_proc
This process shall be design to detect when the start signal is asserted. Once the start
signal has been asserted (equal to ‘1’ a.k.a high) we want to set the tx_ready_reg low, otherwise
we want to set it high.