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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [rtl/] [verilog/] [uart16550/] [rtl/] [verilog/] [uart_regs.v] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1327 jcastillo
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  uart_regs.v                                                 ////
4
////                                                              ////
5
////                                                              ////
6
////  This file is part of the "UART 16550 compatible" project    ////
7
////  http://www.opencores.org/cores/uart16550/                   ////
8
////                                                              ////
9
////  Documentation related to this project:                      ////
10
////  - http://www.opencores.org/cores/uart16550/                 ////
11
////                                                              ////
12
////  Projects compatibility:                                     ////
13
////  - WISHBONE                                                  ////
14
////  RS232 Protocol                                              ////
15
////  16550D uart (mostly supported)                              ////
16
////                                                              ////
17
////  Overview (main Features):                                   ////
18
////  Registers of the uart 16550 core                            ////
19
////                                                              ////
20
////  Known problems (limits):                                    ////
21
////  Inserts 1 wait state in all WISHBONE transfers              ////
22
////                                                              ////
23
////  To Do:                                                      ////
24
////  Nothing or verification.                                    ////
25
////                                                              ////
26
////  Author(s):                                                  ////
27
////      - gorban@opencores.org                                  ////
28
////      - Jacob Gorban                                          ////
29
////      - Igor Mohor (igorm@opencores.org)                      ////
30
////                                                              ////
31
////  Created:        2001/05/12                                  ////
32
////  Last Updated:   (See log for the revision history           ////
33
////                                                              ////
34
////                                                              ////
35
//////////////////////////////////////////////////////////////////////
36
////                                                              ////
37
//// Copyright (C) 2000, 2001 Authors                             ////
38
////                                                              ////
39
//// This source file may be used and distributed without         ////
40
//// restriction provided that this copyright statement is not    ////
41
//// removed from the file and that any derivative work contains  ////
42
//// the original copyright notice and the associated disclaimer. ////
43
////                                                              ////
44
//// This source file is free software; you can redistribute it   ////
45
//// and/or modify it under the terms of the GNU Lesser General   ////
46
//// Public License as published by the Free Software Foundation; ////
47
//// either version 2.1 of the License, or (at your option) any   ////
48
//// later version.                                               ////
49
////                                                              ////
50
//// This source is distributed in the hope that it will be       ////
51
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
52
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
53
//// PURPOSE.  See the GNU Lesser General Public License for more ////
54
//// details.                                                     ////
55
////                                                              ////
56
//// You should have received a copy of the GNU Lesser General    ////
57
//// Public License along with this source; if not, download it   ////
58
//// from http://www.opencores.org/lgpl.shtml                     ////
59
////                                                              ////
60
//////////////////////////////////////////////////////////////////////
61
//
62
// CVS Revision History
63
//
64
// $Log: not supported by cvs2svn $
65
// Revision 1.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
reg [15:0]                                                               dl;  // 32-bit divisor latch
314
reg [7:0]                                                                scratch; // UART scratch register
315
reg                                                                             start_dlc; // activate dlc on writing to UART_DL1
316
reg                                                                             lsr_mask_d; // delay for lsr_mask condition
317
reg                                                                             msi_reset; // reset MSR 4 lower bits indicator
318
//reg                                                                           threi_clear; // THRE interrupt clear flag
319
reg [15:0]                                                               dlc;  // 32-bit divisor latch counter
320
reg                                                                             int_o;
321
 
322
reg [3:0]                                                                trigger_level; // trigger level of the receiver FIFO
323
reg                                                                             rx_reset;
324
reg                                                                             tx_reset;
325
 
326
wire                                                                            dlab;                      // divisor latch access bit
327
wire                                                                            cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
328
wire                                                                            loopback;                  // loopback bit (MCR bit 4)
329
wire                                                                            cts, dsr, ri, dcd;         // effective signals
330
wire                    cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
331
wire                                                                            rts_pad_o, dtr_pad_o;              // modem control outputs
332
 
