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

Subversion Repositories socgen

[/] [socgen/] [trunk/] [Projects/] [opencores.org/] [wishbone/] [ip/] [wb_uart16550/] [rtl/] [verilog/] [regs] - Blame information for rev 131

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 131 jt_eaton
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  uart_regs.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
////  Registers of the uart 16550 core                            ////
19
////                                                              ////
20
////  Known problems (limits):                                    ////
21
////  Inserts 1 wait state in all WISHBONE transfers              ////
22
////                                                              ////
23
////  To Do:                                                      ////
24
////  Nothing or verification.                                    ////
25
////                                                              ////
26
////  Author(s):                                                  ////
27
////      - gorban@opencores.org                                  ////
28
////      - Jacob Gorban                                          ////
29
////      - Igor Mohor (igorm@opencores.org)                      ////
30
////                                                              ////
31
////  Created:        2001/05/12                                  ////
32
////  Last Updated:   (See log for the revision history           ////
33
////                                                              ////
34
////                                                              ////
35
//////////////////////////////////////////////////////////////////////
36
////                                                              ////
37
//// Copyright (C) 2000, 2001 Authors                             ////
38
////                                                              ////
39
//// This source file may be used and distributed without         ////
40
//// restriction provided that this copyright statement is not    ////
41
//// removed from the file and that any derivative work contains  ////
42
//// the original copyright notice and the associated disclaimer. ////
43
////                                                              ////
44
//// This source file is free software; you can redistribute it   ////
45
//// and/or modify it under the terms of the GNU Lesser General   ////
46
//// Public License as published by the Free Software Foundation; ////
47
//// either version 2.1 of the License, or (at your option) any   ////
48
//// later version.                                               ////
49
////                                                              ////
50
//// This source is distributed in the hope that it will be       ////
51
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
52
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
53
//// PURPOSE.  See the GNU Lesser General Public License for more ////
54
//// details.                                                     ////
55
////                                                              ////
56
//// You should have received a copy of the GNU Lesser General    ////
57
//// Public License along with this source; if not, download it   ////
58
//// from http://www.opencores.org/lgpl.shtml                     ////
59
////                                                              ////
60
//////////////////////////////////////////////////////////////////////
61
//
62
// CVS Revision History
63
//
64
// $Log: not supported by cvs2svn $
65
// Revision 1.41  2004/05/21 11:44:41  tadejm
66
// Added synchronizer flops for RX input.
67
//
68
// Revision 1.40  2003/06/11 16:37:47  gorban
69
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
70
//
71
// Revision 1.39  2002/07/29 21:16:18  gorban
72
// The uart_defines.v file is included again in sources.
73
//
74
// Revision 1.38  2002/07/22 23:02:23  gorban
75
// Bug Fixes:
76
//  * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
77
//   Problem reported by Kenny.Tung.
78
//  * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
79
//
80
// Improvements:
81
//  * Made FIFO's as general inferrable memory where possible.
82
//  So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
83
//  This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
84
//
85
//
86
// Revision 1.37  2001/12/27 13:24:09  mohor
87
// lsr[7] was not showing overrun errors.
88
//
89
// Revision 1.36  2001/12/20 13:25:46  mohor
90
// rx push changed to be only one cycle wide.
91
//
92
// Revision 1.35  2001/12/19 08:03:34  mohor
93
// Warnings cleared.
94
//
95
// Revision 1.34  2001/12/19 07:33:54  mohor
96
// Synplicity was having troubles with the comment.
97
//
98
// Revision 1.33  2001/12/17 10:14:43  mohor
99
// Things related to msr register changed. After THRE IRQ occurs, and one
100
// character is written to the transmit fifo, the detection of the THRE bit in the
101
// LSR is delayed for one character time.
102
//
103
// Revision 1.32  2001/12/14 13:19:24  mohor
104
// MSR register fixed.
105
//
106
// Revision 1.31  2001/12/14 10:06:58  mohor
107
// After reset modem status register MSR should be reset.
108
//
109
// Revision 1.30  2001/12/13 10:09:13  mohor
110
// thre irq should be cleared only when being source of interrupt.
111
//
112
// Revision 1.29  2001/12/12 09:05:46  mohor
113
// LSR status bit 0 was not cleared correctly in case of reseting the FCR (rx fifo).
114
//
115
//
116
// Revision 1.27  2001/12/06 14:51:04  gorban
117
// Bug in LSR[0] is fixed.
118
// All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers.
119
//
120
// Revision 1.26  2001/12/03 21:44:29  gorban
121
// Updated specification documentation.
122
// Added full 32-bit data bus interface, now as default.
123
// Address is 5-bit wide in 32-bit data bus mode.
124
// Added wb_sel_i input to the core. It's used in the 32-bit mode.
125
// Added debug interface with two 32-bit read-only registers in 32-bit mode.
126
// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
127
// My small test bench is modified to work with 32-bit mode.
128
//
129
// Revision 1.25  2001/11/28 19:36:39  gorban
130
// Fixed: timeout and break didn't pay attention to current data format when counting time
131
//
132
// Revision 1.24  2001/11/26 21:38:54  gorban
133
// Lots of fixes:
134
// Break condition wasn't handled correctly at all.
135
// LSR bits could lose their values.
136
// LSR value after reset was wrong.
137
// Timing of THRE interrupt signal corrected.
138
// LSR bit 0 timing corrected.
139
//
140
// Revision 1.23  2001/11/12 21:57:29  gorban
141
// fixed more typo bugs
142
//
143
// Revision 1.22  2001/11/12 15:02:28  mohor
144
// lsr1r error fixed.
145
//
146
// Revision 1.21  2001/11/12 14:57:27  mohor
147
// ti_int_pnd error fixed.
148
//
149
// Revision 1.20  2001/11/12 14:50:27  mohor
150
// ti_int_d error fixed.
151
//
152
// Revision 1.19  2001/11/10 12:43:21  gorban
153
// Logic Synthesis bugs fixed. Some other minor changes
154
//
155
// Revision 1.18  2001/11/08 14:54:23  mohor
156
// Comments in Slovene language deleted, few small fixes for better work of
157
// old tools. IRQs need to be fix.
158
//
159
// Revision 1.17  2001/11/07 17:51:52  gorban
160
// Heavily rewritten interrupt and LSR subsystems.
161
// Many bugs hopefully squashed.
162
//
163
// Revision 1.16  2001/11/02 09:55:16  mohor
164
// no message
165
//
166
// Revision 1.15  2001/10/31 15:19:22  gorban
167
// Fixes to break and timeout conditions
168
//
169
// Revision 1.14  2001/10/29 17:00:46  gorban
170
// fixed parity sending and tx_fifo resets over- and underrun
171
//
172
// Revision 1.13  2001/10/20 09:58:40  gorban
173
// Small synopsis fixes
174
//
175
// Revision 1.12  2001/10/19 16:21:40  gorban
176
// Changes data_out to be synchronous again as it should have been.
177
//
178
// Revision 1.11  2001/10/18 20:35:45  gorban
179
// small fix
180
//
181
// Revision 1.10  2001/08/24 21:01:12  mohor
182
// Things connected to parity changed.
183
// Clock devider changed.
184
//
185
// Revision 1.9  2001/08/23 16:05:05  mohor
186
// Stop bit bug fixed.
187
// Parity bug fixed.
188
// WISHBONE read cycle bug fixed,
189
// OE indicator (Overrun Error) bug fixed.
190
// PE indicator (Parity Error) bug fixed.
191
// Register read bug fixed.
192
//
193
// Revision 1.10  2001/06/23 11:21:48  gorban
194
// DL made 16-bit long. Fixed transmission/reception bugs.
195
//
196
// Revision 1.9  2001/05/31 20:08:01  gorban
197
// FIFO changes and other corrections.
198
//
199
// Revision 1.8  2001/05/29 20:05:04  gorban
200
// Fixed some bugs and synthesis problems.
201
//
202
// Revision 1.7  2001/05/27 17:37:49  gorban
203
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
204
//
205
// Revision 1.6  2001/05/21 19:12:02  gorban
206
// Corrected some Linter messages.
207
//
208
// Revision 1.5  2001/05/17 18:34:18  gorban
209
// First 'stable' release. Should be sythesizable now. Also added new header.
210
//
211
// Revision 1.0  2001-05-17 21:27:11+02  jacob
212
// Initial revision
213
//
214
//
215
module `VARIANT`REGS
216
  #(parameter PRESCALER_PRESET = 16'h0000 )
