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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [rtl/] [uart16550/] [rtl/] [verilog-backup/] [uart_receiver.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  uart_receiver.v                                             ////
4
////                                                              ////
5
////                                                              ////
6
////  This file is part of the "UART 16550 compatible" project    ////
7
////  http://www.opencores.org/cores/uart16550/                   ////
8
////                                                              ////
9
////  Documentation related to this project:                      ////
10
////  - http://www.opencores.org/cores/uart16550/                 ////
11
////                                                              ////
12
////  Projects compatibility:                                     ////
13
////  - WISHBONE                                                  ////
14
////  RS232 Protocol                                              ////
15
////  16550D uart (mostly supported)                              ////
16
////                                                              ////
17
////  Overview (main Features):                                   ////
18
////  UART core receiver logic                                    ////
19
////                                                              ////
20
////  Known problems (limits):                                    ////
21
////  None known                                                  ////
22
////                                                              ////
23
////  To Do:                                                      ////
24
////  Thourough testing.                                          ////
25
////                                                              ////
26
////  Author(s):                                                  ////
27
////      - gorban@opencores.org                                  ////
28
////      - Jacob Gorban                                          ////
29
////                                                              ////
30
////  Created:        2001/05/12                                  ////
31
////  Last Updated:   2001/05/17                                  ////
32
////                  (See log for the revision history)          ////
33
////                                                              ////
34
////                                                              ////
35
//////////////////////////////////////////////////////////////////////
36
////                                                              ////
37
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org        ////
38
////                                                              ////
39
//// This source file may be used and distributed without         ////
40
//// restriction provided that this copyright statement is not    ////
41
//// removed from the file and that any derivative work contains  ////
42
//// the original copyright notice and the associated disclaimer. ////
43
////                                                              ////
44
//// This source file is free software; you can redistribute it   ////
45
//// and/or modify it under the terms of the GNU Lesser General   ////
46
//// Public License as published by the Free Software Foundation; ////
47
//// either version 2.1 of the License, or (at your option) any   ////
48
//// later version.                                               ////
49
////                                                              ////
50
//// This source is distributed in the hope that it will be       ////
51
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
52
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
53
//// PURPOSE.  See the GNU Lesser General Public License for more ////
54
//// details.                                                     ////
55
////                                                              ////
56
//// You should have received a copy of the GNU Lesser General    ////
57
//// Public License along with this source; if not, download it   ////
58
//// from http://www.opencores.org/lgpl.shtml                     ////
59
////                                                              ////
60
//////////////////////////////////////////////////////////////////////
61
//
62
// CVS Revision History
63
//
64
// $Log: uart_receiver.v,v $
65
// Revision 1.6  2001/06/23 11:21:48  gorban
66
// DL made 16-bit long. Fixed transmission/reception bugs.
67
//
68
// Revision 1.5  2001/06/02 14:28:14  gorban
69
// Fixed receiver and transmitter. Major bug fixed.
70
//
71
// Revision 1.4  2001/05/31 20:08:01  gorban
72
// FIFO changes and other corrections.
73
//
74
// Revision 1.3  2001/05/27 17:37:49  gorban
75
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
76
//
77
// Revision 1.2  2001/05/21 19:12:02  gorban
78
// Corrected some Linter messages.
79
//
80
// Revision 1.1  2001/05/17 18:34:18  gorban
81
// First 'stable' release. Should be sythesizable now. Also added new header.
82
//
83
// Revision 1.0  2001-05-17 21:27:11+02  jacob
84
// Initial revision
85
//
86
//
87
 
88
`include "timescale.v"
89
`include "uart_defines.v"
90
 
91
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable, rda_int,
92
        counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, rx_lsr_mask);
93
 
94
input                           clk;
95
input                           wb_rst_i;
96
input   [7:0]                    lcr;
97
input                           rf_pop;
98
input                           srx_pad_i;
99
input                           enable;
100
input                           rda_int;
101
input                           rx_reset;
102
input       rx_lsr_mask;
103
 
