Uart

Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

Universal Asynchronous Receiver-Transmitter

By

Susie E. Maestre, ECE

Presented to:
Prof. Margie S. Arda
Mindanao State University – Iligan Institute of Technology

EE278 – FPGA

17 January 2021
1 Introduction
A universal asynchronous receiver and transmitter (UART) is a circuit that sends
parallel data through a serial line. A UART includes a transmitter and a receiver. The
transmitter is essentially a special shift register that loads data in parallel and then shifts
it out bit by bit at a specific rate. The receiver, on the other hand, shifts in data bit by bit
and then reassembles the data. The serial line is 1 when it is idle. The transmission starts
with a start bit, which is 0, followed by data bits and an optional parity bit, and ends with
stop bits, which are 1. The number of data bits can be 6, 7, or 8. The optional parity bit
is used for error detection. For odd parity, it is set to 0 when the data bits have an odd
number of 1’s. For even parity, it is set to 0 when the data bits have an even number of 1’s.
The number of stop bits can be 1, 1.5 or 2. Transmission with 8 data bits, no parity, and 1
stop bit is shown in Figure 1.

Figure 1: Transmission of the Byte (01010101) with Start and Stop Bits (Baud Rate = 9600)

Note that the LSB of the data word is transmitted first. No clock information is
conveyed through the serial line. Before the transmission starts, the transmitter and receiver
must agree on a set of parameters in advance, which include the baud rate (i.e., number
of bits per second), the number of data bits and stop bits, and use of the parity bit. The
design is customized for a UART with a selectable baud rate of 9600 and 115 200, 8 data
bits, 1 stop bit, and no parity bit.
Since no clock information is conveyed from the transmitted signal, the receiver and
transmitter can send and retrieve respectively the data bits only by using the predetermined
parameters. We use an oversampling scheme to estimate the middle points of transmitted
bits and then retrieve them at these points accordingly.

2 Design Specifications
The UART is divided into three sub-modules: baud rate generator, transmitter, and
receiver. It has two external ports, the transmit (txd) and receive (rxd) ports. Figure 2
shows the conceptual block diagram of the UART.

Figure 2: UART Conceptual Block Diagram

EE 278 | FPGA
1
2.1 Baud rate generator
This module generates the bitclk based on a baud rate of 9600 or 115200. A mul-
tiplexer selects between the two baud rates (br sel is logic 0 for 9600, logic 1 for 115200).
The bitclk is used to synchronize the sampling of the data bits on both the receiver and
transmitter. Both the transmitter and receiver should be set to the same baud rate. If there
is no active transmission/reception of data, the bitclk output signal is set to low.

2.2 The UART Transmitter


This module facilitates transmission of data on the txd port. The start bit and stop
bit are incorporated to the data bits to be sent. Data to be transmitted is written to a
transmit buffer, UTXBUF, then loaded to the transmit shift register. Transmission of data
is LSB first. For every bitclk, one bit is transmitted on the txd port. When rst is high, the
transmitter is disabled. If rst is low, the transmitter goes to an idle state and waits until
a transmission is initiated which happens when data is written to UTXBUF. Assume that
data can only be written in UTXBUF if it is empty or until an active transmission is done.
The txd port is set to high during the idle state.

2.3 The UART Receiver


This module samples the data received on the rxd port. Data bits are concatenated
in the receive shift register while the start bit, and stop bit are ignored. Data is received bit
by bit on the rxd port and sampled every half-cycle of a bitclk period. Every bit sampled is
shifted into the receive shift register. The receive data buffer, URXBUF, contains the 8-bit
data moved from the receive shift register after all data bits are received. When a start
bit is received, the baud rate generator outputs a bitclk for the receiver then stops after a
packet is received. When rst is high, the receiver is disabled. If rst is low, the receiver goes
to an idle state and waits for a valid start bit on the rxd port before it changes to an active
receiver state. A valid start bit sets the rxd port to low for one bitclk period. The rxd is
set to high during the idle state.

EE 278 | FPGA
2
3 Design Implementation
By combining the receiving and transmitting subsystems, a complete UART core is
constructed. Below is the code of the the UART top module. Additional UART interface
circuits for both the receiver and transmitter are added to provide a mechanism to signal
the availability of a new data and to prevent the received word from being retrieved multiple
times. It also provides buffer space between the receiver and the main system. The interface
circuit used in the receiver and transmitter is a flag FF and a one word buffer [1]. Figure 3
shows the block diagram of the design.