217
   (
218
   input  wire                             clk,
219
   input  wire                             wb_rst_i,
220
   input  wire [15:0]                      wb_dat_i,
221
   input  wire [7:0]                       tr_reg_wdata,
222
   input  wire [3:0]                       ie_reg_wdata,
223
 
224
   input  wire                             wb_we_i,
225
   input  wire                             wb_re_i,
226
   input  wire                             tr_reg_wr,
227
   input  wire                             rb_dll_reg_rd,
228
 
229
 
230
   input  wire                             ls_reg_rd,
231
   input  wire                             ms_reg_rd,
232
   input  wire                             ii_reg_rd,
233
   input  wire                             ie_reg_wr,
234
 
235
   input  wire                             cts_pad_i,
236
   input  wire                             dsr_pad_i,
237
   input  wire                             ri_pad_i,
238
   input  wire                             dcd_pad_i,
239
   input  wire                             srx_pad_i,
240
 
241
 
242
   output wire                             stx_pad_o,
243
   output wire                             rts_pad_o,
244
   output wire                             dtr_pad_o,
245
   output  reg                             int_o,
246
   output wire                             baud_o,
247
   output  reg  [3:0]                      ier,
248
   output  reg  [3:0]                      iir,
249
   input  wire  [7:0]                      fcr,
250
   input  wire  [4:0]                      mcr,
251
   input  wire  [7:0]                      lcr,
252
   output  reg  [7:0]                      msr,
253
   output wire  [7:0]                      lsr,
254
   output wire  [`UART_FIFO_COUNTER_W-1:0] rf_count,
255
   output wire  [`UART_FIFO_COUNTER_W-1:0] tf_count,
256
   output wire  [2:0]                      tstate,
257
   output wire  [3:0]                      rstate,
258
   output wire  [7:0]                      rdata_rb_dll,
259
   output wire  [7:0]                      rdata_ie_dlh
260
 
261
          );