104
output  [5:0]                    counter_t;
105
output  [3:0]                    counter_b;
106
output  [`UART_FIFO_COUNTER_W-1:0]       rf_count;
107
output  [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
108
output                          rf_overrun;
109
output                          rf_error_bit;
110
 
111
reg     [3:0]    rstate;
112
reg     [3:0]    rcounter16;
113
reg     [2:0]    rbit_counter;
114
reg     [7:0]    rshift;                 // receiver shift register
115
reg             rparity;                // received parity
116
reg             rparity_error;
117
reg             rframing_error;         // framing error flag
118
reg             rbit_in;
119
reg             rparity_xor;
120
 
121
// RX FIFO signals
122
reg     [`UART_FIFO_REC_WIDTH-1:0]       rf_data_in;
123
wire    [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
124
reg                             rf_push;
125
wire                            rf_pop;
126
wire                            rf_underrun;
127
wire                            rf_overrun;
128
wire    [`UART_FIFO_COUNTER_W-1:0]       rf_count;
129
wire                            rf_error_bit; // an error (parity or framing) is inside the fifo
130
 
131
// RX FIFO instance
132
uart_fifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
133
        .clk(           clk             ),
134
        .wb_rst_i(      wb_rst_i        ),
135
        .data_in(       rf_data_in      ),
136
        .data_out(      rf_data_out     ),
137
        .push(          rf_push         ),
138
        .pop(           rf_pop          ),
139
        .underrun(      rf_underrun     ),
140
        .overrun(       rf_overrun      ),
141
        .count(         rf_count        ),
142
        .error_bit(     rf_error_bit    ),
143
        .fifo_reset(    rx_reset        ),
144
        .reset_status(rx_lsr_mask)
145
);
146
 
147
wire            rcounter16_eq_7 = (rcounter16 == 4'd7);
148
wire            rcounter16_eq_0 = (rcounter16 == 4'd0);
149
wire            rcounter16_eq_1 = (rcounter16 == 4'd1);
150
 
151
wire [3:0] rcounter16_minus_1 = rcounter16 - 4'd1;
152
 
153
parameter  sr_idle                                      = 4'd0;
154
parameter  sr_rec_start                         = 4'd1;
155
parameter  sr_rec_bit                           = 4'd2;
156
parameter  sr_rec_parity                        = 4'd3;
157
parameter  sr_rec_stop                          = 4'd4;
158
parameter  sr_check_parity              = 4'd5;
159
parameter  sr_rec_prepare                       = 4'd6;
160
parameter  sr_end_bit                           = 4'd7;
161
parameter  sr_ca_lc_parity            = 4'd8;
162
parameter  sr_wait1                                     = 4'd9;
163
parameter  sr_push                                      = 4'd10;
164
parameter  sr_last                                      = 4'd11;
165
 
166
always @(posedge clk or posedge wb_rst_i)
167
begin
168
  if (wb_rst_i)
169
  begin
170
     rstate                     <= #1 sr_idle;
171
          rbit_in                               <= #1 1'b0;
172
          rcounter16                    <= #1 0;
173
          rbit_counter          <= #1 0;
174
          rparity_xor           <= #1 1'b0;
175
          rframing_error        <= #1 1'b0;
176
          rparity_error                 <= #1 1'b0;
177
          rparity                               <= #1 1'b0;
178
          rshift                                <= #1 0;
179
          rf_push                               <= #1 1'b0;
180
          rf_data_in                    <= #1 0;
181
  end
182
  else
183
  if (enable)
184
  begin
185
        case (rstate)
186
        sr_idle :       if (srx_pad_i==1'b0)   // detected a pulse (start bit?)
187
                        begin
188
                                rstate <= #1 sr_rec_start;
189
                                rcounter16 <= #1 4'b1110;
190
                        end
191
                        else
192
                                rstate <= #1 sr_idle;
193
        sr_rec_start :  begin
194
                                if (rcounter16_eq_7)    // check the pulse
195
                                        if (srx_pad_i==1'b1)   // no start bit
196
                                                rstate <= #1 sr_idle;
197
                                        else            // start bit detected
198
                                                rstate <= #1 sr_rec_prepare;
199
                                rcounter16 <= #1 rcounter16_minus_1;
200
                        end
201
        sr_rec_prepare:begin
202
                                case (lcr[/*`UART_LC_BITS*/1:0])  // number of bits in a word
203
                                2'b00 : rbit_counter <= #1 3'b100;
204
                                2'b01 : rbit_counter <= #1 3'b101;
205
                                2'b10 : rbit_counter <= #1 3'b110;
206
                                2'b11 : rbit_counter <= #1 3'b111;
207
                                endcase
208
                                if (rcounter16_eq_0)
209
                                begin
210
                                        rstate          <= #1 sr_rec_bit;
211
                                        rcounter16      <= #1 4'b1110;
212
                                        rshift          <= #1 0;
213
                                end
214
                                else
215
                                        rstate <= #1 sr_rec_prepare;
216
                                rcounter16 <= #1 rcounter16_minus_1;
217
                        end
218
        sr_rec_bit :    begin
219
                                if (rcounter16_eq_0)
220
                                        rstate <= #1 sr_end_bit;
221
                                if (rcounter16_eq_7) // read the bit
222
                                        case (lcr[/*`UART_LC_BITS*/1:0])  // number of bits in a word
223
                                        2'b00 : rshift[4:0]  <= #1 {srx_pad_i, rshift[4:1]};
224
                                        2'b01 : rshift[5:0]  <= #1 {srx_pad_i, rshift[5:1]};
225
                                        2'b10 : rshift[6:0]  <= #1 {srx_pad_i, rshift[6:1]};
226
                                        2'b11 : rshift[7:0]  <= #1 {srx_pad_i, rshift[7:1]};
227
                                        endcase
228
                                rcounter16 <= #1 rcounter16_minus_1;
229
                        end
230
        sr_end_bit :   begin
