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

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [OC-UART/] [uart_regs.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dmitryr
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  uart_regs.v                                                 ////
4
////                                                              ////
5
////                                                              ////
6
////  This file is part of the "UART 16550 compatible" project    ////
7
////  http://www.opencores.org/cores/uart16550/                   ////
8
////                                                              ////
9
////  Documentation related to this project:                      ////
10
////  - http://www.opencores.org/cores/uart16550/                 ////
11
////                                                              ////
12
////  Projects compatibility:                                     ////
13
////  - WISHBONE                                                  ////
14
////  RS232 Protocol                                              ////
15
////  16550D uart (mostly supported)                              ////
16
////                                                              ////
17
////  Overview (main Features):                                   ////
18
////  Registers of the uart 16550 core                            ////
19
////                                                              ////
20
////  Known problems (limits):                                    ////
21
////  Inserts 1 wait state in all WISHBONE transfers              ////
22
////                                                              ////
23
////  To Do:                                                      ////
24
////  Nothing or verification.                                    ////
25
////                                                              ////
26
////  Author(s):                                                  ////
27
////      - gorban@opencores.org                                  ////
28
////      - Jacob Gorban                                          ////
29
////      - Igor Mohor (igorm@opencores.org)                      ////
30
////                                                              ////
31
////  Created:        2001/05/12                                  ////
32
////  Last Updated:   (See log for the revision history           ////
33
////                                                              ////
34
////                                                              ////
35
//////////////////////////////////////////////////////////////////////
36
////                                                              ////
37
//// Copyright (C) 2000, 2001 Authors                             ////
38
////                                                              ////
39
//// This source file may be used and distributed without         ////
40
//// restriction provided that this copyright statement is not    ////
41
//// removed from the file and that any derivative work contains  ////
42
//// the original copyright notice and the associated disclaimer. ////
43
////                                                              ////
44
//// This source file is free software; you can redistribute it   ////
45
//// and/or modify it under the terms of the GNU Lesser General   ////
46
//// Public License as published by the Free Software Foundation; ////
47
//// either version 2.1 of the License, or (at your option) any   ////
48
//// later version.                                               ////
49
////                                                              ////
50
//// This source is distributed in the hope that it will be       ////
51
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
52
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
53
//// PURPOSE.  See the GNU Lesser General Public License for more ////
54
//// details.                                                     ////
55
////                                                              ////
56
//// You should have received a copy of the GNU Lesser General    ////
57
//// Public License along with this source; if not, download it   ////
58
//// from http://www.opencores.org/lgpl.shtml                     ////
59
////                                                              ////
60
//////////////////////////////////////////////////////////////////////
61
//
62
// CVS Revision History
63
//
64
// $Log: not supported by cvs2svn $
65
// Revision 1.41  2004/05/21 11:44:41  tadejm
66
// Added synchronizer flops for RX input.
67
//
68
// Revision 1.40  2003/06/11 16:37:47  gorban
69
// This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended.
70
//
71
// Revision 1.39  2002/07/29 21:16:18  gorban
72
// The uart_defines.v file is included again in sources.
73
//
74
// Revision 1.38  2002/07/22 23:02:23  gorban
75
// Bug Fixes:
76
//  * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
77
//   Problem reported by Kenny.Tung.
78
//  * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
79
//
80
// Improvements:
81
//  * Made FIFO's as general inferrable memory where possible.
82
//  So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
83
//  This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
84
//
85
//  * 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
        wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
233
 
234
// additional signals
235
        modem_inputs,
236
        stx_pad_o, srx_pad_i,
237
 
238
`ifdef DATA_BUS_WIDTH_8
239
`else
240
// debug interface signals      enabled
241
ier, iir, fcr, mcr, lcr, msr, lsr, rf_count, tf_count, tstate, rstate,
242
`endif
243
        rts_pad_o, dtr_pad_o, int_o
244
`ifdef UART_HAS_BAUDRATE_OUTPUT
245
        , baud_o
246
`endif
247
 
248
        );
249
 
250
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
 
258
output                                                                  stx_pad_o;
259
input                                                                   srx_pad_i;
260
 
261
input [3:0]                                                      modem_inputs;
262
output                                                                  rts_pad_o;
263
output                                                                  dtr_pad_o;
264
output                                                                  int_o;
265
`ifdef UART_HAS_BAUDRATE_OUTPUT
266
output  baud_o;
267
`endif
268
 
269
`ifdef DATA_BUS_WIDTH_8
270
`else
271
// 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
 
284
`endif
285
 
286
wire [3:0]                                                               modem_inputs;
287
reg                                                                             enable;
288
`ifdef UART_HAS_BAUDRATE_OUTPUT
289
assign baud_o = enable; // baud_o is actually the enable signal
290
`endif
291
 
292
 
293
wire                                                                            stx_pad_o;              // received from transmitter module
294
wire                                                                            srx_pad_i;
295
wire                                                                            srx_pad;
296
 
297
reg [7:0]                                                                wb_dat_o;
298
 
299
wire [`UART_ADDR_WIDTH-1:0]              wb_addr_i;
300
wire [7:0]                                                               wb_dat_i;
301
 
302
 
303
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
 
318
reg [3:0]                                                                trigger_level; // trigger level of the receiver FIFO
319
reg                                                                             rx_reset;
320
reg                                                                             tx_reset;
321
 
322
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
 
329
// 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
 
335
//
336
// ASSINGS
337
//
338
 
339
assign                                                                  lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
340
 
341
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
 
344
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
 
347
assign                                                                  dlab = lcr[`UART_LC_DL];
348
assign                                                                  loopback = mcr[4];
349
 
350
// assign modem outputs
351
assign                                                                  rts_pad_o = mcr[`UART_MC_RTS];
352
assign                                                                  dtr_pad_o = mcr[`UART_MC_DTR];
353
 
354
// 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
 
361
// 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
 
372
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
 
376
// Transmitter Instance
377
wire serial_out;
378
 
379
uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, serial_out, tstate, tf_count, tx_reset, lsr_mask);
380
 
