OpenCores
URL https://opencores.org/ocsvn/hive/hive/trunk

Subversion Repositories hive

[/] [hive/] [trunk/] [v04.05/] [uart_rx.v] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module: uart_rx.v
5
 
6
Function:
7
- Forms the RX side of a DATA_W,n,1 RS232 UART.
8
 
9
Instantiates:
10
- functions.h
11
 
12
Notes:
13
- Rising edge of baud_clk_i is employed.
14
- baud_clk_i / BAUD_OSR = uart baud (bit) rate.
15
- baud_clk_i must be synchronous to clk_i.
16
- Serial data is non-inverted; quiescent serial state is high (assumes
17
  external inverting buffer).
18
- Bits are in this order (@ serial port of this module, line s/b inverted):
19
  - 1 start bit (low),
20
  - DATA_W data bits (LSB first, MSB last),
21
  - 1 or more stop bits (high).
22
- The parallel data interface may be connected to a FIFO or similar.
23
- Start & stop errors, if presented, are simultaneous with the write pulse so
24
  external logic can decide whether or not to accept the data.
25
- Start & stop errors are an indication of noise on the line / incorrect baud
26
  rate.
27
- Bad buffer error happens when external data store doesn't take RX data
28
  before another byte arrives.
29
- Parameterized data width.
30
- Parameterized oversampling rate.
31
 
32
--------------------------------------------------------------------------------
33
*/
34
 
35
module uart_rx
36
        #(
37
        parameter               integer                         DATA_W                          = 8,            // parallel data width (bits)
38
        parameter               integer                         BAUD_OSR                        = 16            // BAUD oversample rate (3 or larger)
39
        )
40
        (
41
        // clocks & resets
42
        input           wire                                                    clk_i,                                                  // clock
43
        input           wire                                                    rst_i,                                                  // async. reset, active hi
44
        // timing interface
45
        input           wire                                                    baud_clk_i,                                             // baud clock
46
        // parallel interface   
47
        output  reg     [DATA_W-1:0]             rx_data_o,                                              // data
48
        output  reg                                                     rx_rdy_o,                                               // ready with data, active hi
49
        input           wire                                                    rx_rd_i,                                                        // data read, active hi
50
        // serial interface
51
        input           wire                                                    rx_i,                                                           // serial data
52
        // debug
53
        output  reg                                                     rx_bad_start_o,                         // bad start bit, active hi
54
        output  reg                                                     rx_bad_stop_o,                                  // bad stop bit, active hi
55
        output  reg                                                     rx_bad_buffer_o                         // bad buffering, active hi
56
        );
57
 
58
 
59
        /*
60
        ----------------------
61
        -- internal signals --
62
        ----------------------
63
        */
