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

Subversion Repositories uart16550

[/] [uart16550/] [trunk/] [rtl/] [verilog/] [uart_receiver.v] - Blame information for rev 47

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

Line No. Rev Author Line
1 27 mohor
//////////////////////////////////////////////////////////////////////
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 29 mohor
////      - Igor Mohor (igorm@opencores.org)                      ////
30 27 mohor
////                                                              ////
31
////  Created:        2001/05/12                                  ////
32
////  Last Updated:   2001/05/17                                  ////
33
////                  (See log for the revision history)          ////
34
////                                                              ////
35
////                                                              ////
36
//////////////////////////////////////////////////////////////////////
37
////                                                              ////
38 29 mohor
//// Copyright (C) 2000, 2001 Authors                             ////
39 27 mohor
////                                                              ////
40
//// This source file may be used and distributed without         ////
41
//// restriction provided that this copyright statement is not    ////
42
//// removed from the file and that any derivative work contains  ////
43
//// the original copyright notice and the associated disclaimer. ////
44
////                                                              ////
45
//// This source file is free software; you can redistribute it   ////
46
//// and/or modify it under the terms of the GNU Lesser General   ////
47
//// Public License as published by the Free Software Foundation; ////
48
//// either version 2.1 of the License, or (at your option) any   ////
49
//// later version.                                               ////
50
////                                                              ////
51
//// This source is distributed in the hope that it will be       ////
52
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
53
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
54
//// PURPOSE.  See the GNU Lesser General Public License for more ////
55
//// details.                                                     ////
56
////                                                              ////
57
//// You should have received a copy of the GNU Lesser General    ////
58
//// Public License along with this source; if not, download it   ////
59
//// from http://www.opencores.org/lgpl.shtml                     ////
60
////                                                              ////
61
//////////////////////////////////////////////////////////////////////
62
//
63
// CVS Revision History
64
//
65
// $Log: not supported by cvs2svn $
66 47 gorban
// Revision 1.16  2001/11/27 22:17:09  gorban
67
// Fixed bug that prevented synthesis in uart_receiver.v
68
//
69 46 gorban
// Revision 1.15  2001/11/26 21:38:54  gorban
70
// Lots of fixes:
71
// Break condition wasn't handled correctly at all.
72
// LSR bits could lose their values.
73
// LSR value after reset was wrong.
74
// Timing of THRE interrupt signal corrected.
75
// LSR bit 0 timing corrected.
76
//
77 45 gorban
// Revision 1.14  2001/11/10 12:43:21  gorban
78
// Synthesis bugs fixed. Some other minor changes
79
//
80 40 gorban
// Revision 1.13  2001/11/08 14:54:23  mohor
81
// Comments in Slovene language deleted, few small fixes for better work of
82
// old tools. IRQs need to be fix.
83
//
84 39 mohor
// Revision 1.12  2001/11/07 17:51:52  gorban
85
// Heavily rewritten interrupt and LSR subsystems.
86
// Many bugs hopefully squashed.
87
//
88 37 gorban
// Revision 1.11  2001/10/31 15:19:22  gorban
89
// Fixes to break and timeout conditions
90
//
91 35 gorban
// Revision 1.10  2001/10/20 09:58:40  gorban
92
// Small synopsis fixes
93
//
94 33 gorban
// Revision 1.9  2001/08/24 21:01:12  mohor
95
// Things connected to parity changed.
96
// Clock devider changed.
97
//
98 29 mohor
// Revision 1.8  2001/08/23 16:05:05  mohor
99
// Stop bit bug fixed.
100
// Parity bug fixed.
101
// WISHBONE read cycle bug fixed,
102
// OE indicator (Overrun Error) bug fixed.
103
// PE indicator (Parity Error) bug fixed.
104
// Register read bug fixed.
105
//
106 27 mohor
// Revision 1.6  2001/06/23 11:21:48  gorban
107
// DL made 16-bit long. Fixed transmission/reception bugs.
108
//
109
// Revision 1.5  2001/06/02 14:28:14  gorban
110
// Fixed receiver and transmitter. Major bug fixed.
111
//
112
// Revision 1.4  2001/05/31 20:08:01  gorban
113
// FIFO changes and other corrections.
114
//
115
// Revision 1.3  2001/05/27 17:37:49  gorban
116
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
117
//
118
// Revision 1.2  2001/05/21 19:12:02  gorban
119
// Corrected some Linter messages.
120
//
121
// Revision 1.1  2001/05/17 18:34:18  gorban
122
// First 'stable' release. Should be sythesizable now. Also added new header.
123
//
124
// Revision 1.0  2001-05-17 21:27:11+02  jacob
125
// Initial revision
126
//
127
//
128
 
