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 360

Go to most recent revision | 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
   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
   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 [`UART_FIFO_COUNTER_W-1:0]                                               rf_count;
367
   wire [`UART_FIFO_COUNTER_W-1:0]                                               tf_count;
368
   wire [2:0]                                                                    tstate;
369
   wire [3:0]                                                                    rstate;
370
   wire [9:0]                                                                    counter_t;
371 6 julius
 
372 360 julius
   wire                                                                         thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
373
   reg [7:0]                                                                     block_cnt;   // While counter counts, THRE status is blocked (delayed one character cycle)
374
   reg [7:0]                                                                     block_value; // One character length minus stop bit
375 6 julius
 
376 360 julius
   // Transmitter Instance
377
   wire                                                                         serial_out;
378 6 julius
 
379 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);
380 6 julius
 
381 360 julius
   // Synchronizing and sampling serial RX input
382
   uart_sync_flops    i_uart_sync_flops
383
     (
384
      .rst_i           (wb_rst_i),
385
      .clk_i           (clk),
386
      .stage1_rst_i    (1'b0),
387
      .stage1_clk_en_i (1'b1),
388
      .async_dat_i     (srx_pad_i),
389
      .sync_dat_o      (srx_pad)
390
      );
391
   defparam i_uart_sync_flops.width      = 1;
392
   defparam i_uart_sync_flops.init_value = 1'b1;
393 6 julius
 
394 360 julius
   // handle loopback
395
   wire                                                                         serial_in = loopback ? serial_out : srx_pad;
396
   assign stx_pad_o = loopback ? 1'b1 : serial_out;
397 6 julius
 
398 360 julius
   // Receiver Instance
399
   uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
400
                          counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
401 6 julius
 
402
 
403 360 julius
   // Asynchronous reading here because the outputs are sampled in uart_wb.v file 
404
   always @(dl or dlab or ier or iir or scratch
405
            or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i)   // asynchrounous reading
406
     begin
407 6 julius
        case (wb_addr_i)
408 360 julius
          `UART_REG_RB   : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
409
          `UART_REG_IE  : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
410
          `UART_REG_II  : wb_dat_o = {4'b1100,iir};
411
          `UART_REG_LC  : wb_dat_o = lcr;
412
          `UART_REG_LS  : wb_dat_o = lsr;
413
          `UART_REG_MS  : wb_dat_o = msr;
414
          `UART_REG_SR  : wb_dat_o = scratch;
415
          default:  wb_dat_o = 8'b0; // ??
416 6 julius
        endcase // case(wb_addr_i)
417 360 julius
     end // always @ (dl or dlab or ier or iir or scratch...
418 6 julius
 
419
 
420 360 julius
   // rf_pop signal handling
421
   always @(posedge clk or posedge wb_rst_i)
422
     begin
423 6 julius
        if (wb_rst_i)
424 360 julius
          rf_pop <=  0;
425 6 julius
        else
426 360 julius
          if (rf_pop)   // restore the signal to 0 after one clock cycle
427
            rf_pop <=  0;
428
          else
429
            if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
430
              rf_pop <=  1; // advance read pointer
431
     end
432 6 julius
 
433 360 julius
   wire         lsr_mask_condition;
434
   wire         iir_read;
435
   wire         msr_read;
436
   wire         fifo_read;
437
   wire         fifo_write;
438 6 julius
 
439 360 julius
   assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
440
   assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
441
   assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
442
   assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
443
   assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
444 6 julius
 
445 360 julius
   // lsr_mask_d delayed signal handling
446
   always @(posedge clk or posedge wb_rst_i)
447
     begin
448 6 julius
        if (wb_rst_i)
449 360 julius
          lsr_mask_d <=  0;
450 6 julius
        else // reset bits in the Line Status Register
451 360 julius
          lsr_mask_d <=  lsr_mask_condition;
452
     end
453 6 julius
 
454 360 julius
   // lsr_mask is rise detected
455
   assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
456 6 julius
 
457 360 julius
   // msi_reset signal handling
458
   always @(posedge clk or posedge wb_rst_i)
459
     begin
460 6 julius
        if (wb_rst_i)
461 360 julius
          msi_reset <=  1;
462 6 julius
        else
463 360 julius
          if (msi_reset)
464
            msi_reset <=  0;
465
          else
466
            if (msr_read)
467
              msi_reset <=  1; // reset bits in Modem Status Register
468
     end
469 6 julius
 
470
 
471 360 julius
   //
472
   //   WRITES AND RESETS   //
473
   //
474
   // Line Control Register
475
   always @(posedge clk or posedge wb_rst_i)
476
     if (wb_rst_i)
477
       lcr <=  8'b00000011; // 8n1 setting
478
     else
479
       if (wb_we_i && wb_addr_i==`UART_REG_LC)
480
         lcr <=  wb_dat_i;
481 6 julius
 
482 360 julius
   // Interrupt Enable Register or UART_DL2
483
   always @(posedge clk or posedge wb_rst_i)
484
     if (wb_rst_i)
485
       begin
486
          ier <=  4'b0000; // no interrupts after reset
487
`ifdef PRESCALER_PRESET_HARD
488
          dl[`UART_DL2] <=  `PRESCALER_HIGH_PRESET;
489
`else
490
          dl[`UART_DL2] <=  8'b0;
491
`endif
492
       end
493
     else
494
       if (wb_we_i && wb_addr_i==`UART_REG_IE)
495
         if (dlab)
496
           begin
497
              dl[`UART_DL2] <=
498
`ifdef PRESCALER_PRESET_HARD
499
                dl[`UART_DL2];
