1 |
3 |
guanucolui |
--------------------------------------------------------------------------------
|
2 |
|
|
-- Company: University of Vigo
|
3 |
|
|
-- Engineer: L. Jacobo Alvarez Ruiz de Ojeda
|
4 |
|
|
--
|
5 |
|
|
-- Create Date: 17:27:44 10/18/06
|
6 |
|
|
-- Design Name:
|
7 |
|
|
-- Module Name: uart_rs232 - Behavioral
|
8 |
|
|
-- Project Name:
|
9 |
|
|
-- Target Device:
|
10 |
|
|
-- Tool versions:
|
11 |
|
|
-- Description:
|
12 |
|
|
|
13 |
|
|
-- TRANSMITTER:
|
14 |
|
|
-- The transmitter_busy signal keeps activated during the whole transmitting process of a data (start bit, 8 data bits, parity bit and stop bit)
|
15 |
|
|
-- The activation of "send_data" during one "clk" clock cycle orders this circuit to capture the character present
|
16 |
|
|
-- at the "data_in" inputs and to send it through the RS232 TXD line
|
17 |
|
|
-- The activation of the "send_done" signal during one "clk" clock cycle indicates that the character has been sent
|
18 |
|
|
|
19 |
|
|
-- RECEIVER:
|
20 |
|
|
-- The error flags for the received data (start_error, discrepancy_error and stop_error) keep activated only one clock cycle except the parity error flag, that holds its state
|
21 |
|
|
-- until a new data is received.
|
22 |
|
|
-- The receiver_busy signal keeps activated during the whole receiving process of a data (start bit, 8 data bits, parity bit and stop bit)
|
23 |
|
|
|
24 |
|
|
-- The activation of "new_data" during one clock cycle indicates the arriving of a new character.
|
25 |
|
|
|
26 |
|
|
-- BOTH TRANSMITTER AND RECEIVER
|
27 |
|
|
-- The uart_clock must have a frequency of eight times faster than the desired baud rate
|
28 |
|
|
-- The parity can be selected through the signal even_odd (0: odd/impar; 1: even/par)
|
29 |
|
|
|
30 |
|
|
-- CLOCK DIVIDER
|
31 |
|
|
-- The use of a counter to generate the output clock makes the first period of the output clock only 7 times slower, because
|
32 |
|
|
-- the first time, the counter counts from 0 to 3 (3 cycles) and the following times it counts from 3 to 3 (4 cycles)
|
33 |
|
|
-- This is not important, since the UART detects the rising edges of this output clock and
|
34 |
|
|
-- there are always 8 input clock cycles between two consecutive output clock rising edges.
|
35 |
|
|
--
|
36 |
|
|
-- Dependencies:
|
37 |
|
|
--
|
38 |
|
|
-- Revision:
|
39 |
|
|
-- Revision 0.01 - File Created
|
40 |
|
|
-- Additional Comments:
|
41 |
|
|
--
|
42 |
|
|
--------------------------------------------------------------------------------
|
43 |
|
|
library IEEE;
|
44 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
45 |
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
46 |
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
47 |
|
|
|
48 |
|
|
---- Uncomment the following library declaration if instantiating
|
49 |
|
|
---- any Xilinx primitives in this code.
|
50 |
|
|
--library UNISIM;
|
51 |
|
|
--use UNISIM.VComponents.all;
|
52 |
|
|
|
53 |
|
|
entity uart_rs232 is
|
54 |
|
|
Port ( clk : in std_logic; -- global clock
|
55 |
|
|
reset : in std_logic; -- global reset
|
56 |
|
|
-- uart_clk : in std_logic; -- this clock must have a frequency of each times faster than the desired baud rate
|
57 |
|
|
send_data : in std_logic; -- this signal orders to send the data present at the data_in inputs through the TXD line
|
58 |
|
|
data_in : in std_logic_vector(7 downto 0); -- data to be sent
|
59 |
|
|
even_odd: in std_logic; -- it selects the desired parity (0: odd/impar; 1: even/par)
|
60 |
|
|
rxd : in std_logic; -- The RS232 RXD line
|
61 |
|
|
txd : out std_logic; -- The RS232 TXD line
|
62 |
|
|
transmitter_busy : out std_logic; -- it indicates that the transmitter is busy sending one character
|
63 |
|
|
send_done : out std_logic; -- it indicates that the character has been sent
|
64 |
|
|
data_out : out std_logic_vector(7 downto 0); -- The data received, in parallel
|
65 |
|
|
parity_error : out std_logic; -- it indicates a parity error in the received data
|
66 |
|
|
start_error : out std_logic; -- it indicates an error in the start bit (false start) of the received data. The receiver will wait for a new complete start bit
|
67 |
|
|
stop_error : out std_logic; -- it indicates an error in the stop bit of the received data (though the data could have been received correctly and it is presented at the outputs).
|
68 |
|
|
discrepancy_error: out std_logic; -- it indicates an error because the three samples of the same bit of the data being currently received have different values.
|
69 |
|
|
receiver_busy : out std_logic; -- it indicates that the receiver is busy receiving one character
|
70 |
|
|
new_data : out std_logic -- it indicates that the receiving process has ended and a new character is available
|
71 |
|
|
);
|
72 |
|
|
end uart_rs232;
|
73 |
|
|
|
74 |
|
|
architecture Behavioral of uart_rs232 is
|
75 |
|
|
|
76 |
|
|
-- Component declaration
|
77 |
|
|
|
78 |
|
|
-- RS232 transmitter declaration
|
79 |
|
|
COMPONENT rs232_transmitter
|
80 |
|
|
PORT(
|
81 |
|
|
clk : IN std_logic;
|
82 |
|
|
reset : IN std_logic;
|
83 |
|
|
send_clk : IN std_logic;
|
84 |
|
|
send_data : IN std_logic;
|
85 |
|
|
data_in : IN std_logic_vector(7 downto 0);
|
86 |
|
|
even_odd : IN std_logic;
|
87 |
|
|
txd : OUT std_logic;
|
88 |
|
|
busy : OUT std_logic;
|
89 |
|
|
send_done : OUT std_logic
|
90 |
|
|
);
|
91 |
|
|
END COMPONENT;
|
92 |
|
|
|
93 |
|
|
-- RS232 receiver declaration
|
94 |
|
|
COMPONENT rs232_receiver
|
95 |
|
|
PORT(
|
96 |
|
|
clk : IN std_logic;
|
97 |
|
|
reset : IN std_logic;
|
98 |
|
|
receive_clk : IN std_logic;
|
99 |
|
|
even_odd : IN std_logic;
|
100 |
|
|
rxd : IN std_logic;
|
101 |
|
|
data_out : OUT std_logic_vector(7 downto 0);
|
102 |
|
|
parity_error : OUT std_logic;
|
103 |
|
|
start_error : OUT std_logic;
|
104 |
|
|
stop_error : OUT std_logic;
|
105 |
|
|
discrepancy_error : OUT std_logic;
|
106 |
|
|
busy : OUT std_logic;
|
107 |
|
|
new_data : OUT std_logic
|
108 |
|
|
);
|
109 |
|
|
END COMPONENT;
|
110 |
|
|
|
111 |
|
|
-- Clock divider for transmitter declaration
|
112 |
|
|
COMPONENT divider8_uart
|
113 |
|
|
PORT(
|
114 |
|
|
clk_in : IN std_logic;
|
115 |
|
|
reset : IN std_logic;
|
116 |
|
|
clk_out_8_times_slow : OUT std_logic
|
117 |
|
|
);
|
118 |
|
|
END COMPONENT;
|
119 |
|
|
|
120 |
|
|
-- Divisor de clock de la placa 50 Mhz
|
121 |
|
|
COMPONENT clock_generator_for_uart_rs232
|
122 |
|
|
Port ( clk : in std_logic;
|
123 |
|
|
reset : in std_logic;
|
124 |
|
|
uart_clk : out std_logic);
|
125 |
|
|
END COMPONENT;
|
126 |
|
|
|
127 |
|
|
-- Signals declaration
|
128 |
|
|
|
129 |
|
|
-- Transmitter
|
130 |
|
|
signal send_clk: std_logic;
|
131 |
|
|
-- Receiver
|
132 |
|
|
signal receive_clk: std_logic;
|
133 |
|
|
|
134 |
|
|
-- el clk en función de la velocidad
|
135 |
|
|
signal uart_clk: std_logic;
|
136 |
|
|
|
137 |
|
|
-- discriminadorde pulso
|
138 |
|
|
signal Q1, Q2, Q3 : std_logic;
|
139 |
|
|
signal Ssend_data : std_logic;
|
140 |
|
|
|
141 |
|
|
begin
|
142 |
|
|
|
143 |
|
|
-- Signals assignment
|
144 |
|
|
receive_clk <= uart_clk;
|
145 |
|
|
|
146 |
|
|
-- Component instantiation
|
147 |
|
|
|
148 |
|
|
-- RS232 transmitter instantiation
|
149 |
|
|
Inst_rs232_transmitter: rs232_transmitter PORT MAP(
|
150 |
|
|
clk => clk,
|
151 |
|
|
reset => reset,
|
152 |
|
|
send_clk => send_clk,
|
153 |
|
|
send_data => Ssend_data,
|
154 |
|
|
data_in => data_in,
|
155 |
|
|
even_odd => even_odd,
|
156 |
|
|
txd => txd,
|
157 |
|
|
busy => transmitter_busy,
|
158 |
|
|
send_done => send_done
|
159 |
|
|
);
|
160 |
|
|
|
161 |
|
|
-- RS232 receiver instantiation
|
162 |
|
|
Inst_rs232_receiver: rs232_receiver PORT MAP(
|
163 |
|
|
clk => clk,
|
164 |
|
|
reset => reset,
|
165 |
|
|
receive_clk => receive_clk,
|
166 |
|
|
even_odd => even_odd,
|
167 |
|
|
rxd => rxd,
|
168 |
|
|
data_out => data_out,
|
169 |
|
|
parity_error => parity_error,
|
170 |
|
|
start_error => start_error,
|
171 |
|
|
stop_error => stop_error,
|
172 |
|
|
discrepancy_error => discrepancy_error,
|
173 |
|
|
busy => receiver_busy,
|
174 |
|
|
new_data => new_data
|
175 |
|
|
);
|
176 |
|
|
|
177 |
|
|
-- Clock divider for transmitter instantiation
|
178 |
|
|
Inst_divider8_uart: divider8_uart PORT MAP(
|
179 |
|
|
clk_in => uart_clk,
|
180 |
|
|
clk_out_8_times_slow => send_clk,
|
181 |
|
|
reset => reset
|
182 |
|
|
);
|
183 |
|
|
|
184 |
|
|
-- Clock divider desde el clock general
|
185 |
|
|
Inst_clock_generator: clock_generator_for_uart_rs232 PORT MAP(
|
186 |
|
|
clk => clk,
|
187 |
|
|
uart_clk => uart_clk,
|
188 |
|
|
reset => reset
|
189 |
|
|
);
|
190 |
|
|
|
191 |
|
|
-- Descripción Pulso
|
192 |
|
|
process(clk)
|
193 |
|
|
begin
|
194 |
|
|
if (clk'event and clk = '1') then
|
195 |
|
|
if (reset = '1') then
|
196 |
|
|
Q1 <= '0';
|
197 |
|
|
Q2 <= '0';
|
198 |
|
|
Q3 <= '0';
|
199 |
|
|
else
|
200 |
|
|
Q1 <= send_data;
|
201 |
|
|
Q2 <= Q1;
|
202 |
|
|
Q3 <= Q2;
|
203 |
|
|
end if;
|
204 |
|
|
end if;
|
205 |
|
|
end process;
|
206 |
|
|
Ssend_data <= Q1 and Q2 and (not Q3);
|
207 |
|
|
|
208 |
|
|
end Behavioral;
|