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

Subversion Repositories uart6551

[/] [uart6551/] [trunk/] [trunk/] [rtl/] [uart6551Rx_x12.sv] - Blame information for rev 5

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

Line No. Rev Author Line
1 5 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2005-2022  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8
//
9
// BSD 3-Clause License
10
// Redistribution and use in source and binary forms, with or without
11
// modification, are permitted provided that the following conditions are met:
12
//
13
// 1. Redistributions of source code must retain the above copyright notice, this
14
//    list of conditions and the following disclaimer.
15
//
16
// 2. Redistributions in binary form must reproduce the above copyright notice,
17
//    this list of conditions and the following disclaimer in the documentation
18
//    and/or other materials provided with the distribution.
19
//
20
// 3. Neither the name of the copyright holder nor the names of its
21
//    contributors may be used to endorse or promote products derived from
22
//    this software without specific prior written permission.
23
//
24
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
//
35
// ============================================================================
36
//
37
`define IDLE    0
38
`define CNT             1
39
 
40
module uart6551Rx_x12(rst, clk,
41
        cyc, cs, wr, dout, ack,
42
        fifoEnable, fifoClear, clearGErr,
43
        parityCtrl, frameSize, stop_bits, wordLength, baud16x_ce, clear, rxd,
44
        full, empty, frameErr, overrun, parityErr, break_o, gerr, qcnt, cnt, bitStream);
45
input rst;
46
input clk;
47
input cyc;                              // valid bus cycle
48
input cs;                               // core select
49
input wr;                               // read reciever
50
output [11:0] dout;             // fifo data out
51
output ack;
52
input fifoEnable;               // enable the fifo
53
input fifoClear;
54
input clearGErr;                // clear global error
55
input [2:0] parityCtrl;
56
input [8:0] frameSize;  // frame count
57
input [2:0] stop_bits;
58
input [3:0] wordLength;
59
input baud16x_ce;               // baud rate clock enable
60
input clear;                    // clear reciever
61
input rxd;                              // external serial input
62
output full;                    // receive fifo full
63
output empty;           // receiver fifo is empty
64
output frameErr;                // framing error
65
output overrun;                 // receiver overrun
66
output parityErr;               // parity error
67
output break_o;                 // break detected
68
output gerr;                    // global error indicator
69
output [3:0] qcnt;              // count of number of words queued
70
output [10:0] cnt;              // receiver counter
71
output bitStream;               // received bit stream
72
 
73
//0 - simple sampling at middle of symbol period
74
//>0 - sampling of 3 middle ticks of sumbol perion and results as majority
75
parameter SamplerStyle = 0;
76
 
77
 
78
reg overrun;
79
reg [10:0] cnt;                 // sample bit rate counter / timeout counter
80
reg [14:0] rx_data;             // working receive data register
81
reg [13:0] t4;                  // data minus stop bit(s)
82
reg [11:0] t3;                  // data minus parity bit and start bit
83
reg [11:0] t5;
84
reg [3:0] shft_amt;
85
reg p1;
86
reg gerr;                               // global error status
87
reg perr;                               // parity error
88
reg ferr = 1'b0;                                // framing error
89
wire bz;                                // break detected
90
reg state;                              // state machine
91
reg wf;                                 // fifo write
92
wire empty;
93
reg didRd;
94
wire [11:0] dout1;
95
reg full1;
96
wire fifoFull, fifoEmpty;
97
 