Figure 3: UART Block Diagram

UART Top Module | Verilog Code

/*
Susie Maestre
UART Top Module
*/
module uart
(
input wire mclk , rst ,
input wire wr_uart , rxd , br_sel ,
input wire [ 7 : 0 ] w_data , // data to be written to UTXBUF
output wire txd ,
output wire [ 7 : 0 ] URXBUF ,
output wire [ 7 : 0 ] UTXBUF ,
output wire bitclk_tx , // propagated for simulation purposes
output wire bitclk_rx
);

// signal declaration
wire rx_done_tick , tx_done_tick , tx_start , tx_not_active , rx_not_active ;
wire [ 7 : 0 ] rx_data_out ;

// tx baud generator instantiation


baud_gen b a u d _ g e n _ t x _ u n i t ( . mclk ( mclk ) , . rst ( rst ) , . br_sel ( br_sel ) ,

EE 278 | FPGA
3
. no t _a ct i ve _f l ag ( tx_not_active ) , . bitclk ( bitclk_tx ) ) ;

// rx baud generator instantiation


baud_gen b a u d _ g e n _ r x _ u n i t ( . mclk ( mclk ) , . rst ( rst ) , . br_sel ( br_sel ) ,
. no t _a ct i ve _f l ag ( rx_not_active ) , . bitclk ( bitclk_rx ) ) ;

// receiver instantiation
uart_rx uart_rx_unit
( . mclk ( mclk ) , . rst ( rst ) , . rxd ( rxd ) , . bitclk_rx ( bitclk_rx ) ,
. rx_done_tick ( rx_done_tick ) , . rx_not_active ( rx_not_active ) , . dout ( rx_data_out ) ) ;

// receiver interface instantiation


rx_interface rx_buf_unit
( . mclk ( mclk ) , . rst ( rst ) , . clr_flag ( rx_not_active ) ,
. set_flag ( rx_done_tick ) , . din_buf ( rx_data_out ) , . URXBUF ( URXBUF ) ) ;

// transmitter interface instantiation


tx_interface tx_buf_unit
( . mclk ( mclk ) , . rst ( rst ) , . clr_flag ( tx_done_tick ) ,
. set_flag ( wr_uart ) , . tx_buf_full ( tx_start ) , . din_buf ( w_data ) , . UTXBUF ( UTXBUF ) ) ;

// transmitter instantiation
uart_tx uart_tx_unit
( . mclk ( mclk ) , . rst ( rst ) , . tx_start ( tx_start ) , . bitclk_tx ( bitclk_tx ) , . din ( UTXBUF ) ,
. tx_done_tick ( tx_done_tick ) , . tx_not_active ( tx_not_active ) , . txd ( txd ) ) ;

endmodule

3.1 The Baud Rate Generator


As stated in section 2.1, the baud generator module generates the bitclk based on a
baud rate of 9600 or 115200. In this design, the baud generator is essentially made from
counting clock pulses. To avoid creating a new clock domain and violating the synchronous
design principle, the bitclk is used as an edge-trigged event to the receive and transmit
states. For a system clock of 16MHz, the baud rate generator needs to count:
16M Hz
P ulses to count =
baud rate
16x106
= = 1666.67 (for baud rate = 9600)
9600
16x106
= = 138.89 (for baud rate = 115200)
115200

In this design, the nearest even number of the results, which are 1666 and 138
respectively, are used to have an equal length of pulse for every half cycles. Two separate
baud generators for the transmitter and receiver are instantiated. The reason for this is
to avoid reusing the counters. The not active flag is connected to the tx not active and
rx not active of the transmitter and receiver respectively. The baud rate generator in this
design essentially has two counters. One is used to count 1666-1 pulses and the other is
used to count 138-1 pulses. The size N of the counter registers r0 reg and r1 reg for M
pulses is given by the formula:
N = ceil(log2 M )
= ceil(log2 1666) = 11 (for baud rate = 9600)
= ceil(log2 138) = 8 (for baud rate = 115200)

EE 278 | FPGA
4
Baud Rate Generator | Verilog Code

/*
Susie Maestre
Baud Generator Module
*/
module baud_gen
(
input wire mclk , rst , br_sel , n ot _a c ti v e_ fl a g ,
output wire bitclk
);

localparam PULSE0 = 1666 ; // clock pulses for 9600 baud rate


