VHDL UART Model


space.gif
../../images/main/bullet_green_ball.gif VHDL UART Model
space.gif



   1 -------------------------------------------------------
   2 -- Design Name : uart 
   3 -- File Name   : uart.vhd
   4 -- Function    : Simple UART
   5 -- Coder       : Deepak Kumar Tala (Verilog)
   6 -- Translator  : Alexander H Pham (VHDL)
   7 -------------------------------------------------------
   8 library ieee;
   9     use ieee.std_logic_1164.all;
  10     use ieee.std_logic_unsigned.all;
  11 
  12 entity uart is
  13     port (
  14         reset       :in  std_logic;
  15         txclk       :in  std_logic;
  16         ld_tx_data  :in  std_logic;
  17         tx_data     :in  std_logic_vector (7 downto 0);
  18         tx_enable   :in  std_logic;
  19         tx_out      :out std_logic;
  20         tx_empty    :out std_logic;
  21         rxclk       :in  std_logic;
  22         uld_rx_data :in  std_logic;
  23         rx_data     :out std_logic_vector (7 downto 0);
  24         rx_enable   :in  std_logic;
  25         rx_in       :in  std_logic;
  26         rx_empty    :out std_logic
  27     );
  28 end entity;
  29 architecture rtl of uart is
  30    -- Internal Variables
  31     signal tx_reg         :std_logic_vector (7 downto 0);
  32     signal tx_over_run    :std_logic;
  33     signal tx_cnt         :std_logic_vector (3 downto 0);
  34     signal rx_reg         :std_logic_vector (7 downto 0);
  35     signal rx_sample_cnt  :std_logic_vector (3 downto 0);
  36     signal rx_cnt         :std_logic_vector (3 downto 0);
  37     signal rx_frame_err   :std_logic;
  38     signal rx_over_run    :std_logic;
  39     signal rx_d1          :std_logic;
  40     signal rx_d2          :std_logic;
  41     signal rx_busy        :std_logic;
  42     signal rx_is_empty    :std_logic;
  43     signal tx_is_empty    :std_logic;
  44 begin
  45    -- UART RX Logic
  46     process (rxclk, reset) begin
  47         if (reset = '1') then
  48             rx_reg        <= (others=>'0');
  49             rx_data       <= (others=>'0');
  50             rx_sample_cnt <= (others=>'0');
  51             rx_cnt        <= (others=>'0');
  52             rx_frame_err  <= '0';
  53             rx_over_run   <= '0';
  54             rx_is_empty   <= '1';
  55             rx_d1         <= '1';
  56             rx_d2         <= '1';
  57             rx_busy       <= '0';
  58         elsif (rising_edge(rxclk)) then
  59            -- Synchronize the asynch signal
  60             rx_d1 <= rx_in;
  61             rx_d2 <= rx_d1;
  62            -- Uload the rx data
  63             if (uld_rx_data = '1') then
  64                 rx_data  <= rx_reg;
  65                 rx_is_empty <= '1';
  66             end if;
  67            -- Receive data only when rx is enabled
  68             if (rx_enable = '1') then
  69                -- Check if just received start of frame
  70                 if (rx_busy = '0' and rx_d2 = '0') then
  71                     rx_busy       <= '1';
  72                     rx_sample_cnt <= X"1";
  73                     rx_cnt        <= X"0";
  74                 end if;
  75                -- Start of frame detected, Proceed with rest of data
  76                 if (rx_busy = '1') then
  77                     rx_sample_cnt <= rx_sample_cnt + 1;
  78                    -- Logic to sample at middle of data
  79                     if (rx_sample_cnt = 7) then
  80                         if ((rx_d2 = '1') and (rx_cnt = 0)) then
  81                             rx_busy <= '0';
  82                         else
  83                             rx_cnt <= rx_cnt + 1;
  84                            -- Start storing the rx data
  85                             if (rx_cnt > 0 and rx_cnt < 9) then
  86                                 rx_reg(conv_integer(rx_cnt) - 1) <= rx_d2;
  87                             end if;
  88                             if (rx_cnt = 9) then
  89                                 rx_busy <= '0';
  90                                -- Check if End of frame received correctly
  91                                 if (rx_d2 = '0') then
  92                                     rx_frame_err <= '1';
  93                                 else
  94                                     rx_is_empty  <= '0';
  95                                     rx_frame_err <= '0';
  96                                    -- Check if last rx data was not unloaded,
  97                                     if (rx_is_empty = '1') then
  98                                         rx_over_run  <= '0';
  99                                     else
 100                                         rx_over_run  <= '1';
 101                                     end if;
 102                                 end if;
 103                             end if;
 104                         end if;
 105                     end if;
 106                 end if;
 107             end if;
 108             if (rx_enable = '0') then
 109                 rx_busy <= '0';
 110             end if;
 111         end if;
 112     end process;
 113     rx_empty <= rx_is_empty;
 114     
 115    -- UART TX Logic
 116     process (txclk, reset) begin
 117         if (reset = '1') then
 118             tx_reg        <= (others=>'0');
 119             tx_is_empty   <= '1';
 120             tx_over_run   <= '0';
 121             tx_out        <= '1';
 122             tx_cnt        <= (others=>'0');
 123         elsif (rising_edge(txclk)) then
 124 
 125             if (ld_tx_data = '1') then
 126                 if (tx_is_empty = '0') then
 127                     tx_over_run <= '0';
 128                 else
 129                     tx_reg   <= tx_data;
 130                     tx_is_empty <= '0';
 131                 end if;
 132             end if;
 133             if (tx_enable = '1' and tx_is_empty = '0') then
 134                 tx_cnt <= tx_cnt + 1;
 135                 if (tx_cnt = 0) then
 136                     tx_out <= '0';
 137                 end if;
 138                 if (tx_cnt > 0 and tx_cnt < 9) then
 139                     tx_out <= tx_reg(conv_integer(tx_cnt) -1);
 140                 end if;
 141                 if (tx_cnt = 9) then
 142                     tx_out <= '1';
 143                     tx_cnt <= X"0";
 144                     tx_is_empty <= '1';
 145                 end if;
 146             end if;
 147             if (tx_enable = '0') then
 148                 tx_cnt <= X"0";
 149             end if;
 150         end if;
 151     end process;
 152     tx_empty <= tx_is_empty;
 153 
 154 end architecture;

No comments:

Post a Comment