UART in VHDL and Verilog For An FPGA
UART in VHDL and Verilog For An FPGA
Home
   The Go Board
                               UART, Serial Port, RS-232 Interface
   FPGA 101                    Code in both VHDL and Verilog for FPGA Implementation
   VHDL
                               Do you know how a UART works? If not, first brush up on the basics of UARTs before continuing on. Have you considered how you
   Verilog                     might sample data with an FPGA? Think about data coming into your FPGA. Data can arrive by itself or it can arrive with a clock.
                               When it arrives with a clock, it is call synchronous. When it arrives without a clock, it is called asynchronous. A UART is an
                               asynchronous interface.
        The Go Board
                               In any asynchronous interface, the first thing you need to know is when in time you should sample (look at) the data. If you do not
                               sample the data at the right time, you might see the wrong data. In order to receive your data correctly, the transmitter and receiver
                               must agree on the baud rate. The baud rate is the rate at which the data is transmitted. For example, 9600 baud means 9600 bits
                               per second. The code below uses a generic in VHDL or a parameter in Verilog to determine how many clock cycles there are in
                               each bit. This is how the baud rate gets determined.
Only $65 The FPGA is continuously sampling the line. Once it sees the line transition from high to low, it knows that a UART data word is
       Now Shipping!           coming. This first transition indicates the start bit. Once the beginning of the start bit is found, the FPGA waits for one half of a bit
                               period. This ensures that the middle of the data bit gets sampled. From then on, the FPGA just needs to wait one bit period (as
          Order Now            specified by the baud rate) and sample the rest of the data. The figure below shows how the UART receiver works inside of the
                               FPGA. First a falling edge is detected on the serial data line. This represents the start bit. The FPGA then waits until the middle of
                               the first data bit and samples the data. It does this for all eight data bits.
                               The above data stream shows how the code below is structured. The code below uses one Start Bit, one Stop Bit, eight Data Bits,
                               and no parity. Note that the transmitter modules below both have a signal o_tx_active. This is used to infer a tri-state buffer for half-
                               duplex communication. It is up your specific project requirements if you want to create a half-duplex UART or a full-duplex UART.
                               The code below will work for both!
Learn More
                               If you want to simulate your code (and you should) you need to use a testbench. Luckily there is a test bench already created for
                               you! This testbench below exercises both the Transmitter and the Receiver code. It is programmed to work at 115200 baud. Note
                               that this test bench is for simulation only and can not be synthesized into functional FPGA code.