381
  // 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
 
394
// handle loopback
395
wire serial_in = loopback ? serial_out : srx_pad;
396
assign stx_pad_o = loopback ? 1'b1 : serial_out;
397
 
398
// 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
 
402
 
403
// 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
        case (wb_addr_i)
408
                `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
        endcase // case(wb_addr_i)
417
end // always @ (dl or dlab or ier or iir or scratch...
418
 
419
 
420
// rf_pop signal handling
421
always @(posedge clk or posedge wb_rst_i)
422
begin
423
        if (wb_rst_i)
424
                rf_pop <= #1 0;
425
        else
426
        if (rf_pop)     // restore the signal to 0 after one clock cycle
427
                rf_pop <= #1 0;
428
        else
429
        if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
430
                rf_pop <= #1 1; // advance read pointer
431
end
432
 
433
wire    lsr_mask_condition;
434
wire    iir_read;
435
wire  msr_read;
436
wire    fifo_read;
437
wire    fifo_write;
438
 
439
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
 
445
// lsr_mask_d delayed signal handling
446
always @(posedge clk or posedge wb_rst_i)
447
begin
448
        if (wb_rst_i)
449
                lsr_mask_d <= #1 0;
450
        else // reset bits in the Line Status Register
451
                lsr_mask_d <= #1 lsr_mask_condition;
452
end
453
 
454
// lsr_mask is rise detected
455
assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
456
 
457
// msi_reset signal handling
458
always @(posedge clk or posedge wb_rst_i)
459
begin
460
        if (wb_rst_i)
461
                msi_reset <= #1 1;
462
        else
463
        if (msi_reset)
464
                msi_reset <= #1 0;
465
        else
466
        if (msr_read)
467
                msi_reset <= #1 1; // reset bits in Modem Status Register
468
end
469
 
470
 
471
//
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 <= #1 8'b00000011; // 8n1 setting
478
        else
479
        if (wb_we_i && wb_addr_i==`UART_REG_LC)
480
                lcr <= #1 wb_dat_i;
481
 
482
// Interrupt Enable Register or UART_DL2
483
always @(posedge clk or posedge wb_rst_i)
484
        if (wb_rst_i)
485
        begin
486
                ier <= #1 4'b0000; // no interrupts after reset
487
                dl[`UART_DL2] <= #1 8'b0;
488
        end
489
        else
490
        if (wb_we_i && wb_addr_i==`UART_REG_IE)
