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;