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

Subversion Repositories rs232_interface

[/] [rs232_interface/] [trunk/] [uart.vhd] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 akram.mash
----------------------------------------------------------------------------------
2 6 akram.mash
-- Creation Date: 21:12:48 05/06/2010 
3
-- Module Name: RS232/UART Interface - Behavioral
4 3 akram.mash
-- Used TAB of 4 Spaces
5
----------------------------------------------------------------------------------
6
library IEEE;
7
use IEEE.STD_LOGIC_1164.ALL;
8
use IEEE.STD_LOGIC_ARITH.ALL;
9
use IEEE.STD_LOGIC_UNSIGNED.ALL;
10
 
11
entity uart is
12
generic (
13
        CLK_FREQ        : integer := 50;                -- Main frequency (MHz)
14 5 akram.mash
        SER_FREQ        : integer := 9600               -- Baud rate (bps)
15 3 akram.mash
);
16
port (
17
        -- Control
18 5 akram.mash
        clk                     : in    std_logic;              -- Main clock
19
        rst                     : in    std_logic;              -- Main reset
20 3 akram.mash
        -- External Interface
21 5 akram.mash
        rx                      : in    std_logic;              -- RS232 received serial data
22
        tx                      : out   std_logic;              -- RS232 transmitted serial data
23 7 akram.mash
        -- RS232/UART Configuration
24
        par_en          : in    std_logic;              -- Parity bit enable
25 3 akram.mash
        -- uPC Interface
26 5 akram.mash
        tx_req          : in    std_logic;                                              -- Request SEND of data
27
        tx_end          : out   std_logic;                                              -- Data SENDED
28
        tx_data         : in    std_logic_vector(7 downto 0);    -- Data to transmit
29
        rx_ready        : out   std_logic;                                              -- Received data ready to uPC read
30
        rx_data         : out   std_logic_vector(7 downto 0)     -- Received data 
31 3 akram.mash
);
32
end uart;
33
 
34
architecture Behavioral of uart is
35
 
36
        -- Constants
37 7 akram.mash
        constant UART_IDLE      :       std_logic := '1';
38
        constant UART_START     :       std_logic := '0';
39
        constant PARITY_EN      :       std_logic := '1';
40
        constant RST_LVL        :       std_logic := '1';
41 3 akram.mash
 
42
        -- Types
43 10 akram.mash
        type state is (idle,data,parity,stop1,stop2);                   -- Stop1 and Stop2 are inter frame gap signals
44 3 akram.mash
 
45 10 akram.mash
        -- RX Signals
46 7 akram.mash
        signal rx_fsm           :       state;                                                  -- Control of reception
47 10 akram.mash
        signal rx_clk_en        :       std_logic;                                              -- Received clock enable
48
        signal rx_rcv_init      :       std_logic;                                              -- Start of reception
49
        signal rx_par_bit       :       std_logic;                                              -- Calculated Parity bit
50
        signal rx_data_tmp      :       std_logic_vector(7 downto 0);    -- Serial to parallel converter
51
        signal rx_data_cnt      :       std_logic_vector(2 downto 0);    -- Count received bits
52
 
53
        -- TX Signals
54 7 akram.mash
        signal tx_fsm           :       state;                                                  -- Control of transmission
55 10 akram.mash
        signal tx_clk_en        :       std_logic;                                              -- Transmited clock enable
56
        signal tx_par_bit       :       std_logic;                                              -- Calculated Parity bit
57
        signal tx_data_tmp      :       std_logic_vector(7 downto 0);    -- Parallel to serial converter
58
        signal tx_data_cnt      :       std_logic_vector(2 downto 0);    -- Count transmited bits
59 3 akram.mash
 
60
begin
61
 
62 10 akram.mash
        tx_clk_gen:process(clk)
63 3 akram.mash
                variable counter        :       integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
64
        begin
65
                if clk'event and clk = '1' then
66
                        -- Normal Operation
67
                        if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 then
68 10 akram.mash
                                tx_clk_en       <=      '1';
69 6 akram.mash
                                counter         :=      0;
70 3 akram.mash
                        else
71 10 akram.mash
                                tx_clk_en       <=      '0';
72 6 akram.mash
                                counter         :=      counter + 1;
73 3 akram.mash
                        end if;
74
                        -- Reset condition