localparam PULSE1 = 138 ; // clock pulses for 115200 baud rate
// signal declaration
reg [ 10 : 0 ] r0_reg ; // [N - 1 : 0 ] ; counter for 9600 baud rate
reg [ 7 : 0 ] r1_reg ; // [N - 1 : 0 ] ; counter for 115200 baud rate
wire [ 10 : 0 ] r0_next ;
wire [ 7 : 0 ] r1_next ;
wire br0 , br1 ;

// body
// register
always @ ( posedge mclk , posedge rst )
if ( rst ) // not counting pulses if rst is high and there's no active reception / transmission
begin
r0_reg < = 0 ;
r1_reg < = 0 ;
end
else if ( no t _a ct i ve _f l ag ) // not counting pulses if rx_not_active / tx_not_active is HIGH
begin
r0_reg < = 0 ;
r1_reg < = 0 ;
end
else
begin
r0_reg < = r0_next ;
r1_reg < = r1_next ;
end

// next - state logic


assign r0_next = ( r0_reg = = ( PULSE0 - 1 ) ) ? 0 : r0_reg + 1 ; // 9600 baud rate : needs 1667 pulses
assign r1_next = ( r1_reg = = ( PULSE1 - 1 ) ) ? 0 : r1_reg + 1 ; // 115200 baud rate : needs 139 pulses
// baud rates : br0 = 9600 , br1 = 115200
assign br0 = ( r0_reg > 0 & & r0_reg < = ( PULSE0 / 2 ) ) ? 1'b1 : 1'b0 ;
assign br1 = ( r1_reg > 0 & & r1_reg < = ( PULSE1 / 2 ) ) ? 1'b1 : 1'b0 ;
// output logic ;
assign bitclk = ( br_sel = = 0 ) ? br0 : br1 ;

endmodule

3.2 UART Transmitter Sub-module


The organization of a UART transmitting sub-module consists of a UART transmit-
ter, baud rate generator, and transmitter interface circuit. The w data represents the data
to be written to the UTXBUF, which will be loaded to the shift register, b reg of the trans-
mitter main system. The transmitter interface circuit comprises a flag and a one word(8
bits) buffer.
The transmitter main system(uart tx) includes three finite states: disabled, idle,
and transmit, which represent the disabled state when rst is HIGH, the idle state and the
processing of the start bit, data bits, and stop bit. Figure 4 shows the FSM of the UART
transmitter.

EE 278 | FPGA
5
Figure 4: UART Transmitter FSM

If the rst is HIGH, the transmitter goes into the disabled state. If the rst LOW,
the transmitter goes to the idle state, then waits for a data to be loaded to the UTXBUF.
When data is loaded to the UTXBUF, and the wr uart is asserted, UTXBUF loads the data
to the b reg shift register of the transmitter, then the transmitter goes to transmit state.
The timing control of the transmit state is driven by the positive edge of the bitclk tx.
The n register keeps track of the number of data bits, including the start bit and the stop
bit received in the transmit state. The n register counts a total of 10 bits. One bit is
transmitted every bitclk period. Once the stop bit is transmitted, the transmitter goes back
to idle state.
Figure 5 shows the schematic diagram of the UART transmitter sub-module. The
wr uart sets the flag (tx buf full) and then asserts tx start signal. The main system then
loads the data from UTXBUF to the shift register (b reg). After assertion of the tx start
signal, the transmitter main system loads the data word and then gradually progresses
through the start, data, and stop states to shift out the corresponding bits. It signals
completion by asserting the tx done tick signal for one clock cycle. A 1-bit buffer, tx reg, is
used to filter out any potential glitch. The UART transmitter is essentially a shift register
that shifts out data bits at a specific rate. The rate can be controlled by one-clock-cycle
enable ticks generated by the baud rate generator. The tx not active register tells the baud
rate generator that there is no active transmission, and hence, bitclk tx goes to LOW.

Figure 5: UART Transmitter Sub-module Schematic Diagram

UART Transmitter | Verilog Code

/*
Susie Maestre
UART Transmitter Module
*/

EE 278 | FPGA
6
module uart_tx
( input wire mclk , rst ,
input wire tx_start , bitclk_tx ,
input wire [ 7 : 0 ] din ,
output reg tx_done_tick , tx_not_active ,
output wire txd ) ;

// symbolic state declaration


localparam [ 1 : 0 ]
disabled = 2'b00 ,
idle = 2'b01 ,
transmit = 2'b10 ;
// signal declaration
reg [ 1 : 0 ] state_reg , state_next ;
reg [ 3 : 0 ] n_reg , n_next ; // register used to indicate bit number
reg [ 7 : 0 ] b_reg , b_next ; // register used to shift data bits
reg tx_reg , tx_next ;