333
// LSR bits wires and regs
334
wire [7:0]                                                               lsr;
335
wire                                                                            lsr0, lsr1, lsr2, lsr3, lsr4, lsr5, lsr6, lsr7;
336
reg                                                                             lsr0r, lsr1r, lsr2r, lsr3r, lsr4r, lsr5r, lsr6r, lsr7r;
337
wire                                                                            lsr_mask; // lsr_mask
338
 
339
//
340
// ASSINGS
341
//
342
 
343
assign                                                                  lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
344
 
345
assign                                                                  {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
346
assign                                                                  {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
347
 
348
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]}
349
                                                               : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
350
 
351
assign                                                                  dlab = lcr[`UART_LC_DL];
352
assign                                                                  loopback = mcr[4];
353
 
354
// assign modem outputs
355
assign                                                                  rts_pad_o = mcr[`UART_MC_RTS];
356
assign                                                                  dtr_pad_o = mcr[`UART_MC_DTR];
357
 
358
// Interrupt signals
359
wire                                                                            rls_int;  // receiver line status interrupt
360
wire                                                                            rda_int;  // receiver data available interrupt
361
wire                                                                            ti_int;   // timeout indicator interrupt
362
wire                                                                            thre_int; // transmitter holding register empty interrupt
363
wire                                                                            ms_int;   // modem status interrupt
364
 
365
// FIFO signals
366
reg                                                                             tf_push;
367
reg                                                                             rf_pop;
368
wire [`UART_FIFO_REC_WIDTH-1:0]  rf_data_out;
369
wire                                                                            rf_error_bit; // an error (parity or framing) is inside the fifo
370
wire [`UART_FIFO_COUNTER_W-1:0]  rf_count;
371
wire [`UART_FIFO_COUNTER_W-1:0]  tf_count;
372
wire [2:0]                                                               tstate;
373
wire [3:0]                                                               rstate;
374
wire [9:0]                                                               counter_t;
375
 
376
wire                      thre_set_en; // THRE status is delayed one character time when a character is written to fifo.
377
reg  [7:0]                block_cnt;   // While counter counts, THRE status is blocked (delayed one character cycle)
378
reg  [7:0]                block_value; // One character length minus stop bit
379
 
380
// Transmitter Instance
381
wire serial_out;
382
 
383
uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
384
 
385
  // Synchronizing and sampling serial RX input
386
  uart_sync_flops    i_uart_sync_flops
387
  (
388
    .rst_i           (wb_rst_i),
389
    .clk_i           (clk),
390
    .stage1_rst_i    (1'b0),
391
    .stage1_clk_en_i (1'b1),
392
    .async_dat_i     (srx_pad_i),
393
    .sync_dat_o      (srx_pad)
394
  );
395
  defparam i_uart_sync_flops.width      = 1;
396
  defparam i_uart_sync_flops.init_value = 1'b1;
397
 
398
// handle loopback
399
wire serial_in = loopback ? serial_out : srx_pad;
400
assign stx_pad_o = loopback ? 1'b1 : serial_out;
401
 
402
// Receiver Instance
403
uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
404
        counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
405
 
406
 
407
// Asynchronous reading here because the outputs are sampled in uart_wb.v file 
408
always @(dl or dlab or ier or iir or scratch
409
                        or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i)   // asynchrounous reading
410
begin
411
        case (wb_addr_i)
412
                `UART_REG_RB   : wb_dat_o = dlab ? dl[`UART_DL1] : rf_data_out[10:3];
413
                `UART_REG_IE    : wb_dat_o = dlab ? dl[`UART_DL2] : ier;
414
                `UART_REG_II    : wb_dat_o = {4'b1100,iir};
415
                `UART_REG_LC    : wb_dat_o = lcr;
416
                `UART_REG_LS    : wb_dat_o = lsr;
417
                `UART_REG_MS    : wb_dat_o = msr;