75 7 akram.mash
                        if rst = RST_LVL then
76 10 akram.mash
                                tx_clk_en       :=      '0';
77 3 akram.mash
                                counter         :=      0;
78
                        end if;
79
                end if;
80
        end process;
81
 
82
        tx_proc:process(clk)
83
                variable data_cnt       : std_logic_vector(2 downto 0);
84
        begin
85
                if clk'event and clk = '1' then
86 10 akram.mash
                        if tx_clk_en = '1' then
87 3 akram.mash
                                -- Default values
88 6 akram.mash
                                tx_end                                  <=      '0';
89 7 akram.mash
                                tx                                              <=      UART_IDLE;
90 3 akram.mash
                                -- FSM description
91
                                case tx_fsm is
92
                                        -- Wait to transfer data
93
                                        when idle =>
94
                                                -- Send Init Bit
95
                                                if tx_req = '1' then
96 7 akram.mash
                                                        tx                      <=      UART_START;
97 3 akram.mash
                                                        tx_data_tmp     <=      tx_data;
98 6 akram.mash
                                                        tx_fsm          <=      data;
99 7 akram.mash
                                                        tx_data_cnt     <=      (others=>'1');
100
                                                        tx_par_bit      <=      '0';
101 3 akram.mash
                                                end if;
102
                                        -- Data receive
103
                                        when data =>
104 7 akram.mash
                                                tx                              <=      tx_data_tmp(0);
105
                                                tx_par_bit              <=      tx_par_bit xor tx_data_tmp(0);
106
                                                if tx_data_cnt = 0 then
107
                                                        if par_en = PARITY_EN then
108
                                                                tx_fsm  <=      parity;
109
                                                        else
110
                                                                tx_fsm  <=      stop1;
111
                                                        end if;
112
                                                        tx_data_cnt     <=      (others=>'1');
113 3 akram.mash
                                                else
114
                                                        tx_data_tmp     <=      '0' & tx_data_tmp(7 downto 1);
115 7 akram.mash
                                                        tx_data_cnt     <=      tx_data_cnt - 1;
116 3 akram.mash
                                                end if;
117 7 akram.mash
                                        when parity =>
118
                                                tx                              <=      tx_par_bit;
119
                                                tx_fsm                  <=      stop1;
120 3 akram.mash
                                        -- End of communication
121
                                        when stop1 =>
122
                                                -- Send Stop Bit
123 7 akram.mash
                                                tx                              <=      UART_IDLE;
124 3 akram.mash
                                                tx_fsm                  <=      stop2;
125
                                        when stop2 =>
126
                                                -- Send Stop Bit
127 6 akram.mash
                                                tx_end                  <=      '1';
128 7 akram.mash
                                                tx                              <=      UART_IDLE;
129 3 akram.mash
                                                tx_fsm                  <=      idle;
130
                                        -- Invalid States
131
                                        when others => null;
132
                                end case;
133
                                -- Reset condition
134 7 akram.mash
                                if rst = RST_LVL then
135 3 akram.mash
                                        tx_fsm                          <=      idle;
136 7 akram.mash
                                        tx_par_bit                      <=      '0';
137 6 akram.mash
                                        tx_data_tmp                     <=      (others=>'0');
138 7 akram.mash
                                        tx_data_cnt                     <=      (others=>'0');
139 3 akram.mash
                                end if;
140
                        end if;
141
                end if;
142
        end process;
143
 
144 10 akram.mash
        rx_start_detect:process(clk)
145
                variable deb_buf        :       std_logic_vector(3 downto 0);
146
                variable deb_val        :       std_logic;
147
                variable deb_old        :       std_logic;
148
        begin
149
                if clk'event and clk = '1' then
150
                        -- Store previous debounce value
151
                        deb_old                 :=      deb_val;
152
                        -- Debounce logic
153
                        if deb_buf = "0000" then
154
                                deb_val         :=      '0';
155
                        elsif deb_buf = "1111" then
156
                                deb_val         :=      '1';
157
                        end if;
158
                        -- Data storage to debounce
159
                        deb_buf                 :=      deb_buf(2 downto 0) & rx;
160
 
161
                        -- Check RX idle state
162
                        if rx_fsm = idle then
163
                                -- Falling edge detection
164
                                if deb_old = '1' and deb_val = '0' then