// body
// FSM state & data registers
always @ ( posedge mclk , posedge rst )
if ( rst )
begin
state_reg < = disabled ;
n_reg < = 0 ;
b_reg < = 0 ;
tx_reg < = 1'b1 ;
end
else
begin
state_reg < = state_next ;
n_reg < = n_next ;
b_reg < = b_next ;
tx_reg < = tx_next ;
end

// FSM next - state logic & functional units


always @ *
begin
state_next = state_reg ;
tx_done_tick = 1'b0 ;
n_next = n_reg ;
b_next = b_reg ;
tx_next = tx_reg ;
case ( state_reg )
disabled :
begin
tx_not_active = 1'b1 ;
tx_next = 1'b1 ;
if (∼rst )
state_next = idle ;
end
idle :
begin
tx_next = 1'b1 ; // sends a high signal for an idle state , no data to be transmitted
tx_done_tick = 1'b0 ;
tx_not_active = 1'b1 ;
if ( tx_start )
begin
state_next = transmit ;
n_next = 0 ;
b_next = din ;
tx_not_active = 1'b0 ;
end
end
transmit :
@ ( posedge bitclk_tx )
begin
if ( n_reg = = 0 )
begin
tx_next = 1'b0 ; // send start bit
n_next = n_reg + 1 ;
end

EE 278 | FPGA
7
else if ( n_reg > 0 & & n_reg < 9 )
begin
tx_next = b_reg [ 0 ] ; // send data bit
b_next = b_reg > > 1 ; // shift to the right
n_next = n_reg + 1 ;
end
else if ( n_reg = = 9 )
begin
tx_next = 1'b1 ; // send stop bit
tx_done_tick = 1'b1 ;
n_next = n_reg + 1 ;
end
else
begin
state_next = idle ;
tx_not_active = 1'b1 ;
end
end

endcase
end

// output
assign txd = tx_reg ;
endmodule

UART Transmitter Interface | Verilog Code

/*
Susie Maestre
TX Interface Circuit
*/
module tx_interface
# ( parameter W = 8 ) // # buffer bits
(
input wire mclk , rst ,
input wire clr_flag , set_flag ,
input wire [ W - 1 : 0 ] din_buf ,
output wire tx_buf_full ,
output wire [ W - 1 : 0 ] UTXBUF
);

// signal declaration
reg [ W - 1 : 0 ] buf_reg , buf_next ;
reg flag_reg , flag_next ;

// body
// FF & register
always @ ( posedge mclk , posedge rst )
if ( rst )
begin
buf_reg < = 0 ;
flag_reg < = 1'b0 ;
end
else
begin
buf_reg < = buf_next ;
flag_reg < = flag_next ;
end
// next - state logic
always @ *
begin
buf_next = buf_reg ;
flag_next = flag_reg ;
if ( clr_flag )
begin
flag_next = 1'b0 ;
buf_next = 0 ;
end
else if ( set_flag )
begin
buf_next = din_buf ;

EE 278 | FPGA
8
flag_next = 1'b1 ;
end
end
// output logic
assign UTXBUF = buf_reg ;
assign tx_buf_full = flag_reg ;

endmodule

3.3 UART Receiver Sub-module

The UART receiving sub-module is very similar to the transmitter module. It con-
sists of the receiving main system, baud rate generator, and the receiver interface circuit.
The receiver main system also includes three finite states: disabled, idle, and re-
ceive, which represent the disabled state, the idle state and the processing of the start bit,
data bits, and stop bit. Furthermore, the the number of bits is counted by n registers.
If the rst is HIGH, the receiver goes into the disabled state. If the rst LOW, the receiver
goes to the idle state, then waits a start bit at the rxd port. When the bit received in the
rxd port is 0, the receiver goes to receive state. The timing control of the receive state
is driven by the negative edge of the bitclk rx since the data received is sampled every
half cycle of the bitclk rx period. The n register keeps track of the number of data bits,
including the start bit and the stop bit received in the receive state. The n register counts
a total of 10 bits. One bit is received every one bitclk rx period.
The retrieved bits are shifted into and reassembled in the b register. A status signal,
rx done tick, is included. It is asserted for one clock cycle after the receiving process is
completed. Figure 6 shows the FSM of the UART receiver.

Figure 6: UART Receiver FSM