231
                                if (rbit_counter==3'b0) // no more bits in word
232
                                        if (lcr[`UART_LC_PE]) // choose state based on parity
233
                                                rstate <= #1 sr_rec_parity;
234
                                        else
235
                                        begin
236
                                                rstate <= #1 sr_rec_stop;
237
                                                rparity_error <= #1 1'b0;  // no parity - no error :)
238
                                        end
239
                                else            // else we have more bits to read
240
                                begin
241
                                        rstate <= #1 sr_rec_bit;
242
                                        rbit_counter <= #1 rbit_counter - 3'b1;
243
                                end
244
                                rcounter16 <= #1 4'b1110;
245
                        end
246
        sr_rec_parity: begin
247
                                if (rcounter16_eq_7)    // read the parity
248
                                begin
249
                                        rparity <= #1 srx_pad_i;
250
                                        rstate <= #1 sr_ca_lc_parity;
251
                                end
252
                                rcounter16 <= #1 rcounter16_minus_1;
253
                        end
254
        sr_ca_lc_parity : begin    // rcounter equals 6
255
                                rcounter16  <= #1 rcounter16_minus_1;
256
                                rparity_xor <= #1 ^{rshift,rparity}; // calculate parity on all incoming data
257
                                rstate      <= #1 sr_check_parity;
258
                          end
259
        sr_check_parity: begin    // rcounter equals 5
260
                                case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
261
//                              2'b00: rparity_error <= #1 ~rparity_xor;  // no error if parity 1
262
//                              2'b01: rparity_error <= #1 ~rparity;      // parity should sticked to 1
263
//                              2'b10: rparity_error <= #1 rparity_xor;   // error if parity is odd
264
//                              2'b11: rparity_error <= #1 rparity;       // parity should be sticked to 0
265
                                2'b00: rparity_error <= #1 rparity_xor;  // no error if parity 1
266
                                2'b01: rparity_error <= #1 1'b1;      // parity should sticked to 1
267
                                2'b10: rparity_error <= #1 ~rparity_xor;   // error if parity is odd
268
                                2'b11: rparity_error <= #1 1'b0;          // parity should be sticked to 0
269
                                endcase
270
                                rcounter16 <= #1 rcounter16_minus_1;
271
                                rstate <= #1 sr_wait1;
272
                          end
273
        sr_wait1 :      if (rcounter16_eq_0)
274
                        begin
275
                                rstate <= #1 sr_rec_stop;
276
                                rcounter16 <= #1 4'b1110;
277
                        end
278
                        else
279
                                rcounter16 <= #1 rcounter16_minus_1;
280
        sr_rec_stop :   begin
281
                                if (rcounter16_eq_7)    // read the parity
282
                                begin
283
                                        rframing_error <= #1 !srx_pad_i; // no framing error if input is 1 (stop bit)
284
                                        rf_data_in <= #1 {rshift, rparity_error, rframing_error};
285
                                        rstate <= #1 sr_push;
286
                                end
287
                                rcounter16 <= #1 rcounter16_minus_1;
288
                        end
289
        sr_push :       begin
290
///////////////////////////////////////
291
//                              $display($time, ": received: %b", rf_data_in);
292
                                rf_push    <= #1 1'b1;
293
                                rstate     <= #1 sr_last;
294
                        end
295
        sr_last :       begin
296
                                if (rcounter16_eq_1)
297
                                        rstate <= #1 sr_idle;
298
                                rcounter16 <= #1 rcounter16_minus_1;
299
                                rf_push    <= #1 1'b0;
300
                        end
301
        default : rstate <= #1 sr_idle;
302
        endcase
303
  end  // if (enable)
304
end // always of receiver
305
 
306
//
307
// Break condition detection.
308
// Works in conjuction with the receiver state machine
309
reg     [3:0]    counter_b;      // counts the 1 (idle) signals
310
 
311
always @(posedge clk or posedge wb_rst_i)
312
begin
313
        if (wb_rst_i)
314
                counter_b <= #1 4'd11;
315
        else
316
        if (enable)  // only work on enable times
317
                if (!srx_pad_i)                                                       // Ta vrstica je bila spremenjena igor !!!
318
                        counter_b <= #1 4'd11; // maximum character time length - 1
319
                else
320
                        if (counter_b != 4'b0)            // break reached
321
                                counter_b <= #1 counter_b - 4'd1;  // decrement break counter
322
end // always of break condition detection
323
 
324
///
325
/// Timeout condition detection
326
reg     [5:0]    counter_t;      // counts the timeout condition clocks
327
 
328
always @(posedge clk or posedge wb_rst_i)
329
begin
330
        if (wb_rst_i)
331
                counter_t <= #1 6'd44;
332
        else
333
        if (enable)
334
                if(rf_push || rf_pop || rda_int) // counter is reset when RX FIFO is accessed or above trigger level
335
                        counter_t <= #1 6'd44;
336
                else
337
                        if (counter_t != 6'b0)  // we don't want to underflow
338
                                counter_t <= #1 counter_t - 6'd1;
339
end
340
 
341
endmodule

powered by: WebSVN 2.1.0

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