500
`else
501
                wb_dat_i;
502
`endif
503
           end
504
         else
505
           ier <=  wb_dat_i[3:0]; // ier uses only 4 lsb
506 6 julius
 
507
 
508 360 julius
   // FIFO Control Register and rx_reset, tx_reset signals
509
   always @(posedge clk or posedge wb_rst_i)
510
     if (wb_rst_i) begin
511
        fcr <=  2'b11;
512
        rx_reset <=  0;
513
        tx_reset <=  0;
514
     end else
515
       if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
516
          fcr <=  wb_dat_i[7:6];
517
          rx_reset <=  wb_dat_i[1];
518
          tx_reset <=  wb_dat_i[2];
519
       end else begin
520
          rx_reset <=  0;
521
          tx_reset <=  0;
522
       end
523 6 julius
 
524 360 julius
   // Modem Control Register
525
   always @(posedge clk or posedge wb_rst_i)
526
     if (wb_rst_i)
527
       mcr <=  5'b0;
528
     else
529
       if (wb_we_i && wb_addr_i==`UART_REG_MC)
530
         mcr <=  wb_dat_i[4:0];
531 6 julius
 
532 360 julius
   // Scratch register
533
   // Line Control Register
534
   always @(posedge clk or posedge wb_rst_i)
535
     if (wb_rst_i)
536
       scratch <=  0; // 8n1 setting
537
     else
538
       if (wb_we_i && wb_addr_i==`UART_REG_SR)
539
         scratch <=  wb_dat_i;
540 6 julius
 
541 360 julius
   // TX_FIFO or UART_DL1
542
   always @(posedge clk or posedge wb_rst_i)
543
     if (wb_rst_i)
544
       begin
545
`ifdef PRESCALER_PRESET_HARD
546
          dl[`UART_DL1]  <=  `PRESCALER_LOW_PRESET;
547
`else
548
          dl[`UART_DL1]  <=  8'b0;
549
`endif
550
          tf_push   <=  1'b0;
551
          start_dlc <=  1'b0;
552
       end
553
     else
554
       if (wb_we_i && wb_addr_i==`UART_REG_TR)
555
         if (dlab)
556
           begin
557
`ifdef PRESCALER_PRESET_HARD
558
              dl[`UART_DL1] <= dl[`UART_DL1];
559
`else
560
              dl[`UART_DL1] <=  wb_dat_i;
561
`endif
562
              start_dlc <=  1'b1; // enable DL counter
563
              tf_push <=  1'b0;
564
           end
565
         else
566
           begin
567
              tf_push   <=  1'b1;
568
              start_dlc <=  1'b0;
569
           end // else: !if(dlab)
570
       else
571
         begin
572
            start_dlc <=  1'b0;
573
            tf_push   <=  1'b0;
574
         end // else: !if(dlab)
575 6 julius
 
576 360 julius
   // Receiver FIFO trigger level selection logic (asynchronous mux)
577
   always @(fcr)
578
     case (fcr[`UART_FC_TL])
