implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
1) LIBRARY IEEE;
2) USE IEEE.STD_LOGIC_1164.ALL;
3) USE IEEE.NUMERIC_STD.ALL;
4)
5) ENTITY e_io_uart IS
6) PORT (
7) rst: IN std_logic;
8) clk: IN std_logic;
9) i_addr: IN std_logic_vector( 1 DOWNTO 0);
10) o_rd_data: OUT std_logic_vector(31 DOWNTO 0);
11) i_wr_data: IN std_logic_vector(31 DOWNTO 0);
12) i_wr_en: IN std_logic_vector( 3 DOWNTO 0);
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
13) pin_i_rx: IN std_logic;
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
14) pin_o_tx: OUT std_logic
15) );
16) END ENTITY e_io_uart;
17)
18) ARCHITECTURE a_io_uart OF e_io_uart IS
19)
20) TYPE t_state IS (inactive, start, data, stop);
21)
22) SIGNAL n_cfg_scale: std_logic_vector(15 DOWNTO 0);
23) SIGNAL r_cfg_scale: std_logic_vector(15 DOWNTO 0) := X"0001";
24) SIGNAL n_cfg_bits: std_logic_vector( 3 DOWNTO 0);
25) SIGNAL r_cfg_bits: std_logic_vector( 3 DOWNTO 0) := X"1";
26) SIGNAL n_cfg_stop: std_logic_vector( 1 DOWNTO 0);
27) SIGNAL r_cfg_stop: std_logic_vector( 1 DOWNTO 0) := "01";
28)
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
29) SIGNAL n_rx_scale: natural RANGE 2**16 - 1 DOWNTO 0;
30) SIGNAL r_rx_scale: natural RANGE 2**16 - 1 DOWNTO 0 := 1;
31) SIGNAL n_rx_bits: natural RANGE 15 DOWNTO 0;
32) SIGNAL r_rx_bits: natural RANGE 15 DOWNTO 0 := 1;
33) SIGNAL n_rx_stop: natural RANGE 3 DOWNTO 0;
34) SIGNAL r_rx_stop: natural RANGE 3 DOWNTO 0 := 1;
35) SIGNAL n_rx_state: t_state;
36) SIGNAL r_rx_state: t_state := inactive;
37) SIGNAL n_rx_cnt: natural RANGE 2**16 - 1 DOWNTO 0;
38) SIGNAL r_rx_cnt: natural RANGE 2**16 - 1 DOWNTO 0 := 0;
39) SIGNAL n_rx_sample: natural RANGE 6 DOWNTO 0;
40) SIGNAL r_rx_sample: natural RANGE 6 DOWNTO 0 := 0;
41) SIGNAL n_rx_bit: natural RANGE 15 DOWNTO 0;
42) SIGNAL r_rx_bit: natural RANGE 15 DOWNTO 0 := 0;
43) SIGNAL n_rx_samples: std_logic_vector( 1 DOWNTO 0);
44) SIGNAL r_rx_samples: std_logic_vector( 1 DOWNTO 0) := "00";
45) SIGNAL n_rx_data: std_logic_vector(15 DOWNTO 0);
46) SIGNAL r_rx_data: std_logic_vector(15 DOWNTO 0) := X"0000";
47)
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
48) SIGNAL n_tx_scale: natural RANGE 2**16 - 1 DOWNTO 0;
49) SIGNAL r_tx_scale: natural RANGE 2**16 - 1 DOWNTO 0 := 1;
50) SIGNAL n_tx_bits: natural RANGE 15 DOWNTO 0;
51) SIGNAL r_tx_bits: natural RANGE 15 DOWNTO 0 := 1;
52) SIGNAL n_tx_stop: natural RANGE 3 DOWNTO 0;
53) SIGNAL r_tx_stop: natural RANGE 3 DOWNTO 0 := 1;
54) SIGNAL n_tx_state: t_state;
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
55) SIGNAL r_tx_state: t_state := inactive;
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
56) SIGNAL n_tx_cnt: natural RANGE 2**16 - 1 DOWNTO 0;
57) SIGNAL r_tx_cnt: natural RANGE 2**16 - 1 DOWNTO 0 := 0;
58) SIGNAL n_tx_sample: natural RANGE 6 DOWNTO 0;
59) SIGNAL r_tx_sample: natural RANGE 6 DOWNTO 0 := 0;
60) SIGNAL n_tx_bit: natural RANGE 15 DOWNTO 0;
61) SIGNAL r_tx_bit: natural RANGE 15 DOWNTO 0 := 0;
62) SIGNAL n_tx_data: std_logic_vector(15 DOWNTO 0);
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
63) SIGNAL r_tx_data: std_logic_vector(15 DOWNTO 0) := X"0000";
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
64)
65) BEGIN
66)
67) p_cfg_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
68) i_addr, i_wr_data, i_wr_en)
69) BEGIN
70) n_cfg_scale <= r_cfg_scale;
71) n_cfg_bits <= r_cfg_bits;
72) n_cfg_stop <= r_cfg_stop;
73) IF i_addr = "00" THEN
74) IF i_wr_en(1 DOWNTO 0) = "11" AND
75) i_wr_data(15 DOWNTO 0) /= X"0000" THEN
76) n_cfg_scale <= i_wr_data(15 DOWNTO 0);
77) END IF;
78) IF i_wr_en(2) = '1' AND
79) i_wr_data(23 DOWNTO 20) = X"0" AND
80) i_wr_data(19 DOWNTO 16) /= X"0" THEN
81) n_cfg_bits <= i_wr_data(19 DOWNTO 16);
82) END IF;
83) IF i_wr_en(3) = '1' AND
84) i_wr_data(31 DOWNTO 26) = "000000" AND
85) i_wr_data(25 DOWNTO 24) /= "00" THEN
86) n_cfg_stop <= i_wr_data(25 DOWNTO 24);
87) END IF;
88) END IF;
89) END PROCESS p_cfg_next;
90)
91) p_cfg_sync: PROCESS(rst, clk)
92) BEGIN
93) IF rst = '1' THEN
94) r_cfg_scale <= X"0001";
95) r_cfg_bits <= X"1";
96) r_cfg_stop <= "01";
97) ELSIF rising_edge(clk) THEN
98) r_cfg_scale <= n_cfg_scale;
99) r_cfg_bits <= n_cfg_bits;
100) r_cfg_stop <= n_cfg_stop;
101) END IF;
102) END PROCESS p_cfg_sync;
103)
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
104) p_rx_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
105) r_rx_scale, r_rx_bits, r_rx_stop,
106) r_rx_state, r_rx_cnt, r_rx_sample, r_rx_bit,
107) r_rx_samples, r_rx_data,
108) pin_i_rx)
109) VARIABLE v_next_cnt: boolean;
110) VARIABLE v_next_sample: boolean;
111) VARIABLE v_next_bit: boolean;
112) VARIABLE v_next_state: boolean;
113) VARIABLE v_bits: natural RANGE 15 DOWNTO 0;
114) VARIABLE v_samples: std_logic_vector(2 DOWNTO 0);
115) VARIABLE v_bit_val: std_logic;
116) VARIABLE v_err: boolean;
117) BEGIN
118) n_rx_scale <= r_rx_scale;
119) n_rx_bits <= r_rx_bits;
120) n_rx_stop <= r_rx_stop;
121) n_rx_state <= r_rx_state;
122) n_rx_cnt <= r_rx_cnt;
123) n_rx_sample <= r_rx_sample;
124) n_rx_bit <= r_rx_bit;
125) n_rx_samples <= r_rx_samples;
126) n_rx_data <= r_rx_data;
127) v_next_cnt := false;
128) v_next_sample := false;
129) v_next_bit := false;
130) v_next_state := false;
131) v_bits := 0;
132) v_samples := "000";
133) v_bit_val := '0';
134) v_err := false;
135) IF r_rx_state = inactive THEN
136) IF pin_i_rx = '0' THEN
137) n_rx_scale <= to_integer(unsigned(r_cfg_scale));
138) n_rx_bits <= to_integer(unsigned(r_cfg_bits));
139) n_rx_stop <= to_integer(unsigned(r_cfg_stop));
140) n_rx_state <= start;
141) n_rx_cnt <= 0;
142) n_rx_sample <= 3; -- sample in middle of received bits
143) n_rx_bit <= 0;
144) n_rx_samples <= "00";
145) n_rx_data <= X"0000";
146) END IF;
147) ELSE
148) v_next_cnt := true;
149) END IF;
150) IF v_next_cnt THEN
151) IF r_rx_cnt + 1 /= r_rx_scale THEN
152) n_rx_cnt <= r_rx_cnt + 1;
153) ELSE
154) n_rx_cnt <= 0;
155) v_next_sample := true;
156) END IF;
157) END IF;
158) IF v_next_sample THEN
159) IF r_rx_sample = 4 THEN
160) n_rx_samples(0) <= pin_i_rx;
161) ELSIF r_rx_sample = 5 THEN
162) n_rx_samples(1) <= pin_i_rx;
163) ELSIF r_rx_sample = 6 THEN
164) v_samples := pin_i_rx & r_rx_samples;
165) CASE v_samples IS
166) WHEN "000" | "001" | "010" | "100" => v_bit_val := '0';
167) WHEN "011" | "101" | "110" | "111" => v_bit_val := '1';
168) WHEN OTHERS => NULL;
169) END CASE;
170) IF r_rx_state = data THEN
171) n_rx_data(r_rx_bit) <= v_bit_val;
172) END IF;
173) CASE r_rx_state IS
174) WHEN start => v_err := v_bit_val /= '0';
175) WHEN data => v_err := false;
176) WHEN stop => v_err := v_bit_val /= '1';
177) WHEN OTHERS => NULL;
178) END CASE;
179) IF v_err THEN
180) n_rx_data(15) <= '1';
181) END IF;
182) END IF;
183) IF r_rx_sample /= 6 THEN
184) n_rx_sample <= r_rx_sample + 1;
185) ELSE
186) n_rx_sample <= 0;
187) v_next_bit := true;
188) END IF;
189) END IF;
190) IF v_next_bit THEN
191) CASE r_rx_state IS
192) WHEN start => v_bits := 1;
193) WHEN data => v_bits := r_rx_bits;
194) WHEN stop => v_bits := r_rx_stop;
195) WHEN OTHERS => NULL;
196) END CASE;
197) IF r_rx_bit + 1 /= v_bits THEN
198) n_rx_bit <= r_rx_bit + 1;
199) ELSE
200) n_rx_bit <= 0;
201) v_next_state := true;
202) END IF;
203) END IF;
204) IF v_next_state THEN
205) CASE r_rx_state IS
206) WHEN start => n_rx_state <= data;
207) WHEN data => n_rx_state <= stop;
208) WHEN stop => n_rx_state <= inactive;
209) WHEN OTHERS => NULL;
210) END CASE;
211) END IF;
212) END PROCESS p_rx_next;
213)
214) p_rx_sync: PROCESS(rst, clk)
215) BEGIN
216) IF rst = '1' THEN
217) r_rx_scale <= 1;
218) r_rx_bits <= 1;
219) r_rx_stop <= 1;
220) r_rx_state <= inactive;
221) r_rx_cnt <= 0;
222) r_rx_sample <= 0;
223) r_rx_bit <= 0;
224) r_rx_samples <= "00";
225) r_rx_data <= X"0000";
226) ELSIF rising_edge(clk) THEN
227) r_rx_scale <= n_rx_scale;
228) r_rx_bits <= n_rx_bits;
229) r_rx_stop <= n_rx_stop;
230) r_rx_state <= n_rx_state;
231) r_rx_cnt <= n_rx_cnt;
232) r_rx_sample <= n_rx_sample;
233) r_rx_bit <= n_rx_bit;
234) r_rx_samples <= n_rx_samples;
235) r_rx_data <= n_rx_data;
236) END IF;
237) END PROCESS p_rx_sync;
238)
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
239) p_tx_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
240) r_tx_scale, r_tx_bits, r_tx_stop,
241) r_tx_state, r_tx_cnt, r_tx_sample, r_tx_bit, r_tx_data,
242) i_addr, i_wr_data, i_wr_en)
243) VARIABLE v_next_cnt: boolean;
244) VARIABLE v_next_sample: boolean;
245) VARIABLE v_next_bit: boolean;
246) VARIABLE v_next_state: boolean;
247) VARIABLE v_bits: natural RANGE 15 DOWNTO 0;
248) BEGIN
249) n_tx_scale <= r_tx_scale;
250) n_tx_bits <= r_tx_bits;
251) n_tx_stop <= r_tx_stop;
252) n_tx_state <= r_tx_state;
253) n_tx_cnt <= r_tx_cnt;
254) n_tx_sample <= r_tx_sample;
255) n_tx_bit <= r_tx_bit;
256) n_tx_data <= r_tx_data;
257) v_next_cnt := false;
258) v_next_sample := false;
259) v_next_bit := false;
260) v_next_state := false;
261) v_bits := 0;
262) IF r_tx_state = inactive THEN
263) IF i_addr = "10" AND i_wr_en(1 DOWNTO 0) = "11" THEN
264) n_tx_scale <= to_integer(unsigned(r_cfg_scale));
265) n_tx_bits <= to_integer(unsigned(r_cfg_bits));
266) n_tx_stop <= to_integer(unsigned(r_cfg_stop));
267) n_tx_state <= start;
268) n_tx_cnt <= 0;
269) n_tx_sample <= 0;
270) n_tx_bit <= 0;
271) n_tx_data <= i_wr_data(15 DOWNTO 0);
272) END IF;
273) ELSE
274) v_next_cnt := true;
275) END IF;
276) IF v_next_cnt THEN
277) IF r_tx_cnt + 1 /= r_tx_scale THEN
278) n_tx_cnt <= r_tx_cnt + 1;
279) ELSE
280) n_tx_cnt <= 0;
281) v_next_sample := true;
282) END IF;
283) END IF;
284) IF v_next_sample THEN
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
285) IF r_tx_sample /= 6 THEN
|