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)
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
48) SIGNAL s_tx_wr_rdy: std_logic;
49) SIGNAL s_tx_wr_en: std_logic;
50) SIGNAL s_tx_rd_rdy: std_logic;
51) SIGNAL s_tx_rd_data: std_logic_vector(15 DOWNTO 0);
52) SIGNAL s_tx_rd_en: std_logic;
53)
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
54) SIGNAL n_tx_scale: natural RANGE 2**16 - 1 DOWNTO 0;
55) SIGNAL r_tx_scale: natural RANGE 2**16 - 1 DOWNTO 0 := 1;
56) SIGNAL n_tx_bits: natural RANGE 15 DOWNTO 0;
57) SIGNAL r_tx_bits: natural RANGE 15 DOWNTO 0 := 1;
58) SIGNAL n_tx_stop: natural RANGE 3 DOWNTO 0;
59) SIGNAL r_tx_stop: natural RANGE 3 DOWNTO 0 := 1;
60) SIGNAL n_tx_state: t_state;
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
61) SIGNAL r_tx_state: t_state := inactive;
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
62) SIGNAL n_tx_cnt: natural RANGE 2**16 - 1 DOWNTO 0;
63) SIGNAL r_tx_cnt: natural RANGE 2**16 - 1 DOWNTO 0 := 0;
64) SIGNAL n_tx_sample: natural RANGE 6 DOWNTO 0;
65) SIGNAL r_tx_sample: natural RANGE 6 DOWNTO 0 := 0;
66) SIGNAL n_tx_bit: natural RANGE 15 DOWNTO 0;
67) SIGNAL r_tx_bit: natural RANGE 15 DOWNTO 0 := 0;
68) SIGNAL n_tx_data: std_logic_vector(15 DOWNTO 0);
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
69) SIGNAL r_tx_data: std_logic_vector(15 DOWNTO 0) := X"0000";
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
70)
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
71) COMPONENT e_block_fifo IS
72) GENERIC (
73) addr_width: natural;
74) data_width: natural
75) );
76) PORT (
77) rst: IN std_logic;
78) clk: IN std_logic;
79) o_wr_rdy: OUT std_logic;
80) i_wr_data: IN std_logic_vector(data_width - 1 DOWNTO 0);
81) i_wr_en: IN std_logic;
82) o_rd_rdy: OUT std_logic;
83) o_rd_data: OUT std_logic_vector(data_width - 1 DOWNTO 0);
84) i_rd_en: IN std_logic
85) );
86) END COMPONENT e_block_fifo;
87)
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
88) BEGIN
89)
90) p_cfg_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
91) i_addr, i_wr_data, i_wr_en)
92) BEGIN
93) n_cfg_scale <= r_cfg_scale;
94) n_cfg_bits <= r_cfg_bits;
95) n_cfg_stop <= r_cfg_stop;
96) IF i_addr = "00" THEN
97) IF i_wr_en(1 DOWNTO 0) = "11" AND
98) i_wr_data(15 DOWNTO 0) /= X"0000" THEN
99) n_cfg_scale <= i_wr_data(15 DOWNTO 0);
100) END IF;
101) IF i_wr_en(2) = '1' AND
102) i_wr_data(23 DOWNTO 20) = X"0" AND
103) i_wr_data(19 DOWNTO 16) /= X"0" THEN
104) n_cfg_bits <= i_wr_data(19 DOWNTO 16);
105) END IF;
106) IF i_wr_en(3) = '1' AND
107) i_wr_data(31 DOWNTO 26) = "000000" AND
108) i_wr_data(25 DOWNTO 24) /= "00" THEN
109) n_cfg_stop <= i_wr_data(25 DOWNTO 24);
110) END IF;
111) END IF;
112) END PROCESS p_cfg_next;
113)
114) p_cfg_sync: PROCESS(rst, clk)
115) BEGIN
116) IF rst = '1' THEN
117) r_cfg_scale <= X"0001";
118) r_cfg_bits <= X"1";
119) r_cfg_stop <= "01";
120) ELSIF rising_edge(clk) THEN
121) r_cfg_scale <= n_cfg_scale;
122) r_cfg_bits <= n_cfg_bits;
123) r_cfg_stop <= n_cfg_stop;
124) END IF;
125) END PROCESS p_cfg_sync;
126)
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
127) p_rx_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
128) r_rx_scale, r_rx_bits, r_rx_stop,
129) r_rx_state, r_rx_cnt, r_rx_sample, r_rx_bit,
130) r_rx_samples, r_rx_data,
131) pin_i_rx)
132) VARIABLE v_next_cnt: boolean;
133) VARIABLE v_next_sample: boolean;
134) VARIABLE v_next_bit: boolean;
135) VARIABLE v_next_state: boolean;
136) VARIABLE v_bits: natural RANGE 15 DOWNTO 0;
137) VARIABLE v_samples: std_logic_vector(2 DOWNTO 0);
138) VARIABLE v_bit_val: std_logic;
139) VARIABLE v_err: boolean;
140) BEGIN
141) n_rx_scale <= r_rx_scale;
142) n_rx_bits <= r_rx_bits;
143) n_rx_stop <= r_rx_stop;
144) n_rx_state <= r_rx_state;
145) n_rx_cnt <= r_rx_cnt;
146) n_rx_sample <= r_rx_sample;
147) n_rx_bit <= r_rx_bit;
148) n_rx_samples <= r_rx_samples;
149) n_rx_data <= r_rx_data;
150) v_next_cnt := false;
151) v_next_sample := false;
152) v_next_bit := false;
153) v_next_state := false;
154) v_bits := 0;
155) v_samples := "000";
156) v_bit_val := '0';
157) v_err := false;
158) IF r_rx_state = inactive THEN
159) IF pin_i_rx = '0' THEN
160) n_rx_scale <= to_integer(unsigned(r_cfg_scale));
161) n_rx_bits <= to_integer(unsigned(r_cfg_bits));
162) n_rx_stop <= to_integer(unsigned(r_cfg_stop));
163) n_rx_state <= start;
164) n_rx_cnt <= 0;
165) n_rx_sample <= 3; -- sample in middle of received bits
166) n_rx_bit <= 0;
167) n_rx_samples <= "00";
168) n_rx_data <= X"0000";
169) END IF;
170) ELSE
171) v_next_cnt := true;
172) END IF;
173) IF v_next_cnt THEN
174) IF r_rx_cnt + 1 /= r_rx_scale THEN
175) n_rx_cnt <= r_rx_cnt + 1;
176) ELSE
177) n_rx_cnt <= 0;
178) v_next_sample := true;
179) END IF;
180) END IF;
181) IF v_next_sample THEN
182) IF r_rx_sample = 4 THEN
183) n_rx_samples(0) <= pin_i_rx;
184) ELSIF r_rx_sample = 5 THEN
185) n_rx_samples(1) <= pin_i_rx;
186) ELSIF r_rx_sample = 6 THEN
187) v_samples := pin_i_rx & r_rx_samples;
188) CASE v_samples IS
189) WHEN "000" | "001" | "010" | "100" => v_bit_val := '0';
190) WHEN "011" | "101" | "110" | "111" => v_bit_val := '1';
191) WHEN OTHERS => NULL;
192) END CASE;
193) IF r_rx_state = data THEN
194) n_rx_data(r_rx_bit) <= v_bit_val;
195) END IF;
196) CASE r_rx_state IS
197) WHEN start => v_err := v_bit_val /= '0';
198) WHEN data => v_err := false;
199) WHEN stop => v_err := v_bit_val /= '1';
200) WHEN OTHERS => NULL;
201) END CASE;
202) IF v_err THEN
203) n_rx_data(15) <= '1';
204) END IF;
205) END IF;
206) IF r_rx_sample /= 6 THEN
207) n_rx_sample <= r_rx_sample + 1;
208) ELSE
209) n_rx_sample <= 0;
210) v_next_bit := true;
211) END IF;
212) END IF;
213) IF v_next_bit THEN
214) CASE r_rx_state IS
215) WHEN start => v_bits := 1;
216) WHEN data => v_bits := r_rx_bits;
217) WHEN stop => v_bits := r_rx_stop;
218) WHEN OTHERS => NULL;
219) END CASE;
220) IF r_rx_bit + 1 /= v_bits THEN
221) n_rx_bit <= r_rx_bit + 1;
222) ELSE
223) n_rx_bit <= 0;
224) v_next_state := true;
225) END IF;
226) END IF;
227) IF v_next_state THEN
228) CASE r_rx_state IS
229) WHEN start => n_rx_state <= data;
230) WHEN data => n_rx_state <= stop;
231) WHEN stop => n_rx_state <= inactive;
232) WHEN OTHERS => NULL;
233) END CASE;
234) END IF;
235) END PROCESS p_rx_next;
236)
237) p_rx_sync: PROCESS(rst, clk)
238) BEGIN
239) IF rst = '1' THEN
240) r_rx_scale <= 1;
241) r_rx_bits <= 1;
242) r_rx_stop <= 1;
243) r_rx_state <= inactive;
244) r_rx_cnt <= 0;
245) r_rx_sample <= 0;
246) r_rx_bit <= 0;
247) r_rx_samples <= "00";
248) r_rx_data <= X"0000";
249) ELSIF rising_edge(clk) THEN
250) r_rx_scale <= n_rx_scale;
251) r_rx_bits <= n_rx_bits;
252) r_rx_stop <= n_rx_stop;
253) r_rx_state <= n_rx_state;
254) r_rx_cnt <= n_rx_cnt;
255) r_rx_sample <= n_rx_sample;
256) r_rx_bit <= n_rx_bit;
257) r_rx_samples <= n_rx_samples;
258) r_rx_data <= n_rx_data;
259) END IF;
260) END PROCESS p_rx_sync;
261)
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
262) s_tx_wr_en <= '1' WHEN i_addr = "10" AND i_wr_en(1 DOWNTO 0) = "11"
263) ELSE '0';
264)
265) tx_fifo: e_block_fifo
266) GENERIC MAP (
267) addr_width => 4,
268) data_width => 16
269) )
270) PORT MAP (
271) rst => rst,
272) clk => clk,
273) o_wr_rdy => s_tx_wr_rdy,
274) i_wr_data => i_wr_data(15 DOWNTO 0),
275) i_wr_en => s_tx_wr_en,
276) o_rd_rdy => s_tx_rd_rdy,
277) o_rd_data => s_tx_rd_data,
278) i_rd_en => s_tx_rd_en
279) );
280)
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
281) p_tx_next: PROCESS(r_cfg_scale, r_cfg_bits, r_cfg_stop,
282) r_tx_scale, r_tx_bits, r_tx_stop,
283) r_tx_state, r_tx_cnt, r_tx_sample, r_tx_bit, r_tx_data,
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
284) s_tx_rd_rdy, s_tx_rd_data)
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
285) VARIABLE v_next_cnt: boolean;
286) VARIABLE v_next_sample: boolean;
287) VARIABLE v_next_bit: boolean;
288) VARIABLE v_next_state: boolean;
289) VARIABLE v_bits: natural RANGE 15 DOWNTO 0;
290) BEGIN
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
291) s_tx_rd_en <= '0';
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
292) n_tx_scale <= r_tx_scale;
293) n_tx_bits <= r_tx_bits;
294) n_tx_stop <= r_tx_stop;
295) n_tx_state <= r_tx_state;
296) n_tx_cnt <= r_tx_cnt;
297) n_tx_sample <= r_tx_sample;
298) n_tx_bit <= r_tx_bit;
299) n_tx_data <= r_tx_data;
300) v_next_cnt := false;
301) v_next_sample := false;
302) v_next_bit := false;
303) v_next_state := false;
304) v_bits := 0;
305) IF r_tx_state = inactive THEN
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
306) IF s_tx_rd_rdy = '1' THEN
307) s_tx_rd_en <= '1';
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
308) n_tx_scale <= to_integer(unsigned(r_cfg_scale));
309) n_tx_bits <= to_integer(unsigned(r_cfg_bits));
310) n_tx_stop <= to_integer(unsigned(r_cfg_stop));
311) n_tx_state <= start;
312) n_tx_cnt <= 0;
313) n_tx_sample <= 0;
314) n_tx_bit <= 0;
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
315) n_tx_data <= s_tx_rd_data;
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
316) END IF;
317) ELSE
318) v_next_cnt := true;
319) END IF;
320) IF v_next_cnt THEN
321) IF r_tx_cnt + 1 /= r_tx_scale THEN
322) n_tx_cnt <= r_tx_cnt + 1;
323) ELSE
324) n_tx_cnt <= 0;
325) v_next_sample := true;
326) END IF;
327) END IF;
328) IF v_next_sample THEN
|
implemented RX part of UART...
Stefan Schuermans authored 12 years ago
|
329) IF r_tx_sample /= 6 THEN
|
implemented TX part of UART...
Stefan Schuermans authored 12 years ago
|
330) n_tx_sample <= r_tx_sample + 1;
331) ELSE
332) n_tx_sample <= 0;
333) v_next_bit := true;
334) END IF;
335) END IF;
336) IF v_next_bit THEN
337) CASE r_tx_state IS
338) WHEN start => v_bits := 1;
339) WHEN data => v_bits := r_tx_bits;
340) WHEN stop => v_bits := r_tx_stop;
341) WHEN OTHERS => NULL;
342) END CASE;
343) IF r_tx_bit + 1 /= v_bits THEN
344) n_tx_bit <= r_tx_bit + 1;
345) ELSE
346) n_tx_bit <= 0;
347) v_next_state := true;
348) END IF;
349) END IF;
350) IF v_next_state THEN
351) CASE r_tx_state IS
352) WHEN start => n_tx_state <= data;
353) WHEN data => n_tx_state <= stop;
354) WHEN stop => n_tx_state <= inactive;
355) WHEN OTHERS => NULL;
356) END CASE;
357) END IF;
358) END PROCESS p_tx_next;
359)
360) p_tx_sync: PROCESS(rst, clk)
361) BEGIN
362) IF rst = '1' THEN
363) r_tx_scale <= 1;
364) r_tx_bits <= 1;
365) r_tx_stop <= 1;
366) r_tx_state <= inactive;
367) r_tx_cnt <= 0;
368) r_tx_sample <= 0;
369) r_tx_bit <= 0;
370) r_tx_data <= X"0000";
371) ELSIF rising_edge(clk) THEN
372) r_tx_scale <= n_tx_scale;
373) r_tx_bits <= n_tx_bits;
374) r_tx_stop <= n_tx_stop;
375) r_tx_state <= n_tx_state;
376) r_tx_cnt <= n_tx_cnt;
377) r_tx_sample <= n_tx_sample;
378) r_tx_bit <= n_tx_bit;
379) r_tx_data <= n_tx_data;
380) END IF;
381) END PROCESS p_tx_sync;
382)
383) p_tx_out: PROCESS(r_tx_bit, r_tx_state, r_tx_data)
384) BEGIN
385) pin_o_tx <= '1';
386) CASE r_tx_state IS
387) WHEN start => pin_o_tx <= '0';
388) WHEN data => pin_o_tx <= r_tx_data(r_tx_bit);
389) WHEN stop => pin_o_tx <= '1';
390) WHEN OTHERS => NULL;
391) END CASE;
392) END PROCESS p_tx_out;
393)
394) p_read: PROCESS(rst, clk)
395) BEGIN
396) IF rst = '1' THEN
397) o_rd_data <= (OTHERS => '0');
398) ELSIF rising_edge(clk) THEN
399) o_rd_data <= (OTHERS => '0');
400) CASE i_addr IS
401) WHEN "00" =>
402) o_rd_data(15 DOWNTO 0) <= r_cfg_scale;
403) o_rd_data(19 DOWNTO 16) <= r_cfg_bits;
404) o_rd_data(25 DOWNTO 24) <= r_cfg_stop;
405) WHEN "01" =>
|
added FIFO to UART TX
Stefan Schuermans authored 12 years ago
|
406) o_rd_data(0) <= s_tx_wr_rdy;
|