64
        `include "functions.h"  // for clog2()
65
        //
66
        localparam              integer                         BIT_PHASE_W                     = clog2( BAUD_OSR );
67
        localparam              integer                         BIT_PHASE_MID           = BAUD_OSR/2;
68
        localparam              integer                         BIT_PHASE_MAX           = BAUD_OSR-1;
69
        localparam              integer                         BIT_COUNT_MAX           = DATA_W+1;
70
        localparam              integer                         BIT_COUNT_W             = clog2( BIT_COUNT_MAX );
71
        //
72
        reg                             [1:0]                                    rx_sr;
73
        reg                                                                             baud_clk_reg;
74
        wire                                                                            baud_flg;
75
        //
76
        reg                             [BIT_PHASE_W-1:0]        bit_phase;
77
        wire                                                                            bit_sample_flg, bit_done_flg;
78
        //
79
        reg                             [BIT_COUNT_W-1:0]        bit_count;
80
        wire                                                                            word_done_flg;
81
        //
82
        reg                             [DATA_W+1:0]             rx_data_sr;
83
        //
84
        localparam      integer                                 STATE_W = 2;    // state width (bits)
85
        reg                             [STATE_W-1:0]            state_sel, state;
86
        localparam              [STATE_W-1:0]
87
                st_idle = 0,
88
                st_data = 1,
89
                st_load = 2,
90
                st_wait = 3;
91
 
92
 
93
        /*
94
        ================
95
        == code start ==
96
        ================
97
        */
98
 
99
 
100
        /*
101
        -----------
102
        -- input --
103
        -----------
104
        */
105
 
106
        // register rx_i twice to resync
107
        always @ ( posedge clk_i or posedge rst_i ) begin
108
                if ( rst_i ) begin
109
                        rx_sr <= 2'b11;  // note: preset!
110
                end else begin
111
                        rx_sr <= { rx_sr[0], rx_i };
112
                end
113
        end
114
 
115
        // register to detect edges
116
        always @ ( posedge clk_i or posedge rst_i ) begin
117
                if ( rst_i ) begin
118
                        baud_clk_reg <= 'b0;
119
                end else begin
120
                        baud_clk_reg <= baud_clk_i;
121
                end
122
        end
123
 
124
        // decode rising edge
125
        assign baud_flg = ( ~baud_clk_reg & baud_clk_i );
126
 
127
 
128
        /*
129
        --------------
130
        -- counters --
131
        --------------
132
        */
133
 
134
        // form the bit_phase & bit_count up-counters
135
        always @ ( posedge clk_i or posedge rst_i ) begin
136
                if ( rst_i ) begin
137
                        bit_phase <= 'b0;
138
                        bit_count <= 'b0;
139
                end else begin
140
                        if ( state_sel != st_data ) begin
141
                                bit_phase <= 'b0;
142
                                bit_count <= 'b0;
143
                        end else if ( bit_done_flg ) begin
144
                                bit_phase <= 'b0;
145
                                bit_count <= bit_count + 1'b1;
146
                        end else if ( baud_flg ) begin
147
                                bit_phase <= bit_phase + 1'b1;
148
                        end
149
                end
150
        end
151
 
152
        // decode flags
153
        assign bit_sample_flg = ( ( bit_phase == BIT_PHASE_MID[BIT_PHASE_W-1:0] ) & baud_flg );
154
        assign bit_done_flg   = ( ( bit_phase == BIT_PHASE_MAX[BIT_PHASE_W-1:0] ) & baud_flg );
155
        assign word_done_flg  = ( ( bit_count == BIT_COUNT_MAX[BIT_COUNT_W-1:0] ) & bit_sample_flg );
156
 
157
 
158
        /*
159
        -------------------
160
        -- state machine --
161
        -------------------
162
        */
163
 
164
        // select next state
165
        always @ ( * ) begin
166
                state_sel <= state;  // default: stay in current state
167
                case ( state )
168
                        st_idle : begin  // idle
169
                                if ( ~rx_sr[1] ) begin
170
                                        state_sel <= st_data;  // proceed
171
                                end
172
                        end
173
                        st_data : begin  // data bits
174
                                if ( word_done_flg ) begin
175
                                        state_sel <= st_load;  // load
176
                                end
177
                        end
178
                        st_load, st_wait : begin
179
                                if ( rx_sr[1] ) begin
180
                                        state_sel <= st_idle;  // done
181
                                end else begin
182
                                        state_sel <= st_wait;  // bad stop bit
183
                                end
184
                        end
185
                        default : begin  // for fault tolerance
186
                                state_sel <= st_idle;
187
                        end
188
                endcase
189
        end
190
 
191
        // register state
192
        always @ ( posedge clk_i or posedge rst_i ) begin
193
                if ( rst_i ) begin
194
                        state <= st_idle;
195
                end else begin
196
                        state <= state_sel;
197
                end
198
        end
199
 
200
 
201
        /*
202
        ---------------------
203
        -- data conversion --
204
        ---------------------
205
        */
206
 
207
        // serial => parallel conversion
208
        always @ ( posedge clk_i or posedge rst_i ) begin
209
                if ( rst_i ) begin
210
                        rx_data_sr <= 'b0;
211
                end else begin
212
                        if ( bit_sample_flg ) begin
213
                                rx_data_sr <= { rx_sr[1], rx_data_sr[DATA_W+1:1] };
214
                        end
215
                end
216
        end
217
 
218
 
219
        /*
220
        ------------
221
        -- output --
222
        ------------
223
        */
224
 
225
        // register outputs
226
        always @ ( posedge clk_i or posedge rst_i ) begin
227
                if ( rst_i ) begin
228
                        rx_data_o <= 'b0;
229
                        rx_rdy_o <= 'b0;
230
                        rx_bad_start_o <= 'b0;
231
                        rx_bad_stop_o <= 'b0;
232
                        rx_bad_buffer_o <= 'b0;
233
                end else begin
234
                        if ( state == st_load ) begin
235
                                rx_data_o <= rx_data_sr[DATA_W:1];
236
                                rx_rdy_o <= 'b1;
237
                                rx_bad_start_o <= rx_data_sr[0];
238
                                rx_bad_stop_o <= ~rx_data_sr[DATA_W+1];
239
                                rx_bad_buffer_o <= ( ~rx_rd_i & rx_rdy_o );
240
                        end else begin
241
                                rx_rdy_o <= ~rx_rd_i & rx_rdy_o;
242
                        end
243
                end
244
        end
245
 
246
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.