Skip to content

Commit a828832

Browse files
committed
[FEATURE]: Added PARITY_ERROR output to RX module, code refactoring.
1 parent 5141791 commit a828832

File tree

2 files changed

+87
-85
lines changed

2 files changed

+87
-85
lines changed

rtl/comp/uart_rx.vhd

Lines changed: 62 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,36 @@ entity UART_RX is
1616
PARITY_BIT : string := "none" -- type of parity: "none", "even", "odd", "mark", "space"
1717
);
1818
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
2121
-- 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
2424
-- 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)
2829
);
29-
end UART_RX;
30+
end entity;
3031

31-
architecture FULL of UART_RX is
32+
architecture RTL of UART_RX is
3233

3334
signal rx_clk_en : std_logic;
3435
signal rx_ticks : unsigned(3 downto 0);
35-
signal rx_clk_divider_en : std_logic;
3636
signal rx_data : std_logic_vector(7 downto 0);
3737
signal rx_bit_count : unsigned(2 downto 0);
38-
signal rx_receiving_data : std_logic;
3938
signal rx_parity_bit : std_logic;
4039
signal rx_parity_error : std_logic;
4140
signal rx_parity_check_en : std_logic;
42-
signal rx_output_reg_en : std_logic;
41+
signal rx_done : std_logic;
42+
signal fsm_receiving : std_logic;
43+
signal fsm_databits : std_logic;
44+
signal fsm_stopbit : std_logic;
4345

4446
type state is (idle, startbit, databits, paritybit, stopbit);
45-
signal rx_pstate : state;
46-
signal rx_nstate : state;
47+
signal fsm_pstate : state;
48+
signal fsm_nstate : state;
4749

4850
begin
4951

@@ -54,7 +56,7 @@ begin
5456
uart_rx_clk_divider_p : process (CLK)
5557
begin
5658
if (rising_edge(CLK)) then
57-
if (rx_clk_divider_en = '1') then
59+
if (fsm_receiving = '1') then
5860
if (UART_CLK_EN = '1') then
5961
if (rx_ticks = "1111") then
6062
rx_ticks <= (others => '0');
@@ -92,7 +94,7 @@ begin
9294
if (rising_edge(CLK)) then
9395
if (RST = '1') then
9496
rx_bit_count <= (others => '0');
95-
elsif (rx_clk_en = '1' AND rx_receiving_data = '1') then
97+
elsif (rx_clk_en = '1' AND fsm_databits = '1') then
9698
if (rx_bit_count = "111") then
9799
rx_bit_count <= (others => '0');
98100
else
@@ -109,7 +111,7 @@ begin
109111
uart_rx_data_shift_reg_p : process (CLK)
110112
begin
111113
if (rising_edge(CLK)) then
112-
if (rx_clk_en = '1' AND rx_receiving_data = '1') then
114+
if (rx_clk_en = '1' AND fsm_databits = '1') then
113115
rx_data <= UART_RXD & rx_data(7 downto 1);
114116
end if;
115117
end if;
@@ -150,20 +152,19 @@ begin
150152
-- UART RECEIVER OUTPUT REGISTER
151153
-- -------------------------------------------------------------------------
152154

155+
rx_done <= rx_clk_en and fsm_stopbit;
156+
153157
uart_rx_output_reg_p : process (CLK)
154158
begin
155159
if (rising_edge(CLK)) then
156160
if (RST = '1') then
157-
DOUT_VLD <= '0';
158-
FRAME_ERROR <= '0';
161+
DOUT_VLD <= '0';
162+
FRAME_ERROR <= '0';
163+
PARITY_ERROR <= '0';
159164
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;
165+
DOUT_VLD <= rx_done and not rx_parity_error and UART_RXD;
166+
FRAME_ERROR <= rx_done and not UART_RXD;
167+
PARITY_ERROR <= rx_done and rx_parity_error;
167168
end if;
168169
end if;
169170
end process;
@@ -177,84 +178,84 @@ begin
177178
begin
178179
if (rising_edge(CLK)) then
179180
if (RST = '1') then
180-
rx_pstate <= idle;
181+
fsm_pstate <= idle;
181182
else
182-
rx_pstate <= rx_nstate;
183+
fsm_pstate <= fsm_nstate;
183184
end if;
184185
end if;
185186
end process;
186187

