1 ------------------------------------------------------- 2 -- Design Name : uart_vhdl 3 -- File Name : uart_vhdl.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_vhdl 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_vhdl 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;