165
                                        rx_rcv_init     <=      '1';
166
                                end if;
167
                        -- Default assignments
168
                        else
169
                                rx_rcv_init             <=      '0';
170
                        end if;
171
                        -- Reset condition
172
                        if rst = RST_LVL then
173
                                deb_old                 :=      '0';
174
                                deb_val                 :=      '0';
175
                                deb_buf                 <=      (others=>'0');
176
                                rx_rcv_init             <=      '0';
177
                        end if;
178
                end if;
179
        end if;
180
 
181
 
182
        rx_clk_gen:process(clk)
183
                variable counter        :       integer range 0 to conv_integer((CLK_FREQ*1_000_000)/SER_FREQ-1);
184
        begin
185
                if clk'event and clk = '1' then
186
                        -- Normal Operation
187
                        if counter = (CLK_FREQ*1_000_000)/SER_FREQ-1 and rx_rcv_init = '1' then
188
                                rx_clk_en       <=      '1';
189
                                counter         :=      0;
190
                        else
191
                                rx_clk_en       <=      '0';
192
                                counter         :=      counter + 1;
193
                        end if;
194
                        -- Reset condition
195
                        if rst = RST_LVL then
196
                                rx_clk_en       <=      '0';
197
                                counter         :=      0;
198
                        end if;
199
                end if;
200
        end process;
201
 
202 3 akram.mash
        rx_proc:process(clk)
203
        begin
204
                if clk'event and clk = '1' then
205 10 akram.mash
                        if rx_clk_en = '1' then
206 3 akram.mash
                                -- Default values
207 7 akram.mash
                                rx_ready                <=      '0';
208 3 akram.mash
                                -- FSM description
209
                                case rx_fsm is
210
                                        -- Wait to transfer data
211
                                        when idle =>
212 10 akram.mash
                                                if rx_rcv_init = '1' then
213 3 akram.mash
                                                        rx_fsm          <=      data;
214
                                                end if;
215 7 akram.mash
                                                rx_par_bit              <=      '0';
216
                                                rx_data_cnt             <=      (others=>'0');
217 3 akram.mash
                                        -- Data receive
218
                                        when data =>
219 7 akram.mash
                                                -- Check data to generate parity
220
                                                if par_en = PARITY_EN then
221
                                                        rx_par_bit              <=      rx_par_bit xor rx;
222
                                                end if;
223
 
224
                                                if rx_data_cnt = 7 then
225
                                                        -- Data path
226
                                                        rx_data(7)              <=      rx;
227 3 akram.mash
                                                        for i in 0 to 6 loop
228 7 akram.mash
                                                                rx_data(i)      <=      rx_data_tmp(6-i);
229 3 akram.mash
                                                        end loop;
230 7 akram.mash
 
231
                                                        -- With parity verification
232
                                                        if par_en = PARITY_EN then
233
                                                                rx_fsm          <=      parity;
234
                                                        -- Without parity verification
235
                                                        else
236
                                                                rx_ready        <=      '1';
237
                                                                rx_fsm          <=      idle;
238
                                                        end if;
239 3 akram.mash
                                                else
240 7 akram.mash
                                                        rx_data_tmp             <=      rx_data_tmp(6 downto 0) & rx;
241
                                                        rx_data_cnt             <=      rx_data_cnt + 1;
242 3 akram.mash
                                                end if;
243 7 akram.mash
                                        when parity =>
244
                                                -- Check received parity
245
                                                rx_fsm                          <=      idle;
246
                                                if rx_par_bit = rx then
247
                                                        rx_ready                <=      '1';
248
                                                end if;
249 3 akram.mash
                                        when others => null;
250
                                end case;
251
                                -- Reset condition
252 7 akram.mash
                                if rst = RST_LVL then
253 3 akram.mash
                                        rx_fsm                  <=      idle;
254 6 akram.mash
                                        rx_ready                <=      '0';
255
                                        rx_data                 <=      (others=>'0');
256
                                        rx_data_tmp             <=      (others=>'0');
257 7 akram.mash
                                        rx_data_cnt             <=      (others=>'0');
258 3 akram.mash
                                end if;
259
                        end if;
260
                end if;
261
        end process;
262
 
263
end Behavioral;
264
 

powered by: WebSVN 2.1.0

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