187188
-- NEXT STATE AND OUTPUTS LOGIC
188-
process (rx_pstate, UART_RXD, rx_clk_en, rx_bit_count)
189+
process (fsm_pstate, UART_RXD, rx_clk_en, rx_bit_count)
189190
begin
190-
case rx_pstate is
191+
case fsm_pstate is
191192

192193
when idle =>
193-
rx_output_reg_en <= '0';
194-
rx_receiving_data <= '0';
195-
rx_clk_divider_en <= '0';
194+
fsm_stopbit <= '0';
195+
fsm_databits <= '0';
196+
fsm_receiving <= '0';
196197

197198
if (UART_RXD = '0') then
198-
rx_nstate <= startbit;
199+
fsm_nstate <= startbit;
199200
else
200-
rx_nstate <= idle;
201+
fsm_nstate <= idle;
201202
end if;
202203

203204
when startbit =>
204-
rx_output_reg_en <= '0';
205-
rx_receiving_data <= '0';
206-
rx_clk_divider_en <= '1';
205+
fsm_stopbit <= '0';
206+
fsm_databits <= '0';
207+
fsm_receiving <= '1';
207208

208209
if (rx_clk_en = '1') then
209-
rx_nstate <= databits;
210+
fsm_nstate <= databits;
210211
else
211-
rx_nstate <= startbit;
212+
fsm_nstate <= startbit;
212213
end if;
213214

214215
when databits =>
215-
rx_output_reg_en <= '0';
216-
rx_receiving_data <= '1';
217-
rx_clk_divider_en <= '1';
216+
fsm_stopbit <= '0';
217+
fsm_databits <= '1';
218+
fsm_receiving <= '1';
218219

219220
if ((rx_clk_en = '1') AND (rx_bit_count = "111")) then
220221
if (PARITY_BIT = "none") then
221-
rx_nstate <= stopbit;
222+
fsm_nstate <= stopbit;
222223
else
223-
rx_nstate <= paritybit;
224+
fsm_nstate <= paritybit;
224225
end if ;
225226
else
226-
rx_nstate <= databits;
227+
fsm_nstate <= databits;
227228
end if;
228229

229230
when paritybit =>
230-
rx_output_reg_en <= '0';
231-
rx_receiving_data <= '0';
232-
rx_clk_divider_en <= '1';
231+
fsm_stopbit <= '0';
232+
fsm_databits <= '0';
233+
fsm_receiving <= '1';
233234

234235
if (rx_clk_en = '1') then
235-
rx_nstate <= stopbit;
236+
fsm_nstate <= stopbit;
236237
else
237-
rx_nstate <= paritybit;
238+
fsm_nstate <= paritybit;
238239
end if;
239240

240241
when stopbit =>
241-
rx_output_reg_en <= '1';
242-
rx_receiving_data <= '0';
243-
rx_clk_divider_en <= '1';
242+
fsm_stopbit <= '1';
243+
fsm_databits <= '0';
244+
fsm_receiving <= '1';
244245

245246
if (rx_clk_en = '1') then
246-
rx_nstate <= idle;
247+
fsm_nstate <= idle;
247248
else
248-
rx_nstate <= stopbit;
249+
fsm_nstate <= stopbit;
249250
end if;
250251

251252
when others =>
252-
rx_output_reg_en <= '0';
253-
rx_receiving_data <= '0';
254-
rx_clk_divider_en <= '0';
255-
rx_nstate <= idle;
253+
fsm_stopbit <= '0';
254+
fsm_databits <= '0';
255+
fsm_receiving <= '0';
256+
fsm_nstate <= idle;
256257

257258
end case;
258259
end process;
259260

260-
end FULL;
261+
end architecture;

rtl/uart.vhd

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -55,40 +55,40 @@ entity UART is
5555
);
5656
end entity;
5757

58-
architecture FULL of UART is
58+
architecture RTL of UART is
5959

