11module uart_rx # (
2+ parameter Parity = 1'b0 ,
3+ parameter StopBit = 1'b1 ,
4+ parameter OverSample = 8
25 // params
36)(
47 // i/o
@@ -11,19 +14,28 @@ module uart_rx #(
1114 /* Sample Timing */
1215 input logic i_strobe,
1316 input logic i_half,
14- output logic o_prescaler_en
17+ output logic o_prescaler_en,
18+ output logic o_parity_error,
19+ output logic o_stop_bit_error
1520);
1621
22+ localparam counter_width = $clog2 (OverSample);
23+
1724 typedef enum logic [2 : 0 ] {
18- RESET = 3'b000 ,
19- WAIT = 2'b001 ,
20- LOAD = 3'b010 ,
21- STOP = 3'b011 ,
22- READY = 3'b100
25+ RESET = 3'b000 ,
26+ WAIT = 2'b001 ,
27+ LOAD = 3'b010 ,
28+ PARITY = 3'b011 ,
29+ STOP = 3'b100 ,
30+ READY = 3'b101
2331 } states_t ;
2432
2533 states_t curr_state, next_state;
26- logic [2 : 0 ] counter;
34+
35+ logic [counter_width: 0 ] counter;
36+ logic counter_rst_n;
37+
38+ logic parity_bit;
2739
2840 // State controller
2941 always_ff @ (posedge i_clk) begin
@@ -33,45 +45,59 @@ module uart_rx #(
3345
3446 // Next State Logic Controller
3547 always_comb begin
36- unique case (state )
48+ unique case (curr_state )
3749 RESET :
3850 next_state = WAIT ;
3951 WAIT :
40- if (serial_in == '0 )
52+ if (i_rx == '0 )
4153 next_state = LOAD ;
4254 else
4355 next_state = WAIT ;
4456 LOAD :
4557 if (counter == '0 )
46- next_state = STOP ;
58+ generate
59+ case (Parity)
60+ 0 : next_state = STOP ;
61+ 1 : next_state = PARITY ;
62+ endcase
63+ endgenerate
4764 else
4865 next_state = LOAD ;
66+ PARITY :
67+ if (i_half)
68+ next_state = STOP ;
69+ else
70+ next_state = PARITY ;
4971 STOP :
50- // wait for stop bit
72+ if (i_half && i_rx) // halfway strobe AND rx == 1 (stop bit)
73+ next_state = READY ;
74+ else
75+ next_state = STOP ;
5176 READY :
5277 next_state = WAIT ;
5378 endcase
5479 end
5580
5681 always_comb begin
57- unique case (state)
58- RESET :
59- WAIT :
60- LOAD :
61- STOP :
62- READY :
82+ unique case (curr_state)
83+ RESET : { o_prescaler_en, counter_rst_n} = 2'b00 ;
84+ WAIT : { o_prescaler_en, counter_rst_n} = 2'b00 ;
85+ LOAD : { o_prescaler_en, counter_rst_n} = 2'b11 ;
86+ PARITY : { o_prescaler_en, counter_rst_n} = 2'b10 ;
87+ STOP : { o_prescaler_en, counter_rst_n} = 2'b10 ;
88+ READY : { o_prescaler_en, counter_rst_n} = 2'b00 ;
6389 endcase
6490 end
6591
6692 always_ff @ (posedge i_clk)
6793 if (! i_rst_n)
6894 o_rx_data <= 0 ;
6995 else if (i_half)
70- o_rx_data <= { rx , o_rx_data[7 : 1 ]} ;
96+ o_rx_data <= { i_rx , o_rx_data[7 : 1 ]} ;
7197
7298 always_ff @ (posedge i_clk)
73- if (! i_rst_n )
74- counter <= '0 ;
99+ if (! counter_rst_n )
100+ counter <= '1 ;
75101 else if (i_half)
76102 counter <= counter - 3'b1 ;
77103
0 commit comments