262
 
263
 
264
 
265
   reg                      enable;
266
   wire                     srx_pad;
267
 
268
   reg [15:0]               dl;  // 32-bit divisor latch
269
 
270
   reg                      start_dlc; // activate dlc on writing to UART_DL1
271
   reg                      lsr_mask_d; // delay for lsr_mask condition
272
   reg                      msi_reset; // reset MSR 4 lower bits indicator
273
   //reg                                         threi_clear; // THRE interrupt clear flag
274
   reg [15:0]               dlc;  // 32-bit divisor latch counter
275
 
276
   reg [3:0]                trigger_level; // trigger level of the receiver FIFO
277
   reg                      rx_reset;
278
   reg                      tx_reset;
279
 
280
   wire                     dlab;               // divisor latch access bit
281
 
282
   wire                     loopback;           // loopback bit (MCR bit 4)
283
   wire                     cts, dsr, ri, dcd;       // effective signals
284
   wire                     cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
285
 
286
 
287
   // LSR bits wires and regs
288
 
289
   wire                  lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
290
   reg                      lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
291
   wire                  lsr_mask; // lsr_mask
292
 
293
 
294
   // Interrupt signals
295
   wire                  rls_int;  // receiver line status interrupt
296
   wire                  rda_int;  // receiver data available interrupt
297
   wire                  ti_int;   // timeout indicator interrupt
298
   wire                  thre_int; // transmitter holding register empty interrupt
299
   wire                  ms_int;   // modem status interrupt
300
 
301
   // FIFO signals
302
   reg                      tf_push;
303
   reg                      rf_pop;