In the receiver interface, the rx done tick is connected to the set flag signal and
sets the flag rx done when a new data word arrives. When the rx done tick is asserted, the
data from the shift register (b register) is loaded to the URXBUF. After the data has been
read, it then asserts the clr flag which is connected to rx not active signal one clock cycle
after the read process. The rx not active register tells the baud rate generator that there
is no active reception, and hence, the bitclk rx goes to LOW. Figure 7 shows the schematic
diagram of the UART receiver sub-module.

EE 278 | FPGA
9
Figure 7: UART Receiver Sub-module Schematic Diagram

UART Receiver | Verilog Code

/*
Susie Maestre
UART Receiver Module
*/

module uart_rx
(
input wire mclk , rst ,
input wire rxd , bitclk_rx ,
output reg rx_done_tick , rx_not_active ,
output wire [ 7 : 0 ] dout
);
// symbolic state declaration
localparam [ 1 : 0 ]
disabled = 2'b00 ,
idle = 2'b01 ,
receive = 2'b10 ;
// signal declaration
reg [ 1 : 0 ] state_reg , state_next ;
reg [ 3 : 0 ] n_reg , n_next ;
reg [ 7 : 0 ] b_reg , b_next ; // register used to shift data bits

// body
// FSM state & data registers
always @ ( posedge mclk , posedge rst )
if ( rst )
begin
state_reg < = disabled ;
n_reg < = 0 ;
b_reg < = 0 ;
end
else
begin
state_reg < = state_next ;
n_reg < = n_next ;
b_reg < = b_next ;
end
// FSM next - state logic
always @ *
begin
state_next = state_reg ;
rx_done_tick = 1'b0 ;
n_next = n_reg ;
b_next = b_reg ;
case ( state_reg )
disabled :
begin
rx_not_active = 1'b1 ;
if (∼rst )
state_next = idle ;
end

idle :
begin
rx_not_active = 1'b1 ;
if (∼rxd ) // detects start bit
begin

EE 278 | FPGA
10
state_next = receive ;
n_next = 0 ;
rx_not_active = 1'b0 ;
end
end
receive :
@ ( negedge bitclk_rx )
begin
if ( n_reg < 9 )
begin
b_next = { rxd , b_reg [ 7 : 1 ] } ; // concatenation happens here
n_next = n_reg + 1 ;
end
else if ( n_reg = = 9 )
begin
rx_done_tick = 1'b1 ;
n_next = n_reg + 1 ;
end
else
begin
state_next = idle ;
rx_not_active = 1'b1 ;
end
end
endcase
end
// output
assign dout = b_reg ;

endmodule

UART Receiver Interface | Verilog Code

/*
Susie Maestre
RX Interface Circuit
*/
module rx_interface
# ( parameter W = 8 ) // # buffer bits
(
input wire mclk , rst ,
input wire clr_flag , set_flag ,
input wire [ W - 1 : 0 ] din_buf ,
output wire rx_done ,
output wire [ W - 1 : 0 ] URXBUF
);

// signal declaration
reg [ W - 1 : 0 ] buf_reg , buf_next ;
reg flag_reg , flag_next ;

// body
// FF & register
always @ ( posedge mclk , posedge rst )
if ( rst )
begin
buf_reg < = 0 ;
flag_reg < = 1'b0 ;
end
else
begin
buf_reg < = buf_next ;
flag_reg < = flag_next ;
end
// next - state logic
always @ *
begin
buf_next = buf_reg ;
flag_next = flag_reg ;
if ( set_flag )
begin
buf_next = din_buf ;

EE 278 | FPGA
11
flag_next = 1'b1 ;
end
else if ( clr_flag )
flag_next = 1'b0 ;
end
// output logic
assign URXBUF = buf_reg ;
assign rx_done = flag_reg ;

endmodule

4 Simulation Results
For the UART simulation, four stimulus modules are created to test the baud gener-
ator, the transmitter, receiver, and both the transmitter and receiver simultaneously.

4.1 Baud Generator Stimulus Module


The code below shows the stimulus module for the baud generator. The input br sel
selects between the baud rates 9600 and 115200.
Baud Generator Stimulus Module | Verilog Code

/*
Susie Maestre
Baud Generator Stimulus Module
*/
module baud_stimulus ;

reg mclk , rst , br_sel , n ot _a c ti ve _ fl a g ;


wire bitclk ;

baud_gen bg ( mclk , rst , br_sel , n o t_ ac t iv e_ f la g , bitclk ) ;