VHDL Implementation:
                                   1     ----------------------------------------------------------------------
  Search nandland.com:
                                   2     -- File Downloaded from http://www.nandland.com
             Custom Search         3     ----------------------------------------------------------------------
   Search                          4     -- This file contains the UART Receiver. This receiver is able to
                                   5     -- receive 8 bits of serial data, one start bit, one stop bit,
                                   6     -- and no parity bit. When receive is complete o_rx_dv will be
                                   7     -- driven high for one clock cycle.
                                   8     --
                                   9     -- Set Generic g_CLKS_PER_BIT as follows:
                                  10     -- g_CLKS_PER_BIT = (Frequency of i_Clk)/(Frequency of UART)
                                  11     -- Example: 10 MHz Clock, 115200 baud UART
                                  12     -- (10000000)/(115200) = 87
                                  13     --
                                  14     library ieee;
                                  15     use ieee.std_logic_1164.ALL;
                                  16     use ieee.numeric_std.all;
                                  17
                                  18     entity UART_RX is
                                  19       generic (
                                  20         g_CLKS_PER_BIT : integer := 115                    -- Needs to be set correctly
                                  21         );
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                                                                                   1/10
17/10/2017                                                     UART in VHDL and Verilog for an FPGA
                                  22     port (
                                  23       i_Clk          :   in    std_logic;
                                  24       i_RX_Serial    :   in    std_logic;
                                  25       o_RX_DV        :   out   std_logic;
                                  26       o_RX_Byte      :   out   std_logic_vector(7 downto 0)
                                  27       );
                                  28   end UART_RX;
                                  29
                                  30
                                  31   architecture rtl of UART_RX is
                                  32
                                  33     type t_SM_Main is (s_Idle, s_RX_Start_Bit, s_RX_Data_Bits,
                                  34                        s_RX_Stop_Bit, s_Cleanup);
                                  35     signal r_SM_Main : t_SM_Main := s_Idle;
                                  36
                                  37     signal r_RX_Data_R : std_logic := '0';
                                  38     signal r_RX_Data   : std_logic := '0';
                                  39
                                  40     signal    r_Clk_Count   :   integer range 0 to g_CLKS_PER_BIT-1 := 0;
                                  41     signal    r_Bit_Index   :   integer range 0 to 7 := 0; -- 8 Bits Total
                                  42     signal    r_RX_Byte     :   std_logic_vector(7 downto 0) := (others => '0');
                                  43     signal    r_RX_DV       :   std_logic := '0';
                                  44
                                  45   begin
                                  46
                                  47     -- Purpose: Double-register the incoming data.
                                  48     -- This allows it to be used in the UART RX Clock Domain.
                                  49     -- (It removes problems caused by metastabiliy)
                                  50     p_SAMPLE : process (i_Clk)
                                  51     begin
                                  52       if rising_edge(i_Clk) then
                                  53         r_RX_Data_R <= i_RX_Serial;
                                  54         r_RX_Data   <= r_RX_Data_R;
                                  55       end if;
                                  56     end process p_SAMPLE;
                                  57
                                  58
                                  59     -- Purpose: Control RX state machine
                                  60     p_UART_RX : process (i_Clk)
                                  61     begin
                                  62       if rising_edge(i_Clk) then
                                  63
                                  64           case r_SM_Main is
                                  65
                                  66              when s_Idle =>
                                  67                r_RX_DV      <= '0';
                                  68                r_Clk_Count <= 0;
                                  69                r_Bit_Index <= 0;
                                  70
                                  71                if r_RX_Data = '0' then       -- Start bit detected
                                  72                  r_SM_Main <= s_RX_Start_Bit;
                                  73                else
                                  74                  r_SM_Main <= s_Idle;
                                  75                end if;
                                  76
                                  77
                                  78              -- Check middle of start bit to make sure it's still low
                                  79              when s_RX_Start_Bit =>
                                  80                if r_Clk_Count = (g_CLKS_PER_BIT-1)/2 then
                                  81                  if r_RX_Data = '0' then
                                  82                     r_Clk_Count <= 0; -- reset counter since we found the middle
                                  83                     r_SM_Main   <= s_RX_Data_Bits;
                                  84                  else
                                  85                     r_SM_Main   <= s_Idle;
                                  86                  end if;
                                  87                else
                                  88                  r_Clk_Count <= r_Clk_Count + 1;
                                  89                  r_SM_Main    <= s_RX_Start_Bit;
                                  90                end if;
                                  91
                                  92
                                  93              -- Wait g_CLKS_PER_BIT-1 clock cycles to sample serial data
                                  94              when s_RX_Data_Bits =>
                                  95                if r_Clk_Count < g_CLKS_PER_BIT-1 then
                                  96                  r_Clk_Count <= r_Clk_Count + 1;
                                  97                  r_SM_Main   <= s_RX_Data_Bits;
                                  98                else
                                  99                  r_Clk_Count            <= 0;
                                 100                  r_RX_Byte(r_Bit_Index) <= r_RX_Data;
                                 101
                                 102                  -- Check if we have sent out all bits
                                 103                  if r_Bit_Index < 7 then
                                 104                    r_Bit_Index <= r_Bit_Index + 1;
                                 105                    r_SM_Main   <= s_RX_Data_Bits;
                                 106                  else
                                 107                    r_Bit_Index <= 0;
                                 108                    r_SM_Main   <= s_RX_Stop_Bit;
                                 109                  end if;
                                 110                end if;
                                 111
                                 112
                                 113              -- Receive Stop bit. Stop bit = 1
                                 114              when s_RX_Stop_Bit =>
                                 115                -- Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to finish
                                 116                if r_Clk_Count < g_CLKS_PER_BIT-1 then
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                                2/10
17/10/2017                                                    UART in VHDL and Verilog for an FPGA
                                 117                  r_Clk_Count     <= r_Clk_Count + 1;
                                 118                  r_SM_Main       <= s_RX_Stop_Bit;
                                 119                else
                                 120                  r_RX_DV         <= '1';
                                 121                  r_Clk_Count     <= 0;
                                 122                  r_SM_Main       <= s_Cleanup;
                                 123                end if;
                                 124
                                 125
                                 126              -- Stay here 1     clock
                                 127              when s_Cleanup     =>
                                 128                r_SM_Main <=     s_Idle;
                                 129                r_RX_DV   <=     '0';
                                 130
                                 131
                                 132              when others =>
                                 133                r_SM_Main <= s_Idle;
                                 134
                                 135         end case;
                                 136       end if;
                                 137     end process p_UART_RX;
                                 138
                                 139     o_RX_DV   <= r_RX_DV;
                                 140     o_RX_Byte <= r_RX_Byte;
                                 141
                                 142   end rtl;
                                   1   ----------------------------------------------------------------------
                                   2   -- File Downloaded from http://www.nandland.com
                                   3   ----------------------------------------------------------------------
                                   4   -- This file contains the UART Transmitter. This transmitter is able
                                   5   -- to transmit 8 bits of serial data, one start bit, one stop bit,
                                   6   -- and no parity bit. When transmit is complete o_TX_Done will be
                                   7   -- driven high for one clock cycle.
                                   8   --
                                   9   -- Set Generic g_CLKS_PER_BIT as follows:
                                  10   -- g_CLKS_PER_BIT = (Frequency of i_Clk)/(Frequency of UART)
                                  11   -- Example: 10 MHz Clock, 115200 baud UART
                                  12   -- (10000000)/(115200) = 87
                                  13   --
                                  14   library ieee;
                                  15   use ieee.std_logic_1164.all;
                                  16   use ieee.numeric_std.all;
                                  17
                                  18   entity UART_TX is
                                  19     generic (
                                  20       g_CLKS_PER_BIT : integer := 115    -- Needs to be set correctly
                                  21       );
                                  22     port (
                                  23       i_Clk       : in std_logic;
                                  24       i_TX_DV     : in std_logic;
                                  25       i_TX_Byte   : in std_logic_vector(7 downto 0);
                                  26       o_TX_Active : out std_logic;
                                  27       o_TX_Serial : out std_logic;
                                  28       o_TX_Done   : out std_logic
                                  29       );
                                  30   end UART_TX;
                                  31
                                  32
                                  33   architecture RTL of UART_TX is
                                  34
                                  35     type t_SM_Main is (s_Idle, s_TX_Start_Bit, s_TX_Data_Bits,
                                  36                        s_TX_Stop_Bit, s_Cleanup);
                                  37     signal r_SM_Main : t_SM_Main := s_Idle;
                                  38
                                  39     signal    r_Clk_Count   :   integer range 0 to g_CLKS_PER_BIT-1 := 0;
                                  40     signal    r_Bit_Index   :   integer range 0 to 7 := 0; -- 8 Bits Total
                                  41     signal    r_TX_Data     :   std_logic_vector(7 downto 0) := (others => '0');
                                  42     signal    r_TX_Done     :   std_logic := '0';
                                  43
                                  44   begin
                                  45
                                  46
                                  47     p_UART_TX : process (i_Clk)
                                  48     begin
                                  49       if rising_edge(i_Clk) then
                                  50
                                  51           case r_SM_Main is
                                  52
                                  53              when s_Idle =>
                                  54                o_TX_Active <=     '0';
                                  55                o_TX_Serial <=     '1';           -- Drive Line High for Idle
                                  56                r_TX_Done    <=    '0';
                                  57                r_Clk_Count <=     0;
                                  58                r_Bit_Index <=     0;
                                  59
                                  60                if i_TX_DV = '1' then
                                  61                  r_TX_Data <= i_TX_Byte;
                                  62                  r_SM_Main <= s_TX_Start_Bit;
                                  63                else
                                  64                  r_SM_Main <= s_Idle;
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                                3/10
17/10/2017                                                    UART in VHDL and Verilog for an FPGA
                                  65                end if;
                                  66
                                  67
                                  68              -- Send out Start Bit. Start bit = 0
                                  69              when s_TX_Start_Bit =>
                                  70                o_TX_Active <= '1';
                                  71                o_TX_Serial <= '0';
                                  72
                                  73                -- Wait g_CLKS_PER_BIT-1 clock cycles for start bit to finish
                                  74                if r_Clk_Count < g_CLKS_PER_BIT-1 then
                                  75                  r_Clk_Count <= r_Clk_Count + 1;
                                  76                  r_SM_Main   <= s_TX_Start_Bit;
                                  77                else
                                  78                  r_Clk_Count <= 0;
                                  79                  r_SM_Main   <= s_TX_Data_Bits;
                                  80                end if;
                                  81
                                  82
                                  83              -- Wait g_CLKS_PER_BIT-1 clock cycles for data bits to finish
                                  84              when s_TX_Data_Bits =>
                                  85                o_TX_Serial <= r_TX_Data(r_Bit_Index);
                                  86
                                  87                if r_Clk_Count <   g_CLKS_PER_BIT-1 then
                                  88                  r_Clk_Count <=   r_Clk_Count + 1;
                                  89                  r_SM_Main   <=   s_TX_Data_Bits;
                                  90                else
                                  91                  r_Clk_Count <=   0;
                                  92
                                  93                  -- Check if we have sent out all bits
                                  94                  if r_Bit_Index < 7 then
                                  95                    r_Bit_Index <= r_Bit_Index + 1;
                                  96                    r_SM_Main   <= s_TX_Data_Bits;
                                  97                  else
                                  98                    r_Bit_Index <= 0;
                                  99                    r_SM_Main   <= s_TX_Stop_Bit;
                                 100                  end if;
                                 101                end if;
                                 102
                                 103
                                 104              -- Send out Stop bit.     Stop bit = 1
                                 105              when s_TX_Stop_Bit =>
                                 106                o_TX_Serial <= '1';
                                 107
                                 108                -- Wait g_CLKS_PER_BIT-1 clock cycles for Stop bit to finish
                                 109                if r_Clk_Count < g_CLKS_PER_BIT-1 then
                                 110                  r_Clk_Count <= r_Clk_Count + 1;
                                 111                  r_SM_Main   <= s_TX_Stop_Bit;
                                 112                else
                                 113                  r_TX_Done   <= '1';
                                 114                  r_Clk_Count <= 0;
                                 115                  r_SM_Main   <= s_Cleanup;
                                 116                end if;
                                 117
                                 118
                                 119              -- Stay here 1 clock
                                 120              when s_Cleanup =>
                                 121                o_TX_Active <= '0';
                                 122                r_TX_Done   <= '1';
                                 123                r_SM_Main   <= s_Idle;
                                 124
                                 125
                                 126              when others =>
                                 127                r_SM_Main <= s_Idle;
                                 128
                                 129         end case;
                                 130       end if;
                                 131     end process p_UART_TX;
                                 132
                                 133     o_TX_Done <= r_TX_Done;
                                 134
                                 135   end RTL;
                                   1   ----------------------------------------------------------------------
                                   2   -- File Downloaded from http://www.nandland.com
                                   3   ----------------------------------------------------------------------
                                   4   library ieee;
                                   5   use ieee.std_logic_1164.ALL;
                                   6   use ieee.numeric_std.all;
                                   7
                                   8   entity uart_tb is
                                   9   end uart_tb;
                                  10
                                  11   architecture behave of uart_tb is
                                  12
                                  13     component uart_tx is
                                  14       generic (
                                  15         g_CLKS_PER_BIT : integer := 115        -- Needs to be set correctly
                                  16         );
                                  17       port (
                                  18         i_clk       : in std_logic;
                                  19         i_tx_dv     : in std_logic;
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                            4/10
17/10/2017                                                  UART in VHDL and Verilog for an FPGA
                                  20         i_tx_byte   : in std_logic_vector(7 downto 0);
                                  21         o_tx_active : out std_logic;
                                  22         o_tx_serial : out std_logic;
                                  23         o_tx_done   : out std_logic
                                  24         );
                                  25     end component uart_tx;
                                  26
                                  27     component uart_rx is
                                  28       generic (
                                  29         g_CLKS_PER_BIT : integer := 115   -- Needs to be set correctly
                                  30         );
                                  31       port (
                                  32         i_clk       : in std_logic;
                                  33         i_rx_serial : in std_logic;
                                  34         o_rx_dv     : out std_logic;
                                  35         o_rx_byte   : out std_logic_vector(7 downto 0)
                                  36         );
                                  37     end component uart_rx;
                                  38
                                  39
                                  40     -- Test Bench uses a 10 MHz Clock
                                  41     -- Want to interface to 115200 baud UART
                                  42     -- 10000000 / 115200 = 87 Clocks Per Bit.
                                  43     constant c_CLKS_PER_BIT : integer := 87;
                                  44
                                  45     constant c_BIT_PERIOD : time := 8680 ns;
                                  46
                                  47     signal   r_CLOCK       :   std_logic                    := '0';
                                  48     signal   r_TX_DV       :   std_logic                    := '0';
                                  49     signal   r_TX_BYTE     :   std_logic_vector(7 downto 0) := (others => '0');
                                  50     signal   w_TX_SERIAL   :   std_logic;
                                  51     signal   w_TX_DONE     :   std_logic;
                                  52     signal   w_RX_DV       :   std_logic;
                                  53     signal   w_RX_BYTE     :   std_logic_vector(7 downto 0);
                                  54     signal   r_RX_SERIAL   :   std_logic := '1';
                                  55
                                  56
                                  57     -- Low-level byte-write
                                  58     procedure UART_WRITE_BYTE (
                                  59       i_data_in       : in std_logic_vector(7 downto 0);
                                  60       signal o_serial : out std_logic) is
                                  61     begin
                                  62
                                  63        -- Send Start Bit
                                  64        o_serial <= '0';
                                  65        wait for c_BIT_PERIOD;
                                  66
                                  67        -- Send Data Byte
                                  68        for ii in 0 to 7 loop
                                  69          o_serial <= i_data_in(ii);
                                  70          wait for c_BIT_PERIOD;
                                  71        end loop; -- ii
                                  72
                                  73       -- Send Stop Bit
                                  74       o_serial <= '1';
                                  75       wait for c_BIT_PERIOD;
                                  76     end UART_WRITE_BYTE;
                                  77
                                  78
                                  79   begin
                                  80
                                  81     -- Instantiate UART transmitter
                                  82     UART_TX_INST : uart_tx
                                  83       generic map (
                                  84         g_CLKS_PER_BIT => c_CLKS_PER_BIT
                                  85         )
                                  86       port map (
                                  87         i_clk       => r_CLOCK,
                                  88         i_tx_dv     => r_TX_DV,
                                  89         i_tx_byte   => r_TX_BYTE,
                                  90         o_tx_active => open,
                                  91         o_tx_serial => w_TX_SERIAL,
                                  92         o_tx_done   => w_TX_DONE
                                  93         );
                                  94
                                  95     -- Instantiate UART Receiver
                                  96     UART_RX_INST : uart_rx
                                  97       generic map (
                                  98         g_CLKS_PER_BIT => c_CLKS_PER_BIT
                                  99         )
                                 100       port map (
                                 101         i_clk       => r_CLOCK,
                                 102         i_rx_serial => r_RX_SERIAL,
                                 103         o_rx_dv     => w_RX_DV,
                                 104         o_rx_byte   => w_RX_BYTE
                                 105         );
                                 106
                                 107     r_CLOCK <= not r_CLOCK after 50 ns;
                                 108
                                 109     process is
                                 110     begin
                                 111
                                 112        -- Tell the UART to send a command.
                                 113        wait until rising_edge(r_CLOCK);
                                 114        wait until rising_edge(r_CLOCK);
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                               5/10
17/10/2017                                                     UART in VHDL and Verilog for an FPGA
                                 115         r_TX_DV   <= '1';
                                 116         r_TX_BYTE <= X"AB";
                                 117         wait until rising_edge(r_CLOCK);
                                 118         r_TX_DV   <= '0';
                                 119         wait until w_TX_DONE = '1';
                                 120
                                 121
                                 122         -- Send a command to the UART
                                 123         wait until rising_edge(r_CLOCK);
                                 124         UART_WRITE_BYTE(X"3F", r_RX_SERIAL);
                                 125         wait until rising_edge(r_CLOCK);
                                 126
                                 127         -- Check that the correct command was received
                                 128         if w_RX_BYTE = X"3F" then
                                 129           report "Test Passed - Correct Byte Received" severity note;
                                 130         else
                                 131           report "Test Failed - Incorrect Byte Received" severity note;
                                 132         end if;
                                 133
                                 134         assert false report "Tests Complete" severity failure;
                                 135
                                 136      end process;
                                 137
                                 138    end behave;
