1 |
3 |
guanucolui |
--------------------------------------------------------------------------------
|
2 |
|
|
-- Company: University of Vigo
|
3 |
|
|
-- Engineer: L. Jacobo Alvarez Ruiz de Ojeda
|
4 |
|
|
--
|
5 |
|
|
-- Create Date: 18:26:28 10/17/06
|
6 |
|
|
-- Design Name:
|
7 |
|
|
-- Module Name: rs232_transmitter - Behavioral
|
8 |
|
|
-- Project Name:
|
9 |
|
|
-- Target Device:
|
10 |
|
|
-- Tool versions:
|
11 |
|
|
-- Description:
|
12 |
|
|
-- The parity can be selected through the signal even_odd (0: odd/impar; 1: even/par)
|
13 |
|
|
-- The busy signal keeps activated during the whole transmitting process of a data (start bit, 8 data bits, parity bit and stop bit)
|
14 |
|
|
-- The send clock must have a frequency equal to the desired baud rate
|
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 |
|
|
-- Dependencies:
|
20 |
|
|
--
|
21 |
|
|
-- Revision:
|
22 |
|
|
-- Revision 0.01 - File Created
|
23 |
|
|
-- Additional Comments:
|
24 |
|
|
--
|
25 |
|
|
--------------------------------------------------------------------------------
|
26 |
|
|
library IEEE;
|
27 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
28 |
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
29 |
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
30 |
|
|
|
31 |
|
|
---- Uncomment the following library declaration if instantiating
|
32 |
|
|
---- any Xilinx primitives in this code.
|
33 |
|
|
--library UNISIM;
|
34 |
|
|
--use UNISIM.VComponents.all;
|
35 |
|
|
|
36 |
|
|
entity rs232_transmitter is
|
37 |
|
|
Port ( clk : in std_logic; -- global clock
|
38 |
|
|
reset : in std_logic; -- global reset
|
39 |
|
|
send_clk : in std_logic; -- this clock gives the duration of each bit in the transmission, that is, the baud rate
|
40 |
|
|
send_data : in std_logic; -- this signal orders to send the data present at the data_in inputs
|
41 |
|
|
data_in : in std_logic_vector(7 downto 0); -- data to be sent
|
42 |
|
|
even_odd: in std_logic; -- it selects the desired parity (0: odd/impar; 1: even/par)
|
43 |
|
|
txd : out std_logic; -- The RS232 TXD line
|
44 |
|
|
busy : out std_logic; -- it indicates that the transmitter is busy sending one character
|
45 |
|
|
send_done : out std_logic); -- it indicates that the sending process has ended
|
46 |
|
|
end rs232_transmitter;
|
47 |
|
|
|
48 |
|
|
architecture Behavioral of rs232_transmitter is
|
49 |
|
|
|
50 |
|
|
-- Component declaration
|
51 |
|
|
|
52 |
|
|
-- 9 bits shift register declaration
|
53 |
|
|
COMPONENT shift9_lr
|
54 |
|
|
PORT(
|
55 |
|
|
clk : IN std_logic;
|
56 |
|
|
reset : IN std_logic;
|
57 |
|
|
load_8_lsb_bits : IN std_logic;
|
58 |
|
|
load_msb_bit : IN std_logic;
|
59 |
|
|
data_in : IN std_logic_vector(7 downto 0);
|
60 |
|
|
msb_in : IN std_logic;
|
61 |
|
|
shift_enable : IN std_logic;
|
62 |
|
|
q_shift : OUT std_logic_vector(8 downto 0);
|
63 |
|
|
lsb_out : OUT std_logic
|
64 |
|
|
);
|
65 |
|
|
END COMPONENT;
|
66 |
|
|
|
67 |
|
|
-- BCD counter declaration
|
68 |
|
|
COMPONENT ctr_bcd
|
69 |
|
|
PORT(
|
70 |
|
|
clk : IN std_logic;
|
71 |
|
|
reset : IN std_logic;
|
72 |
|
|
sync_reset : IN std_logic;
|
73 |
|
|
gctr : IN std_logic;
|
74 |
|
|
qctr : OUT std_logic_vector(3 downto 0);
|
75 |
|
|
ctr_eq_9 : OUT std_logic
|
76 |
|
|
);
|
77 |
|
|
END COMPONENT;
|
78 |
|
|
|
79 |
|
|
-- Transmitter control state machine declaration
|
80 |
|
|
COMPONENT tx_ctrl
|
81 |
|
|
PORT(
|
82 |
|
|
CLK : IN std_logic;
|
83 |
|
|
ctr_eq_9 : IN std_logic;
|
84 |
|
|
fa_send_clk : IN std_logic;
|
85 |
|
|
RESET : IN std_logic;
|
86 |
|
|
send_data : IN std_logic;
|
87 |
|
|
incr_ctr : OUT std_logic;
|
88 |
|
|
load_parity_bit : OUT std_logic;
|
89 |
|
|
load_txd : OUT std_logic;
|
90 |
|
|
reset_busy : OUT std_logic;
|
91 |
|
|
reset_ctr : OUT std_logic;
|
92 |
|
|
reset_txd : OUT std_logic;
|
93 |
|
|
send_done : OUT std_logic;
|
94 |
|
|
set_busy : OUT std_logic;
|
95 |
|
|
set_txd : OUT std_logic;
|
96 |
|
|
shift_enable : OUT std_logic
|
97 |
|
|
);
|
98 |
|
|
END COMPONENT;
|
99 |
|
|
|
100 |
|
|
-- Signals declaration
|
101 |
|
|
-- Edge detector for send_clk
|
102 |
|
|
signal send_clk_t_1 , send_clk_s, fa_send_clk: std_logic;
|
103 |
|
|
|
104 |
|
|
-- Shift register
|
105 |
|
|
signal parity_bit, load_parity_bit, shift_enable, lsb_out: std_logic;
|
106 |
|
|
signal q_shift : std_logic_vector(8 downto 0);
|
107 |
|
|
|
108 |
|
|
-- BCD counter
|
109 |
|
|
signal incr_ctr, ctr_eq_9, reset_ctr: std_logic;
|
110 |
|
|
signal q_ctr: std_logic_vector (3 downto 0);
|
111 |
|
|
|
112 |
|
|
-- Busy register
|
113 |
|
|
signal set_busy, reset_busy: std_logic;
|
114 |
|
|
|
115 |
|
|
-- TXD register
|
116 |
|
|
signal set_txd, reset_txd, load_txd: std_logic;
|
117 |
|
|
|
118 |
|
|
begin
|
119 |
|
|
|
120 |
|
|
-- Edge detector for send_clk
|
121 |
|
|
process (reset,clk,send_clk_s,send_clk_t_1)
|
122 |
|
|
begin
|
123 |
|
|
if reset = '1' then send_clk_s <= '0';
|
124 |
|
|
send_clk_t_1 <= '0';
|
125 |
|
|
elsif clk = '1' and clk'event then send_clk_t_1 <= send_clk_s;
|
126 |
|
|
send_clk_s <= send_clk;
|
127 |
|
|
end if;
|
128 |
|
|
|
129 |
|
|
fa_send_clk <= send_clk_s and not send_clk_t_1;
|
130 |
|
|
-- fd_send_clk <= not send_clk_s and send_clk_t_1;
|
131 |
|
|
end process;
|
132 |
|
|
|
133 |
|
|
-- Busy register
|
134 |
|
|
Busy_register: process (clk, reset, reset_busy, set_busy)
|
135 |
|
|
begin
|
136 |
|
|
if reset = '1' then
|
137 |
|
|
busy <= '0';
|
138 |
|
|
elsif clk'event and clk ='1' then
|
139 |
|
|
if reset_busy = '1' then busy <= '0';
|
140 |
|
|
elsif set_busy ='1' then busy <= '1';
|
141 |
|
|
end if;
|
142 |
|
|
end if;
|
143 |
|
|
end process;
|
144 |
|
|
|
145 |
|
|
-- TXD register
|
146 |
|
|
TXD_register: process (clk, reset, reset_txd, set_txd)
|
147 |
|
|
begin
|
148 |
|
|
if reset = '1' then
|
149 |
|
|
txd <= '1';
|
150 |
|
|
elsif clk'event and clk ='1' then
|
151 |
|
|
if set_txd = '1' then txd <= '1';
|
152 |
|
|
elsif reset_txd ='1' then txd <= '0';
|
153 |
|
|
elsif load_txd = '1' then txd <= lsb_out;
|
154 |
|
|
end if;
|
155 |
|
|
end if;
|
156 |
|
|
end process;
|
157 |
|
|
|
158 |
|
|
-- Parity calculator
|
159 |
|
|
parity_calculator: process(even_odd, q_shift)
|
160 |
|
|
begin
|
161 |
|
|
if even_odd = '0' then -- odd parity (the 9 bits has an odd number of ones)
|
162 |
|
|
-- 8 bits XNOR
|
163 |
|
|
parity_bit <= not (q_shift(7) xor q_shift(6) xor q_shift(5) xor q_shift(4) xor q_shift(3) xor q_shift(2) xor q_shift(1) xor q_shift(0));
|
164 |
|
|
|
165 |
|
|
elsif even_odd = '1' then -- even parity (the 9 bits has an even number of ones)
|
166 |
|
|
-- 8 bits XOR
|
167 |
|
|
parity_bit <= q_shift(7) xor q_shift(6) xor q_shift(5) xor q_shift(4) xor q_shift(3) xor q_shift(2) xor q_shift(1) xor q_shift(0);
|
168 |
|
|
end if;
|
169 |
|
|
end process;
|
170 |
|
|
|
171 |
|
|
-- Component instantiation
|
172 |
|
|
|
173 |
|
|
-- 9 bits shift register instantiation
|
174 |
|
|
Inst_shift9_lr: shift9_lr PORT MAP(
|
175 |
|
|
clk => clk,
|
176 |
|
|
reset => reset,
|
177 |
|
|
load_8_lsb_bits => send_data,
|
178 |
|
|
load_msb_bit => load_parity_bit,
|
179 |
|
|
data_in => data_in,
|
180 |
|
|
msb_in => parity_bit,
|
181 |
|
|
shift_enable => shift_enable,
|
182 |
|
|
q_shift => q_shift,
|
183 |
|
|
lsb_out => lsb_out
|
184 |
|
|
);
|
185 |
|
|
|
186 |
|
|
-- BCD counter instantiation
|
187 |
|
|
Inst_ctr_bcd: ctr_bcd PORT MAP(
|
188 |
|
|
clk => clk,
|
189 |
|
|
reset => reset,
|
190 |
|
|
sync_reset => reset_ctr,
|
191 |
|
|
gctr => incr_ctr,
|
192 |
|
|
qctr => q_ctr,
|
193 |
|
|
ctr_eq_9 => ctr_eq_9
|
194 |
|
|
);
|
195 |
|
|
|
196 |
|
|
-- Transmitter control state machine instantiation
|
197 |
|
|
Inst_tx_ctrl: tx_ctrl PORT MAP(
|
198 |
|
|
CLK => clk,
|
199 |
|
|
ctr_eq_9 => ctr_eq_9,
|
200 |
|
|
fa_send_clk => fa_send_clk,
|
201 |
|
|
RESET => reset,
|
202 |
|
|
send_data => send_data,
|
203 |
|
|
incr_ctr => incr_ctr,
|
204 |
|
|
load_parity_bit => load_parity_bit,
|
205 |
|
|
load_txd => load_txd,
|
206 |
|
|
reset_busy => reset_busy,
|
207 |
|
|
reset_ctr => reset_ctr,
|
208 |
|
|
reset_txd => reset_txd,
|
209 |
|
|
send_done => send_done,
|
210 |
|
|
set_busy => set_busy,
|
211 |
|
|
set_txd => set_txd,
|
212 |
|
|
shift_enable => shift_enable
|
213 |
|
|
);
|
214 |
|
|
|
215 |
|
|
end Behavioral;
|