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

Subversion Repositories uart6551

[/] [uart6551/] [trunk/] [trunk/] [rtl/] [uart6551Rx.sv] - Blame information for rev 3

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

Line No. Rev Author Line
1 2 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2005-2019  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9
// This source file is free software: you can redistribute it and/or modify
10
// it under the terms of the GNU Lesser General Public License as published
11
// by the Free Software Foundation, either version 3 of the License, or
12
// (at your option) any later version.
13
//
14
// This source file is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
//
19
// You should have received a copy of the GNU General Public License
20
// along with this program.  If not, see .
21
//
22
// ============================================================================
23
//
24
`define IDLE    0
25
`define CNT             1
26
 
27
module uart6551Rx(rst, clk,
28
        cyc, cs, wr, dout, ack,
29
        fifoEnable, fifoClear, clearGErr,
30
        parityCtrl, frameSize, stop_bits, wordLength, baud16x_ce, clear, rxd,
31
        full, empty, frameErr, overrun, parityErr, break_o, gerr, qcnt, cnt, bitStream);
32
input rst;
33
input clk;
34
input cyc;                              // valid bus cycle
35
input cs;                               // core select
36
input wr;                               // read reciever
37
output [7:0] dout;              // fifo data out
38
output ack;
39
input fifoEnable;               // enable the fifo
40
input fifoClear;
41
input clearGErr;                // clear global error
42
input [2:0] parityCtrl;
43
input [7:0] frameSize;  // frame count
44
input [2:0] stop_bits;
45
input [3:0] wordLength;
46
input baud16x_ce;               // baud rate clock enable
47
input clear;                    // clear reciever
48
input rxd;                              // external serial input
49
output full;                    // receive fifo full
50
output empty;           // receiver fifo is empty
51
output frameErr;                // framing error
52
output overrun;                 // receiver overrun
53
output parityErr;               // parity error
54
output break_o;                 // break detected
55
output gerr;                    // global error indicator
56
output [3:0] qcnt;              // count of number of words queued
57
output [9:0] cnt;               // receiver counter
58
output bitStream;               // received bit stream
59
 
60
//0 - simple sampling at middle of symbol period
61
//>0 - sampling of 3 middle ticks of sumbol perion and results as majority
62
parameter SamplerStyle = 0;
63
 
64
 
65
reg overrun;
66
reg [9:0] cnt;                  // sample bit rate counter / timeout counter
67
reg [10:0] rx_data;             // working receive data register
68
reg [9:0] t2;                   // data minus stop bit(s)
69
reg [7:0] t3,t4;                // data minus parity bit and start bit
70 3 robfinch
reg [7:0] t5;
71 2 robfinch
reg p1;
72
reg gerr;                               // global error status
73
reg perr;                               // parity error
74
reg ferr = 1'b0;                                // framing error
75
wire bz;                                // break detected
76
reg state;                              // state machine
77
reg wf;                                 // fifo write
78
wire empty;
79
reg didRd;
80 3 robfinch
wire [7:0] dout1;
81
reg full1;
82
wire fifoFull, fifoEmpty;
83 2 robfinch
 