491
                if (dlab)
492
                begin
493
                        dl[`UART_DL2] <= #1 wb_dat_i;
494
                end
495
                else
496
                        ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb
497
 
498
 
499
// FIFO Control Register and rx_reset, tx_reset signals
500
always @(posedge clk or posedge wb_rst_i)
501
        if (wb_rst_i) begin
502
                fcr <= #1 2'b11;
503
                rx_reset <= #1 0;
504
                tx_reset <= #1 0;
505
        end else
506
        if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
507
                fcr <= #1 wb_dat_i[7:6];
508
                rx_reset <= #1 wb_dat_i[1];
509
                tx_reset <= #1 wb_dat_i[2];
510
        end else begin
511
                rx_reset <= #1 0;
512
                tx_reset <= #1 0;
513
        end
514
 
515
// Modem Control Register
516
always @(posedge clk or posedge wb_rst_i)
517
        if (wb_rst_i)
518
                mcr <= #1 5'b0;
519
        else
520
        if (wb_we_i && wb_addr_i==`UART_REG_MC)
521
                        mcr <= #1 wb_dat_i[4:0];
522
 
523
// Scratch register
524
// Line Control Register
525
always @(posedge clk or posedge wb_rst_i)
526
        if (wb_rst_i)
527
                scratch <= #1 0; // 8n1 setting
528
        else
529
        if (wb_we_i && wb_addr_i==`UART_REG_SR)
530
                scratch <= #1 wb_dat_i;
531
 
532
// TX_FIFO or UART_DL1
533
always @(posedge clk or posedge wb_rst_i)
534
        if (wb_rst_i)
535
        begin
536
                dl[`UART_DL1]  <= #1 8'b0;
537
                tf_push   <= #1 1'b0;
538
                start_dlc <= #1 1'b0;
539
        end
540
        else
541
        if (wb_we_i && wb_addr_i==`UART_REG_TR)
542
                if (dlab)
543
                begin
544
                        dl[`UART_DL1] <= #1 wb_dat_i;
545
                        start_dlc <= #1 1'b1; // enable DL counter
546
                        tf_push <= #1 1'b0;
547
                end
548
                else
549
                begin
550
                        tf_push   <= #1 1'b1;
551
                        start_dlc <= #1 1'b0;
552
                end // else: !if(dlab)
553
        else
554
        begin
555
                start_dlc <= #1 1'b0;
556
                tf_push   <= #1 1'b0;
557
        end // else: !if(dlab)
558
 
559
// Receiver FIFO trigger level selection logic (asynchronous mux)
560
always @(fcr)
561
        case (fcr[`UART_FC_TL])
562
                2'b00 : trigger_level = 1;
563
                2'b01 : trigger_level = 4;
564
                2'b10 : trigger_level = 8;
565
                2'b11 : trigger_level = 14;
566
        endcase // case(fcr[`UART_FC_TL])
567
 
568
//
569
//  STATUS REGISTERS  //
570
//
571
 
572
// Modem Status Register
573
reg [3:0] delayed_modem_signals;
574
always @(posedge clk or posedge wb_rst_i)
575
begin
576
        if (wb_rst_i)
577
          begin
578
                msr <= #1 0;
579
                delayed_modem_signals[3:0] <= #1 0;
580
          end
581
        else begin
582
                msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 :
583
                        msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ delayed_modem_signals[3:0]);
584
                msr[`UART_MS_CDCD:`UART_MS_CCTS] <= #1 {dcd_c, ri_c, dsr_c, cts_c};
585
                delayed_modem_signals[3:0] <= #1 {dcd, ri, dsr, cts};
586
        end
587
end
588
 
589
 
590
// Line Status Register
591
 
