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

Subversion Repositories uart6551

[/] [uart6551/] [trunk/] [trunk/] [rtl/] [uart6551_x12.sv] - Blame information for rev 6

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 UART_TRB                4'd0    // transmit/receive buffer
38
`define UART_STAT               4'd1
39
`define UART_CMD                4'd2
40
`define UART_CTRL               4'd3
41
`define UART_IRQS               4'd4
42
`define UART_MS                 4'd5
43
`define UART_LS                 4'd6
44
`define UART_CMD1               4'd7
45
`define UART_CMD2               4'd8
46
`define UART_CMD3               4'd9
47
`define UART_CTRL1      4'd10
48
`define UART_CTRL2      4'd11
49
`define UART_CTRL3      4'd12
50
`define UART_CLK1               4'd13
51
`define UART_CLK2               4'd14
52
 
53
module uart6551_x12 (rst_i, clk_i, cs_i, irq_o,
54
        cyc_i, stb_i, ack_o, we_i, adr_i, dat_i, dat_o,
55
        cts_ni, rts_no, dsr_ni, dcd_ni, dtr_no, ri_ni,
56
        rxd_i, txd_o, data_present,
57
        rxDRQ_o, txDRQ_o,
58
        xclk_i, RxC_i
59
);
60 6 robfinch
parameter CLK_FREQ = 100;
61 5 robfinch
parameter pCounterBits = 24;
62
parameter pFifoSize = 1024;
63
parameter pClkDiv = 24'd1302;   // 9.6k baud, 200.000MHz clock
64
parameter HIGH = 1'b1;
65
parameter LOW = 1'b0;
66
input rst_i;
67
input clk_i;                    // eg 50.000MHz
68
input cs_i;             // circuit select
69
// WISHBONE -------------------------------
70
input cyc_i;            // bus cycle valid
71
input stb_i;
72
output ack_o;
73
input we_i;                     // 1 = write
74
input [3:0] adr_i;      // register address
75
input [11:0] dat_i;     // data input bus
76
output reg [11:0] dat_o;        // data output bus
77
//------------------------------------------
78
output reg irq_o;               // interrupt request
79
input cts_ni;                   // clear to send - (flow control) active low
80
output reg rts_no;              // request to send - (flow control) active low
81
input dsr_ni;   // data set ready - active low
82
input dcd_ni;   // data carrier detect - active low
83
output reg dtr_no;      // data terminal ready - active low
84
input ri_ni;            // ring indicator
85
input rxd_i;            // serial data in
86
output txd_o;           // serial data out
87
output data_present;
88
output rxDRQ_o; // reciever DMA request
89
output txDRQ_o; // transmitter DMA request
90
input xclk_i;           // external clock source
91
input RxC_i;            // external receiver clock source
92
 
93
reg accessCD;           // clock multiplier access flag
94
reg llb;                        // local loopback mode
95
reg dmaEnable;
96
// baud rate clock control
97
reg [4:0] baudRateSel;
98
reg selCD;                              // Use clock multiplier register
99
reg [pCounterBits-1:0] c;       // current count
100
reg [pCounterBits-1:0] ckdiv;   // baud rate clock divider
101
reg [pCounterBits-1:0] clkdiv;  // clock multiplier register
102
reg [1:0] xclks;        // synchronized external clock
103
reg [1:0] RxCs;         // synchronized external receiver clock
104
reg baud16;                     // 16x baud rate clock
105
wire baud16rx;          // reciever clock
106
reg xClkSrc;            // uart baud clock is external
107
reg rxClkSrc;           // receiver clock is external
108
 
109
// frame format registers
110
reg [3:0] wordLength;
111
reg stopBit;
112
reg [2:0] stopBits;
113
reg [2:0] parityCtrl;
114
reg [8:0] frameSize;
115
 
116
reg txBreak;            // transmit a break
117
 