84
assign ack = cyc & cs;
85
wire pe_rd;
86
edge_det ued1 (.rst(rst), .clk(clk), .ce(1'b1), .i(ack & ~wr), .pe(pe_rd), .ne(), .ee());
87
 
88
assign bitStream = rx_data[10];
89
assign bz = t4==8'd0;
90
wire rdf = fifoEnable ? pe_rd : wf;
91
 
92
uart6551Fifo #(.WID(11)) uf1
93
(
94
        .clk(clk),
95
        .rst(rst|clear|fifoClear),
96
        .wr(wf),
97
        .rd(rdf),
98
        .din({bz,perr,ferr,t4}),
99 3 robfinch
        .dout({break_o,parityErr,frameErr,dout1}),
100 2 robfinch
        .ctr(qcnt),
101 3 robfinch
        .full(fifoFull),
102
        .empty(fifoEmpty)
103 2 robfinch
);
104
 
105 3 robfinch
assign dout = fifoEnable ? dout1 : t5;
106
assign empty = fifoEnable ? fifoEmpty : ~full1;
107
assign full = fifoEnable ? fifoFull : full1;
108
 
109 2 robfinch
// compute 1/2 the length of the last bit
110
// needed for framing error detection
111
reg [7:0] halfLastBit;
112
always @(stop_bits)
113
if (stop_bits==3'd3)    // 1.5 stop bits ?
114
        halfLastBit <= 8'd4;
115
else
116
        halfLastBit <= 8'd8;
117
 
118
// record a global error status
119
always @(posedge clk)
120
if (rst)
121
        gerr <= 0;
122
else begin
123
        if (clearGErr)
124
                gerr <= perr | ferr | bz;
125
        else
126
                gerr <= gerr | perr | ferr | bz;
127
end
128
 
129
 
130
// strip off stop bits
131
always @(stop_bits or rx_data)
132
if (stop_bits==3'd2)
133
        t2 <= rx_data[9:0];
134
else
135
        t2 <= {rx_data[8:0],1'b0};
136
 
137
// grab the parity bit
138
always @(t2)
139 3 robfinch
        p1 <= t2[9];
140 2 robfinch
 
141
// strip off parity and start bit
142
always @(parityCtrl or t2)
143
if (parityCtrl[0])
144
        t3 <= t2[8:1];
145
else
146
        t3 <= t2[9:2];
147
 
148
// mask receive data for word length
149
// depending on the word length, the first few bits in the
150
// recieve shift register will be invalid because the shift
151
// register shifts from MSB to LSB and shorter frames
152
// won't shift as far towards the LSB.
153
always @(wordLength or t3)
154
        t4 <= t3 >> (4'd8 - wordLength);
155
 
156
// detect a parity err
157
always @(parityCtrl or t4 or p1) begin
158
        case (parityCtrl)
159
        3'b001: perr <= p1 != ~^t4;     // odd parity
160
        3'b011: perr <= p1 != ^t4;      // even parity
161
        default: perr <= 0;
162
        endcase
163
end
164
 
165
 
166
// Three stage synchronizer to synchronize incoming data to
167
// the local clock (avoids metastability).
168
 
169
reg [5:0] rxdd          /* synthesis ramstyle = "logic" */; // synchronizer flops
170
reg rxdsmp;             // majority samples
171
reg rdxstart;           // for majority style sample solid 3tik-wide sample
172
reg [1:0] rxdsum [0:1];
173
always @(posedge clk)
174
if (baud16x_ce) begin
175
        rxdd <= {rxdd[4:0],rxd};
176
  if (SamplerStyle == 0) begin
177
    rxdsmp <= rxdd[3];
178
    rdxstart <= rxdd[4]&~rxdd[3];
179
  end
180
  else begin
181
    rxdsum[1] <= rxdsum[0];
182
    rxdsum[0] <= {1'b0,rxdd[3]} + {1'b0,rxdd[4]} + {1'b0,rxdd[5]};
183
    rxdsmp <= rxdsum[1] > 2'd1;
184
    rdxstart <= (rxdsum[0] == 2'b00) & (rxdsum[1] == 2'b11);
185
  end
186
end
187
 
188
 
189
always @(posedge clk)
190
if (rst)
191
        state <= `IDLE;
192
else begin
193
        if (clear)
194
                state <= `IDLE;
195
        else if (baud16x_ce) begin
196
                case (state)
197
                // Sit in the idle state until a start bit is
198
                // detected.
199
                `IDLE:
200
                        if (rdxstart)
201
                                state <= `CNT;
202
                `CNT:
203
                        begin
204
                                // Switch back to the idle state a little
205
                                // bit too soon.
206
                                if (cnt[7:2]==frameSize[7:2])
207
                                        state <= `IDLE;
208
                                // On start bit check make sure the start
209
                                // bit is low, otherwise go back to the
210
                                // idle state because it's a false start.
211
                                if (cnt[7:0]==8'h07) begin
212
                                        if (rxdsmp)
213
                                                state <= `IDLE;
214
                                end
215
                        end
216
                default:        ;
217
                endcase
218
        end
219
end
220
 
221
always @(posedge clk)
222
if (rst)
223
        cnt <= 8'h00;
224
else begin
225
        if (clear)
226
                cnt <= 8'h00;
227
        else if (baud16x_ce) begin
228
                cnt <= cnt + 8'h1;
229
                case (state)
230
                `IDLE:
231
                        begin
232
                                // reset counter on read of reciever
233
                                // (resets timeout count).
234
                                if (didRd)
235
                                        cnt <= 8'h0;
236
                                if (rdxstart)
237
                                        cnt <= 8'h0;
238
                        end
239
                default:        ;
240
                endcase
241
        end
242
end
243
 
244
always @(posedge clk)
245
if (rst)
246
        wf <= 1'b0;
247
else begin
248
        // Clear write flag
249
        wf <= 1'b0;
250
        if (clear)
251
                wf <= 1'b0;
252
        else if (baud16x_ce) begin
253
                case (state)
254
                `CNT:
255
                        // End of the frame ?
256
                        // - write data to fifo
257
                        if (cnt[7:0]==frameSize-halfLastBit) begin
258
                                if (!full)
259
                                        wf <= 1'b1;
260
                        end
261
                default:        ;
262
                endcase
263
        end
264
end
265
 
266
always @(posedge clk)
267
if (rst)
268 3 robfinch
        t5 <= 1'b0;
269
else begin
270
        if (wf)
271
                t5 <= t4;
272
end
273
 
274
always @(posedge clk)
275
if (rst)
276
        full1 <= 1'b0;
277
else begin
278
        if (wf)
279
                full1 <= 1'b1;
280
        else if (pe_rd)
281
                full1 <= 1'b0;
282
end
283
 
284
always @(posedge clk)
285
if (rst)
286 2 robfinch
        didRd <= 1'b0;
287
else begin
288
        // set a read flag for later reference
289
        if (pe_rd)
290
                didRd <= 1'b1;
291
        if (clear)
292
                didRd <= 1'b0;
293
        else if (baud16x_ce) begin
294
                case (state)
295
                `IDLE:
296
                        begin
297
                                if (didRd)
298
                                        didRd <= 1'b0;
299
                                if (rdxstart)
300
                                        didRd <= 1'b0;
301
                        end
302
                default:        ;
303
                endcase
304
        end
305
end
306
 
307
always @(posedge clk)
308
if (rst)
309
        rx_data <= 11'h0;
310
else begin
311
        if (clear)
312
                rx_data <= 11'h0;
313
        else if (baud16x_ce) begin
314
                case (state)
315
                `CNT:
316
                        begin
317
                                //if (cnt[7:2]==frameSize[7:2])
318
                                //      rx_data <= 11'h0;
319
                                if (cnt[3:0]==4'h7)
320
                                        rx_data <= {rxdsmp,rx_data[10:1]};
321
                        end
322
                default:        ;
323
                endcase
324
        end
325
end
326
 
327
// Overrun: trying to recieve data when recieve buffer is already full.
328
always @(posedge clk)
329
if (rst)
330
        overrun <= 1'b0;
331
else begin
332
        if (!full)
333
                overrun <= 1'b0;
334
        if (clear)
335
                overrun <= 1'b0;
336
        else if (baud16x_ce) begin
337
                case (state)
338
                `CNT:
339
                        if (cnt[7:0]==frameSize-halfLastBit) begin
340
                                if (full)
341
                                        overrun <= 1'b1;
342
                        end
343
                default:        ;
344
                endcase
345
        end
346
end
347
 
348
always @(posedge clk)
349
if (rst)
350
        ferr <= 1'b0;
351
else begin
352
        if (clear)
353
                ferr <= 1'b0;
354
        else if (baud16x_ce) begin
355
                case (state)
356
                `CNT:
357
                        if (cnt[7:0]==frameSize-halfLastBit)
358
                                ferr <= ~rxdsmp;
359
                default:        ;
360
                endcase
361
        end
362
end
363
 
364
endmodule
365
 

powered by: WebSVN 2.1.0

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