418
                `UART_REG_SR    : wb_dat_o = scratch;
419
                default:  wb_dat_o = 8'b0; // ??
420
        endcase // case(wb_addr_i)
421
end // always @ (dl or dlab or ier or iir or scratch...
422
 
423
 
424
// rf_pop signal handling
425
always @(posedge clk or posedge wb_rst_i)
426
begin
427
        if (wb_rst_i)
428
                rf_pop <= #1 0;
429
        else
430
        if (rf_pop)     // restore the signal to 0 after one clock cycle
431
                rf_pop <= #1 0;
432
        else
433
        if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
434
                rf_pop <= #1 1; // advance read pointer
435
end
436
 
437
wire    lsr_mask_condition;
438
wire    iir_read;
439
wire  msr_read;
440
wire    fifo_read;
441
wire    fifo_write;
442
 
443
assign lsr_mask_condition = (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab);
444
assign iir_read = (wb_re_i && wb_addr_i == `UART_REG_II && !dlab);
445
assign msr_read = (wb_re_i && wb_addr_i == `UART_REG_MS && !dlab);
446
assign fifo_read = (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab);
447
assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
448
 
449
// lsr_mask_d delayed signal handling
450
always @(posedge clk or posedge wb_rst_i)
451
begin
452
        if (wb_rst_i)
453
                lsr_mask_d <= #1 0;
454
        else // reset bits in the Line Status Register
455
                lsr_mask_d <= #1 lsr_mask_condition;
456
end
457
 
458
// lsr_mask is rise detected
459
assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
460
 
461
// msi_reset signal handling
462
always @(posedge clk or posedge wb_rst_i)
463
begin
464
        if (wb_rst_i)
465
                msi_reset <= #1 1;
466
        else
467
        if (msi_reset)
468
                msi_reset <= #1 0;
469
        else
470
        if (msr_read)
471
                msi_reset <= #1 1; // reset bits in Modem Status Register
472
end
473
 
474
 
475
//
476
//   WRITES AND RESETS   //
477
//
478
// Line Control Register
479
always @(posedge clk or posedge wb_rst_i)
480
        if (wb_rst_i)
481
                lcr <= #1 8'b00000011; // 8n1 setting
482
        else
483
        if (wb_we_i && wb_addr_i==`UART_REG_LC)
484
                lcr <= #1 wb_dat_i;
485
 
486
// Interrupt Enable Register or UART_DL2
487
always @(posedge clk or posedge wb_rst_i)
488
        if (wb_rst_i)
489
        begin
490
                ier <= #1 4'b0000; // no interrupts after reset
491
                dl[`UART_DL2] <= #1 8'b0;
492
        end
493
        else
494
        if (wb_we_i && wb_addr_i==`UART_REG_IE)
495
                if (dlab)
496
                begin
497
                        dl[`UART_DL2] <= #1 wb_dat_i;
498
                end
499
                else
500
                        ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb
501
 
502
 
503
// FIFO Control Register and rx_reset, tx_reset signals
504
always @(posedge clk or posedge wb_rst_i)
505
        if (wb_rst_i) begin
506
                fcr <= #1 2'b11;
507
                rx_reset <= #1 0;
508
                tx_reset <= #1 0;
509
        end else
510
        if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
511
                fcr <= #1 wb_dat_i[7:6];
512
                rx_reset <= #1 wb_dat_i[1];
513
                tx_reset <= #1 wb_dat_i[2];
514
        end else begin
515
                rx_reset <= #1 0;
516
                tx_reset <= #1 0;
517
        end
518
 
519
// Modem Control Register
520
always @(posedge clk or posedge wb_rst_i)
521
        if (wb_rst_i)
522
                mcr <= #1 5'b0;
523
        else
524
        if (wb_we_i && wb_addr_i==`UART_REG_MC)
525
                        mcr <= #1 wb_dat_i[4:0];
526
 
