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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [testbench/] [External_IP/] [uart16550/] [rtl/] [uart_regs.v] - Blame information for rev 43

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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