60-
constant DIVIDER_VALUE : integer := CLK_FREQ/(16*BAUD_RATE);
61-
constant CLK_CNT_WIDTH : integer := integer(ceil(log2(real(DIVIDER_VALUE))));
62-
constant CLK_CNT_MAX : unsigned := to_unsigned(DIVIDER_VALUE-1, CLK_CNT_WIDTH);
60+
constant DIVIDER_VALUE : integer := CLK_FREQ/(16*BAUD_RATE);
61+
constant CLK_CNT_WIDTH : integer := integer(ceil(log2(real(DIVIDER_VALUE))));
62+
constant CLK_CNT_MAX : unsigned := to_unsigned(DIVIDER_VALUE-1, CLK_CNT_WIDTH);
6363

64-
signal uart_clk_cnt : unsigned(CLK_CNT_WIDTH-1 downto 0);
65-
signal uart_clk_en : std_logic;
66-
signal uart_rxd_meta : std_logic;
67-
signal uart_rxd_synced : std_logic;
68-
signal uart_rxd_debounced : std_logic;
64+
signal oversampling_clk_cnt : unsigned(CLK_CNT_WIDTH-1 downto 0);
65+
signal oversampling_clk_en : std_logic;
66+
signal uart_rxd_meta : std_logic;
67+
signal uart_rxd_synced : std_logic;
68+
signal uart_rxd_debounced : std_logic;
6969

7070
begin
7171

7272
-- -------------------------------------------------------------------------
73-
-- UART CLOCK COUNTER AND CLOCK ENABLE FLAG
73+
-- UART OVERSAMPLING (16X) CLOCK COUNTER AND CLOCK ENABLE FLAG
7474
-- -------------------------------------------------------------------------
7575

76-
uart_clk_cnt_p : process (CLK)
76+
oversampling_clk_cnt_p : process (CLK)
7777
begin
7878
if (rising_edge(CLK)) then
7979
if (RST = '1') then
80-
uart_clk_cnt <= (others => '0');
80+
oversampling_clk_cnt <= (others => '0');
8181
else
82-
if (uart_clk_en = '1') then
83-
uart_clk_cnt <= (others => '0');
82+
if (oversampling_clk_en = '1') then
83+
oversampling_clk_cnt <= (others => '0');
8484
else
85-
uart_clk_cnt <= uart_clk_cnt + 1;
85+
oversampling_clk_cnt <= oversampling_clk_cnt + 1;
8686
end if;
8787
end if;
8888
end if;
8989
end process;
9090

91-
uart_clk_en <= '1' when (uart_clk_cnt = CLK_CNT_MAX) else '0';
91+
oversampling_clk_en <= '1' when (oversampling_clk_cnt = CLK_CNT_MAX) else '0';
9292

9393
-- -------------------------------------------------------------------------
9494
-- UART RXD CROSS DOMAIN CROSSING
@@ -131,15 +131,16 @@ begin
131131
PARITY_BIT => PARITY_BIT
132132
)
133133
port map (
134-
CLK => CLK,
135-
RST => RST,
134+
CLK => CLK,
135+
RST => RST,
136136
-- UART INTERFACE
137-
UART_CLK_EN => uart_clk_en,
138-
UART_RXD => uart_rxd_debounced,
137+
UART_CLK_EN => oversampling_clk_en,
138+
UART_RXD => uart_rxd_debounced,
139139
-- USER DATA OUTPUT INTERFACE
140-
DOUT => DOUT,
141-
DOUT_VLD => DOUT_VLD,
142-
FRAME_ERROR => FRAME_ERROR
140+
DOUT => DOUT,
141+
DOUT_VLD => DOUT_VLD,
142+
FRAME_ERROR => FRAME_ERROR,
143+
PARITY_ERROR => open
143144
);
144145

145146
-- -------------------------------------------------------------------------
@@ -154,7 +155,7 @@ begin
154155
CLK => CLK,
155156
RST => RST,
156157
-- UART INTERFACE
157-
UART_CLK_EN => uart_clk_en,
158+
UART_CLK_EN => oversampling_clk_en,
158159
UART_TXD => UART_TXD,
159160
-- USER DATA INPUT INTERFACE
160161
DIN => DIN,

0 commit comments

Comments
 (0)