527
// Scratch register
528
// Line Control Register
529
always @(posedge clk or posedge wb_rst_i)
530
        if (wb_rst_i)
531
                scratch <= #1 0; // 8n1 setting
532
        else
533
        if (wb_we_i && wb_addr_i==`UART_REG_SR)
534
                scratch <= #1 wb_dat_i;
535
 
536
// TX_FIFO or UART_DL1
537
always @(posedge clk or posedge wb_rst_i)
538
        if (wb_rst_i)
539
        begin
540
                dl[`UART_DL1]  <= #1 8'b0;
541
                tf_push   <= #1 1'b0;
542
                start_dlc <= #1 1'b0;
543
        end
544
        else
545
        if (wb_we_i && wb_addr_i==`UART_REG_TR)
546
                if (dlab)
547
                begin
548
                        dl[`UART_DL1] <= #1 wb_dat_i;
549
                        start_dlc <= #1 1'b1; // enable DL counter
550
                        tf_push <= #1 1'b0;
551
                end
552
                else
553
                begin
554
                        tf_push   <= #1 1'b1;
555
                        start_dlc <= #1 1'b0;
556
                end // else: !if(dlab)
557
        else
558
        begin
559
                start_dlc <= #1 1'b0;
560
                tf_push   <= #1 1'b0;
561
        end // else: !if(dlab)
562
 
563
// Receiver FIFO trigger level selection logic (asynchronous mux)
564
always @(fcr)
565
        case (fcr[`UART_FC_TL])
566
                2'b00 : trigger_level = 1;
567
                2'b01 : trigger_level = 4;
568
                2'b10 : trigger_level = 8;
569
                2'b11 : trigger_level = 14;
570
        endcase // case(fcr[`UART_FC_TL])
571
 
572
//
573
//  STATUS REGISTERS  //
574
//
575
 
576
// Modem Status Register
577
reg [3:0] delayed_modem_signals;
578
always @(posedge clk or posedge wb_rst_i)
579
begin
580
        if (wb_rst_i)
581
          begin
582
                msr <= #1 0;
583
                delayed_modem_signals[3:0] <= #1 0;
584
          end
585
        else begin
586
                msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 :
587
                        msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
588
                msr[`UART_MS_CDCD:`UART_MS_CCTS] <= #1 {dcd_c, ri_c, dsr_c, cts_c};
589
                delayed_modem_signals[3:0] <= #1 {dcd, ri, dsr, cts};
590
        end
591
end
592
 
593
 
594
// Line Status Register
595
 