initial
begin
mclk = 1'b1 ;
forever # 31250 mclk = ∼mclk ; // mclk = 16MHz
end

initial
begin
// br_sel = 0 ; // baud rate = 9600
br_sel = 1 ; // baud rate = 115200
rst = 1'b1 ;
repeat ( 3 ) @ ( posedge mclk ) ;
rst = 1'b0 ;
n ot _a c ti ve _ fl a g = 1'b1 ;
repeat ( 6000 ) @ ( posedge mclk ) ;
n ot _a c ti ve _ fl a g = 1'b0 ;
repeat ( 10000 ) @ ( posedge mclk ) ;
$finish ;
end

endmodule

Figures 8 and 9 indicate the outputs of bitclk and bitclk at 9600 and 115200 baud
rates. As stated in section 3.1, for a 9600 baud rate, the baud generator counts 1666 mclk
pulses. On the other hand, for a 115200 baud rate, the baud generator counts 138 mclk
1
pulses. The main clock has a period of = 62.5ns. Thus, the bitclk periods for
16x106 Hz
EE 278 | FPGA
12
9600 and 115200 are equal to:

BIT CLK P ERIOD = (# pulses)(mclk period)


= (1666)(62.5ns) = 104 125 ns (for baud rate = 9600)
= (138)(62.5ns) = 8 625 ns (for baud rate = 115200)

Also shown in the waveforms, when the not active flag is asserted, the bitclk goes to
a logic LOW.

Figure 8: bitclk (Baud Rate = 9600)

Figure 9: bitclk (Baud Rate = 115200)

4.2 UART Transmitter Stimulus Module


The code below shows the stimulus module of the UART transmitter. The wr uart
tells the transmitter interface to load the 8-bit data from the w data input signal to the
UTXBUF. After one clock cycle, the tx buf full is raised which is connected to tx start.
When the tx start is HIGH, the data from the UTXBUF is loaded to the shift register
b reg. The FSM goes to transmitstate, where the shifting and transmission of bits happen.

EE 278 | FPGA
13
After the stop bit has been transmitted, it goes back to idle state.

UART Transmitter Stimulus Module | Verilog Code

/*
Susie Maestre
UART Transmitter Stimulus Module
*/

module stimulus_tx ;
reg mclk , rst , wr_uart , br_sel ;
reg [ 7 : 0 ] w_data ;
wire txd ;
wire [ 7 : 0 ] UTXBUF ;
wire bitclk_tx ; // propagated for simulation purposes
parameter CL OC K _P ER I OD _P S = 31250 ; // ( 31 . 25 ns )
parameter B I T C L K _ P E R I O d _ P S = 104125000 ; // ( 104 125 ns ) for 9600 baud rate ( br_sel = 0 )
// parameter B I T C L K _ P E R I O d _ P S = 8625000 ; //( 8625 ns ) 115200 baud rate ( br_sel = 1 )

uart dut ( . mclk ( mclk ) , . rst ( rst ) , . wr_uart ( wr_uart ) , . br_sel ( br_sel ) ,
. w_data ( w_data ) , . txd ( txd ) , . UTXBUF ( UTXBUF ) , . bitclk_tx ( bitclk_tx ) , . rxd ( ) , . URXBUF ( ) ) ;

initial
begin
mclk = 1'b1 ;
forever # C LO CK _ PE R IO D_ P S mclk = ∼mclk ; // mclk = 16MHz
end

initial
begin
br_sel = 0 ; // baud rate = 9600
// br_sel = 1 ; // baud rate = 115200
rst = 1'b1 ;
repeat ( 3 ) @ ( posedge mclk ) ;
rst = 1'b0 ;
// testing the transmitter
wr_uart = 1'b1 ;
w_data = 8'h5B ; // transmitting 8'b0101_1011
# BITCLK_PERIOd_PS
wr_uart = 1'b0 ;
repeat ( 20000 ) @ ( posedge mclk ) ;

$finish ;
end

endmodule

Figure 10 shows the transmission of a byte of data including the start and stop bits.
A total of 10 bits is transmitted. The transmitter sends data with a value of 8’h5B =
8’b0101 1011. As can be seen that the LSB is first transmitted. Figure 10 is transmitting
at a baud rate of 9600. As mentioned in the previous section, one bit is transmitted every
1 bitclk tx period. Note that at 9600 baud rate, the bitclk period is 104 125ns.
The start bit is sent at 104 500ns, after 1 bitclk period, the LSB is sent. The
waveform shows that 1 bit is sent every one bitclk period. Notice that each bit sent every
positive edge of the bitclk tx. After the stop bit is transmitted at 1 041 625ns, the UTXBUF
is cleared to allow another data to be written.

EE 278 | FPGA
14
Figure 10: Transmission of the Byte (01011011) with Start and Stop Bits (Baud Rate = 9600)

Figure 11 shows the transmission of a byte at 115200 baud rate. The time in
between the transmission of a bit at 115200 baud rate is 8 625ns as stated in the previous
section.

Figure 11: Transmission of the Byte (01011011) with Start and Stop Bits (Baud Rate = 115200)

4.3 UART Receiver Stimulus Module


The code below shows the stimulus module of the UART receiver. Since the UART
receiver is simulated alone, a task is added to the code to emulate the transmission of data to
the rxd port. The rxd port is initialized to a logic HIGH which means no data is received[2].

UART Receiver Stimulus Module | Verilog Code

/*
Susie Maestre
UART Receiver Stimulus Module
*/

module stimulus_rx ;
reg mclk , rst , rxd , br_sel ;
wire [ 7 : 0 ] URXBUF ;
wire bitclk_rx ;

EE 278 | FPGA
15
parameter CL OC K _P ER I OD _P S = 31250 ; // ( 31 . 25 ns )
parameter B I T C L K _ P E R I O d _ P S = 104125000 ; // ( 104 125 ns ) for 9600 baud rate ( br_sel = 0 )
// parameter B I T C L K _ P E R I O d _ P S = 8625000 ; //( 8625 ns ) 115200 baud rate ( br_sel = 1 )

uart dut ( . mclk ( mclk ) , . rst ( rst ) , . rxd ( rxd ) , . br_sel ( br_sel ) ,
. URXBUF ( URXBUF ) , . bitclk_rx ( bitclk_rx ) , . wr_uart ( ) , . w_data ( ) , . UTXBUF ( ) , . txd ( ) ) ;

initial
begin
mclk = 1'b1 ;
rxd = 1'b1 ; // set to 1 , no data available to be received
forever # C LO CK _ PE R IO D_ P S mclk = ∼mclk ;
end

// Takes in input byte and serializes it ; emulated data transmission to rxd


task U AR T_ W RI TE _ BY T E ;
input [ 7 : 0 ] i_Data ;
integer ii ;
begin

// Send Start Bit to rxd port


rxd < = 1'b0 ;
# BITCLK_PERIOd_PS ;

// Send Data Byte 1 bit at a time to rxd port


for ( ii = 0 ; ii < 8 ; ii = ii + 1 )
begin
rxd < = i_Data [ ii ] ;
# BITCLK_PERIOd_PS ;
end

// Send Stop Bit


rxd < = 1'b1 ;
# BITCLK_PERIOd_PS ;
end
endtask // UA RT _ WR IT E _B YT E

initial
begin
br_sel = 0 ; // baud rate = 9600
// br_sel = 1 ; // baud rate = 115200
rst = 1'b1 ;
repeat ( 3 ) @ ( posedge mclk ) ;
rst = 1'b0 ;
@ ( posedge mclk ) ;
// testing the receiver
U AR T_ W RI TE _ BY T E ( 8'h5B ) ; // receiving 8'b0101_1011
# BITCLK_PERIOd_PS ;
repeat ( 300 ) @ ( posedge mclk ) ;
$finish ;
end

endmodule

EE 278 | FPGA
16
At 52 375ns, a start bit is received by the rxd port. The time, in between the
bits are received, is similar to the transmitter for a corresponding baud rate. Figure 12
shows a reception of a byte with a value 8’h5B = 8’b01011011 including the start and stop
bits at a baud rate of 9600. The LSB is received first. Notice that the bits are sampled at
the negative edge of the bitclk rx. After the stop bit is received, the data is loaded to the
URXBUF after sampling.

Figure 12: Reception of a Byte (01011011) with Start and Stop Bits (Baud Rate = 9600)

Figure 13 shows a reception of a byte with a value 8’h5B = 8’b01011011 including


the start and stop bits at a baud rate of 115200. The LSB is received first.

Figure 13: Reception of a Byte (01011011) with Start and Stop Bits (Baud Rate = 115200)

EE 278 | FPGA
17
4.4 UART TX/RX Stimulus Module
To test both the transmitter and receiver simultaneously, two UART modules are
instantiated in the stimulus module as can be seen in the code below. The txd port of
UART1 is connected to the rxd port of UART2 as shown in figure 14.

Figure 14: UART Stimulus Connection

UART Stimulus Module | Verilog Code

/*
Susie Maestre
TX / RX Stimulus Module
*/

module stimulus ;
reg mclk , rst , wr_uart , br_sel ;
reg [ 7 : 0 ] w_data ;
wire txrx ;
wire [ 7 : 0 ] URXBUF ;
wire [ 7 : 0 ] UTXBUF ;
wire bitclk_tx ;
wire bitclk_rx ;

parameter CL OC K _P ER I OD _P S = 31250 ; // ( 31 . 25 ns )
// parameter B I T C L K _ P E R I O d _ P S = 104125000 ; //( 104 125 ns ) for 9600 baud rate ( br_sel = 0 )
parameter B I T C L K _ P E R I O d _ P S = 8625000 ; // ( 8625 ns ) 115200 baud rate ( br_sel = 1 )

// UART1 instantiation ; transmitter is connected to txrx , receiver is unconnected


uart u1
( . mclk ( mclk ) , . rst ( rst ) , . wr_uart ( wr_uart ) , . txd ( txrx ) ,
. br_sel ( br_sel ) , . w_data ( w_data ) , . UTXBUF ( UTXBUF ) , . bitclk_tx ( bitclk_tx ) , . rxd ( ) , . URXBUF ( ) ) ;

// UART2 instantiation ; receiver is connected to txrx , transmitter is unconnected


uart u2
( . mclk ( mclk ) , . rst ( rst ) , . rxd ( txrx ) ,
. br_sel ( br_sel ) , . URXBUF ( URXBUF ) , . bitclk_rx ( bitclk_rx ) , . wr_uart ( ) , . w_data ( ) , . UTXBUF ( ) , . txd ( ) ) ;

initial
begin
mclk = 1'b1 ;
// rxd = 1'b1 ; // set to 1 , no data available to be received
forever # C LO CK _ PE R IO D_ P S mclk = ∼mclk ;
end

initial
begin
// br_sel = 0 ; // baud rate = 9600
br_sel = 1 ; // baud rate = 115200
rst = 1'b1 ;
repeat ( 3 ) @ ( posedge mclk ) ;
rst = 1'b0 ;
// transmitting data
wr_uart = 1'b1 ;
w_data = 8'h53 ; // data = 8'b0101_0011

EE 278 | FPGA
18
# BITCLK_PERIOd_PS
wr_uart = 1'b0 ;
// receiving data

repeat ( 24000 ) @ ( posedge mclk ) ;

$finish ;
end

endmodule

Figure 15 shows the transmission and reception of the data 8’h53 (8’b0101 0011) at a
baud rate of 9600. At 104 500ns, the start bit has been transmitted. The stop bit has been
sent at 1 041 625ns. After the stop bit has been sampled by receiver, the data, excluding
the start and stop bit is loaded to the URXBUF.

Figure 15: Transmission and Reception of a Byte (01010011) (Baud Rate = 9600)

Figures 16 shows the same transmission and reception of data at a 115 200 baud
rate.

Figure 16: Transmission and Reception of a Byte (01010011) (Baud Rate = 115200)

EE 278 | FPGA
19
4.5 Netlist
Figure 17 shows the netlist of the whole UART module.

Figure 17: UART Netlist

5 Conclusions
The UART, which consists mainly of three sub-modules, has been successfully im-
plemented in Verilog HDL. The transmitter is implemented with the transmitter interface
circuit in which the data is loaded to the UTXBUF first, then the corresponding bit is
shifted to the right upon transmission. On the other hand, the receiver is implemented
with the receiver interface circuit in which the bits received by the rxd port are sampled.
Data bits are concatenated in the receive shift register while the start bit, and stop bit are
ignored.The baud generator acts like a counter in which it counts clock pulses and gives a
logic HIGH when it reached a corresponding number of pulses of a certain baud rate. It is
important that the transmitter and receiver have the same baud rate to ensure that the data
transmitted is received correctly. Results of the stimulus simulation show that the UART
is capable of receiving and transmitting an 8-bit of data with 1 start bit, 1 stop bit and no
parity bit.

References
[1] P. P. Chu, FPGA Prototyping by Verilog Examples. Hoboken, New Jersey: John Wiley
Sons, 1999.
[2] Nandland, “Uart, serial port, rs-232 interface,” accessed on 5 January 2021. [Online].
Available: https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.
html

EE 278 | FPGA
20

You might also like