592
// activation conditions
593
assign lsr0 = (rf_count==0 && rf_push_pulse);  // data in receiver fifo available set condition
594
assign lsr1 = rf_overrun;     // Receiver overrun error
595
assign lsr2 = rf_data_out[1]; // parity error bit
596
assign lsr3 = rf_data_out[0]; // framing error bit
597
assign lsr4 = rf_data_out[2]; // break error in the character
598
assign lsr5 = (tf_count==5'b0 && thre_set_en);  // transmitter fifo is empty
599
assign lsr6 = (tf_count==5'b0 && thre_set_en && (tstate == /*`S_IDLE */ 0)); // transmitter empty
600
assign lsr7 = rf_error_bit | rf_overrun;
601
 
602
// lsr bit0 (receiver data available)
603
reg      lsr0_d;
604
 
605
always @(posedge clk or posedge wb_rst_i)
606
        if (wb_rst_i) lsr0_d <= #1 0;
607
        else lsr0_d <= #1 lsr0;
608
 
609
always @(posedge clk or posedge wb_rst_i)
610
        if (wb_rst_i) lsr0r <= #1 0;
611
        else lsr0r <= #1 (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
612
                                          lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted 
613
 
614
// lsr bit 1 (receiver overrun)
615
reg lsr1_d; // delayed
616
 
617
always @(posedge clk or posedge wb_rst_i)
618
        if (wb_rst_i) lsr1_d <= #1 0;
619
        else lsr1_d <= #1 lsr1;
620
 
621
always @(posedge clk or posedge wb_rst_i)
622
        if (wb_rst_i) lsr1r <= #1 0;
623
        else    lsr1r <= #1     lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
624
 
625
// lsr bit 2 (parity error)
626
reg lsr2_d; // delayed
627
 
628
always @(posedge clk or posedge wb_rst_i)
629
        if (wb_rst_i) lsr2_d <= #1 0;
630
        else lsr2_d <= #1 lsr2;
631
 
632
always @(posedge clk or posedge wb_rst_i)
633
        if (wb_rst_i) lsr2r <= #1 0;
634
        else lsr2r <= #1 lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
635
 
636
// lsr bit 3 (framing error)
637
reg lsr3_d; // delayed
638
 
639
always @(posedge clk or posedge wb_rst_i)
640
        if (wb_rst_i) lsr3_d <= #1 0;
641
        else lsr3_d <= #1 lsr3;
642
 
643
always @(posedge clk or posedge wb_rst_i)
644
        if (wb_rst_i) lsr3r <= #1 0;
645
        else lsr3r <= #1 lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
646
 
647
// lsr bit 4 (break indicator)
648
reg lsr4_d; // delayed
649
 
650
always @(posedge clk or posedge wb_rst_i)
651
        if (wb_rst_i) lsr4_d <= #1 0;
652
        else lsr4_d <= #1 lsr4;
653
 
654
always @(posedge clk or posedge wb_rst_i)
655
        if (wb_rst_i) lsr4r <= #1 0;
656
        else lsr4r <= #1 lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
657
 
658
// lsr bit 5 (transmitter fifo is empty)
659
reg lsr5_d;
660
 
661
always @(posedge clk or posedge wb_rst_i)
662
        if (wb_rst_i) lsr5_d <= #1 1;
663
        else lsr5_d <= #1 lsr5;
664
 
665
always @(posedge clk or posedge wb_rst_i)
666
        if (wb_rst_i) lsr5r <= #1 1;
667
        else lsr5r <= #1 (fifo_write) ? 0 :  lsr5r || (lsr5 && ~lsr5_d);
668
 
669
// lsr bit 6 (transmitter empty indicator)
670
reg lsr6_d;
671
 
672
always @(posedge clk or posedge wb_rst_i)
673
        if (wb_rst_i) lsr6_d <= #1 1;
674
        else lsr6_d <= #1 lsr6;
675
 
676
always @(posedge clk or posedge wb_rst_i)
677
        if (wb_rst_i) lsr6r <= #1 1;
678
        else lsr6r <= #1 (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
679
 
680
// lsr bit 7 (error in fifo)
681
reg lsr7_d;
682
 
683
always @(posedge clk or posedge wb_rst_i)
684
        if (wb_rst_i) lsr7_d <= #1 0;
685
        else lsr7_d <= #1 lsr7;
686
 
687
always @(posedge clk or posedge wb_rst_i)
688
        if (wb_rst_i) lsr7r <= #1 0;
689
        else lsr7r <= #1 lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
690
 
691
// Frequency divider
692
always @(posedge clk or posedge wb_rst_i)
693
begin
694
        if (wb_rst_i)
695
                dlc <= #1 0;
696
        else
697
                if (start_dlc | ~ (|dlc))
698
                        dlc <= #1 dl - 1;               // preset counter
699
                else
700
                        dlc <= #1 dlc - 1;              // decrement counter
701
end
702
 
703
// Enable signal generation logic
704
always @(posedge clk or posedge wb_rst_i)
705
begin
706
        if (wb_rst_i)
707
                enable <= #1 1'b0;
708
        else
709
                if (|dl & ~(|dlc))     // dl>0 & dlc==0
710
                        enable <= #1 1'b1;
711
                else
712
                        enable <= #1 1'b0;
713
end
714
 
715
// Delaying THRE status for one character cycle after a character is written to an empty fifo.
716
always @(lcr)
717
  case (lcr[3:0])
718
    4'b0000                             : block_value =  95; // 6 bits
719
    4'b0100                             : block_value = 103; // 6.5 bits
720
    4'b0001, 4'b1000                    : block_value = 111; // 7 bits
721
    4'b1100                             : block_value = 119; // 7.5 bits
722
    4'b0010, 4'b0101, 4'b1001           : block_value = 127; // 8 bits
723
    4'b0011, 4'b0110, 4'b1010, 4'b1101  : block_value = 143; // 9 bits
724
    4'b0111, 4'b1011, 4'b1110           : block_value = 159; // 10 bits
725
    4'b1111                             : block_value = 175; // 11 bits
726
  endcase // case(lcr[3:0])
727
 
728
// Counting time of one character minus stop bit
729
always @(posedge clk or posedge wb_rst_i)
730
begin
731
  if (wb_rst_i)
732
    block_cnt <= #1 8'd0;
733
  else
734
  if(lsr5r & fifo_write)  // THRE bit set & write to fifo occured
735
    block_cnt <= #1 block_value;
736
  else
737
  if (enable & block_cnt != 8'b0)  // only work on enable times
738
    block_cnt <= #1 block_cnt - 1;  // decrement break counter
739
end // always of break condition detection
740
 
741
// Generating THRE status enable signal
742
assign thre_set_en = ~(|block_cnt);
743
 
744
 
745
//
746
//      INTERRUPT LOGIC
747
//
748
 
749
assign rls_int  = ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
750
assign rda_int  = ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
751
assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
752
assign ms_int   = ier[`UART_IE_MS] && (| msr[3:0]);
753
assign ti_int   = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
754
 
755
reg      rls_int_d;
756
reg      thre_int_d;
757
reg      ms_int_d;
758
reg      ti_int_d;
759
reg      rda_int_d;
760
 
761
// delay lines
762
always  @(posedge clk or posedge wb_rst_i)
763
        if (wb_rst_i) rls_int_d <= #1 0;
764
        else rls_int_d <= #1 rls_int;
765
 
766
always  @(posedge clk or posedge wb_rst_i)
767
        if (wb_rst_i) rda_int_d <= #1 0;
768
        else rda_int_d <= #1 rda_int;
769
 
770
always  @(posedge clk or posedge wb_rst_i)
771
        if (wb_rst_i) thre_int_d <= #1 0;
772
        else thre_int_d <= #1 thre_int;
773
 
774
always  @(posedge clk or posedge wb_rst_i)
775
        if (wb_rst_i) ms_int_d <= #1 0;
776
        else ms_int_d <= #1 ms_int;
777
 
778
always  @(posedge clk or posedge wb_rst_i)
779
        if (wb_rst_i) ti_int_d <= #1 0;
780
        else ti_int_d <= #1 ti_int;
781
 
782
// rise detection signals
783
 
784
wire     rls_int_rise;
785
wire     thre_int_rise;
786
wire     ms_int_rise;
787
wire     ti_int_rise;
788
wire     rda_int_rise;
789
 
790
assign rda_int_rise    = rda_int & ~rda_int_d;
791
assign rls_int_rise       = rls_int & ~rls_int_d;
792
assign thre_int_rise   = thre_int & ~thre_int_d;
793
assign ms_int_rise        = ms_int & ~ms_int_d;
794
assign ti_int_rise        = ti_int & ~ti_int_d;
795
 
796
// interrupt pending flags
797
reg     rls_int_pnd;
798
reg     rda_int_pnd;
799
reg     thre_int_pnd;
800
reg     ms_int_pnd;
801
reg     ti_int_pnd;
802
 
803
// interrupt pending flags assignments
804
always  @(posedge clk or posedge wb_rst_i)
805
        if (wb_rst_i) rls_int_pnd <= #1 0;
806
        else
807
                rls_int_pnd <= #1 lsr_mask ? 0 :                                                 // reset condition
808
                                                        rls_int_rise ? 1 :                                              // latch condition
809
                                                        rls_int_pnd && ier[`UART_IE_RLS];       // default operation: remove if masked
810
 
811
always  @(posedge clk or posedge wb_rst_i)
812
        if (wb_rst_i) rda_int_pnd <= #1 0;
813
        else
814
                rda_int_pnd <= #1 ((rf_count == {1'b0,trigger_level}) && fifo_read) ? 0 :        // reset condition
815
                                                        rda_int_rise ? 1 :                                              // latch condition
816
                                                        rda_int_pnd && ier[`UART_IE_RDA];       // default operation: remove if masked
817
 
818
always  @(posedge clk or posedge wb_rst_i)
819
        if (wb_rst_i) thre_int_pnd <= #1 0;
820
        else
821
                thre_int_pnd <= #1 fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
822
                                                        thre_int_rise ? 1 :
823
                                                        thre_int_pnd && ier[`UART_IE_THRE];
824
 
825
always  @(posedge clk or posedge wb_rst_i)
826
        if (wb_rst_i) ms_int_pnd <= #1 0;
827
        else
828
                ms_int_pnd <= #1 msr_read ? 0 :
829
                                                        ms_int_rise ? 1 :
830
                                                        ms_int_pnd && ier[`UART_IE_MS];
831
 
832
always  @(posedge clk or posedge wb_rst_i)
833
        if (wb_rst_i) ti_int_pnd <= #1 0;
834
        else
835
                ti_int_pnd <= #1 fifo_read ? 0 :
836
                                                        ti_int_rise ? 1 :
837
                                                        ti_int_pnd && ier[`UART_IE_RDA];
838
// end of pending flags
839
 
840
// INT_O logic
841
always @(posedge clk or posedge wb_rst_i)
842
begin
843
        if (wb_rst_i)
844
                int_o <= #1 1'b0;
845
        else
846
                int_o <= #1
847
                                        rls_int_pnd             ?       ~lsr_mask                                       :
848
                                        rda_int_pnd             ? 1                                                             :
849
                                        ti_int_pnd              ? ~fifo_read                                    :
850
                                        thre_int_pnd    ? !(fifo_write & iir_read) :
851
                                        ms_int_pnd              ? ~msr_read                                             :
852
                                        0;       // if no interrupt are pending
853
end
854
 
855
 
856
// Interrupt Identification register
857
always @(posedge clk or posedge wb_rst_i)
858
begin
859
        if (wb_rst_i)
860
                iir <= #1 1;
861
        else
862
        if (rls_int_pnd)  // interrupt is pending
863
        begin
864
                iir[`UART_II_II] <= #1 `UART_II_RLS;    // set identification register to correct value
865
                iir[`UART_II_IP] <= #1 1'b0;            // and clear the IIR bit 0 (interrupt pending)
866
        end else // the sequence of conditions determines priority of interrupt identification
867
        if (rda_int)
868
        begin
869
                iir[`UART_II_II] <= #1 `UART_II_RDA;
870
                iir[`UART_II_IP] <= #1 1'b0;
871
        end
872
        else if (ti_int_pnd)
873
        begin
874
                iir[`UART_II_II] <= #1 `UART_II_TI;
875
                iir[`UART_II_IP] <= #1 1'b0;
876
        end
877
        else if (thre_int_pnd)
878
        begin
879
                iir[`UART_II_II] <= #1 `UART_II_THRE;
880
                iir[`UART_II_IP] <= #1 1'b0;
881
        end
882
        else if (ms_int_pnd)
883
        begin
884
                iir[`UART_II_II] <= #1 `UART_II_MS;
885
                iir[`UART_II_IP] <= #1 1'b0;
886
        end else        // no interrupt is pending
887
        begin
888
                iir[`UART_II_II] <= #1 0;
889
                iir[`UART_II_IP] <= #1 1'b1;
890
        end
891
end
892
 
893
endmodule

powered by: WebSVN 2.1.0

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