304
   wire [`UART_FIFO_REC_WIDTH-1:0]   rf_data_out;
305
   wire                  rf_error_bit; // an error (parity or framing) is inside the fifo
306
   wire                  rf_overrun;
307
   wire                  rf_push_pulse;
308
 
309
 
310
   wire [9:0]                  counter_t;
311
 
312
   wire                  thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
313
   reg [7:0]                  block_cnt;   // While counter counts, THRE status is blocked (delayed one character cycle)
314
   reg [7:0]                  block_value; // One character length minus stop bit
315
 
316
   // Transmitter Instance
317
   wire                  serial_out;
318
 
319
   wire                  serial_in;
320
 
321
   wire     lsr_mask_condition;
322
   wire     iir_read;
323
   wire     msr_read;
324
   wire     fifo_read;
325
   wire     fifo_write;
326
 
327
   wire  rls_int_rise;
328
   wire  thre_int_rise;
329
   wire  ms_int_rise;
330
   wire  ti_int_rise;
331
   wire  rda_int_rise;
332
 
333
   reg      lsr0_d;
334
   reg      lsr1_d; // delayed
335
 
336
   reg      lsr2_d; // delayed
337
 
338
   reg      lsr3_d; // delayed
339
   reg      lsr4_d; // delayed
340
   reg      lsr5_d;
341
   reg      lsr6_d;
342
 
343
   reg      lsr7_d;
344
 
345
 
346
   reg      rls_int_d;
347
   reg      thre_int_d;
348
   reg      ms_int_d;
349
   reg      ti_int_d;
350
   reg      rda_int_d;
351
 
352
   reg      rls_int_pnd;
353
   reg      rda_int_pnd;
354
   reg      thre_int_pnd;
355
   reg      ms_int_pnd;
356
   reg      ti_int_pnd;
357
 
358
 
359
   //
360
   // ASSIGNS
361
   //
362
 
363
   assign              rdata_rb_dll = dlab ? dl[7:0]  : rf_data_out[10:3];
364
   assign              rdata_ie_dlh = dlab ? dl[15:8] : {4'd0,ier};
365
 
366
 
367
   assign baud_o = enable; // baud_o is actually the enable signal
368
 
369
   assign                                     lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
370
 
371
 
372
   assign                                     {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
373
 
374
   assign                  {cts_c, dsr_c, ri_c, dcd_c} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
375
   : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
376
 
377
   assign                                     dlab = lcr[`UART_LC_DL];
378
   assign                                     loopback = mcr[4];
379
 
380
   // assign modem outputs
381
   assign                                     rts_pad_o = mcr[`UART_MC_RTS];
382
   assign                                     dtr_pad_o = mcr[`UART_MC_DTR];
383
   // handle loopback
384
   assign                  serial_in = loopback ? serial_out : srx_pad;
385
   assign stx_pad_o = loopback ? 1'b1 : serial_out;
386
 
387
 
388
 
389
 
390
   `VARIANT`TRANSMITTER  transmitter(
391
        .clk             (clk),
392
        .wb_rst_i        (wb_rst_i),
393
        .lcr             (lcr),
394
        .tf_push         (tf_push),
395
        .tf_data_in      (tr_reg_wdata),
396
        .enable          (enable),
397
        .stx_pad_o       (serial_out),
398
        .tstate          (tstate),
399
        .tf_count        (tf_count),
400
        .tx_reset        (tx_reset),
401
        .lsr_mask        (lsr_mask));
402
 
403
 
404
 
405
   // Synchronizing and sampling serial RX input
406
   `VARIANT`SYNC_FLOPS
407
    #(.width(1),