579
       2'b00 : trigger_level = 1;
580
       2'b01 : trigger_level = 4;
581
       2'b10 : trigger_level = 8;
582
       2'b11 : trigger_level = 14;
583
     endcase // case(fcr[`UART_FC_TL])
584
 
585
   //
586
   //  STATUS REGISTERS  //
587
   //
588 6 julius
 
589 360 julius
   // Modem Status Register
590
   reg [3:0] delayed_modem_signals;
591
   always @(posedge clk or posedge wb_rst_i)
592
     begin
593 6 julius
        if (wb_rst_i)
594
          begin
595 360 julius
             msr <=  0;
596
             delayed_modem_signals[3:0] <=  0;
597 6 julius
          end
598
        else begin
599 360 julius
           msr[`UART_MS_DDCD:`UART_MS_DCTS] <=  msi_reset ? 4'b0 :
600
                                                msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
601
           msr[`UART_MS_CDCD:`UART_MS_CCTS] <=  {dcd_c, ri_c, dsr_c, cts_c};
602
           delayed_modem_signals[3:0] <=  {dcd, ri, dsr, cts};
603 6 julius
        end
604 360 julius
     end
605 6 julius
 
606
 
607 360 julius
   // Line Status Register
608 6 julius
 
609 360 julius
   // activation conditions
610
   assign lsr0 = (rf_count==0 && rf_push_pulse);  // data in receiver fifo available set condition
611
   assign lsr1 = rf_overrun;     // Receiver overrun error
612
   assign lsr2 = rf_data_out[1]; // parity error bit
613
   assign lsr3 = rf_data_out[0]; // framing error bit
614
   assign lsr4 = rf_data_out[2]; // break error in the character