98
assign ack = cyc & cs;
99
wire pe_rd, pe_wf;
100
edge_det ued1 (.rst(rst), .clk(clk), .ce(1'b1), .i(ack & ~wr), .pe(pe_rd), .ne(), .ee());
101
edge_det ued2 (.rst(rst), .clk(clk), .ce(1'b1), .i(wf), .pe(pe_wf), .ne(), .ee());
102
 
103
assign bitStream = rx_data[14];
104
assign bz = t3==12'd0;
105
wire rdf = fifoEnable ? pe_rd : pe_wf;
106
 
107
uart6551Fifo #(.WID(15)) uf1
108
(
109
        .clk(clk),
110
        .rst(rst|clear|fifoClear),
111
        .wr(wf),
112
        .rd(rdf),
113
        .din({bz,perr,ferr,t3}),
114
        .dout({break_o,parityErr,frameErr,dout1}),
115
        .ctr(qcnt),
116
        .full(fifoFull),
117
        .empty(fifoEmpty)
118
);
119
 
120
assign dout = fifoEnable ? dout1 : t5;
121
assign empty = fifoEnable ? fifoEmpty : ~full1;
122
assign full = fifoEnable ? fifoFull : full1;
123
 
124
// compute 1/2 the length of the last bit
125
// needed for framing error detection
126
reg [8:0] halfLastBit;
127
always_ff @(posedge clk)
128
if (stop_bits==3'd3)    // 1.5 stop bits ?
129
        halfLastBit <= 9'd8;
130
else
131
        halfLastBit <= 9'd16;
132
 
133
reg [8:0] fhb;
134
always_ff @(posedge clk)
135
  fhb <= frameSize-halfLastBit;
136
 
137
// record a global error status
138
always_ff @(posedge clk)
139
if (rst)
140
        gerr <= 0;
141
else begin
142
        if (clearGErr)
143
                gerr <= perr | ferr | bz;
144
        else
145
                gerr <= gerr | perr | ferr | bz;
146
end
147
 
148
 
149
// right align data for word length, strip start bit
150
// depending on the word length, the first few bits in the
151
// recieve shift register will be invalid because the shift
152
// register shifts from MSB to LSB and shorter frames
153
// won't shift as far towards the LSB.
154
always_ff @(posedge clk)
155
        shft_amt <= (5'd16 - (wordLength + ({stop_bits[3],~stop_bits[3]}) + parityCtrl[0]));
156
always_comb
157
        t4 <= rx_data >> shft_amt;
158
 
159
// grab the parity bit
160
// Note the data is right aligned
161
always_comb
162
        p1 <= t4[wordLength];
163
 
164
// strip off parity, stop
165
integer n2;
166
always_comb
167
        for (n2 = 0; n2 < 12; n2 = n2 + 1)
168
                if (n2 < wordLength)
169
                        t3[n2] <= t4[n2];
170
                else
171
                        t3[n2] <= 1'b0;
172
 
173
// detect a parity err
174
always_comb begin
175
        case (parityCtrl)
176
        3'b001: perr <= p1 != ~^t3;     // odd parity
177
        3'b011: perr <= p1 != ^t3;      // even parity
178
        default: perr <= 0;
179
        endcase
180
end
181
 
182
 
183
// Three stage synchronizer to synchronize incoming data to
184
// the local clock (avoids metastability).
185
 
186
reg [5:0] rxdd          /* synthesis ramstyle = "logic" */; // synchronizer flops
187
reg rxdsmp;             // majority samples
188
reg rdxstart;           // for majority style sample solid 3tik-wide sample
189
reg [1:0] rxdsum [0:1];
190
always_ff @(posedge clk)
191
if (baud16x_ce) begin
192
        rxdd <= {rxdd[4:0],rxd};
193
  if (SamplerStyle == 0) begin
194
    rxdsmp <= rxdd[3];
195
    rdxstart <= rxdd[4]&~rxdd[3];
196
  end
197
  else begin
198
    rxdsum[1] <= rxdsum[0];
199
    rxdsum[0] <= {1'b0,rxdd[3]} + {1'b0,rxdd[4]} + {1'b0,rxdd[5]};
200
    rxdsmp <= rxdsum[1] > 2'd1;
201
    rdxstart <= (rxdsum[0] == 2'b00) & (rxdsum[1] == 2'b11);
202
  end
203
end
204
 
205
 
206
always_ff @(posedge clk)
207
if (rst)
208
        state <= `IDLE;
209
else begin
210
        if (clear)
211
                state <= `IDLE;
212
        else if (baud16x_ce) begin
213
                case (state)
214
                // Sit in the idle state until a start bit is
215
                // detected.
216
                `IDLE:
217
                        if (rdxstart)
218
                                state <= `CNT;
219
                `CNT:
220
                        begin
221
                                // Switch back to the idle state a little
222
                                // bit too soon.
223
                                if (cnt[8:2]==frameSize[8:2])
224
                                        state <= `IDLE;
225
                                // On start bit check make sure the start
226
                                // bit is low, otherwise go back to the
227
                                // idle state because it's a false start.
228
                                if (cnt[8:0]==8'h07) begin
229
                                        if (rxdsmp)
230
                                                state <= `IDLE;
231
                                end
232
                        end
233
                endcase
234
        end
235
end
236
 
237
always_ff @(posedge clk)
238
if (rst)
239
        cnt <= 9'h00;
240
else begin
241
        if (clear)
242
                cnt <= 9'h00;
243
        else if (baud16x_ce) begin
244
                cnt <= cnt + 2'h1;
245
                case (state)
246
                `IDLE:
247
                        begin
248
                                // reset counter on read of reciever
249
                                // (resets timeout count).
250
                                if (didRd)
251
                                        cnt <= 9'h0;
252
                                if (rdxstart)
253
                                        cnt <= 9'h0;
254
                        end
255
                default:        ;
256
                endcase
257
        end
258
end
259
 
260
always_ff @(posedge clk)
261
if (rst)
262
        wf <= 1'b0;
263
else begin
264
        // Clear write flag
265
        wf <= 1'b0;
266
        if (baud16x_ce) begin
267
                case (state)
268
                `CNT:
269
                        // End of the frame ?
270
                        // - write data to fifo
271
                        if (cnt[8:0]==fhb) begin
272
                                if (!full)
273
                                        wf <= 1'b1;
274
                        end
275
                default:        ;
276
                endcase
277
        end
278
end
279
 
280
always_ff @(posedge clk)
281
if (rst)
282
        t5 <= 1'b0;
283
else begin
284
        if (pe_wf)
285
                t5 <= t3;
286
end
287
 
288
always_ff @(posedge clk)
289
if (rst)
290
        full1 <= 1'b0;
291
else begin
292
        if (pe_wf)
293
                full1 <= 1'b1;
294
        else if (pe_rd)
295
                full1 <= 1'b0;
296
end
297
 
298
always_ff @(posedge clk)
299
if (rst)
300
        didRd <= 1'b0;
301
else begin
302
        // set a read flag for later reference
303
        if (pe_rd)
304
                didRd <= 1'b1;
305
        if (clear)
306
                didRd <= 1'b0;
307
        else if (baud16x_ce) begin
308
                case (state)
309
                `IDLE:
310
                        begin
311
                                if (didRd)
312
                                        didRd <= 1'b0;
313
                                if (rdxstart)
314
                                        didRd <= 1'b0;
315
                        end
316
                default:        ;
317
                endcase
318
        end
319
end
320
 
321
always_ff @(posedge clk)
322
if (rst)
323
        rx_data <= 15'h0;
324
else begin
325
        if (clear)
326
                rx_data <= 15'h0;
327
        else if (baud16x_ce) begin
328
                case (state)
329
                `CNT:
330
                        begin
331
                                //if (cnt[7:2]==frameSize[7:2])
332
                                //      rx_data <= 11'h0;
333
                                if (cnt[3:0]==4'h7)
334
                                        rx_data <= {rxdsmp,rx_data[14:1]};
335
                        end
336
                default:        ;
337
                endcase
338
        end
339
end
340
 
341
// Overrun: trying to recieve data when recieve buffer is already full.
342
always_ff @(posedge clk)
343
if (rst)
344
        overrun <= 1'b0;
345
else begin
346
        if (!full)
347
                overrun <= 1'b0;
348
        if (clear)
349
                overrun <= 1'b0;
350
        else if (baud16x_ce) begin
351
                case (state)
352
                `CNT:
353
                        if (cnt[8:0]==fhb) begin
354
                                if (full)
355
                                        overrun <= 1'b1;
356
                        end
357
                default:        ;
358
                endcase
359
        end
360
end
361
 
362
always_ff @(posedge clk)
363
if (rst)
364
        ferr <= 1'b0;
365
else begin
366
        if (clear)
367
                ferr <= 1'b0;
368
        else if (baud16x_ce) begin
369
                case (state)
370
                `CNT:
371
                        if (cnt[8:0]==fhb)
372
                                ferr <= ~rxdsmp;
373
                default:        ;
374
                endcase
375
        end
376
end
377
 
378
endmodule
379
 

powered by: WebSVN 2.1.0

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