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

Subversion Repositories uart16550

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

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 40 gorban
// Revision 1.13  2001/11/08 14:54:23  mohor
67
// Comments in Slovene language deleted, few small fixes for better work of
68
// old tools. IRQs need to be fix.
69
//
70 39 mohor
// Revision 1.12  2001/11/07 17:51:52  gorban
71
// Heavily rewritten interrupt and LSR subsystems.
72
// Many bugs hopefully squashed.
73
//
74 37 gorban
// Revision 1.11  2001/10/31 15:19:22  gorban
75
// Fixes to break and timeout conditions
76
//
77 35 gorban
// Revision 1.10  2001/10/20 09:58:40  gorban
78
// Small synopsis fixes
79
//
80 33 gorban
// Revision 1.9  2001/08/24 21:01:12  mohor
81
// Things connected to parity changed.
82
// Clock devider changed.
83
//
84 29 mohor
// Revision 1.8  2001/08/23 16:05:05  mohor
85
// Stop bit bug fixed.
86
// Parity bug fixed.
87
// WISHBONE read cycle bug fixed,
88
// OE indicator (Overrun Error) bug fixed.
89
// PE indicator (Parity Error) bug fixed.
90
// Register read bug fixed.
91
//
92 27 mohor
// Revision 1.6  2001/06/23 11:21:48  gorban
93
// DL made 16-bit long. Fixed transmission/reception bugs.
94
//
95
// Revision 1.5  2001/06/02 14:28:14  gorban
96
// Fixed receiver and transmitter. Major bug fixed.
97
//
98
// Revision 1.4  2001/05/31 20:08:01  gorban
99
// FIFO changes and other corrections.
100
//
101
// Revision 1.3  2001/05/27 17:37:49  gorban
102
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
103
//
104
// Revision 1.2  2001/05/21 19:12:02  gorban
105
// Corrected some Linter messages.
106
//
107
// Revision 1.1  2001/05/17 18:34:18  gorban
108
// First 'stable' release. Should be sythesizable now. Also added new header.
109
//
110
// Revision 1.0  2001-05-17 21:27:11+02  jacob
111
// Initial revision
112
//
113
//
114
 
115 33 gorban
// synopsys translate_off
116 27 mohor
`include "timescale.v"
117 33 gorban
// synopsys translate_on
118
 
119 27 mohor
`include "uart_defines.v"
120
 
121
module uart_receiver (clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable, rda_int,
122 37 gorban
        counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask);
123 27 mohor
 
124
input                           clk;
125
input                           wb_rst_i;
126 39 mohor
input   [7:0]    lcr;
127 27 mohor
input                           rf_pop;
128
input                           srx_pad_i;
129
input                           enable;
130
input                           rda_int;
131
input                           rx_reset;
132 37 gorban
input       lsr_mask;
133 27 mohor
 