408
      .init_value(1'b1))
409
    i_uart_sync_flops
410
     (
411
      .rst_i           (wb_rst_i),
412
      .clk_i           (clk),
413
      .stage1_rst_i    (1'b0),
414
      .stage1_clk_en_i (1'b1),
415
      .async_dat_i     (srx_pad_i),
416
      .sync_dat_o      (srx_pad)
417
      );
418
 
419
 
420
 
421
 
422
 
423
 
424
   // Receiver Instance
425
   `VARIANT`RECEIVER  receiver(
426
                .clk               (clk),
427
                .wb_rst_i          (wb_rst_i),
428
                .lcr               (lcr),
429
                .rf_pop            (rf_pop),
430
                .srx_pad_in        (serial_in),
431
                .enable            (enable),
432
                .counter_t         (counter_t),
433
                .rf_count          (rf_count),
434
                .rf_data_out       (rf_data_out),
435
                .rf_error_bit      (rf_error_bit),
436
                .rf_overrun        (rf_overrun),
437
                .rx_reset          (rx_reset),
438
                .lsr_mask          (lsr_mask),
439
                .rstate            (rstate),
440
                .rf_push_pulse     ( rf_push_pulse)
441
 
442
);
443
 
444
 
445
 
446
   // rf_pop signal handling
447
   always @(posedge clk )
448
     begin
449
    if (wb_rst_i)
450
      rf_pop <=  0;
451
    else
452
      if (rf_pop)    // restore the signal to 0 after one clock cycle
453
        rf_pop <=  0;
454
      else
455
        if (wb_re_i && rb_dll_reg_rd && !dlab)
456
          rf_pop <=  1; // advance read pointer
457
     end
458
 
459
 
460
 
461
   assign lsr_mask_condition = (wb_re_i && ls_reg_rd && !dlab);
462
   assign iir_read = (wb_re_i && ii_reg_rd && !dlab);
463
   assign msr_read = (wb_re_i && ms_reg_rd && !dlab);
464
   assign fifo_read = (wb_re_i && rb_dll_reg_rd && !dlab);
465
   assign fifo_write = (tr_reg_wr && wb_we_i && !dlab);
466
 
467
   // lsr_mask_d delayed signal handling
468
   always @(posedge clk )
469
     begin
470
    if (wb_rst_i)
471
      lsr_mask_d <=  0;
472
    else // reset bits in the Line Status Register
473
      lsr_mask_d <=  lsr_mask_condition;
474
     end
475
 
476
   // lsr_mask is rise detected
477
   assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
478
 
479
   // msi_reset signal handling
480
   always @(posedge clk )
481
     begin
482
    if (wb_rst_i)
483
      msi_reset <=  1;
484
    else
485
      if (msi_reset)
486
        msi_reset <=  0;
487
      else
488
        if (msr_read)
489
          msi_reset <=  1; // reset bits in Modem Status Register
490
     end
491
 
492
 
493
 
494
 
495
   // Interrupt Enable Register
496
 
497
   always @(posedge clk )
498
     if (wb_rst_i)
499
       begin
500
      ier <=  4'b0000; // no interrupts after reset
501
       end
502
     else
503
       if (wb_we_i && ie_reg_wr && !dlab)
504
       ier <=  ie_reg_wdata;
505
 
506
 
507
 
508
 
509
   // UART_DL2
510
 
511
   always @(posedge clk )
512
     if (wb_rst_i)       dl[15:8] <=  PRESCALER_PRESET[15:8];
513
     else
514
     if (wb_we_i && ie_reg_wr && dlab)
515
       dl[15:8] <=          wb_dat_i[15:8];
516
 
517
 
518
 
519
 
520
   // UART_DL1
521
   always @(posedge clk )
522
     if (wb_rst_i)
523
        dl[7:0]   <=  PRESCALER_PRESET[7:0];
524
     else
525
     if (tr_reg_wr && wb_we_i  && dlab)
526
         dl[7:0]   <=  wb_dat_i[7:0];
527
 
528
 
529
 
530
 
531
 
532
 
533
 
534
 
535
 
536
 
537
   // FIFO Control Register and rx_reset, tx_reset signals
538
   always @(posedge clk )
539
     if (wb_rst_i) begin
540
    rx_reset <=  0;
541
    tx_reset <=  0;
542
     end else
543
       begin
544
      rx_reset <=  fcr[2];
545
      tx_reset <=  fcr[1];
546
       end
547
 
548
 
549
 
550
 
551
 
552
   // TX_FIFO
553
   always @(posedge clk )
554
     if (wb_rst_i)
555
       begin
556
      tf_push   <=  1'b0;
557
      start_dlc <=  1'b0;
558
       end
559
     else
560
       if (tr_reg_wr && wb_we_i)
561
     if (dlab)
562
       begin
563
          start_dlc <=  1'b1; // enable DL counter
564
          tf_push   <=  1'b0;
565
       end
566
     else
567
       begin
568
          tf_push   <=  1'b1;
569
          start_dlc <=  1'b0;
570
       end // else: !if(dlab)
571
       else
572
     begin
573
        start_dlc <=  1'b0;
574
        tf_push   <=  1'b0;
575
     end // else: !if(dlab)
576
 
577
 
578
 
579
 
580
 
581
 
582
 
583
   // Receiver FIFO trigger level selection logic (asynchronous mux)
584
   always @(fcr)
585
     case (fcr[`UART_FC_TL])
586
       2'b00 : trigger_level = 1;
587
       2'b01 : trigger_level = 4;
588
       2'b10 : trigger_level = 8;
589
       2'b11 : trigger_level = 14;
590
     endcase // case(fcr[`UART_FC_TL])
591
 
592
   //
593
   //  STATUS REGISTERS  //
594
   //
595
 
596
   // Modem Status Register
597
   reg [3:0] delayed_modem_signals;
598
   always @(posedge clk )
599
     begin
600
    if (wb_rst_i)
601
      begin
602
           msr <=  0;
603
         delayed_modem_signals[3:0] <=  0;
604
      end
605
    else begin
606
       msr[`UART_MS_DDCD:`UART_MS_DCTS] <=  msi_reset ? 4'b0 :
607
                        msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
608
       msr[`UART_MS_CDCD:`UART_MS_CCTS] <=  {dcd_c, ri_c, dsr_c, cts_c};
609
       delayed_modem_signals[3:0] <=  {dcd, ri, dsr, cts};
610
    end
611
     end
612
 
613
 
614
   // Line Status Register
615
 
616
   // activation conditions
617
   assign lsr0 = (rf_count==0 && rf_push_pulse);  // data in receiver fifo available set condition
618
   assign lsr1 = rf_overrun;     // Receiver overrun error
619
   assign lsr2 = rf_data_out[1]; // parity error bit
620
   assign lsr3 = rf_data_out[0]; // framing error bit
621
   assign lsr4 = rf_data_out[2]; // break error in the character
622
   assign lsr5 = (tf_count==5'b0 && thre_set_en);  // transmitter fifo is empty
623
   assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
624
   assign lsr7 = rf_error_bit | rf_overrun;
625
 
626
   // lsr bit0 (receiver data available)
627
 
628
 
629
   always @(posedge clk )
630
     if (wb_rst_i) lsr0_d <=  0;
631
     else lsr0_d <=  lsr0;
632
 
633
   always @(posedge clk )
634
     if (wb_rst_i) lsr0r <=  0;
635
     else lsr0r <=  (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
636
            lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted
637
 
638
   // lsr bit 1 (receiver overrun)
639
 
640
   always @(posedge clk )
641
     if (wb_rst_i) lsr1_d <=  0;
642
     else lsr1_d <=  lsr1;
643
 
644
   always @(posedge clk )
645
     if (wb_rst_i) lsr1r <=  0;
646
     else    lsr1r <=     lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
647
 
648
   // lsr bit 2 (parity error)
649
 
650
   always @(posedge clk )
651
     if (wb_rst_i) lsr2_d <=  0;
652
     else lsr2_d <=  lsr2;
653
 
654
   always @(posedge clk )
655
     if (wb_rst_i) lsr2r <=  0;
656
     else lsr2r <=  lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
657
 
658
   // lsr bit 3 (framing error)
659
 
660
 
661
 
662
   always @(posedge clk )
663
     if (wb_rst_i) lsr3_d <=  0;
664
     else lsr3_d <=  lsr3;
665
 
666
   always @(posedge clk )
667
     if (wb_rst_i) lsr3r <=  0;
668
     else lsr3r <=  lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
669
 
670
   // lsr bit 4 (break indicator)
671
 
672
 
673
 
674
 
675
   always @(posedge clk )
676
     if (wb_rst_i) lsr4_d <=  0;
677
     else lsr4_d <=  lsr4;
678
 
679
   always @(posedge clk )
680
     if (wb_rst_i) lsr4r <=  0;
681
     else lsr4r <=  lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
682
 
683
   // lsr bit 5 (transmitter fifo is empty)
684
 
685
 
686
 
687
   always @(posedge clk )
688
     if (wb_rst_i) lsr5_d <=  1;
689
     else lsr5_d <=  lsr5;
690
 
691
   always @(posedge clk )
692
     if (wb_rst_i) lsr5r <=  1;
693
     else lsr5r <=  (fifo_write) ? 0 :  lsr5r || (lsr5 && ~lsr5_d);
694
 
695
   // lsr bit 6 (transmitter empty indicator)
696
 
697
 
698
   always @(posedge clk )
699
     if (wb_rst_i) lsr6_d <=  1;
700
     else lsr6_d <=  lsr6;
701
 
702
   always @(posedge clk )
703
     if (wb_rst_i) lsr6r <=  1;
704
     else lsr6r <=  (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
705
 
706
   // lsr bit 7 (error in fifo)
707
 
708
 
709
   always @(posedge clk )
710
     if (wb_rst_i) lsr7_d <=  0;
711
     else lsr7_d <=  lsr7;
712
 
713
   always @(posedge clk )
714
     if (wb_rst_i) lsr7r <=  0;
715
     else lsr7r <=  lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
716
 
717
   // Frequency divider
718
   always @(posedge clk )
719
     begin
720
    if (wb_rst_i)
721
      dlc <=  0;
722
    else
723
      if (start_dlc | ~ (|dlc))
724
          dlc <=  dl - 1;               // preset counter
725
      else
726
        dlc <=  dlc - 1;              // decrement counter
727
     end
728
 
729
   // Enable signal generation logic
730
   always @(posedge clk )
731
     begin
732
    if (wb_rst_i)
733
      enable <=  1'b0;
734
    else
735
      if (|dl & ~(|dlc))     // dl>0 & dlc==0
736
        enable <=  1'b1;
737
      else
738
        enable <=  1'b0;
739
     end
740
 
741
   // Delaying THRE status for one character cycle after a character is written to an empty fifo.
742
   always @(lcr)
743
     case (lcr[3:0])
744
       4'b0000                             : block_value =  95; // 6 bits
745
       4'b0100                             : block_value = 103; // 6.5 bits
746
       4'b0001, 4'b1000                    : block_value = 111; // 7 bits
747
       4'b1100                             : block_value = 119; // 7.5 bits
748
       4'b0010, 4'b0101, 4'b1001           : block_value = 127; // 8 bits
749
       4'b0011, 4'b0110, 4'b1010, 4'b1101  : block_value = 143; // 9 bits
750
       4'b0111, 4'b1011, 4'b1110           : block_value = 159; // 10 bits
751
       4'b1111                             : block_value = 175; // 11 bits
752
     endcase // case(lcr[3:0])
753
 
754
   // Counting time of one character minus stop bit
755
   always @(posedge clk )
756
     begin
757
    if (wb_rst_i)
758
      block_cnt <=  8'd0;
759
    else
760
      if(lsr5r & fifo_write)  // THRE bit set & write to fifo occured
761
        block_cnt <=  block_value;
762
      else
763
        if (enable & block_cnt != 8'b0)  // only work on enable times
764
          block_cnt <=  block_cnt - 1;  // decrement break counter
765
     end // always of break condition detection
766
 
767
   // Generating THRE status enable signal
768
   assign thre_set_en = ~(|block_cnt);
769
 
770
 
771
   //
772
   //    INTERRUPT LOGIC
773
   //
774
 
775
   assign rls_int  = ier[`UART_IE_RLS]  && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
776
   assign rda_int  = ier[`UART_IE_RDA]  && (rf_count >= {1'b0,trigger_level});
777
   assign thre_int = ier[`UART_IE_THRE] &&  lsr[`UART_LS_TFE];
778
   assign ms_int   = ier[`UART_IE_MS]   && (| msr[3:0]);
779
   assign ti_int   = ier[`UART_IE_RDA]  && (counter_t == 10'b0) && (|rf_count);
780
 
781
 
782
 
783
 
784
 
785
   // delay lines
786
   always  @(posedge clk )
787
     if (wb_rst_i) rls_int_d <=  0;
788
     else rls_int_d <=  rls_int;
789
 
790
   always  @(posedge clk )
791
     if (wb_rst_i) rda_int_d <=  0;
792
     else rda_int_d <=  rda_int;
793
 
794
   always  @(posedge clk )
795
     if (wb_rst_i) thre_int_d <=  0;
796
     else thre_int_d <=  thre_int;
797
 
798
   always  @(posedge clk )
799
     if (wb_rst_i) ms_int_d <=  0;
800
     else ms_int_d <=  ms_int;
801
 
802
   always  @(posedge clk )
803
     if (wb_rst_i) ti_int_d <=  0;
804
     else ti_int_d <=  ti_int;
805
 
806
   // rise detection signals
807
 
808
 
809
 
810
   assign rda_int_rise      = rda_int & ~rda_int_d;
811
   assign rls_int_rise      = rls_int & ~rls_int_d;
812
   assign thre_int_rise     = thre_int & ~thre_int_d;
813
   assign ms_int_rise       = ms_int & ~ms_int_d;
814
   assign ti_int_rise       = ti_int & ~ti_int_d;
815
 
816
   // interrupt pending flags
817
 
818
 
819
   // interrupt pending flags assignments
820
   always  @(posedge clk )
821
     if (wb_rst_i) rls_int_pnd <=  0;
822
     else
823
       rls_int_pnd <=  lsr_mask ? 0 :                          // reset condition
824
               rls_int_rise ? 1 :                        // latch condition
825
               rls_int_pnd && ier[`UART_IE_RLS];    // default operation: remove if masked
826
 
827
   always  @(posedge clk )
828
     if (wb_rst_i) rda_int_pnd <=  0;
829
     else
830
       rda_int_pnd <=  ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 :      // reset condition
831
               rda_int_rise ? 1 :                        // latch condition
832
               rda_int_pnd && ier[`UART_IE_RDA];    // default operation: remove if masked
833
 
834
   always  @(posedge clk )
835
     if (wb_rst_i) thre_int_pnd <=  0;
836
     else
837
       thre_int_pnd <=  fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
838
            thre_int_rise ? 1 :
839
            thre_int_pnd && ier[`UART_IE_THRE];
840
 
841
   always  @(posedge clk )
842
     if (wb_rst_i) ms_int_pnd <=  0;
843
     else
844
       ms_int_pnd <=  msr_read ? 0 :
845
              ms_int_rise ? 1 :
846
              ms_int_pnd && ier[`UART_IE_MS];
847
 
848
   always  @(posedge clk )
849
     if (wb_rst_i) ti_int_pnd <=  0;
850
     else
851
       ti_int_pnd <=  fifo_read ? 0 :
852
              ti_int_rise ? 1 :
853
              ti_int_pnd && ier[`UART_IE_RDA];
854
   // end of pending flags
855
 
856
   // INT_O logic
857
   always @(posedge clk )
858
     begin
859
    if (wb_rst_i)
860
      int_o <=  1'b0;
861
    else
862
      int_o <=
863
            rls_int_pnd        ?    ~lsr_mask             :
864
            rda_int_pnd        ? 1                        :
865
            ti_int_pnd         ? ~fifo_read               :
866
            thre_int_pnd       ? !(fifo_write & iir_read) :
867
            ms_int_pnd         ? ~msr_read                :
868
            0;    // if no interrupt are pending
869
     end
870
 
871
 
872
   // Interrupt Identification register
873
   always @(posedge clk )
874
     begin
875
    if (wb_rst_i)
876
      iir <=  1;
877
    else
878
      if (rls_int_pnd)  // interrupt is pending
879
        begin
880
           iir[`UART_II_II] <=  `UART_II_RLS;    // set identification register to correct value
881
           iir[`UART_II_IP] <=  1'b0;        // and clear the IIR bit 0 (interrupt pending)
882
        end else // the sequence of conditions determines priority of interrupt identification
883
          if (rda_int)
884
        begin
885
           iir[`UART_II_II] <=  `UART_II_RDA;
886
           iir[`UART_II_IP] <=  1'b0;
887
        end
888
          else if (ti_int_pnd)
889
        begin
890
           iir[`UART_II_II] <=  `UART_II_TI;
891
           iir[`UART_II_IP] <=  1'b0;
892
        end
893
          else if (thre_int_pnd)
894
        begin
895
           iir[`UART_II_II] <=  `UART_II_THRE;
896
           iir[`UART_II_IP] <=  1'b0;
897
        end
898
          else if (ms_int_pnd)
899
        begin
900
           iir[`UART_II_II] <=  `UART_II_MS;
901
           iir[`UART_II_IP] <=  1'b0;
902
        end else    // no interrupt is pending
903
          begin
904
             iir[`UART_II_II] <=  0;
905
             iir[`UART_II_IP] <=  1'b1;
906
          end
907
     end
908
 
909
endmodule

powered by: WebSVN 2.1.0

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