129 33 gorban
// synopsys translate_off
130 27 mohor
`include "timescale.v"
131 33 gorban
// synopsys translate_on
132
 
133 27 mohor
`include "uart_defines.v"
134
 
135
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable, rda_int,
136 45 gorban
        counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask);
137 27 mohor
 
138
input                           clk;
139
input                           wb_rst_i;
140 39 mohor
input   [7:0]    lcr;
141 27 mohor
input                           rf_pop;
142
input                           srx_pad_i;
143
input                           enable;
144
input                           rda_int;
145
input                           rx_reset;
146 37 gorban
input       lsr_mask;
147 27 mohor
 
148 35 gorban
output  [9:0]                    counter_t;
149 27 mohor
output  [`UART_FIFO_COUNTER_W-1:0]       rf_count;
150
output  [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
151
output                          rf_overrun;
152
output                          rf_error_bit;
153
 
154
reg     [3:0]    rstate;
155
reg     [3:0]    rcounter16;
156
reg     [2:0]    rbit_counter;
157
reg     [7:0]    rshift;                 // receiver shift register
158
reg             rparity;                // received parity
159
reg             rparity_error;
160
reg             rframing_error;         // framing error flag
161
reg             rbit_in;
162
reg             rparity_xor;
163 45 gorban
reg     [7:0]    counter_b;      // counts the 0 (low) signals
164 27 mohor
 
165
// RX FIFO signals
166
reg     [`UART_FIFO_REC_WIDTH-1:0]       rf_data_in;
167
wire    [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
168
reg                             rf_push;
169
wire                            rf_pop;
170
wire                            rf_underrun;
171
wire                            rf_overrun;
172
wire    [`UART_FIFO_COUNTER_W-1:0]       rf_count;
173
wire                            rf_error_bit; // an error (parity or framing) is inside the fifo
174 45 gorban
wire                            break_error = (counter_b == 0);
175 27 mohor
 
176
// RX FIFO instance
177
uart_fifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
178
        .clk(           clk             ),
179
        .wb_rst_i(      wb_rst_i        ),
180
        .data_in(       rf_data_in      ),
181
        .data_out(      rf_data_out     ),
182
        .push(          rf_push         ),
183
        .pop(           rf_pop          ),
184
        .underrun(      rf_underrun     ),
185
        .overrun(       rf_overrun      ),
186
        .count(         rf_count        ),
187
        .error_bit(     rf_error_bit    ),
188
        .fifo_reset(    rx_reset        ),
189 37 gorban
        .reset_status(lsr_mask)
190 27 mohor
);
191
 
192
wire            rcounter16_eq_7 = (rcounter16 == 4'd7);
193
wire            rcounter16_eq_0 = (rcounter16 == 4'd0);
194
wire            rcounter16_eq_1 = (rcounter16 == 4'd1);
195
 
196 39 mohor
wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
197 27 mohor
 
198
parameter  sr_idle                                      = 4'd0;
199
parameter  sr_rec_start                         = 4'd1;
200
parameter  sr_rec_bit                           = 4'd2;
201
parameter  sr_rec_parity                        = 4'd3;
202
parameter  sr_rec_stop                          = 4'd4;
203
parameter  sr_check_parity              = 4'd5;
204
parameter  sr_rec_prepare                       = 4'd6;
205
parameter  sr_end_bit                           = 4'd7;
206
parameter  sr_ca_lc_parity            = 4'd8;
207
parameter  sr_wait1                                     = 4'd9;
208
parameter  sr_push                                      = 4'd10;
209
parameter  sr_last                                      = 4'd11;
210
 
211
always @(posedge clk or posedge wb_rst_i)
212
begin
213
  if (wb_rst_i)
214
  begin
215
     rstate                     <= #1 sr_idle;
216
          rbit_in                               <= #1 1'b0;
217
          rcounter16                    <= #1 0;
218
          rbit_counter          <= #1 0;
219
          rparity_xor           <= #1 1'b0;
220
          rframing_error        <= #1 1'b0;
221
          rparity_error                 <= #1 1'b0;
222
          rparity                               <= #1 1'b0;
223
          rshift                                <= #1 0;
224
          rf_push                               <= #1 1'b0;
225
          rf_data_in                    <= #1 0;
226
  end
227
  else
228 45 gorban
          if (break_error && rstate != sr_idle) // break condition met while receiver is not idle
229
          begin
230
                  rstate                 <= #1 sr_idle;
231
                  rf_data_in     <= #1 {8'b0, 3'b100}; // break input (empty character) to receiver FIFO
232
                  rf_push                <= #1 1'b1;
233
          end
234 46 gorban
  else
235 27 mohor
  if (enable)
236
  begin
237
        case (rstate)
238 45 gorban
        sr_idle : begin
239
                        rf_push                           <= #1 1'b0;
240
                        rf_data_in        <= #1 0;
241
                        if (srx_pad_i==1'b0)   // detected a pulse (start bit?)
242 27 mohor
                        begin
243 45 gorban
                                rstate            <= #1 sr_rec_start;
244
                                rcounter16        <= #1 4'b1110;
245 27 mohor
                        end
246 45 gorban
                end
247 27 mohor
        sr_rec_start :  begin
248
                                if (rcounter16_eq_7)    // check the pulse
249
                                        if (srx_pad_i==1'b1)   // no start bit
250
                                                rstate <= #1 sr_idle;
251
                                        else            // start bit detected
252
                                                rstate <= #1 sr_rec_prepare;
253
                                rcounter16 <= #1 rcounter16_minus_1;
254
                        end
255
        sr_rec_prepare:begin
256
                                case (lcr[/*`UART_LC_BITS*/1:0])  // number of bits in a word
