UART VHDL code | UART Transmitter,UART Receiver VHDL code

This page mentions UART vhdl code. It describes UART transmitter vhdl code and UART receiver vhdl code.

The figure-1 below depicts UART based serial data transmission system. It is used to transmit data over telephone line using modem. PC and modem are connected using UART interface.

UART Transmitter Receiver system

UART serial data format consists of one start bit, 8 data bits and one stop bit. 8 data bits contains 1 bit as parity bit.

UART Block Diagram

The figure-2 depicts block diagram of UART. It has three parts viz. UART transmitter, baud rate generator and UART receiver.

UART transmitter vhdl code

UART Transmitter flow chart

The figure-3 depicts UART transmitter flow chart and following is the UART transmitter vhdl code for the same.


library ieee; 
use ieee.std_logic_1164.all;
entity UART_Transmitter is
port(Bclk, sysclk, rst_b, TDRE, loadTDR: in std_logic;
DBUS:in std_logic_vector(7 downto 0);
setTDRE, TxD: out std_logic);
end UART_Transmitter;
architecture xmit of UART_Transmitter is
type stateType is (IDLE, SYNCH, TDATA);
signal state, nextstate : stateType;
signal TSR : std_logic_vector (8 downto 0); -- Transmit Shift Register
signal TDR : std_logic_vector(7 downto 0); -- Transmit Data Register
signal Bct: integer range 0 to 9; -- counts number of bits sent
signal inc, clr, loadTSR, shftTSR, start: std_logic;
signal Bclk_rising, Bclk_dlayed: std_logic;
begin
TxD <= TSR(0);
setTDRE <= loadTSR;
Bclk_rising <= Bclk and (not Bclk_dlayed); -- indicates the rising edge of bit clock
Xmit_Control: process(state, TDRE, Bct, Bclk_rising)
begin
inc <= '0'; clr <= '0'; loadTSR <= '0'; shftTSR <= '0'; start <= '0';
-- reset control signals
case state is
when IDLE => if (TDRE = '0' ) then
loadTSR <= '1'; nextstate <= SYNCH;
else nextstate <= IDLE; end if;
when SYNCH => -- synchronize with the bit clock
if (Bclk_rising = '1') then
start <= '1'; nextstate <= TDATA;
else nextstate <= SYNCH; end if;
when TDATA =>
if (Bclk_rising = '0') then nextstate <= TDATA;
elsif (Bct /= 9) then
shftTSR <= '1'; inc <= '1'; nextstate <= TDATA;
else clr <= '1'; nextstate <= IDLE; end if;
end case;
end process;
Xmit_update: process (sysclk, rst_b)
begin
if (rst_b = '0') then
TSR <= "111111111"; state <= IDLE; Bct <= 0; Bclk_dlayed <= '0';
elsif (sysclk'event and sysclk = '1') then
state <= nextstate;
if (clr = '1') then Bct <= 0; elsif (inc = '1') then
Bct <= Bct + 1; end if;
if (loadTDR = '1') then TDR <= DBUS; end if;
if (loadTSR = '1') then TSR <= TDR & '1'; end if;
if (start = '1') then TSR(0) <= '0'; end if;
if (shftTSR = '1') then TSR <= '1' & TSR(8 downto 1); end if; -- shift out one bit
Bclk_dlayed <= Bclk; -- Bclk delayed by 1 sysclk
end if;
end process;
end xmit;

UART receiver vhdl code

UART Receiver flow chart

The figure-4 depicts UART receiver flow chart and following is the UART receiver vhdl code for the same.


library ieee;
use ieee.std_logic_1164.all;
entity UART_Receiver is
port(RxD, BclkX8, sysclk, rst_b, RDRF: in std_logic;
RDR: out std_logic_vector(7 downto 0);
setRDRF, setOE, setFE: out std_logic);
end UART_Receiver;
architecture rcvr of UART_Receiver is
type stateType is (IDLE, START_DETECTED, RECV_DATA);
signal state, nextstate: stateType;
signal RSR: std_logic_vector (7 downto 0); -- receive shift register
signal ct1 : integer range 0 to 7; -- indicates when to read the RxD input
signal ct2 : integer range 0 to 8; -- counts number of bits read
signal inc1, inc2, clr1, clr2, shftRSR, loadRDR : std_logic;
signal BclkX8_Dlayed, BclkX8_rising : std_logic;
begin
BclkX8_rising <= BclkX8 and (not BclkX8_Dlayed);
-- indicates the rising edge of bitX8 clock
Rcvr_Control: process(state, RxD, RDRF, ct1, ct2, BclkX8_rising)
begin
-- reset control signals
inc1 <= '0'; inc2 <= '0'; clr1 <= '0'; clr2 <= '0';
shftRSR <= '0'; loadRDR <= '0'; setRDRF <= '0'; setOE <= '0'; setFE <= '0';
case state is
when IDLE => if (RxD = '0' ) then nextstate <= START_DETECTED;
else nextstate <= IDLE; end if;
when START_DETECTED =>
if (BclkX8_rising = '0') then nextstate <= START_DETECTED;
elsif (RxD = '1') then clr1 <= '1'; nextstate <= IDLE;
elsif (ct1 = 3) then clr1 <= '1'; nextstate <= RECV_DATA;
else inc1 <= '1'; nextstate <= START_DETECTED; end if;
when RECV_DATA =>
if (BclkX8_rising = '0') then nextstate <= RECV_DATA;
else inc1 <= '1';
if (ct1 /= 7) then nextstate <= RECV_DATA;
-- wait for 8 clock cycles
elsif (ct2 /= 8) then
shftRSR <= '1'; inc2 <= '1'; clr1 <= '1'; -- read next data bit
nextstate <= RECV_DATA;
else
nextstate <= IDLE;
setRDRF <= '1'; clr1 <= '1'; clr2 <= '1';
if (RDRF = '1') then setOE <= '1'; -- overrun error
elsif (RxD = '0') then setFE <= '1'; -- framing error
else loadRDR <= '1'; end if; -- load recv data register
end if;
end if;
end case;
end process;

Rcvr_update: process (sysclk, rst_b)
begin
if (rst_b = '0') then state <= IDLE; BclkX8_Dlayed <= '0';
ct1 <= 0; ct2 <= 0;
elsif (sysclk'event and sysclk = '1') then
state <= nextstate;
if (clr1 = '1') then ct1 <= 0; elsif (inc1 = '1') then
ct1 <= ct1 + 1; end if;
if (clr2 = '1') then ct2 <= 0; elsif (inc2 = '1') then
ct2 <= ct2 + 1; end if;
if (shftRSR = '1') then RSR <= RxD & RSR(7 downto 1); end if;
-- update shift reg.
if (loadRDR = '1') then RDR <= RSR; end if;
BclkX8_Dlayed <= BclkX8; -- BclkX8 delayed by 1 sysclk
end if;
end process;
end rcvr;

Baud rate generator VHDL code

Refer Baud rate generator VHDL code>>.

Complete UART vhdl code

library ieee; 
use ieee.std_logic_1164.all;
entity UART is
port (SCI_sel, R_W, clk, rst_b, RxD : in std_logic;
ADDR2: in std_logic_vector(1 downto 0);
DBUS : inout std_logic_vector(7 downto 0);
SCI_IRQ, TxD : out std_logic);
end UART;
architecture uart1 of UART is
component UART_Receiver
port (RxD, BclkX8, sysclk, rst_b, RDRF: in std_logic;
RDR: out std_logic_vector(7 downto 0);
setRDRF, setOE, setFE: out std_logic);
end component;
component UART_Transmitter
port (Bclk, sysclk, rst_b, TDRE, loadTDR: in std_logic;
DBUS: in std_logic_vector(7 downto 0);
setTDRE, TxD: out std_logic);
end component;
component clk_divider
port (Sysclk, rst_b: in std_logic;
Sel: in std_logic_vector(2 downto 0);
BclkX8: buffer std_logic;
Bclk: out std_logic);
end component;

signal RDR : std_logic_vector(7 downto 0); -- Receive Data Register
signal SCSR : std_logic_vector(7 downto 0); -- Status Register
signal SCCR : std_logic_vector(7 downto 0); -- Control Register
signal TDRE, RDRF, OE, FE, TIE, RIE : std_logic;
signal BaudSel : std_logic_vector(2 downto 0);
signal setTDRE, setRDRF, setOE, setFE, loadTDR, loadSCCR : std_logic;
signal clrRDRF, Bclk, BclkX8, SCI_Read, SCI_Write : std_logic;
begin
RCVR: UART_Receiver port map(RxD, BclkX8, clk, rst_b, RDRF, RDR, setRDRF,
setOE, setFE);
XMIT: UART_Transmitter port map(Bclk, clk, rst_b, TDRE, loadTDR, DBUS,
setTDRE, TxD);
CLKDIV: clk_divider port map(clk, rst_b, BaudSel, BclkX8, Bclk);
-- This process updates the control and status registers
process (clk, rst_b)
begin
if (rst_b = '0') then
TDRE <= '1'; RDRF <= '0'; OE<= '0'; FE <= '0';
TIE <= '0'; RIE <= '0';
elsif (rising_edge(clk)) then
TDRE <= (setTDRE and not TDRE) or (not loadTDR and TDRE);
RDRF <= (setRDRF and not RDRF) or (not clrRDRF and RDRF);
OE <= (setOE and not OE) or (not clrRDRF and OE);
FE <= (setFE and not FE) or (not clrRDRF and FE);

if (loadSCCR = '1') then TIE <= DBUS(7); RIE <= DBUS(6);
BaudSel <= DBUS(2 downto 0);
end if;
end if;
end process;
-- IRQ generation logic
SCI_IRQ <= '1' when ((RIE = '1' and (RDRF = '1' or OE = '1'))
or (TIE = '1' and TDRE = '1'))
else '0';
-- Bus Interface
SCSR <= TDRE & RDRF & "0000" & OE & FE;
SCCR <= TIE & RIE & "000" & BaudSel;
SCI_Read <= '1' when (SCI_sel = '1' and R_W = '0') else '0';
SCI_Write <= '1' when (SCI_sel = '1' and R_W = '1') else '0';
clrRDRF <= '1' when (SCI_Read = '1' and ADDR2 = "00") else '0';
loadTDR <= '1' when (SCI_Write = '1' and ADDR2 = "00") else '0';
loadSCCR <= '1' when (SCI_Write = '1' and ADDR2 = "10") else '0';
DBUS <= "ZZZZZZZZ" when (SCI_Read = '0') -- tristate bus when not reading
else RDR when (ADDR2 = "00") -- write appropriate register to the bus
else SCSR when (ADDR2 = "01")
else SCCR; -- dbus = sccr, if ADDR2 is "10" or "11"
end uart1;


USEFUL LINKS to VHDL CODES

Refer following as well as links mentioned on left side panel for useful VHDL codes.
D Flipflop
T Flipflop
Read Write RAM
4X1 MUX
4 bit binary counter
Radix4 Butterfly
16QAM Modulation
2bit Parallel to serial

RF and Wireless tutorials

WLAN  802.11ac  802.11ad  wimax  Zigbee  z-wave  GSM  LTE  UMTS  Bluetooth  UWB  IoT  satellite  Antenna  RADAR