Verilog Implementation:
                                   1    //////////////////////////////////////////////////////////////////////
                                   2    // File Downloaded from http://www.nandland.com
                                   3    //////////////////////////////////////////////////////////////////////
                                   4    // This file contains the UART Receiver. This receiver is able to
                                   5    // receive 8 bits of serial data, one start bit, one stop bit,
                                   6    // and no parity bit. When receive is complete o_rx_dv will be
                                   7    // driven high for one clock cycle.
                                   8    //
                                   9    // Set Parameter CLKS_PER_BIT as follows:
                                  10    // CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
                                  11    // Example: 10 MHz Clock, 115200 baud UART
                                  12    // (10000000)/(115200) = 87
                                  13
                                  14    module uart_rx
                                  15      #(parameter CLKS_PER_BIT)
                                  16      (
                                  17        input        i_Clock,
                                  18        input        i_Rx_Serial,
                                  19        output       o_Rx_DV,
                                  20        output [7:0] o_Rx_Byte
                                  21        );
                                  22
                                  23      parameter     s_IDLE           =   3'b000;
                                  24      parameter     s_RX_START_BIT   =   3'b001;
                                  25      parameter     s_RX_DATA_BITS   =   3'b010;
                                  26      parameter     s_RX_STOP_BIT    =   3'b011;
                                  27      parameter     s_CLEANUP        =   3'b100;
                                  28
                                  29      reg               r_Rx_Data_R = 1'b1;
                                  30      reg               r_Rx_Data   = 1'b1;
                                  31
                                  32      reg   [7:0]      r_Clock_Count     =   0;
                                  33      reg   [2:0]      r_Bit_Index       =   0; //8 bits total
                                  34      reg   [7:0]      r_Rx_Byte         =   0;
                                  35      reg              r_Rx_DV           =   0;
                                  36      reg   [2:0]      r_SM_Main         =   0;
                                  37
                                  38      // Purpose: Double-register the incoming data.
                                  39      // This allows it to be used in the UART RX Clock Domain.
                                  40      // (It removes problems caused by metastability)
                                  41      always @(posedge i_Clock)
                                  42        begin
                                  43          r_Rx_Data_R <= i_Rx_Serial;
                                  44          r_Rx_Data   <= r_Rx_Data_R;
                                  45        end
                                  46
                                  47
                                  48      // Purpose: Control RX state machine
                                  49      always @(posedge i_Clock)
                                  50        begin
                                  51
                                  52            case (r_SM_Main)
                                  53              s_IDLE :
                                  54                begin
                                  55                  r_Rx_DV       <= 1'b0;
                                  56                  r_Clock_Count <= 0;
                                  57                  r_Bit_Index   <= 0;
                                  58
                                  59                    if (r_Rx_Data == 1'b0)               // Start bit detected
                                  60                      r_SM_Main <= s_RX_START_BIT;
                                  61                    else
                                  62                      r_SM_Main <= s_IDLE;
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                             6/10
17/10/2017                                                        UART in VHDL and Verilog for an FPGA
                                  63                end
                                  64
                                  65              // Check middle of start bit to make sure it's still low
                                  66              s_RX_START_BIT :
                                  67                begin
                                  68                  if (r_Clock_Count == (CLKS_PER_BIT-1)/2)
                                  69                    begin
                                  70                       if (r_Rx_Data == 1'b0)
                                  71                         begin
                                  72                           r_Clock_Count <= 0; // reset counter, found the middle
                                  73                           r_SM_Main     <= s_RX_DATA_BITS;
                                  74                         end
                                  75                       else
                                  76                         r_SM_Main <= s_IDLE;
                                  77                    end
                                  78                  else
                                  79                    begin
                                  80                       r_Clock_Count <= r_Clock_Count + 1;
                                  81                       r_SM_Main     <= s_RX_START_BIT;
                                  82                    end
                                  83                end // case: s_RX_START_BIT
                                  84
                                  85
                                  86              // Wait CLKS_PER_BIT-1 clock cycles to sample serial data
                                  87              s_RX_DATA_BITS :
                                  88                begin
                                  89                  if (r_Clock_Count < CLKS_PER_BIT-1)
                                  90                    begin
                                  91                       r_Clock_Count <= r_Clock_Count + 1;
                                  92                       r_SM_Main     <= s_RX_DATA_BITS;
                                  93                    end
                                  94                  else
                                  95                    begin
                                  96                       r_Clock_Count          <= 0;
                                  97                       r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
                                  98
                                  99                      // Check if we have received all bits
                                 100                      if (r_Bit_Index < 7)
                                 101                        begin
                                 102                          r_Bit_Index <= r_Bit_Index + 1;
                                 103                          r_SM_Main   <= s_RX_DATA_BITS;
                                 104                        end
                                 105                      else
                                 106                        begin
                                 107                          r_Bit_Index <= 0;
                                 108                          r_SM_Main   <= s_RX_STOP_BIT;
                                 109                        end
                                 110                    end
                                 111                end // case: s_RX_DATA_BITS
                                 112
                                 113
                                 114              // Receive Stop bit. Stop bit = 1
                                 115              s_RX_STOP_BIT :
                                 116                begin
                                 117                  // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
                                 118                  if (r_Clock_Count < CLKS_PER_BIT-1)
                                 119                    begin
                                 120                       r_Clock_Count <= r_Clock_Count + 1;
                                 121                       r_SM_Main     <= s_RX_STOP_BIT;
                                 122                    end
                                 123                  else
                                 124                    begin
                                 125                       r_Rx_DV       <= 1'b1;
                                 126                       r_Clock_Count <= 0;
                                 127                       r_SM_Main     <= s_CLEANUP;
                                 128                    end
                                 129                end // case: s_RX_STOP_BIT
                                 130
                                 131
                                 132              // Stay here 1 clock
                                 133              s_CLEANUP :
                                 134                begin
                                 135                  r_SM_Main <= s_IDLE;
                                 136                  r_Rx_DV   <= 1'b0;
                                 137                end
                                 138
                                 139
                                 140              default :
                                 141                r_SM_Main <= s_IDLE;
                                 142
                                 143           endcase
                                 144         end
                                 145
                                 146       assign o_Rx_DV   = r_Rx_DV;
                                 147       assign o_Rx_Byte = r_Rx_Byte;
                                 148
                                 149    endmodule // uart_rx
                                   1    //////////////////////////////////////////////////////////////////////
                                   2    // File Downloaded from http://www.nandland.com
                                   3    //////////////////////////////////////////////////////////////////////
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                                7/10
17/10/2017                                                     UART in VHDL and Verilog for an FPGA
                                   4   //   This file contains the UART Transmitter. This transmitter is able
                                   5   //   to transmit 8 bits of serial data, one start bit, one stop bit,
                                   6   //   and no parity bit. When transmit is complete o_Tx_done will be
                                   7   //   driven high for one clock cycle.
                                   8   //
                                   9   //   Set Parameter CLKS_PER_BIT as follows:
                                  10   //   CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
                                  11   //   Example: 10 MHz Clock, 115200 baud UART
                                  12   //   (10000000)/(115200) = 87
                                  13
                                  14   module uart_tx
                                  15     #(parameter CLKS_PER_BIT)
                                  16     (
                                  17       input       i_Clock,
                                  18       input       i_Tx_DV,
                                  19       input [7:0] i_Tx_Byte,
                                  20       output      o_Tx_Active,
                                  21       output reg o_Tx_Serial,
                                  22       output      o_Tx_Done
                                  23       );
                                  24
                                  25     parameter     s_IDLE           =    3'b000;
                                  26     parameter     s_TX_START_BIT   =    3'b001;
                                  27     parameter     s_TX_DATA_BITS   =    3'b010;
                                  28     parameter     s_TX_STOP_BIT    =    3'b011;
                                  29     parameter     s_CLEANUP        =    3'b100;
                                  30
                                  31     reg   [2:0]      r_SM_Main          =   0;
                                  32     reg   [7:0]      r_Clock_Count      =   0;
                                  33     reg   [2:0]      r_Bit_Index        =   0;
                                  34     reg   [7:0]      r_Tx_Data          =   0;
                                  35     reg              r_Tx_Done          =   0;
                                  36     reg              r_Tx_Active        =   0;
                                  37
                                  38     always @(posedge i_Clock)
                                  39       begin
                                  40
                                  41           case (r_SM_Main)
                                  42             s_IDLE :
                                  43               begin
                                  44                 o_Tx_Serial        <=   1'b1;           // Drive Line High for Idle
                                  45                 r_Tx_Done          <=   1'b0;
                                  46                 r_Clock_Count      <=   0;
                                  47                 r_Bit_Index        <=   0;
                                  48
                                  49                 if (i_Tx_DV == 1'b1)
                                  50                   begin
                                  51                      r_Tx_Active <= 1'b1;
                                  52                      r_Tx_Data   <= i_Tx_Byte;
                                  53                      r_SM_Main   <= s_TX_START_BIT;
                                  54                   end
                                  55                 else
                                  56                   r_SM_Main <= s_IDLE;
                                  57               end // case: s_IDLE
                                  58
                                  59
                                  60             // Send out Start Bit. Start bit = 0
                                  61             s_TX_START_BIT :
                                  62               begin
                                  63                 o_Tx_Serial <= 1'b0;
                                  64
                                  65                 // Wait CLKS_PER_BIT-1 clock cycles for start bit to finish
                                  66                 if (r_Clock_Count < CLKS_PER_BIT-1)
                                  67                   begin
                                  68                      r_Clock_Count <= r_Clock_Count + 1;
                                  69                      r_SM_Main     <= s_TX_START_BIT;
                                  70                   end
                                  71                 else
                                  72                   begin
                                  73                      r_Clock_Count <= 0;
                                  74                      r_SM_Main     <= s_TX_DATA_BITS;
                                  75                   end
                                  76               end // case: s_TX_START_BIT
                                  77
                                  78
                                  79             // Wait CLKS_PER_BIT-1 clock cycles for data bits to finish
                                  80             s_TX_DATA_BITS :
                                  81               begin
                                  82                 o_Tx_Serial <= r_Tx_Data[r_Bit_Index];
                                  83
                                  84                   if (r_Clock_Count      < CLKS_PER_BIT-1)
                                  85                     begin
                                  86                        r_Clock_Count        <= r_Clock_Count + 1;
                                  87                        r_SM_Main            <= s_TX_DATA_BITS;
                                  88                     end
                                  89                   else
                                  90                     begin
                                  91                        r_Clock_Count        <= 0;
                                  92
                                  93                       // Check if we have sent out all bits
                                  94                       if (r_Bit_Index < 7)
                                  95                         begin
                                  96                           r_Bit_Index <= r_Bit_Index + 1;
                                  97                           r_SM_Main   <= s_TX_DATA_BITS;
                                  98                         end
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                                   8/10
17/10/2017                                                      UART in VHDL and Verilog for an FPGA
                                  99                      else
                                 100                        begin
                                 101                          r_Bit_Index <= 0;
                                 102                          r_SM_Main   <= s_TX_STOP_BIT;
                                 103                        end
                                 104                    end
                                 105                end // case: s_TX_DATA_BITS
                                 106
                                 107
                                 108             // Send out Stop bit. Stop bit = 1
                                 109             s_TX_STOP_BIT :
                                 110               begin
                                 111                 o_Tx_Serial <= 1'b1;
                                 112
                                 113                  // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
                                 114                  if (r_Clock_Count < CLKS_PER_BIT-1)
                                 115                    begin
                                 116                       r_Clock_Count <= r_Clock_Count + 1;
                                 117                       r_SM_Main     <= s_TX_STOP_BIT;
                                 118                    end
                                 119                  else
                                 120                    begin
                                 121                       r_Tx_Done     <= 1'b1;
                                 122                       r_Clock_Count <= 0;
                                 123                       r_SM_Main     <= s_CLEANUP;
                                 124                       r_Tx_Active   <= 1'b0;
                                 125                    end
                                 126                end // case: s_Tx_STOP_BIT
                                 127
                                 128
                                 129             // Stay here 1 clock
                                 130             s_CLEANUP :
                                 131               begin
                                 132                 r_Tx_Done <= 1'b1;
                                 133                 r_SM_Main <= s_IDLE;
                                 134               end
                                 135
                                 136
                                 137             default :
                                 138               r_SM_Main <= s_IDLE;
                                 139
                                 140           endcase
                                 141         end
                                 142
                                 143      assign o_Tx_Active = r_Tx_Active;
                                 144      assign o_Tx_Done   = r_Tx_Done;
                                 145
                                 146    endmodule
                                   1    //////////////////////////////////////////////////////////////////////
                                   2    // File Downloaded from http://www.nandland.com
                                   3    //////////////////////////////////////////////////////////////////////
                                   4
                                   5    // This testbench will exercise both the UART Tx and Rx.
                                   6    // It sends out byte 0xAB over the transmitter
                                   7    // It then exercises the receive by receiving byte 0x3F
                                   8    `timescale 1ns/10ps
                                   9
                                  10    `include "uart_tx.v"
                                  11    `include "uart_rx.v"
                                  12
                                  13    module uart_tb ();
                                  14
                                  15      // Testbench uses a 10 MHz clock
                                  16      // Want to interface to 115200 baud UART
                                  17      // 10000000 / 115200 = 87 Clocks Per Bit.
                                  18      parameter c_CLOCK_PERIOD_NS = 100;
                                  19      parameter c_CLKS_PER_BIT    = 87;
                                  20      parameter c_BIT_PERIOD      = 8600;
                                  21
                                  22      reg r_Clock = 0;
                                  23      reg r_Tx_DV = 0;
                                  24      wire w_Tx_Done;
                                  25      reg [7:0] r_Tx_Byte = 0;
                                  26      reg r_Rx_Serial = 1;
                                  27      wire [7:0] w_Rx_Byte;
                                  28
                                  29
                                  30      // Takes in input byte and serializes it
                                  31      task UART_WRITE_BYTE;
                                  32        input [7:0] i_Data;
                                  33        integer     ii;
                                  34        begin
                                  35
                                  36           // Send Start Bit
                                  37           r_Rx_Serial <= 1'b0;
                                  38           #(c_BIT_PERIOD);
                                  39           #1000;
                                  40
                                  41
                                  42           // Send Data Byte
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html                                           9/10
17/10/2017                                                      UART in VHDL and Verilog for an FPGA
                                  43              for (ii=0; ii<8; ii=ii+1)
                                  44                begin
                                  45                  r_Rx_Serial <= i_Data[ii];
                                  46                  #(c_BIT_PERIOD);
                                  47                end
                                  48
                                  49           // Send Stop Bit
                                  50           r_Rx_Serial <= 1'b1;
                                  51           #(c_BIT_PERIOD);
                                  52          end
                                  53       endtask // UART_WRITE_BYTE
                                  54
                                  55
                                  56       uart_rx #(.CLKS_PER_BIT(c_CLKS_PER_BIT)) UART_RX_INST
                                  57         (.i_Clock(r_Clock),
                                  58          .i_Rx_Serial(r_Rx_Serial),
                                  59          .o_Rx_DV(),
                                  60          .o_Rx_Byte(w_Rx_Byte)
                                  61          );
                                  62
                                  63       uart_tx #(.CLKS_PER_BIT(c_CLKS_PER_BIT)) UART_TX_INST
                                  64         (.i_Clock(r_Clock),
                                  65          .i_Tx_DV(r_Tx_DV),
                                  66          .i_Tx_Byte(r_Tx_Byte),
                                  67          .o_Tx_Active(),
                                  68          .o_Tx_Serial(),
                                  69          .o_Tx_Done(w_Tx_Done)
                                  70          );
                                  71
                                  72
                                  73       always
                                  74         #(c_CLOCK_PERIOD_NS/2) r_Clock <= !r_Clock;
                                  75
                                  76
                                  77       // Main Testing:
                                  78       initial
                                  79         begin
                                  80
                                  81              // Tell UART to send a command (exercise Tx)
                                  82              @(posedge r_Clock);
                                  83              @(posedge r_Clock);
                                  84              r_Tx_DV <= 1'b1;
                                  85              r_Tx_Byte <= 8'hAB;
                                  86              @(posedge r_Clock);
                                  87              r_Tx_DV <= 1'b0;
                                  88              @(posedge w_Tx_Done);
                                  89
                                  90              // Send a command to the UART (exercise Rx)
                                  91              @(posedge r_Clock);
                                  92              UART_WRITE_BYTE(8'h3F);
                                  93              @(posedge r_Clock);
                                  94
                                  95              // Check that the correct command was received
                                  96              if (w_Rx_Byte == 8'h3F)
                                  97                $display("Test Passed - Correct Byte Received");
                                  98              else
                                  99                $display("Test Failed - Incorrect Byte Received");
                                 100
                                 101         end
                                 102
                                 103    endmodule
                                          All VHDL and Verilog code on this webpage is free to download and modify.
                                             Content cannot be re-hosted without author's permission. (contact me)
                                             Please give credit to www.nandland.com, your support is appreciated!
https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html 10/10