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

Subversion Repositories sio

[/] [sio/] [trunk/] [rtl/] [uart_regs_33m.v] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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