118
wire rxFull;
119
wire rxEmpty;
120
wire txFull;
121
wire txEmpty;
122
reg hwfc;                       // hardware flow control enable
123
wire [11:0] lineStatusReg;
124
wire [11:0] modemStatusReg;
125
wire [11:0] irqStatusReg;
126
// interrupt
127
reg rxIe;
128
reg txIe;
129
reg modemStatusChangeIe;
130
wire modemStatusChange;
131
reg lineStatusChangeIe;
132
wire lineStatusChange;
133
reg rxToutIe;           // receiver timeout interrupt enable
134
reg [3:0] rxThres;      // receiver threshold for interrupt
135
reg [3:0] txThres;      // transmitter threshold for interrupt
136
reg rxTout;                     // receiver timeout
137
wire [9:0] rxCnt;       // reciever counter value
138
reg [7:0] rxToutMax;
139
reg [2:0] irqenc;       // encoded irq cause
140
wire rxITrig;           // receiver interrupt trigger level
141
wire txITrig;           // transmitter interrupt trigger level
142
// reciever errors
143
wire parityErr;         // reciever detected a parity error
144
wire frameErr;          // receiver char framing error
145
wire overrun;           // receiver over run
146
wire rxBreak;           // reciever detected a break
147
wire rxGErr;            // global error: there is at least one error in the reciever fifo
148
// modem controls
149
reg [1:0] ctsx;         // cts_n sampling
150
reg [1:0] dcdx;
151
reg [1:0] dsrx;
152
reg [1:0] rix;
153
reg deltaCts;
154
reg deltaDcd;
155
reg deltaDsr;
156
reg deltaRi;
157
 
158
// fifo
159
reg rxFifoClear;
160
reg txFifoClear;
161 6 robfinch
reg rxFifoEnable;
162
reg txFifoEnable;
163
wire [5:0] rxQued;
164
wire [5:0] txQued;
165 5 robfinch
 
166
// test
167
wire txd1;
168
 
169
assign data_present = ~rxEmpty;
170
 
171 6 robfinch
assign rxITrig = rxQued[5:2] >= rxThres;
172
assign txITrig = txQued[5:2] <= txThres;
173
wire rxDRQ1 = (rxFifoEnable ? rxITrig : ~rxEmpty);
174
wire txDRQ1 = (txFifoEnable ? txITrig : txEmpty);
175 5 robfinch
assign rxDRQ_o = dmaEnable & rxDRQ1;
176
assign txDRQ_o = dmaEnable & txDRQ1;
177
wire rxIRQ = rxIe & rxDRQ1;
178
wire txIRQ = txIe & txDRQ1;
179
 
180
reg [11:0] cmd0, cmd1, cmd2, cmd3;
181
reg [11:0] ctrl0, ctrl1, ctrl2, ctrl3;
182
 
183
always_ff @(posedge clk_i)
184
        irq_o <=
185
          rxIRQ
186
        | txIRQ
187
        | (rxTout & rxToutIe)
188
        | (lineStatusChange & lineStatusChangeIe)
189
        | (modemStatusChange & modemStatusChangeIe)
190
        ;
191
 
192
// Hold onto address and data an extra cycle.
193
// The extra cycle updates or reads the serial transmit / receive.
194
reg [11:0] dati;
195
always_ff @(posedge clk_i)
196
        dati <= dat_i;
197
reg [3:0] adr_h;
198
always_ff @(posedge clk_i)
199
        adr_h <= adr_i;
200
reg we;
201
always_ff @(posedge clk_i)
202
        we <= we_i;
203
 
204
wire [11:0] rx_do;
205
wire rdrx = ack_o && adr_h==`UART_TRB && ~we;
206
wire txrx = ack_o && adr_h==`UART_TRB;
207
 
208
wire cs = cs_i & cyc_i & stb_i;
209
 
210
ack_gen #(
211
        .READ_STAGES(1),
212
        .WRITE_STAGES(0),
213
        .REGISTER_OUTPUT(1)
