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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [rtl/] [verilog/] [components/] [uart16550/] [uart_regs.v] - Blame information for rev 38

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

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

powered by: WebSVN 2.1.0

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