257
                                2'b00 : rbit_counter <= #1 3'b100;
258
                                2'b01 : rbit_counter <= #1 3'b101;
259
                                2'b10 : rbit_counter <= #1 3'b110;
260
                                2'b11 : rbit_counter <= #1 3'b111;
261
                                endcase
262
                                if (rcounter16_eq_0)
263
                                begin
264
                                        rstate          <= #1 sr_rec_bit;
265
                                        rcounter16      <= #1 4'b1110;
266
                                        rshift          <= #1 0;
267
                                end
268
                                else
269
                                        rstate <= #1 sr_rec_prepare;
270
                                rcounter16 <= #1 rcounter16_minus_1;
271
                        end
272
        sr_rec_bit :    begin
273
                                if (rcounter16_eq_0)
274
                                        rstate <= #1 sr_end_bit;
275
                                if (rcounter16_eq_7) // read the bit
276
                                        case (lcr[/*`UART_LC_BITS*/1:0])  // number of bits in a word
277
                                        2'b00 : rshift[4:0]  <= #1 {srx_pad_i, rshift[4:1]};
278
                                        2'b01 : rshift[5:0]  <= #1 {srx_pad_i, rshift[5:1]};
279
                                        2'b10 : rshift[6:0]  <= #1 {srx_pad_i, rshift[6:1]};
280
                                        2'b11 : rshift[7:0]  <= #1 {srx_pad_i, rshift[7:1]};
281
                                        endcase
282
                                rcounter16 <= #1 rcounter16_minus_1;
283
                        end
284
        sr_end_bit :   begin