615
   assign lsr5 = (tf_count==5'b0 && thre_set_en);  // transmitter fifo is empty
616
   assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
617
   assign lsr7 = rf_error_bit | rf_overrun;
618 6 julius
 
619 360 julius
   // lsr bit0 (receiver data available)
620
   reg   lsr0_d;
621 6 julius
 
622 360 julius
   always @(posedge clk or posedge wb_rst_i)
623
     if (wb_rst_i) lsr0_d <=  0;
624
     else lsr0_d <=  lsr0;
625 6 julius
 
626 360 julius
   always @(posedge clk or posedge wb_rst_i)
627
     if (wb_rst_i) lsr0r <=  0;
628
     else lsr0r <=  (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
629
                    lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted 
630 6 julius
 
631 360 julius
   // lsr bit 1 (receiver overrun)
632
   reg   lsr1_d; // delayed
633 6 julius
 
634 360 julius
   always @(posedge clk or posedge wb_rst_i)
635
     if (wb_rst_i) lsr1_d <=  0;
636
     else lsr1_d <=  lsr1;
637 6 julius
 
638 360 julius
   always @(posedge clk or posedge wb_rst_i)
639
     if (wb_rst_i) lsr1r <=  0;
640
     else       lsr1r <=        lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
641 6 julius
 
642 360 julius
   // lsr bit 2 (parity error)
643
   reg   lsr2_d; // delayed
644 6 julius
 
645 360 julius
   always @(posedge clk or posedge wb_rst_i)
646
     if (wb_rst_i) lsr2_d <=  0;
647
     else lsr2_d <=  lsr2;
648 6 julius
 
649 360 julius
   always @(posedge clk or posedge wb_rst_i)
650
     if (wb_rst_i) lsr2r <=  0;
651
     else lsr2r <=  lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
652 6 julius
 
653 360 julius
   // lsr bit 3 (framing error)
654
   reg   lsr3_d; // delayed
655 6 julius
 
656 360 julius
   always @(posedge clk or posedge wb_rst_i)
657
     if (wb_rst_i) lsr3_d <=  0;
658
     else lsr3_d <=  lsr3;
659 6 julius
 
660 360 julius
   always @(posedge clk or posedge wb_rst_i)
661
     if (wb_rst_i) lsr3r <=  0;
662
     else lsr3r <=  lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
663 6 julius
 
664 360 julius
   // lsr bit 4 (break indicator)
665
   reg   lsr4_d; // delayed
666 6 julius
 
667 360 julius
   always @(posedge clk or posedge wb_rst_i)
668
     if (wb_rst_i) lsr4_d <=  0;
669
     else lsr4_d <=  lsr4;
670 6 julius
 
671 360 julius
   always @(posedge clk or posedge wb_rst_i)
672
     if (wb_rst_i) lsr4r <=  0;
673
     else lsr4r <=  lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
674 6 julius
 
675 360 julius
   // lsr bit 5 (transmitter fifo is empty)
676
   reg   lsr5_d;
677 6 julius
 
678 360 julius
   always @(posedge clk or posedge wb_rst_i)
679
     if (wb_rst_i) lsr5_d <=  1;
680
     else lsr5_d <=  lsr5;
681 6 julius
 
682 360 julius
   always @(posedge clk or posedge wb_rst_i)
683
     if (wb_rst_i) lsr5r <=  1;
684
     else lsr5r <=  (fifo_write) ? 0 :  lsr5r || (lsr5 && ~lsr5_d);
685 6 julius
 
686 360 julius
   // lsr bit 6 (transmitter empty indicator)
687
   reg   lsr6_d;
688 6 julius
 
689 360 julius
   always @(posedge clk or posedge wb_rst_i)
690
     if (wb_rst_i) lsr6_d <=  1;
691
     else lsr6_d <=  lsr6;
692 6 julius
 
693 360 julius
   always @(posedge clk or posedge wb_rst_i)
694
     if (wb_rst_i) lsr6r <=  1;
695
     else lsr6r <=  (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
696 6 julius
 
697 360 julius
   // lsr bit 7 (error in fifo)
698
   reg   lsr7_d;
699 6 julius
 
700 360 julius
   always @(posedge clk or posedge wb_rst_i)
701
     if (wb_rst_i) lsr7_d <=  0;
702
     else lsr7_d <=  lsr7;
703 6 julius
 
704 360 julius
   always @(posedge clk or posedge wb_rst_i)
705
     if (wb_rst_i) lsr7r <=  0;
706
     else lsr7r <=  lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
707 6 julius
 
708 360 julius
   // Frequency divider
709
   always @(posedge clk or posedge wb_rst_i)
710
     begin
711 6 julius
        if (wb_rst_i)
712 360 julius
          dlc <=  0;
713 6 julius
        else
714 360 julius
          if (start_dlc | ~ (|dlc))
715
            dlc <=  dl - 1;               // preset counter
716
          else
717
            dlc <=  dlc - 1;              // decrement counter
718
     end
719 6 julius
 
720 360 julius
   // Enable signal generation logic
721
   always @(posedge clk or posedge wb_rst_i)
722
     begin
723 6 julius
        if (wb_rst_i)
724 360 julius
          enable <=  1'b0;
725 6 julius
        else
726 360 julius
          if (|dl & ~(|dlc))     // dl>0 & dlc==0
727
            enable <=  1'b1;
728
          else
729
            enable <=  1'b0;
730
     end
731 6 julius
 
732 360 julius
   // Delaying THRE status for one character cycle after a character is written to an empty fifo.
733
   always @(lcr)
734
     case (lcr[3:0])
735
       4'b0000                             : block_value =  95; // 6 bits
736
       4'b0100                             : block_value = 103; // 6.5 bits
737
       4'b0001, 4'b1000                    : block_value = 111; // 7 bits
738
       4'b1100                             : block_value = 119; // 7.5 bits
739
       4'b0010, 4'b0101, 4'b1001           : block_value = 127; // 8 bits
740
       4'b0011, 4'b0110, 4'b1010, 4'b1101  : block_value = 143; // 9 bits
741
       4'b0111, 4'b1011, 4'b1110           : block_value = 159; // 10 bits
742
       4'b1111                             : block_value = 175; // 11 bits
743
     endcase // case(lcr[3:0])
744 6 julius
 
745 360 julius
   // Counting time of one character minus stop bit
746
   always @(posedge clk or posedge wb_rst_i)
747
     begin
748
        if (wb_rst_i)
749
          block_cnt <=  8'd0;
750
        else
751
          if(lsr5r & fifo_write)  // THRE bit set & write to fifo occured
752
            block_cnt <=  block_value;
753
          else
754
            if (enable & block_cnt != 8'b0)  // only work on enable times
755
              block_cnt <=  block_cnt - 1;  // decrement break counter
756
     end // always of break condition detection
757 6 julius
 
758 360 julius
   // Generating THRE status enable signal
759
   assign thre_set_en = ~(|block_cnt);
760 6 julius
 
761
 
762 360 julius
   //
763
   //   INTERRUPT LOGIC
764
   //
765 6 julius
 
766 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]);
767
   assign rda_int  = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
768
   assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
769
   assign ms_int   = ier[`UART_IE_MS] && (| msr[3:0]);
770
   assign ti_int   = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
771 6 julius
 
772 360 julius
   reg   rls_int_d;
773
   reg   thre_int_d;
774
   reg   ms_int_d;
775
   reg   ti_int_d;
776
   reg   rda_int_d;
777 6 julius
 
778 360 julius
   // delay lines
779
   always  @(posedge clk or posedge wb_rst_i)
780
     if (wb_rst_i) rls_int_d <=  0;
781
     else rls_int_d <=  rls_int;
782 6 julius
 
783 360 julius
   always  @(posedge clk or posedge wb_rst_i)
784
     if (wb_rst_i) rda_int_d <=  0;
785
     else rda_int_d <=  rda_int;
786 6 julius
 
787 360 julius
   always  @(posedge clk or posedge wb_rst_i)
788
     if (wb_rst_i) thre_int_d <=  0;
789
     else thre_int_d <=  thre_int;
790 6 julius
 
791 360 julius
   always  @(posedge clk or posedge wb_rst_i)
792
     if (wb_rst_i) ms_int_d <=  0;
793
     else ms_int_d <=  ms_int;
794 6 julius
 
795 360 julius
   always  @(posedge clk or posedge wb_rst_i)
796
     if (wb_rst_i) ti_int_d <=  0;
797
     else ti_int_d <=  ti_int;
798 6 julius
 
799 360 julius
   // rise detection signals
800 6 julius
 
801 360 julius
   wire  rls_int_rise;
802
   wire  thre_int_rise;
803
   wire  ms_int_rise;
804
   wire  ti_int_rise;
805
   wire  rda_int_rise;
806 6 julius
 
807 360 julius
   assign rda_int_rise    = rda_int & ~rda_int_d;
808
   assign rls_int_rise    = rls_int & ~rls_int_d;
809
   assign thre_int_rise   = thre_int & ~thre_int_d;
810
   assign ms_int_rise     = ms_int & ~ms_int_d;
811
   assign ti_int_rise     = ti_int & ~ti_int_d;
812 6 julius
 
813 360 julius
   // interrupt pending flags
814
   reg   rls_int_pnd;
815
   reg   rda_int_pnd;
816
   reg   thre_int_pnd;
817
   reg   ms_int_pnd;
818
   reg   ti_int_pnd;
819 6 julius
 
820 360 julius
   // interrupt pending flags assignments
821
   always  @(posedge clk or posedge wb_rst_i)
822
     if (wb_rst_i) rls_int_pnd <=  0;
823
     else
824
       rls_int_pnd <=  lsr_mask ? 0 :                                            // reset condition
825
                       rls_int_rise ? 1 :                                               // latch condition
826
                       rls_int_pnd && ier[`UART_IE_RLS];        // default operation: remove if masked
827 6 julius
 
828 360 julius
   always  @(posedge clk or posedge wb_rst_i)
829
     if (wb_rst_i) rda_int_pnd <=  0;
830
     else
831
       rda_int_pnd <=  ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 :   // reset condition
832
                       rda_int_rise ? 1 :                                               // latch condition
833
                       rda_int_pnd && ier[`UART_IE_RDA];        // default operation: remove if masked
834 6 julius
 
835 360 julius
   always  @(posedge clk or posedge wb_rst_i)
836
     if (wb_rst_i) thre_int_pnd <=  0;
837
     else
838
       thre_int_pnd <=  fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
839
                        thre_int_rise ? 1 :
840
                        thre_int_pnd && ier[`UART_IE_THRE];
841 6 julius
 
842 360 julius
   always  @(posedge clk or posedge wb_rst_i)
843
     if (wb_rst_i) ms_int_pnd <=  0;
844
     else
845
       ms_int_pnd <=  msr_read ? 0 :
846
                      ms_int_rise ? 1 :
847
                      ms_int_pnd && ier[`UART_IE_MS];
848 6 julius
 
849 360 julius
   always  @(posedge clk or posedge wb_rst_i)
850
     if (wb_rst_i) ti_int_pnd <=  0;
851
     else
852
       ti_int_pnd <=  fifo_read ? 0 :
853
                      ti_int_rise ? 1 :
854
                      ti_int_pnd && ier[`UART_IE_RDA];
855
   // end of pending flags
856 6 julius
 
857 360 julius
   // INT_O logic
858
   always @(posedge clk or posedge wb_rst_i)
859
     begin
860 6 julius
        if (wb_rst_i)
861 360 julius
          int_o <=  1'b0;
862 6 julius
        else
863 360 julius
          int_o <=
864
                    rls_int_pnd         ?       ~lsr_mask                                       :
865
                    rda_int_pnd         ? 1                                                             :
866
                    ti_int_pnd          ? ~fifo_read                                    :
867
                    thre_int_pnd        ? !(fifo_write & iir_read) :
868
                    ms_int_pnd          ? ~msr_read                                             :
869
                    0;   // if no interrupt are pending
870
     end
871 6 julius
 
872
 
873 360 julius
   // Interrupt Identification register
874
   always @(posedge clk or posedge wb_rst_i)
875
     begin
876 6 julius
        if (wb_rst_i)
877 360 julius
          iir <=  1;
878 6 julius
        else
879 360 julius
          if (rls_int_pnd)  // interrupt is pending
880
            begin
881
               iir[`UART_II_II] <=  `UART_II_RLS;       // set identification register to correct value
882
               iir[`UART_II_IP] <=  1'b0;               // and clear the IIR bit 0 (interrupt pending)
883
            end else // the sequence of conditions determines priority of interrupt identification
884
              if (rda_int)
885
                begin
886
                   iir[`UART_II_II] <=  `UART_II_RDA;
887
                   iir[`UART_II_IP] <=  1'b0;
888
                end
889
              else if (ti_int_pnd)
890
                begin
891
                   iir[`UART_II_II] <=  `UART_II_TI;
892
                   iir[`UART_II_IP] <=  1'b0;
893
                end
894
              else if (thre_int_pnd)
895
                begin
896
                   iir[`UART_II_II] <=  `UART_II_THRE;
897
                   iir[`UART_II_IP] <=  1'b0;
898
                end
899
              else if (ms_int_pnd)
900
                begin
901
                   iir[`UART_II_II] <=  `UART_II_MS;
902
                   iir[`UART_II_IP] <=  1'b0;
903
                end else        // no interrupt is pending
904
                  begin
905
                     iir[`UART_II_II] <=  0;
906
                     iir[`UART_II_IP] <=  1'b1;
907
                  end
908
     end
909 6 julius
 
910
endmodule

powered by: WebSVN 2.1.0

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