24e5d842d5bbe7de2650c872adf41f2c0b2cdb0d
Stefan Schuermans 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);
Stefan Schuermans implemented RX part of UART...

Stefan Schuermans authored 12 years ago

13)         pin_i_rx:  IN  std_logic;
Stefan Schuermans 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) 
Stefan Schuermans 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) 
Stefan Schuermans 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;
Stefan Schuermans implemented RX part of UART...

Stefan Schuermans authored 12 years ago

55)     SIGNAL r_tx_state:  t_state                          := inactive;
Stefan Schuermans 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);
Stefan Schuermans implemented RX part of UART...

Stefan Schuermans authored 12 years ago

63)     SIGNAL r_tx_data:   std_logic_vector(15 DOWNTO 0)    := X"0000";
Stefan Schuermans 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) 
Stefan Schuermans 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) 
Stefan Schuermans 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
Stefan Schuermans implemented RX part of UART...

Stefan Schuermans authored 12 years ago

285)             IF r_tx_sample /= 6 THEN