285
                                if (rbit_counter==3'b0) // no more bits in word
286
                                        if (lcr[`UART_LC_PE]) // choose state based on parity
287
                                                rstate <= #1 sr_rec_parity;
288
                                        else
289
                                        begin
290
                                                rstate <= #1 sr_rec_stop;
291
                                                rparity_error <= #1 1'b0;  // no parity - no error :)
292
                                        end
293
                                else            // else we have more bits to read
294
                                begin
295
                                        rstate <= #1 sr_rec_bit;
296 39 mohor
                                        rbit_counter <= #1 rbit_counter - 1'b1;
297 27 mohor
                                end
298
                                rcounter16 <= #1 4'b1110;
299
                        end
300
        sr_rec_parity: begin
301
                                if (rcounter16_eq_7)    // read the parity
302
                                begin
303
                                        rparity <= #1 srx_pad_i;
304
                                        rstate <= #1 sr_ca_lc_parity;
305
                                end
306
                                rcounter16 <= #1 rcounter16_minus_1;
307
                        end
308
        sr_ca_lc_parity : begin    // rcounter equals 6
309
                                rcounter16  <= #1 rcounter16_minus_1;
310 37 gorban
                                rparity_xor <= #1 ^{rshift,rparity}; // calculate parity on all incoming data
311 27 mohor
                                rstate      <= #1 sr_check_parity;
312
                          end
313
        sr_check_parity: begin    // rcounter equals 5
314
                                case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
315 37 gorban
                                        2'b00: rparity_error <= #1  rparity_xor == 0;  // no error if parity 1
316
                                        2'b01: rparity_error <= #1 ~rparity;      // parity should sticked to 1
317
                                        2'b10: rparity_error <= #1  rparity_xor == 1;   // error if parity is odd
318
                                        2'b11: rparity_error <= #1  rparity;      // parity should be sticked to 0
319 27 mohor
                                endcase
320
                                rcounter16 <= #1 rcounter16_minus_1;
321
                                rstate <= #1 sr_wait1;
322
                          end
323
        sr_wait1 :      if (rcounter16_eq_0)
324
                        begin
325
                                rstate <= #1 sr_rec_stop;
326
                                rcounter16 <= #1 4'b1110;
327
                        end
328
                        else
329
                                rcounter16 <= #1 rcounter16_minus_1;
330
        sr_rec_stop :   begin
331
                                if (rcounter16_eq_7)    // read the parity
332
                                begin
333
                                        rframing_error <= #1 !srx_pad_i; // no framing error if input is 1 (stop bit)
334
                                        rstate <= #1 sr_push;
335
                                end
336
                                rcounter16 <= #1 rcounter16_minus_1;
337
                        end
338
        sr_push :       begin
339
///////////////////////////////////////
340
//                              $display($time, ": received: %b", rf_data_in);
341 45 gorban
                        rf_data_in <= #1 {rshift, 1'b0, rparity_error, rframing_error};
342 27 mohor
                                rf_push    <= #1 1'b1;
343
                                rstate     <= #1 sr_last;
344
                        end
345
        sr_last :       begin
346
                                if (rcounter16_eq_1)
347
                                        rstate <= #1 sr_idle;
348
                                rcounter16 <= #1 rcounter16_minus_1;
349
                                rf_push    <= #1 1'b0;
350
                        end
351
        default : rstate <= #1 sr_idle;
352
        endcase
353
  end  // if (enable)
354
end // always of receiver
355
 
356
//
357
// Break condition detection.
358
// Works in conjuction with the receiver state machine
359
 
360 47 gorban
reg     [9:0]    toc_value; // value to be set to timeout counter
361
 
362
always @(lcr)
363
        case (lcr[3:0])
364
                4'b0000                                                                         : toc_value = 447; // 7 bits
365
                4'b0100                                                                         : toc_value = 479; // 7.5 bits
366
                4'b0001,        4'b1000                                                 : toc_value = 511; // 8 bits
367
                4'b1100                                                                         : toc_value = 543; // 8.5 bits
368
                4'b0010, 4'b0101, 4'b1001                               : toc_value = 575; // 9 bits
369
                4'b0011, 4'b0110, 4'b1010, 4'b1101      : toc_value = 639; // 10 bits
370
                4'b0111, 4'b1011, 4'b1110                               : toc_value = 703; // 11 bits
371
                4'b1111                                                                         : toc_value = 767; // 12 bits
372
        endcase // case(lcr[3:0])
373
 
374
wire [7:0]       brc_value; // value to be set to break counter
375
assign          brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times
376
 
377 27 mohor
always @(posedge clk or posedge wb_rst_i)
378
begin
379
        if (wb_rst_i)
380 47 gorban
                counter_b <= #1 8'd159;
381 27 mohor
        else
382 39 mohor
  if(lsr_mask)
383 47 gorban
                counter_b <= #1 brc_value;
384 39 mohor
  else
385 27 mohor
        if (enable)  // only work on enable times
386 39 mohor
                if (srx_pad_i)
387 47 gorban
                        counter_b <= #1 brc_value; // character time length - 1
388 27 mohor
                else
389 40 gorban
                        if (counter_b != 8'b0)            // break not reached it
390
                                counter_b <= #1 counter_b - 1;  // decrement break counter
391 27 mohor
end // always of break condition detection
392
 
393
///
394
/// Timeout condition detection
395 35 gorban
reg     [9:0]    counter_t;      // counts the timeout condition clocks
396 27 mohor
 
397
always @(posedge clk or posedge wb_rst_i)
398
begin
399
        if (wb_rst_i)
400 47 gorban
                counter_t <= #1 10'd639; // 10 bits for the default 8N1
401 27 mohor
        else
402 35 gorban
                if(rf_push || rf_pop || rda_int || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level
403 47 gorban
                        counter_t <= #1 toc_value;
404 27 mohor
                else
405 39 mohor
                if (enable && counter_t != 10'b0)  // we don't want to underflow
406
                        counter_t <= #1 counter_t - 1;
407 27 mohor
end
408
 
409
endmodule

powered by: WebSVN 2.1.0

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