214
) uag1
215
(
216
        .rst_i(rst_i),
217
        .clk_i(clk_i),
218
        .ce_i(1'b1),
219
        .i(cs),
220
        .we_i(cs & we),
221
        .o(ack_o),
222
        .rid_i(0),
223
        .wid_i(0),
224
        .rid_o(),
225
        .wid_o()
226
);
227
 
228
uart6551Rx_x12 uart_rx0
229
(
230
        .rst(rst_i),
231
        .clk(clk_i),
232
        .cyc(cyc_i),
233
        .cs(rdrx),
234
        .wr(we),
235
        .dout(rx_do),
236
        .ack(),
237 6 robfinch
        .fifoEnable(rxFifoEnable),
238 5 robfinch
        .fifoClear(rxFifoClear),
239
        .clearGErr(1'b0),
240
        .wordLength(wordLength),
241
        .parityCtrl(parityCtrl),
242
        .frameSize(frameSize),
243
        .stop_bits(stopBits),
244
        .baud16x_ce(baud16rx),
245
        .clear(1'b0),
246
        .rxd(llb ? txd1 : rxd_i),
247
        .full(),
248
        .empty(rxEmpty),
249
        .frameErr(frameErr),
250
        .overrun(overrun),
251
        .parityErr(parityErr),
252
        .break_o(rxBreak),
253
        .gerr(rxGErr),
254
        .qcnt(rxQued),
255
        .cnt(rxCnt)
256
);
257
 
258
uart6551Tx_x12 uart_tx0
259
(
260
        .rst(rst_i),
261
        .clk(clk_i),
262
        .cyc(cyc_i),
263
        .cs(txrx),
264
        .wr(we),
265
        .din(dati),
266
        .ack(),
267 6 robfinch
        .fifoEnable(txFifoEnable),
268 5 robfinch
        .fifoClear(txFifoClear),
269
        .txBreak(txBreak),
270
        .frameSize(frameSize),  // 16 x 10 bits
271
        .wordLength(wordLength),// 8 bits
272
        .parityCtrl(parityCtrl),// no parity
273
        .baud16x_ce(baud16),
274
        .cts(ctsx[1]|~hwfc),
275
        .clear(clear),
276
        .txd(txd1),
277
        .full(txFull),
278
        .empty(txEmpty),
279
        .qcnt(txQued)
280
);
281
 
282
assign txd_o = llb ? 1'b1 : txd1;
283
 
284
assign lineStatusReg = {4'h0,rxGErr,1'b0,txFull,rxBreak,1'b0,1'b0,1'b0,1'b0};
285
assign modemStatusChange = deltaDcd|deltaRi|deltaDsr|deltaCts;  // modem status delta
286
assign modemStatusReg = {4'h0,1'b0,~rix[1],1'b0,~ctsx[1],deltaDcd, deltaRi, deltaDsr, deltaCts};
287
assign irqStatusReg = {irq_o,3'b0,irq_o,2'b00,irqenc,2'b00};
288
 
289
// mux the reg outputs
290
always_ff @(posedge clk_i)
291
if (cs) begin
292
        case(adr_h)
293
        `UART_TRB:      dat_o <= {4'h0,rx_do};  // receiver holding register
294 6 robfinch
        `UART_STAT:     dat_o <= {irq_o,3'h0,irq_o,dsrx[1],dcdx[1],txFifoEnable ? ~txFull : txEmpty,~rxEmpty,overrun,frameErr,parityErr};
295 5 robfinch
        `UART_CMD:      dat_o <= cmd0;
296
        `UART_CTRL:     dat_o <= ctrl0;
297
        `UART_IRQS:     dat_o <= irqStatusReg;
298
        `UART_MS:               dat_o <= modemStatusReg;
299
        `UART_LS:               dat_o <= lineStatusReg;
300
        `UART_CMD1:     dat_o <= cmd1;
301
        `UART_CMD2:     dat_o <= cmd2;
302
        `UART_CMD3:     dat_o <= cmd3;
303
        `UART_CTRL1:    dat_o <= ctrl1;
304
        `UART_CTRL2:    dat_o <= ctrl2;
305
        `UART_CTRL3:    dat_o <= ctrl3;
306
        `UART_CLK1:             dat_o <= clkdiv[23:12];
307
        `UART_CLK2:             dat_o <= clkdiv[11: 0];
308
        default:        dat_o <= 12'h0;
309
        endcase
310
end
311
else
312
        dat_o <= 12'h0;
313
 
314
 
315
// register updates
316
always_ff @(posedge clk_i)
317
if (rst_i) begin
318
        rts_no <= HIGH;
319
        dtr_no <= HIGH;
320
        // interrupts
321
        rxIe                            <= 1'b0;
322
        txIe                            <= 1'b0;
323
        modemStatusChangeIe     <= 1'b0;
324
        lineStatusChangeIe      <= 1'b0;
325
        hwfc                            <= 1'b0;
326
        modemStatusChangeIe     <= 1'b0;
327
        lineStatusChangeIe      <= 1'b0;
328
        dmaEnable                       <= 1'b0;
329
        // clock control
330
        baudRateSel <= 5'h0;
331
        rxClkSrc        <= 1'b0;                // ** 6551 defaults to zero (external receiver clock)
332
        clkdiv <= pClkDiv;
333
        // frame format
334
        wordLength      <= 4'd8;        // 8 bits
335
        stopBit         <= 1'b0;                // 1 stop bit
336
        parityCtrl      <= 3'd0;        // no parity
337
 
338
        txBreak         <= 1'b0;
339
        // Fifo control
340
        txFifoClear     <= 1'b1;
341
        rxFifoClear <= 1'b1;
342 6 robfinch
        rxFifoEnable    <= 1'b1;
343
        txFifoEnable    <= 1'b1;
344 5 robfinch
        // Test
345
        llb                     <= 1'b0;
346
        selCD           <= 1'b0;
347
        accessCD   <= 1'b0;
348
end
349
else begin
350
 
351
        //llb <= 1'b1;
352
        rxFifoClear <= 1'b0;
353
        txFifoClear <= 1'b0;
354
        ctrl2[1] <= 1'b0;
355
        ctrl2[2] <= 1'b0;
356
 
357
        if (cs & we) begin
358
                case (adr_h)    // synopsys full_case parallel_case
359
 
360
                `UART_TRB:      ;
361
                `UART_CLK2:     clkdiv[11: 0] <= dati;
362
                `UART_CLK1:     clkdiv[23:12] <= dati;
363
 
364
                // Writing to the status register does a software reset of some bits.
365
                `UART_STAT:
366
                        begin
367
                                dtr_no <= HIGH;
368
                                rxIe <= 1'b0;
369
                                rts_no <= HIGH;
370
                                txIe <= 1'b0;
371
                                txBreak <= 1'b0;
372
                                llb <= 1'b0;
373
                        end
374
                `UART_CMD:
375
        begin
376
                cmd0 <= dati[7:0];
377
                                        dtr_no <= ~dati[0];
378
                rxIe   <= ~dati[1];
379
                case(dati[3:2])
380
                2'd0:   begin rts_no <= 1'b1; txIe <= 1'b0; txBreak <= 1'b0; end
381
                2'd1: begin rts_no <= 1'b0; txIe <= 1'b1; txBreak <= 1'b0; end
382
                2'd2: begin rts_no <= 1'b0; txIe <= 1'b0; txBreak <= 1'b0; end
383
                2'd3: begin rts_no <= 1'b0; txIe <= 1'b0; txBreak <= 1'b1; end
384
                endcase
385
                llb <= dati[4];
386
          parityCtrl <= dati[7:5];    //000=none,001=odd,011=even,101=force 1,111 = force 0
387
        end
388
    `UART_CMD1:
389
        begin
390
                cmd1 <= dati;
391
                lineStatusChangeIe  <= dati[0];
392
                modemStatusChangeIe <= dati[1];
393
                rxToutIe <= dati[2];
394
        end
395
    `UART_CMD2:
396
        cmd2 <= dati;
397
    `UART_CMD3:
398
                cmd3 <= dati;
399
 
400
    `UART_CTRL:
401
                begin
402
                        ctrl0 <= dati;
403
                baudRateSel[3:0] <= dati[3:0];
404
                                rxClkSrc <= dati[4];                            // 1 = baud rate generator, 0 = external
405
        //11=5,10=6,01=7,00=8
406
        case({dati[8],dati[6:5]})
407
        3'd0:   wordLength <= 4'd8;
408
        3'd1:   wordLength <= 4'd7;
409
        3'd2:   wordLength <= 4'd6;
410
        3'd3:   wordLength <= 4'd5;
411
        3'd4:   wordLength <= 4'd12;
412
        3'd5:   wordLength <= 4'd11;
413
        3'd6:   wordLength <= 4'd10;
414
        3'd7:   wordLength <= 4'd9;
415
        endcase
416
        stopBit    <= dati[7];      //0=1,1=1.5 or 2
417
        end
418
    `UART_CTRL1:
419
                // Extended word length, values beyond 11 not supported.
420
                ctrl1 <= dati;
421
        `UART_CTRL2:
422
        begin
423
                ctrl2 <= dati;
424 6 robfinch
        rxFifoEnable <= dati[0];
425
        txFifoEnable <= dati[1];
426
        rxFifoClear <= dati[2];
427
        txFifoClear <= dati[3];
428 5 robfinch
        case (dati[5:4])
429
        2'd0:   txThres <= 4'd1;                // one-byte
430
        2'd1:   txThres <= pFifoSize / 4;       // one-quarter full
431
        2'd2:   txThres <= pFifoSize / 2;       // one-half full
432
        2'd3:   txThres <= pFifoSize * 3 / 4;   // three-quarters full
433
        endcase
434
        case (dati[7:6])
435
        2'd0:   rxThres <= 4'd1;                // one-byte
436
        2'd1:   rxThres <= pFifoSize / 4;       // one-quarter full
437
        2'd2:   rxThres <= pFifoSize / 2;       // one-half full
438
        2'd3:   rxThres <= pFifoSize * 3 / 4;   // three quarters full
439
        endcase
440
      end
441
    `UART_CTRL3:
442
      begin
443
        ctrl3 <= dati;
444
                                hwfc <= dati[0];
445
                                dmaEnable <= dati[2];
446
                baudRateSel[4] <= dati[3];
447
                selCD <= dati[6];
448
                accessCD <= dati[7];
449
        end
450
                default:
451
                        ;
452
                endcase
453
        end
454
end
455
 
456
// ----------------------------------------------------------------------------
457
// Baud rate control.
458
// ----------------------------------------------------------------------------
459
 
460
always_ff @(posedge clk_i)
461
        xClkSrc <= baudRateSel==5'd0;
462
 
463
wire [pCounterBits-1:0] bclkdiv;
464 6 robfinch
uart6551BaudLUT #(
465
        .CLK_FREQ(CLK_FREQ),
466
        .pCounterBits(pCounterBits)
467
) ublt1 (.a(baudRateSel), .o(bclkdiv));
468 5 robfinch
 
469
reg [pCounterBits-1:0] clkdiv2;
470
always_ff @(posedge clk_i)
471
        clkdiv2 <= selCD ? clkdiv : bclkdiv;
472
 
473
always_ff @(posedge clk_i)
474
if (rst_i)
475
        c <= 1'd1;
476
else begin
477
        c <= c + 2'd1;
478
        if (c >= clkdiv2)
479
                c <= 2'd1;
480
end
481
 
482
// for detecting an edge on the baud clock
483
wire ibaud16 = c == 2'd1;
484
 
485
// Detect an edge on the external clock
486
wire xclkEdge;
487
edge_det ed1(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(xclks[1]), .pe(xclkEdge), .ne() );
488
 
489
// Detect an edge on the external clock
490
wire rxClkEdge;
491
edge_det ed2(.rst(rst_i), .clk(clk_i), .ce(1'b1), .i(RxCs[1]), .pe(rxClkEdge), .ne() );
492
 
493
always_comb
494
if (xClkSrc)            // 16x external clock (xclk)
495
        baud16 <= xclkEdge;
496
else
497
        baud16 <= ibaud16;
498
 
499
assign baud16rx = rxClkSrc ? baud16 : rxClkEdge;
500
 
501
//------------------------------------------------------------
502
// external signal synchronization
503
//------------------------------------------------------------
504
 
505
// External receiver clock
506
always_ff @(posedge clk_i)
507
        RxCs <= {RxCs[1:0],RxC_i};
508
 
509
// External baud clock
510
always_ff @(posedge clk_i)
511
        xclks <= {xclks[1:0],xclk_i};
512
 
513
 
514
always_ff @(posedge clk_i)
515
        ctsx <= {ctsx[0],llb?~rts_no:~cts_ni};
516
 
517
always_ff @(posedge clk_i)
518
        dcdx <= {dcdx[0],~dcd_ni};
519
 
520
always_ff @(posedge clk_i)
521
        dsrx <= {dsrx[0],llb?~dtr_no:~dsr_ni};
522
 
523
always_ff @(posedge clk_i)
524
        rix <= {rix[0],~ri_ni};
525
 
526
//------------------------------------------------------------
527
// state change detectors
528
//------------------------------------------------------------
529
 
530
wire ne_stat;
531
edge_det ued3 (
532
        .rst(rst_i),
533
        .clk(clk_i),
534
        .ce(1'b1),
535
        .i(ack_o && adr_i==`UART_MS && ~we_i),
536
        .pe(),
537
        .ne(ne_stat),
538
        .ee()
539
);
540
 
541
// detect a change on the dsr signal
542
always_ff @(posedge clk_i)
543
if (rst_i)
544
        deltaDsr <= 1'b0;
545
else begin
546
        if (ne_stat)
547
                deltaDsr <= 0;
548
        else if (~deltaDsr)
549
                deltaDsr <= dsrx[1] ^ dsrx[0];
550
end
551
 
552
// detect a change on the dcd signal
553
always_ff @(posedge clk_i)
554
if (rst_i)
555
        deltaDcd <= 1'b0;
556
else begin
557
        if (ne_stat)
558
                deltaDcd <= 0;
559
        else if (~deltaDcd)
560
                deltaDcd <= dcdx[1] ^ dcdx[0];
561
end
562
 
563
// detect a change on the cts signal
564
always_ff @(posedge clk_i)
565
if (rst_i)
566
        deltaCts <= 1'b0;
567
else begin
568
        if (ne_stat)
569
                deltaCts <= 0;
570
        else if (~deltaCts)
571
                deltaCts <= ctsx[1] ^ ctsx[0];
572
end
573
 
574
// detect a change on the ri signal
575
always_ff @(posedge clk_i)
576
if (rst_i)
577
        deltaRi <= 1'b0;
578
else begin
579
        if (ne_stat)
580
                deltaRi <= 0;
581
        else if (~deltaRi)
582
                deltaRi <= rix[1] ^ rix[0];
583
end
584
 
585
// detect a change in line status
586
reg [7:0] pLineStatusReg;
587
always_ff @(posedge clk_i)
588
        pLineStatusReg <= lineStatusReg;
589
 
590
assign lineStatusChange = pLineStatusReg != lineStatusReg;
591
 
592
//-----------------------------------------------------
593
 
594
// compute recieve timeout
595
always_comb
596
        rxToutMax <= (wordLength << 2) + 6'd12;
597
 
598
always_ff @(posedge clk_i)
599
if (rst_i)
600
        rxTout <= 1'b0;
601
else begin
602
        // read of receiver clears timeout counter
603
        if (rdrx)
604
                rxTout <= 1'b0;
605
        // Don't time out if the fifo is empty
606
        else if (rxCnt[9:4]==rxToutMax && ~rxEmpty)
607
                rxTout <= 1'b1;
608
end
609
 
610
 
611
//-----------------------------------------------------
612
// compute the 2x number of stop bits
613
always_comb
614
if (stopBit==1'b0)          // one stop bit
615
        stopBits <= 3'd2;
616
else if (wordLength==4'd8 && parityCtrl != 3'd0)
617
        stopBits <= 3'd2;
618
else if (wordLength==4'd5 && parityCtrl == 3'd0)        // 5 bits - 1 1/2 stop bit
619
        stopBits <= 3'd3;
620
else
621
        stopBits <= 3'd4;          // two stop bits
622
 
623
 
624
// compute frame size
625
// frame size is one less
626
always_ff @(posedge clk_i)
627
        frameSize <= {wordLength + 4'd1 + stopBits[2:1] + parityCtrl[0], stopBits[0],3'b0} - 2'd1;
628
 
629
//-----------------------------------------------------
630
// encode IRQ mailbox
631
always_comb
632
        irqenc <=
633
                lineStatusChange ? 3'd0 :
634
                ~rxDRQ_o ? 3'd1 :
635
                rxTout ? 3'd2 :
636
                ~txDRQ_o ? 3'd3 :
637
                modemStatusChange ? 3'd4 :
638
                3'd0;
639
 
640
endmodule

powered by: WebSVN 2.1.0

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