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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [uart16550/] [uart_regs.v] - Blame information for rev 363

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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