OpenCores
URL https://opencores.org/ocsvn/wishbone_uart_controller/wishbone_uart_controller/trunk

Subversion Repositories wishbone_uart_controller

[/] [wishbone_uart_controller/] [branches/] [uartcontroller/] [uart.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 themassau
--------------------------------------------------------------------------------
2
-- UART
3
-- Implements a universal asynchronous receiver transmitter with parameterisable
4
-- BAUD rate. Tested on a Spartan 6 LX9 connected to a Silicon Labs Cp210
5
-- USB-UART Bridge.
6
--          
7
-- @author         Peter A Bennett
8
-- @copyright      (c) 2012 Peter A Bennett
9
-- @license        LGPL      
10
-- @email          pab850@googlemail.com
11
-- @contact        www.bytebash.com
12
--
13
--------------------------------------------------------------------------------
14
 
15
library ieee;
16
use ieee.std_logic_1164.all;
17
use ieee.numeric_std.all;
18
 
19
entity UART is
20
    Generic (
21
            BAUD_RATE           : positive:= 115200;
22
            CLOCK_FREQUENCY     : positive:= 50000000
23
        );
24
    Port (  -- General
25
            CLOCK           :   in      std_logic;
26
            RESET               :   in      std_logic;
27
            DATA_STREAM_IN      :   in      std_logic_vector(7 downto 0);
28
            DATA_STREAM_IN_STB  :   in      std_logic;
29
            DATA_STREAM_IN_ACK  :   out     std_logic;
30
            DATA_STREAM_OUT     :   out     std_logic_vector(7 downto 0);
31
            DATA_STREAM_OUT_STB :   out     std_logic;
32
            DATA_STREAM_OUT_ACK :   in      std_logic;
33
            TX                  :   out     std_logic;
34
            RX                  :   in      std_logic
35
         );
36
end UART;
37
 
38
architecture Behavioral of UART is
39
 
40
    ----------------------------------------------------------------------------
41
    -- BAUD Generation
42
    ----------------------------------------------------------------------------
43
    constant c_tx_divider_val : positive := CLOCK_FREQUENCY / BAUD_RATE;
44
    constant c_rx_divider_val : positive := CLOCK_FREQUENCY / (BAUD_RATE * 16);
45
 
46
    signal baud_counter             :   integer range 0 to c_tx_divider_val;
47
    signal baud_tick                :   std_logic := '0';
48
    signal oversample_baud_counter  :   integer range 0 to c_rx_divider_val;
49
    signal oversample_baud_tick     :   std_logic := '0';
50
 
51
    ----------------------------------------------------------------------------
52
    -- Transmitter Signals
53
    ----------------------------------------------------------------------------
54
    type    uart_tx_states is ( idle,
55
                                wait_for_tick,
56
                                send_start_bit,
57
                                transmit_data,
58
                                send_stop_bit);
59
 
60
    signal  uart_tx_state       : uart_tx_states := idle;
61
 
62
    signal  uart_tx_data_block  : std_logic_vector(7 downto 0) := (others => '0');
63
    signal  uart_tx_data        : std_logic := '1';
64
    signal  uart_tx_count       : integer range 0 to  7 := 0;
65
    signal  uart_rx_data_in_ack : std_logic := '0';
66
    ----------------------------------------------------------------------------
67
    -- Receiver Signals
68
    ----------------------------------------------------------------------------
69
    type    uart_rx_states is ( rx_wait_start_synchronise,
70
                                rx_get_start_bit,
71
                                rx_get_data,
72
                                rx_get_stop_bit,
73
                                rx_send_block);
74
 
75
    signal  uart_rx_state       : uart_rx_states := rx_get_start_bit;
76
    signal  uart_rx_bit         : std_logic := '0';
77
    signal  uart_rx_data_block  : std_logic_vector(7 downto 0) := (others => '0');
78
    signal  uart_rx_data_vec    : std_logic_vector(1 downto 0) := (others => '0');
79
    signal  uart_rx_filter      : unsigned(1 downto 0)  := (others => '0');
80
    signal  uart_rx_count       : integer range 0 to 7    := 0;
81
    signal  uart_rx_data_out_stb: std_logic := '0';
82
    signal  uart_rx_bit_spacing : unsigned (3 downto 0) := (others => '0');
83
    signal  uart_rx_bit_tick    : std_logic := '0';
84
begin
85
 
86
    DATA_STREAM_IN_ACK  <= uart_rx_data_in_ack;
87
    DATA_STREAM_OUT     <= uart_rx_data_block;
88
    DATA_STREAM_OUT_STB <= uart_rx_data_out_stb;
89
    TX                  <= uart_tx_data;
90
 
91
    -- The input clock is 100Mhz, this needs to be divided down to the
92
    -- rate dictated by the BAUD_RATE. For example, if 115200 baud is selected
93
    -- (115200 baud = 115200 bps - 115.2kbps) a tick must be generated once
94
    -- every 1/115200
95
    TX_CLOCK_DIVIDER   : process (CLOCK)
96
    begin
97
        if rising_edge (CLOCK) then
98
            if RESET = '1' then
99
                baud_counter     <= 0;
100
                baud_tick        <= '0';
101
            else
102
                if baud_counter = c_tx_divider_val then
103
                    baud_counter <= 0;
104
                    baud_tick    <= '1';
105
                else
106
                    baud_counter <= baud_counter + 1;
107
                    baud_tick    <= '0';
108
                end if;
109
            end if;
110
        end if;
111
    end process TX_CLOCK_DIVIDER;
112
 
113
    -- Get data from DATA_STREAM_IN and send it one bit at a time
114
    -- upon each BAUD tick. LSB first.
115
    -- Wait 1 tick, Send Start Bit (0), Send Data 0-7, Send Stop Bit (1)
116
    UART_SEND_DATA :    process(CLOCK)
117
    begin
118
        if rising_edge(CLOCK) then
119
            if RESET = '1' then
120
                uart_tx_data            <= '1';
121
                --uart_tx_data_block      <= (others => '0');
122
                uart_tx_count           <= 0;
123
                uart_tx_state           <= idle;
124
                uart_rx_data_in_ack     <= '0';
125
            else
126
 
127
                case uart_tx_state is
128
                    when idle =>
129
                                                         if DATA_STREAM_IN_STB = '1' then
130
                            uart_tx_data_block  <= DATA_STREAM_IN;
131
                            uart_rx_data_in_ack <= '1';
132
                            uart_tx_state       <= wait_for_tick;
133
                                                         end if;
134
                    when wait_for_tick =>
135
                                                                uart_rx_data_in_ack<= '0';
136
                        if baud_tick = '1' then
137
                            uart_tx_state   <= send_start_bit;
138
                        end if;
139
                    when send_start_bit =>
140
                        if baud_tick = '1' then
141
                            uart_tx_data    <= '0';
142
                            uart_tx_state   <= transmit_data;
143
                            uart_tx_count   <= 0;
144
                        end if;
145
                    when transmit_data =>
146
                        if baud_tick = '1' then
147
 
148
                                                                         if uart_tx_count < 7 then
149
                                uart_tx_data    <=
150
                                uart_tx_data_block(uart_tx_count);
151
                                uart_tx_count   <= uart_tx_count + 1;
152
                            else
153
                                                                                  uart_tx_data    <= uart_tx_data_block(uart_tx_count);
154
                                uart_tx_count   <= 0;
155
                                uart_tx_state   <= send_stop_bit;
156
                            end if;
157
                        end if;
158
                    when send_stop_bit =>
159
                        if baud_tick = '1' then
160
                                                                        uart_tx_data <= '1';
161
                                                                        uart_tx_state <= idle;
162
                        end if;
163
                    when others =>
164
                        uart_tx_data <= '1';
165
                        uart_tx_state <= idle;
166
                end case;
167
            end if;
168
        end if;
169
         end process UART_SEND_DATA;
170
 
171
    -- Generate an oversampled tick (BAUD * 16)
172
    OVERSAMPLE_CLOCK_DIVIDER   : process (CLOCK)
173
    begin
174
        if rising_edge (CLOCK) then
175
            if RESET = '1' then
176
                oversample_baud_counter     <= 0;
177
                oversample_baud_tick        <= '0';
178
            else
179
                if oversample_baud_counter = c_rx_divider_val then
180
                    oversample_baud_counter <= 0;
181
                    oversample_baud_tick    <= '1';
182
                else
183
                    oversample_baud_counter <= oversample_baud_counter + 1;
184
                    oversample_baud_tick    <= '0';
185
                end if;
186
            end if;
187
        end if;
188
    end process OVERSAMPLE_CLOCK_DIVIDER;
189
    -- Synchronise RXD to the oversampled BAUD
190
    RXD_SYNCHRONISE : process(CLOCK)
191
    begin
192
        if rising_edge(CLOCK) then
193
            if RESET = '1' then
194
                uart_rx_data_vec   <= (others => '1');
195
            else
196
                if oversample_baud_tick = '1' then
197
                    uart_rx_data_vec(0)    <= RX;
198
                    uart_rx_data_vec(1)    <= uart_rx_data_vec(0);
199
                end if;
200
            end if;
201
        end if;
202
    end process RXD_SYNCHRONISE;
203
 
204
    -- Filter RXD with a 2 bit counter.
205
    RXD_FILTER  :   process(CLOCK)
206
    begin
207
        if rising_edge(CLOCK) then
208
            if RESET = '1' then
209
                uart_rx_filter <= (others => '1');
210
                uart_rx_bit    <= '1';
211
            else
212
                if oversample_baud_tick = '1' then
213
                    -- Filter RXD.
214
                    if uart_rx_data_vec(1) = '1' and uart_rx_filter < 3 then
215
                        uart_rx_filter <= uart_rx_filter + 1;
216
                    elsif uart_rx_data_vec(1) = '0' and uart_rx_filter > 0 then
217
                        uart_rx_filter <= uart_rx_filter - 1;
218
                    end if;
219
                    -- Set the RX bit.
220
                    if uart_rx_filter = 3 then
221
                        uart_rx_bit <= '1';
222
                    elsif uart_rx_filter = 0 then
223
                        uart_rx_bit <= '0';
224
                    end if;
225
                end if;
226
            end if;
227
        end if;
228
    end process RXD_FILTER;
229
 
230
    RX_BIT_SPACING : process (CLOCK)
231
    begin
232
        if rising_edge(CLOCK) then
233
            uart_rx_bit_tick <= '0';
234
            if oversample_baud_tick = '1' then
235
                if uart_rx_bit_spacing = 15 then
236
                    uart_rx_bit_tick <= '1';
237
                    uart_rx_bit_spacing <= (others => '0');
238
                else
239
                    uart_rx_bit_spacing <= uart_rx_bit_spacing + 1;
240
                end if;
241
                if uart_rx_state = rx_get_start_bit then
242
                    uart_rx_bit_spacing <= (others => '0');
243
                end if;
244
            end if;
245
        end if;
246
    end process RX_BIT_SPACING;
247
 
248
    UART_RECEIVE_DATA   : process(DATA_STREAM_OUT_ACK,CLOCK)
249
    begin
250
        if rising_edge(CLOCK) then
251
            if RESET = '1' then
252
                uart_rx_state           <= rx_get_start_bit;
253
                uart_rx_data_block      <= (others => '0');
254
                uart_rx_count           <= 0;
255
                uart_rx_data_out_stb    <= '0';
256
            else
257
                case uart_rx_state is
258
                    when rx_get_start_bit =>
259
                        if oversample_baud_tick = '1' and uart_rx_bit = '0' then
260
                            uart_rx_state <= rx_get_data;
261
                        end if;
262
                    when rx_get_data =>
263
                        if uart_rx_bit_tick = '1' then
264
 
265
                            if uart_rx_count < 7 then
266
                                                                                uart_rx_data_block(uart_rx_count)
267
                                    <= uart_rx_bit;
268
                                uart_rx_count   <= uart_rx_count + 1;
269
                            else
270
                                                                                        uart_rx_data_block(uart_rx_count) <= uart_rx_bit;
271
                                                                                        uart_rx_count <= 0;
272
                                                                                        uart_rx_state <= rx_get_stop_bit;
273
                           end if;
274
                        end if;
275
                    when rx_get_stop_bit =>
276
                        if uart_rx_bit_tick = '1' then
277
                            if uart_rx_bit = '1' then
278
                                uart_rx_state <= rx_send_block;
279
                                uart_rx_data_out_stb    <= '1';
280
                            end if;
281
                        end if;
282
                    when rx_send_block =>
283
                        if DATA_STREAM_OUT_ACK = '1' then
284
                                                                        uart_rx_state           <= rx_get_start_bit;
285
                                                                        uart_rx_data_out_stb    <= '0';
286
                                                                end if;
287
                    when others =>
288
                        uart_rx_state   <= rx_get_start_bit;
289
                end case;
290
            end if;
291
        end if;
292
                        if DATA_STREAM_OUT_ACK ='1' then
293
                                uart_rx_data_out_stb<='0';
294
                        end if;
295
    end process UART_RECEIVE_DATA;
296
end Behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.