596
// activation conditions
597
assign lsr0 = (rf_count==0 && rf_push_pulse);  // data in receiver fifo available set condition
598
assign lsr1 = rf_overrun;     // Receiver overrun error
599
assign lsr2 = rf_data_out[1]; // parity error bit
600
assign lsr3 = rf_data_out[0]; // framing error bit
601
assign lsr4 = rf_data_out[2]; // break error in the character
602
assign lsr5 = (tf_count==5'b0 && thre_set_en);  // transmitter fifo is empty
603
assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
604
assign lsr7 = rf_error_bit | rf_overrun;
605
 
606
// lsr bit0 (receiver data available)
607
reg      lsr0_d;
608
 
609
always @(posedge clk or posedge wb_rst_i)
610
        if (wb_rst_i) lsr0_d <= #1 0;
611
        else lsr0_d <= #1 lsr0;
612
 
613
always @(posedge clk or posedge wb_rst_i)
614
        if (wb_rst_i) lsr0r <= #1 0;
615
        else lsr0r <= #1 (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
616
                                          lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted 
617
 
618
// lsr bit 1 (receiver overrun)
619
reg lsr1_d; // delayed
620
 
621
always @(posedge clk or posedge wb_rst_i)
622
        if (wb_rst_i) lsr1_d <= #1 0;
623
        else lsr1_d <= #1 lsr1;
624
 
625
always @(posedge clk or posedge wb_rst_i)
626
        if (wb_rst_i) lsr1r <= #1 0;
627
        else    lsr1r <= #1     lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
628
 
629
// lsr bit 2 (parity error)
630
reg lsr2_d; // delayed
631
 
632
always @(posedge clk or posedge wb_rst_i)
633
        if (wb_rst_i) lsr2_d <= #1 0;
634
        else lsr2_d <= #1 lsr2;
635
 
636
always @(posedge clk or posedge wb_rst_i)
637
        if (wb_rst_i) lsr2r <= #1 0;
638
        else lsr2r <= #1 lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
639
 
640
// lsr bit 3 (framing error)
641
reg lsr3_d; // delayed
642
 
643
always @(posedge clk or posedge wb_rst_i)
644
        if (wb_rst_i) lsr3_d <= #1 0;
645
        else lsr3_d <= #1 lsr3;
646
 
647
always @(posedge clk or posedge wb_rst_i)
648
        if (wb_rst_i) lsr3r <= #1 0;
649
        else lsr3r <= #1 lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
650
 
651
// lsr bit 4 (break indicator)
652
reg lsr4_d; // delayed
653
 
654
always @(posedge clk or posedge wb_rst_i)
655
        if (wb_rst_i) lsr4_d <= #1 0;
656
        else lsr4_d <= #1 lsr4;
657
 
658
always @(posedge clk or posedge wb_rst_i)
659
        if (wb_rst_i) lsr4r <= #1 0;
660
        else lsr4r <= #1 lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
661
 
662
// lsr bit 5 (transmitter fifo is empty)
663
reg lsr5_d;
664
 
665
always @(posedge clk or posedge wb_rst_i)
666
        if (wb_rst_i) lsr5_d <= #1 1;
667
        else lsr5_d <= #1 lsr5;
668
 
669
always @(posedge clk or posedge wb_rst_i)
670
        if (wb_rst_i) lsr5r <= #1 1;
671
        else lsr5r <= #1 (fifo_write) ? 0 :  lsr5r || (lsr5 && ~lsr5_d);
672
 
673
// lsr bit 6 (transmitter empty indicator)
674
reg lsr6_d;
675
 
676
always @(posedge clk or posedge wb_rst_i)
677
        if (wb_rst_i) lsr6_d <= #1 1;
678
        else lsr6_d <= #1 lsr6;
679
 
680
always @(posedge clk or posedge wb_rst_i)
681
        if (wb_rst_i) lsr6r <= #1 1;
682
        else lsr6r <= #1 (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
683
 
684
// lsr bit 7 (error in fifo)
685
reg lsr7_d;
686
 
687
always @(posedge clk or posedge wb_rst_i)
688
        if (wb_rst_i) lsr7_d <= #1 0;
689
        else lsr7_d <= #1 lsr7;
690
 
691
always @(posedge clk or posedge wb_rst_i)
692
        if (wb_rst_i) lsr7r <= #1 0;
693
        else lsr7r <= #1 lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
694
 
695
// Frequency divider
696
always @(posedge clk or posedge wb_rst_i)
697
begin
698
        if (wb_rst_i)
699
                dlc <= #1 0;
700
        else
701
                if (start_dlc | ~ (|dlc))
702
                        dlc <= #1 dl - 1;               // preset counter
703
                else
704
                        dlc <= #1 dlc - 1;              // decrement counter
705
end
706
 
707
// Enable signal generation logic
708
always @(posedge clk or posedge wb_rst_i)
709
begin
710
        if (wb_rst_i)
711
                enable <= #1 1'b0;
712
        else
713
                if (|dl & ~(|dlc))     // dl>0 & dlc==0
714
                        enable <= #1 1'b1;
715
                else
716
                        enable <= #1 1'b0;
717
end
718
 
719
// Delaying THRE status for one character cycle after a character is written to an empty fifo.
720
always @(lcr)
721
  case (lcr[3:0])
722
    4'b0000                             : block_value =  95; // 6 bits
723
    4'b0100                             : block_value = 103; // 6.5 bits
724
    4'b0001, 4'b1000                    : block_value = 111; // 7 bits
725
    4'b1100                             : block_value = 119; // 7.5 bits
726
    4'b0010, 4'b0101, 4'b1001           : block_value = 127; // 8 bits
727
    4'b0011, 4'b0110, 4'b1010, 4'b1101  : block_value = 143; // 9 bits
728
    4'b0111, 4'b1011, 4'b1110           : block_value = 159; // 10 bits
729
    4'b1111                             : block_value = 175; // 11 bits
730
  endcase // case(lcr[3:0])
731
 
732
// Counting time of one character minus stop bit
733
always @(posedge clk or posedge wb_rst_i)
734
begin
735
  if (wb_rst_i)
736
    block_cnt <= #1 8'd0;
737
  else
738
  if(lsr5r & fifo_write)  // THRE bit set & write to fifo occured
739
    block_cnt <= #1 block_value;
740
  else
741
  if (enable & block_cnt != 8'b0)  // only work on enable times
742
    block_cnt <= #1 block_cnt - 1;  // decrement break counter
743
end // always of break condition detection
744
 
745
// Generating THRE status enable signal
746
assign thre_set_en = ~(|block_cnt);
747
 
748
 
749
//
750
//      INTERRUPT LOGIC
751
//
752
 
753
assign rls_int  = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
754
assign rda_int  = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
755
assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
756
assign ms_int   = ier[`UART_IE_MS] && (| msr[3:0]);
757
assign ti_int   = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
758
 
759
reg      rls_int_d;
760
reg      thre_int_d;
761
reg      ms_int_d;
762
reg      ti_int_d;
763
reg      rda_int_d;
764
 
765
// delay lines
766
always  @(posedge clk or posedge wb_rst_i)
767
        if (wb_rst_i) rls_int_d <= #1 0;
768
        else rls_int_d <= #1 rls_int;
769
 
770
always  @(posedge clk or posedge wb_rst_i)
771
        if (wb_rst_i) rda_int_d <= #1 0;
772
        else rda_int_d <= #1 rda_int;
773
 
774
always  @(posedge clk or posedge wb_rst_i)
775
        if (wb_rst_i) thre_int_d <= #1 0;
776
        else thre_int_d <= #1 thre_int;
777
 
778
always  @(posedge clk or posedge wb_rst_i)
779
        if (wb_rst_i) ms_int_d <= #1 0;
780
        else ms_int_d <= #1 ms_int;
781
 
782
always  @(posedge clk or posedge wb_rst_i)
783
        if (wb_rst_i) ti_int_d <= #1 0;
784
        else ti_int_d <= #1 ti_int;
785
 
786
// rise detection signals
787
 
788
wire     rls_int_rise;
789
wire     thre_int_rise;
790
wire     ms_int_rise;
791
wire     ti_int_rise;
792
wire     rda_int_rise;
793
 
794
assign rda_int_rise    = rda_int & ~rda_int_d;
795
assign rls_int_rise       = rls_int & ~rls_int_d;
796
assign thre_int_rise   = thre_int & ~thre_int_d;
797
assign ms_int_rise        = ms_int & ~ms_int_d;
798
assign ti_int_rise        = ti_int & ~ti_int_d;
799
 
800
// interrupt pending flags
801
reg     rls_int_pnd;
802
reg     rda_int_pnd;
803
reg     thre_int_pnd;
804
reg     ms_int_pnd;
805
reg     ti_int_pnd;
806
 
807
// interrupt pending flags assignments
808
always  @(posedge clk or posedge wb_rst_i)
809
        if (wb_rst_i) rls_int_pnd <= #1 0;
810
        else
811
                rls_int_pnd <= #1 lsr_mask ? 0 :                                                 // reset condition
812
                                                        rls_int_rise ? 1 :                                              // latch condition
813
                                                        rls_int_pnd && ier[`UART_IE_RLS];       // default operation: remove if masked
814
 
815
always  @(posedge clk or posedge wb_rst_i)
816
        if (wb_rst_i) rda_int_pnd <= #1 0;
817
        else
818
                rda_int_pnd <= #1 ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 :        // reset condition
819
                                                        rda_int_rise ? 1 :                                              // latch condition
820
                                                        rda_int_pnd && ier[`UART_IE_RDA];       // default operation: remove if masked
821
 
822
always  @(posedge clk or posedge wb_rst_i)
823
        if (wb_rst_i) thre_int_pnd <= #1 0;
824
        else
825
                thre_int_pnd <= #1 fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
826
                                                        thre_int_rise ? 1 :
827
                                                        thre_int_pnd && ier[`UART_IE_THRE];
828
 
829
always  @(posedge clk or posedge wb_rst_i)
830
        if (wb_rst_i) ms_int_pnd <= #1 0;
831
        else
832
                ms_int_pnd <= #1 msr_read ? 0 :
833
                                                        ms_int_rise ? 1 :
834
                                                        ms_int_pnd && ier[`UART_IE_MS];
835
 
836
always  @(posedge clk or posedge wb_rst_i)
837
        if (wb_rst_i) ti_int_pnd <= #1 0;
838
        else
839
                ti_int_pnd <= #1 fifo_read ? 0 :
840
                                                        ti_int_rise ? 1 :
841
                                                        ti_int_pnd && ier[`UART_IE_RDA];
842
// end of pending flags
843
 
844
// INT_O logic
845
always @(posedge clk or posedge wb_rst_i)
846
begin
847
        if (wb_rst_i)
848
                int_o <= #1 1'b0;
849
        else
850
                int_o <= #1
851
                                        rls_int_pnd             ?       ~lsr_mask                                       :
852
                                        rda_int_pnd             ? 1                                                             :
853
                                        ti_int_pnd              ? ~fifo_read                                    :
854
                                        thre_int_pnd    ? !(fifo_write & iir_read) :
855
                                        ms_int_pnd              ? ~msr_read                                             :
856
                                        0;       // if no interrupt are pending
857
end
858
 
859
 
860
// Interrupt Identification register
861
always @(posedge clk or posedge wb_rst_i)
862
begin
863
        if (wb_rst_i)
864
                iir <= #1 1;
865
        else
866
        if (rls_int_pnd)  // interrupt is pending
867
        begin
868
                iir[`UART_II_II] <= #1 `UART_II_RLS;    // set identification register to correct value
869
                iir[`UART_II_IP] <= #1 1'b0;            // and clear the IIR bit 0 (interrupt pending)
870
        end else // the sequence of conditions determines priority of interrupt identification
871
        if (rda_int)
872
        begin
873
                iir[`UART_II_II] <= #1 `UART_II_RDA;
874
                iir[`UART_II_IP] <= #1 1'b0;
875
        end
876
        else if (ti_int_pnd)
877
        begin
878
                iir[`UART_II_II] <= #1 `UART_II_TI;
879
                iir[`UART_II_IP] <= #1 1'b0;
880
        end
881
        else if (thre_int_pnd)
882
        begin
883
                iir[`UART_II_II] <= #1 `UART_II_THRE;
884
                iir[`UART_II_IP] <= #1 1'b0;
885
        end
886
        else if (ms_int_pnd)
887
        begin
888
                iir[`UART_II_II] <= #1 `UART_II_MS;
889
                iir[`UART_II_IP] <= #1 1'b0;
890
        end else        // no interrupt is pending
891
        begin
892
                iir[`UART_II_II] <= #1 0;
893
                iir[`UART_II_IP] <= #1 1'b1;
894
        end
895
end
896
 
897
endmodule

powered by: WebSVN 2.1.0

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