134 35 gorban
output  [9:0]                    counter_t;
135
output  [7:0]                    counter_b;
136 27 mohor
output  [`UART_FIFO_COUNTER_W-1:0]       rf_count;
137
output  [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
138
output                          rf_overrun;
139
output                          rf_error_bit;
140
 
141
reg     [3:0]    rstate;
142
reg     [3:0]    rcounter16;
143
reg     [2:0]    rbit_counter;
144
reg     [7:0]    rshift;                 // receiver shift register
145
reg             rparity;                // received parity
146
reg             rparity_error;
147
reg             rframing_error;         // framing error flag
148
reg             rbit_in;
149
reg             rparity_xor;
150
 
151
// RX FIFO signals
152
reg     [`UART_FIFO_REC_WIDTH-1:0]       rf_data_in;
153
wire    [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
154
reg                             rf_push;
155
wire                            rf_pop;
156
wire                            rf_underrun;
157
wire                            rf_overrun;
158
wire    [`UART_FIFO_COUNTER_W-1:0]       rf_count;
159
wire                            rf_error_bit; // an error (parity or framing) is inside the fifo
160
 
161
// RX FIFO instance
162
uart_fifo #(`UART_FIFO_REC_WIDTH) fifo_rx(
163
        .clk(           clk             ),
164
        .wb_rst_i(      wb_rst_i        ),
165
        .data_in(       rf_data_in      ),
166
        .data_out(      rf_data_out     ),
167
        .push(          rf_push         ),
168
        .pop(           rf_pop          ),
169
        .underrun(      rf_underrun     ),
170
        .overrun(       rf_overrun      ),
171
        .count(         rf_count        ),
172
        .error_bit(     rf_error_bit    ),
173
        .fifo_reset(    rx_reset        ),
174 37 gorban
        .reset_status(lsr_mask)
175 27 mohor
);
176
 
177
wire            rcounter16_eq_7 = (rcounter16 == 4'd7);
178
wire            rcounter16_eq_0 = (rcounter16 == 4'd0);
179
wire            rcounter16_eq_1 = (rcounter16 == 4'd1);
180
 
181 39 mohor
wire [3:0] rcounter16_minus_1 = rcounter16 - 1'b1;
182 27 mohor
 
183
parameter  sr_idle                                      = 4'd0;
184
parameter  sr_rec_start                         = 4'd1;
185
parameter  sr_rec_bit                           = 4'd2;
186
parameter  sr_rec_parity                        = 4'd3;
187
parameter  sr_rec_stop                          = 4'd4;
188
parameter  sr_check_parity              = 4'd5;
189
parameter  sr_rec_prepare                       = 4'd6;
190
parameter  sr_end_bit                           = 4'd7;
191
parameter  sr_ca_lc_parity            = 4'd8;
192
parameter  sr_wait1                                     = 4'd9;
193
parameter  sr_push                                      = 4'd10;
194
parameter  sr_last                                      = 4'd11;
195
 
196
always @(posedge clk or posedge wb_rst_i)
197
begin
198
  if (wb_rst_i)
199
  begin
200
     rstate                     <= #1 sr_idle;
201
          rbit_in                               <= #1 1'b0;
202
          rcounter16                    <= #1 0;
203
          rbit_counter          <= #1 0;
204
          rparity_xor           <= #1 1'b0;
205
          rframing_error        <= #1 1'b0;
206
          rparity_error                 <= #1 1'b0;
207
          rparity                               <= #1 1'b0;
208
          rshift                                <= #1 0;
209
          rf_push                               <= #1 1'b0;
210
          rf_data_in                    <= #1 0;
211
  end
212
  else
213
  if (enable)
214
  begin
215
        case (rstate)
216
        sr_idle :       if (srx_pad_i==1'b0)   // detected a pulse (start bit?)
217
                        begin
218
                                rstate <= #1 sr_rec_start;
219
                                rcounter16 <= #1 4'b1110;
220
                        end
221
        sr_rec_start :  begin
222
                                if (rcounter16_eq_7)    // check the pulse
223
                                        if (srx_pad_i==1'b1)   // no start bit
224
                                                rstate <= #1 sr_idle;
225
                                        else            // start bit detected
226
                                                rstate <= #1 sr_rec_prepare;
227
                                rcounter16 <= #1 rcounter16_minus_1;
228
                        end
229
        sr_rec_prepare:begin
230
                                case (lcr[/*`UART_LC_BITS*/1:0])  // number of bits in a word
231
                                2'b00 : rbit_counter <= #1 3'b100;
232
                                2'b01 : rbit_counter <= #1 3'b101;
233
                                2'b10 : rbit_counter <= #1 3'b110;
234
                                2'b11 : rbit_counter <= #1 3'b111;
235
                                endcase
236
                                if (rcounter16_eq_0)
237
                                begin
238
                                        rstate          <= #1 sr_rec_bit;
239
                                        rcounter16      <= #1 4'b1110;
240
                                        rshift          <= #1 0;
241
                                end
242
                                else
243
                                        rstate <= #1 sr_rec_prepare;
244
                                rcounter16 <= #1 rcounter16_minus_1;
245
                        end
246
        sr_rec_bit :    begin
247
                                if (rcounter16_eq_0)
248
                                        rstate <= #1 sr_end_bit;
249
                                if (rcounter16_eq_7) // read the bit
250
                                        case (lcr[/*`UART_LC_BITS*/1:0])  // number of bits in a word
251
                                        2'b00 : rshift[4:0]  <= #1 {srx_pad_i, rshift[4:1]};
252
                                        2'b01 : rshift[5:0]  <= #1 {srx_pad_i, rshift[5:1]};
253
                                        2'b10 : rshift[6:0]  <= #1 {srx_pad_i, rshift[6:1]};
254
                                        2'b11 : rshift[7:0]  <= #1 {srx_pad_i, rshift[7:1]};
255
                                        endcase
256
                                rcounter16 <= #1 rcounter16_minus_1;
257
                        end
258
        sr_end_bit :   begin
259
                                if (rbit_counter==3'b0) // no more bits in word
260
                                        if (lcr[`UART_LC_PE]) // choose state based on parity
261
                                                rstate <= #1 sr_rec_parity;
262
                                        else
263
                                        begin
264
                                                rstate <= #1 sr_rec_stop;
265
                                                rparity_error <= #1 1'b0;  // no parity - no error :)
266
                                        end
267
                                else            // else we have more bits to read
268
                                begin
269
                                        rstate <= #1 sr_rec_bit;
270 39 mohor
                                        rbit_counter <= #1 rbit_counter - 1'b1;
271 27 mohor
                                end
272
                                rcounter16 <= #1 4'b1110;
273
                        end
274
        sr_rec_parity: begin
275
                                if (rcounter16_eq_7)    // read the parity
276
                                begin
277
                                        rparity <= #1 srx_pad_i;
278
                                        rstate <= #1 sr_ca_lc_parity;
279
                                end
280
                                rcounter16 <= #1 rcounter16_minus_1;
281
                        end
282
        sr_ca_lc_parity : begin    // rcounter equals 6
283
                                rcounter16  <= #1 rcounter16_minus_1;
284 37 gorban
                                rparity_xor <= #1 ^{rshift,rparity}; // calculate parity on all incoming data
285 27 mohor
                                rstate      <= #1 sr_check_parity;
286
                          end
287
        sr_check_parity: begin    // rcounter equals 5
288
                                case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]})
289 37 gorban
                                        2'b00: rparity_error <= #1  rparity_xor == 0;  // no error if parity 1
290
                                        2'b01: rparity_error <= #1 ~rparity;      // parity should sticked to 1
291
                                        2'b10: rparity_error <= #1  rparity_xor == 1;   // error if parity is odd
292
                                        2'b11: rparity_error <= #1  rparity;      // parity should be sticked to 0
293 27 mohor
                                endcase
294
                                rcounter16 <= #1 rcounter16_minus_1;
295
                                rstate <= #1 sr_wait1;
296
                          end
297
        sr_wait1 :      if (rcounter16_eq_0)
298
                        begin
299
                                rstate <= #1 sr_rec_stop;
300
                                rcounter16 <= #1 4'b1110;
301
                        end
302
                        else
303
                                rcounter16 <= #1 rcounter16_minus_1;
304
        sr_rec_stop :   begin
305
                                if (rcounter16_eq_7)    // read the parity
306
                                begin
307
                                        rframing_error <= #1 !srx_pad_i; // no framing error if input is 1 (stop bit)
308
                                        rstate <= #1 sr_push;
309
                                end
310
                                rcounter16 <= #1 rcounter16_minus_1;
311
                        end
312
        sr_push :       begin
313
///////////////////////////////////////
314
//                              $display($time, ": received: %b", rf_data_in);
315 39 mohor
                        rf_data_in <= #1 {rshift, rparity_error, rframing_error};
316 27 mohor
                                rf_push    <= #1 1'b1;
317
                                rstate     <= #1 sr_last;
318
                        end
319
        sr_last :       begin
320
                                if (rcounter16_eq_1)
321
                                        rstate <= #1 sr_idle;
322
                                rcounter16 <= #1 rcounter16_minus_1;
323
                                rf_push    <= #1 1'b0;
324
                        end
325
        default : rstate <= #1 sr_idle;
326
        endcase
327
  end  // if (enable)
328
end // always of receiver
329
 
330
//
331
// Break condition detection.
332
// Works in conjuction with the receiver state machine
333 40 gorban
reg     [7:0]    counter_b;      // counts the 0 (low) signals
334 27 mohor
 
335
always @(posedge clk or posedge wb_rst_i)
336
begin
337
        if (wb_rst_i)
338 35 gorban
                counter_b <= #1 8'd191;
339 27 mohor
        else
340 39 mohor
  if(lsr_mask)
341
                counter_b <= #1 8'd191;
342
  else
343 27 mohor
        if (enable)  // only work on enable times
344 39 mohor
                if (srx_pad_i)
345 35 gorban
                        counter_b <= #1 8'd191; // maximum character time length - 1
346 27 mohor
                else
347 40 gorban
                        if (counter_b != 8'b0)            // break not reached it
348
                                counter_b <= #1 counter_b - 1;  // decrement break counter
349 27 mohor
end // always of break condition detection
350
 
351
///
352
/// Timeout condition detection
353 35 gorban
reg     [9:0]    counter_t;      // counts the timeout condition clocks
354 27 mohor
 
355
always @(posedge clk or posedge wb_rst_i)
356
begin
357
        if (wb_rst_i)
358 35 gorban
                counter_t <= #1 10'd767;
359 27 mohor
        else
360 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
361
                        counter_t <= #1 10'd767;
362 27 mohor
                else
363 39 mohor
                if (enable && counter_t != 10'b0)  // we don't want to underflow
364
                        counter_t <= #1 counter_t - 1;
365 27 mohor
end
366
 
367
endmodule

powered by: WebSVN 2.1.0

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