1
1
-- ------------------------------------------------------------------------------
2
2
-- PROJECT: SIMPLE UART FOR FPGA
3
3
-- ------------------------------------------------------------------------------
4
- -- MODULE: UART RECEIVER
5
4
-- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
6
5
-- LICENSE: The MIT License (MIT), please read LICENSE file
7
6
-- WEBSITE: https://github.com/jakubcabal/uart-for-fpga
@@ -13,75 +12,58 @@ use IEEE.NUMERIC_STD.ALL;
13
12
14
13
entity UART_RX is
15
14
Generic (
16
- PARITY_BIT : string := " none" -- type of parity: "none", "even", "odd", "mark", "space"
15
+ CLK_DIV_VAL : integer := 16 ;
16
+ PARITY_BIT : string := " none" -- type of parity: "none", "even", "odd", "mark", "space"
17
17
);
18
18
Port (
19
- CLK : in std_logic ; -- system clock
20
- RST : in std_logic ; -- high active synchronous reset
19
+ CLK : in std_logic ; -- system clock
20
+ RST : in std_logic ; -- high active synchronous reset
21
21
-- UART INTERFACE
22
- UART_CLK_EN : in std_logic ; -- oversampling (16x) UART clock enable
23
- UART_RXD : in std_logic ; -- serial receive data
22
+ UART_CLK_EN : in std_logic ; -- oversampling (16x) UART clock enable
23
+ UART_RXD : in std_logic ; -- serial receive data
24
24
-- USER DATA OUTPUT INTERFACE
25
- DOUT : out std_logic_vector (7 downto 0 ); -- output data received via UART
26
- DOUT_VLD : out std_logic ; -- when DOUT_VLD = 1, output data (DOUT) are valid (is assert only for one clock cycle)
27
- FRAME_ERROR : out std_logic -- when FRAME_ERROR = 1, stop bit was invalid (is assert only for one clock cycle)
25
+ DOUT : out std_logic_vector (7 downto 0 ); -- output data received via UART
26
+ DOUT_VLD : out std_logic ; -- when DOUT_VLD = 1, output data (DOUT) are valid without errors (is assert only for one clock cycle)
27
+ FRAME_ERROR : out std_logic ; -- when FRAME_ERROR = 1, stop bit was invalid (is assert only for one clock cycle)
28
+ PARITY_ERROR : out std_logic -- when PARITY_ERROR = 1, parity bit was invalid (is assert only for one clock cycle)
28
29
);
29
- end UART_RX ;
30
+ end entity ;
30
31
31
- architecture FULL of UART_RX is
32
+ architecture RTL of UART_RX is
32
33
33
34
signal rx_clk_en : std_logic ;
34
- signal rx_ticks : unsigned (3 downto 0 );
35
- signal rx_clk_divider_en : std_logic ;
36
35
signal rx_data : std_logic_vector (7 downto 0 );
37
36
signal rx_bit_count : unsigned (2 downto 0 );
38
- signal rx_receiving_data : std_logic ;
39
37
signal rx_parity_bit : std_logic ;
40
38
signal rx_parity_error : std_logic ;
41
39
signal rx_parity_check_en : std_logic ;
42
- signal rx_output_reg_en : std_logic ;
40
+ signal rx_done : std_logic ;
41
+ signal fsm_idle : std_logic ;
42
+ signal fsm_databits : std_logic ;
43
+ signal fsm_stopbit : std_logic ;
43
44
44
45
type state is (idle, startbit, databits, paritybit, stopbit);
45
- signal rx_pstate : state;
46
- signal rx_nstate : state;
46
+ signal fsm_pstate : state;
47
+ signal fsm_nstate : state;
47
48
48
49
begin
49
50
50
51
-- -------------------------------------------------------------------------
51
52
-- UART RECEIVER CLOCK DIVIDER AND CLOCK ENABLE FLAG
52
53
-- -------------------------------------------------------------------------
53
54
54
- uart_rx_clk_divider_p : process (CLK)
55
- begin
56
- if (rising_edge (CLK)) then
57
- if (rx_clk_divider_en = '1' ) then
58
- if (UART_CLK_EN = '1' ) then
59
- if (rx_ticks = "1111" ) then
60
- rx_ticks <= (others => '0' );
61
- else
62
- rx_ticks <= rx_ticks + 1 ;
63
- end if ;
64
- else
65
- rx_ticks <= rx_ticks;
66
- end if ;
67
- else
68
- rx_ticks <= (others => '0' );
69
- end if ;
70
- end if ;
71
- end process ;
72
-
73
- uart_rx_clk_en_p : process (CLK)
74
- begin
75
- if (rising_edge (CLK)) then
76
- if (RST = '1' ) then
77
- rx_clk_en <= '0' ;
78
- elsif (UART_CLK_EN = '1' AND rx_ticks = "0111" ) then
79
- rx_clk_en <= '1' ;
80
- else
81
- rx_clk_en <= '0' ;
82
- end if ;
83
- end if ;
84
- end process ;
55
+ rx_clk_divider_i : entity work .UART_CLK_DIV
56
+ generic map (
57
+ DIV_MAX_VAL => CLK_DIV_VAL,
58
+ DIV_MARK_POS => 3
59
+ )
60
+ port map (
61
+ CLK => CLK,
62
+ RST => RST,
63
+ CLEAR => fsm_idle,
64
+ ENABLE => UART_CLK_EN,
65
+ DIV_MARK => rx_clk_en
66
+ );
85
67
86
68
-- -------------------------------------------------------------------------
87
69
-- UART RECEIVER BIT COUNTER
92
74
if (rising_edge (CLK)) then
93
75
if (RST = '1' ) then
94
76
rx_bit_count <= (others => '0' );
95
- elsif (rx_clk_en = '1' AND rx_receiving_data = '1' ) then
77
+ elsif (rx_clk_en = '1' AND fsm_databits = '1' ) then
96
78
if (rx_bit_count = "111" ) then
97
79
rx_bit_count <= (others => '0' );
98
80
else
109
91
uart_rx_data_shift_reg_p : process (CLK)
110
92
begin
111
93
if (rising_edge (CLK)) then
112
- if (rx_clk_en = '1' AND rx_receiving_data = '1' ) then
94
+ if (rx_clk_en = '1' AND fsm_databits = '1' ) then
113
95
rx_data <= UART_RXD & rx_data(7 downto 1 );
114
96
end if ;
115
97
end if ;
@@ -150,20 +132,19 @@ begin
150
132
-- UART RECEIVER OUTPUT REGISTER
151
133
-- -------------------------------------------------------------------------
152
134
135
+ rx_done <= rx_clk_en and fsm_stopbit;
136
+
153
137
uart_rx_output_reg_p : process (CLK)
154
138
begin
155
139
if (rising_edge (CLK)) then
156
140
if (RST = '1' ) then
157
- DOUT_VLD <= '0' ;
158
- FRAME_ERROR <= '0' ;
141
+ DOUT_VLD <= '0' ;
142
+ FRAME_ERROR <= '0' ;
143
+ PARITY_ERROR <= '0' ;
159
144
else
160
- if (rx_clk_en = '1' AND rx_output_reg_en = '1' ) then
161
- DOUT_VLD <= NOT rx_parity_error AND UART_RXD;
162
- FRAME_ERROR <= NOT UART_RXD;
163
- else
164
- DOUT_VLD <= '0' ;
165
- FRAME_ERROR <= '0' ;
166
- end if ;
145
+ DOUT_VLD <= rx_done and not rx_parity_error and UART_RXD;
146
+ FRAME_ERROR <= rx_done and not UART_RXD;
147
+ PARITY_ERROR <= rx_done and rx_parity_error;
167
148
end if ;
168
149
end if ;
169
150
end process ;
@@ -177,84 +158,84 @@ begin
177
158
begin
178
159
if (rising_edge (CLK)) then
179
160
if (RST = '1' ) then
180
- rx_pstate <= idle;
161
+ fsm_pstate <= idle;
181
162
else
182
- rx_pstate <= rx_nstate ;
163
+ fsm_pstate <= fsm_nstate ;
183
164
end if ;
184
165
end if ;
185
166
end process ;
186
167
187
168
-- NEXT STATE AND OUTPUTS LOGIC
188
- process (rx_pstate , UART_RXD, rx_clk_en, rx_bit_count)
169
+ process (fsm_pstate , UART_RXD, rx_clk_en, rx_bit_count)
189
170
begin
190
- case rx_pstate is
171
+ case fsm_pstate is
191
172
192
173
when idle =>
193
- rx_output_reg_en <= '0' ;
194
- rx_receiving_data <= '0' ;
195
- rx_clk_divider_en <= '0 ' ;
174
+ fsm_stopbit <= '0' ;
175
+ fsm_databits <= '0' ;
176
+ fsm_idle <= '1 ' ;
196
177
197
178
if (UART_RXD = '0' ) then
198
- rx_nstate <= startbit;
179
+ fsm_nstate <= startbit;
199
180
else
200
- rx_nstate <= idle;
181
+ fsm_nstate <= idle;
201
182
end if ;
202
183
203
184
when startbit =>
204
- rx_output_reg_en <= '0' ;
205
- rx_receiving_data <= '0' ;
206
- rx_clk_divider_en <= '1 ' ;
185
+ fsm_stopbit <= '0' ;
186
+ fsm_databits <= '0' ;
187
+ fsm_idle <= '0 ' ;
207
188
208
189
if (rx_clk_en = '1' ) then
209
- rx_nstate <= databits;
190
+ fsm_nstate <= databits;
210
191
else
211
- rx_nstate <= startbit;
192
+ fsm_nstate <= startbit;
212
193
end if ;
213
194
214
195
when databits =>
215
- rx_output_reg_en <= '0' ;
216
- rx_receiving_data <= '1' ;
217
- rx_clk_divider_en <= '1 ' ;
196
+ fsm_stopbit <= '0' ;
197
+ fsm_databits <= '1' ;
198
+ fsm_idle <= '0 ' ;
218
199
219
200
if ((rx_clk_en = '1' ) AND (rx_bit_count = "111" )) then
220
201
if (PARITY_BIT = " none" ) then
221
- rx_nstate <= stopbit;
202
+ fsm_nstate <= stopbit;
222
203
else
223
- rx_nstate <= paritybit;
204
+ fsm_nstate <= paritybit;
224
205
end if ;
225
206
else
226
- rx_nstate <= databits;
207
+ fsm_nstate <= databits;
227
208
end if ;
228
209
229
210
when paritybit =>
230
- rx_output_reg_en <= '0' ;
231
- rx_receiving_data <= '0' ;
232
- rx_clk_divider_en <= '1 ' ;
211
+ fsm_stopbit <= '0' ;
212
+ fsm_databits <= '0' ;
213
+ fsm_idle <= '0 ' ;
233
214
234
215
if (rx_clk_en = '1' ) then
235
- rx_nstate <= stopbit;
216
+ fsm_nstate <= stopbit;
236
217
else
237
- rx_nstate <= paritybit;
218
+ fsm_nstate <= paritybit;
238
219
end if ;
239
220
240
221
when stopbit =>
241
- rx_output_reg_en <= '1' ;
242
- rx_receiving_data <= '0' ;
243
- rx_clk_divider_en <= '1 ' ;
222
+ fsm_stopbit <= '1' ;
223
+ fsm_databits <= '0' ;
224
+ fsm_idle <= '0 ' ;
244
225
245
226
if (rx_clk_en = '1' ) then
246
- rx_nstate <= idle;
227
+ fsm_nstate <= idle;
247
228
else
248
- rx_nstate <= stopbit;
229
+ fsm_nstate <= stopbit;
249
230
end if ;
250
231
251
232
when others =>
252
- rx_output_reg_en <= '0' ;
253
- rx_receiving_data <= '0' ;
254
- rx_clk_divider_en <= '0' ;
255
- rx_nstate <= idle;
233
+ fsm_stopbit <= '0' ;
234
+ fsm_databits <= '0' ;
235
+ fsm_idle <= '0' ;
236
+ fsm_nstate <= idle;
256
237
257
238
end case ;
258
239
end process ;
259
240
260
- end FULL ;
241
+ end architecture ;
0 commit comments