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

Subversion Repositories uart16550

[/] [uart16550/] [trunk/] [rtl/] [verilog/] [uart_regs.v] - Blame information for rev 106

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 mohor
//////////////////////////////////////////////////////////////////////
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 29 mohor
////      - Igor Mohor (igorm@opencores.org)                      ////
30 27 mohor
////                                                              ////
31
////  Created:        2001/05/12                                  ////
32
////  Last Updated:   (See log for the revision history           ////
33
////                                                              ////
34
////                                                              ////
35
//////////////////////////////////////////////////////////////////////
36
////                                                              ////
37 29 mohor
//// Copyright (C) 2000, 2001 Authors                             ////
38 27 mohor
////                                                              ////
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 105 igorm
// Revision 1.41  2004/05/21 11:44:41  tadejm
66
// Added synchronizer flops for RX input.
67
//
68 99 tadejm
// 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 87 gorban
// Revision 1.39  2002/07/29 21:16:18  gorban
72
// The uart_defines.v file is included again in sources.
73
//
74 84 gorban
// 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 79 gorban
// Revision 1.37  2001/12/27 13:24:09  mohor
91
// lsr[7] was not showing overrun errors.
92
//
93 68 mohor
// Revision 1.36  2001/12/20 13:25:46  mohor
94
// rx push changed to be only one cycle wide.
95
//
96 66 mohor
// Revision 1.35  2001/12/19 08:03:34  mohor
97
// Warnings cleared.
98
//
99 64 mohor
// Revision 1.34  2001/12/19 07:33:54  mohor
100
// Synplicity was having troubles with the comment.
101
//
102 63 mohor
// 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 60 mohor
// Revision 1.32  2001/12/14 13:19:24  mohor
108
// MSR register fixed.
109
//
110 59 mohor
// Revision 1.31  2001/12/14 10:06:58  mohor
111
// After reset modem status register MSR should be reset.
112
//
113 58 mohor
// Revision 1.30  2001/12/13 10:09:13  mohor
114
// thre irq should be cleared only when being source of interrupt.
115
//
116 56 mohor
// 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 54 mohor
// Revision 1.28  2001/12/10 19:52:41  gorban
120
// Scratch register added
121
//
122 52 gorban
// 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 50 gorban
// 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 48 gorban
// 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 47 gorban
// 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 45 gorban
// Revision 1.23  2001/11/12 21:57:29  gorban
147
// fixed more typo bugs
148
//
149 44 gorban
// Revision 1.22  2001/11/12 15:02:28  mohor
150
// lsr1r error fixed.
151
//
152 43 mohor
// Revision 1.21  2001/11/12 14:57:27  mohor
153
// ti_int_pnd error fixed.
154
//
155 42 mohor
// Revision 1.20  2001/11/12 14:50:27  mohor
156
// ti_int_d error fixed.
157
//
158 41 mohor
// Revision 1.19  2001/11/10 12:43:21  gorban
159 63 mohor
// Logic Synthesis bugs fixed. Some other minor changes
160 41 mohor
//
161 40 gorban
// 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 39 mohor
// Revision 1.17  2001/11/07 17:51:52  gorban
166
// Heavily rewritten interrupt and LSR subsystems.
167
// Many bugs hopefully squashed.
168
//
169 37 gorban
// Revision 1.16  2001/11/02 09:55:16  mohor
170
// no message
171
//
172 36 mohor
// Revision 1.15  2001/10/31 15:19:22  gorban
173
// Fixes to break and timeout conditions
174
//
175 35 gorban
// Revision 1.14  2001/10/29 17:00:46  gorban
176
// fixed parity sending and tx_fifo resets over- and underrun
177
//
178 34 gorban
// Revision 1.13  2001/10/20 09:58:40  gorban
179
// Small synopsis fixes
180
//
181 33 gorban
// 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 32 gorban
// Revision 1.11  2001/10/18 20:35:45  gorban
185
// small fix
186
//
187 31 gorban
// Revision 1.10  2001/08/24 21:01:12  mohor
188
// Things connected to parity changed.
189
// Clock devider changed.
190
//
191 29 mohor
// 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 27 mohor
// 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 33 gorban
// synopsys translate_off
223 27 mohor
`include "timescale.v"
224 33 gorban
// synopsys translate_on
225
 
226 84 gorban
`include "uart_defines.v"
227 27 mohor
 
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 48 gorban
 
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 27 mohor
        rts_pad_o, dtr_pad_o, int_o
244 79 gorban
`ifdef UART_HAS_BAUDRATE_OUTPUT
245
        , baud_o
246
`endif
247
 
248 27 mohor
        );
249
 
250 37 gorban
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 27 mohor
 
258 37 gorban
output                                                                  stx_pad_o;
259
input                                                                   srx_pad_i;
260 27 mohor
 
261 37 gorban
input [3:0]                                                      modem_inputs;
262
output                                                                  rts_pad_o;
263
output                                                                  dtr_pad_o;
264
output                                                                  int_o;
265 79 gorban
`ifdef UART_HAS_BAUDRATE_OUTPUT
266
output  baud_o;
267
`endif
268 27 mohor
 
269 48 gorban
`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 37 gorban
wire [3:0]                                                               modem_inputs;
287
reg                                                                             enable;
288 79 gorban
`ifdef UART_HAS_BAUDRATE_OUTPUT
289
assign baud_o = enable; // baud_o is actually the enable signal
290
`endif
291
 
292
 
293 37 gorban
wire                                                                            stx_pad_o;              // received from transmitter module
294
wire                                                                            srx_pad_i;
295 99 tadejm
wire                                                                            srx_pad;
296 27 mohor
 
297 37 gorban
reg [7:0]                                                                wb_dat_o;
298 27 mohor
 
299 37 gorban
wire [`UART_ADDR_WIDTH-1:0]              wb_addr_i;
300
wire [7:0]                                                               wb_dat_i;
301 27 mohor
 
302
 
303 37 gorban
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 52 gorban
reg [7:0]                                                                scratch; // UART scratch register
311 37 gorban
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 40 gorban
//reg                                                                           threi_clear; // THRE interrupt clear flag
315 37 gorban
reg [15:0]                                                               dlc;  // 32-bit divisor latch counter
316
reg                                                                             int_o;
317 27 mohor
 
318 37 gorban
reg [3:0]                                                                trigger_level; // trigger level of the receiver FIFO
319
reg                                                                             rx_reset;
320
reg                                                                             tx_reset;
321 27 mohor
 
322 37 gorban
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 60 mohor
wire                                                                            cts, dsr, ri, dcd;         // effective signals
326 59 mohor
wire                    cts_c, dsr_c, ri_c, dcd_c; // Complement effective signals (considering loopback)
327 37 gorban
wire                                                                            rts_pad_o, dtr_pad_o;              // modem control outputs
328 27 mohor
 
329 37 gorban
// 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 27 mohor
//
336
// ASSINGS
337
//
338
 
339 37 gorban
assign                                                                  lsr[7:0] = { lsr7r, lsr6r, lsr5r, lsr4r, lsr3r, lsr2r, lsr1r, lsr0r };
340 27 mohor
 
341 37 gorban
assign                                                                  {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
342 60 mohor
assign                                                                  {cts, dsr, ri, dcd} = ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
343 37 gorban
 
344 59 mohor
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 60 mohor
                                                               : {cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
346 59 mohor
 
347 37 gorban
assign                                                                  dlab = lcr[`UART_LC_DL];
348
assign                                                                  loopback = mcr[4];
349
 
350 27 mohor
// assign modem outputs
351 37 gorban
assign                                                                  rts_pad_o = mcr[`UART_MC_RTS];
352
assign                                                                  dtr_pad_o = mcr[`UART_MC_DTR];
353 27 mohor
 
354
// Interrupt signals
355 37 gorban
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 27 mohor
 
361
// FIFO signals
362 37 gorban
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 48 gorban
wire [2:0]                                                               tstate;
369
wire [3:0]                                                               rstate;
370 37 gorban
wire [9:0]                                                               counter_t;
371 27 mohor
 
372 60 mohor
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 37 gorban
 
376 27 mohor
// Transmitter Instance
377 79 gorban
wire serial_out;
378 27 mohor
 
379 79 gorban
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 99 tadejm
  // 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 79 gorban
// handle loopback
395 99 tadejm
wire serial_in = loopback ? serial_out : srx_pad;
396 79 gorban
assign stx_pad_o = loopback ? 1'b1 : serial_out;
397
 
398 27 mohor
// Receiver Instance
399 79 gorban
uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, serial_in, enable,
400 66 mohor
        counter_t, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, lsr_mask, rstate, rf_push_pulse);
401 27 mohor
 
402 32 gorban
 
403 48 gorban
// Asynchronous reading here because the outputs are sampled in uart_wb.v file 
404 52 gorban
always @(dl or dlab or ier or iir or scratch
405 48 gorban
                        or lcr or lsr or msr or rf_data_out or wb_addr_i or wb_re_i)   // asynchrounous reading
406 27 mohor
begin
407 52 gorban
        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 27 mohor
 
419 52 gorban
 
420 27 mohor
// 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 37 gorban
wire    lsr_mask_condition;
434
wire    iir_read;
435
wire  msr_read;
436
wire    fifo_read;
437 45 gorban
wire    fifo_write;
438 37 gorban
 
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 45 gorban
assign fifo_write = (wb_we_i && wb_addr_i == `UART_REG_TR && !dlab);
444 37 gorban
 
445
// lsr_mask_d delayed signal handling
446 27 mohor
always @(posedge clk or posedge wb_rst_i)
447
begin
448
        if (wb_rst_i)
449 37 gorban
                lsr_mask_d <= #1 0;
450
        else // reset bits in the Line Status Register
451
                lsr_mask_d <= #1 lsr_mask_condition;
452 27 mohor
end
453
 
454 37 gorban
// lsr_mask is rise detected
455
assign lsr_mask = lsr_mask_condition && ~lsr_mask_d;
456 27 mohor
 
457
// msi_reset signal handling
458
always @(posedge clk or posedge wb_rst_i)
459
begin
460
        if (wb_rst_i)
461 58 mohor
                msi_reset <= #1 1;
462 27 mohor
        else
463
        if (msi_reset)
464
                msi_reset <= #1 0;
465
        else
466 47 gorban
        if (msr_read)
467 27 mohor
                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 37 gorban
        end else begin
511 27 mohor
                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 52 gorban
// 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 27 mohor
// 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 37 gorban
                end // else: !if(dlab)
553 27 mohor
        else
554
        begin
555
                start_dlc <= #1 1'b0;
556
                tf_push   <= #1 1'b0;
557 37 gorban
        end // else: !if(dlab)
558 27 mohor
 
559
// Receiver FIFO trigger level selection logic (asynchronous mux)
560 31 gorban
always @(fcr)
561 27 mohor
        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 37 gorban
        endcase // case(fcr[`UART_FC_TL])
567 27 mohor
 
568
//
569
//  STATUS REGISTERS  //
570
//
571
 
572
// Modem Status Register
573 59 mohor
reg [3:0] delayed_modem_signals;
574 27 mohor
always @(posedge clk or posedge wb_rst_i)
575
begin
576
        if (wb_rst_i)
577 64 mohor
          begin
578
                msr <= #1 0;
579
                delayed_modem_signals[3:0] <= #1 0;
580
          end
581 27 mohor
        else begin
582
                msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 :
583 59 mohor
                        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 27 mohor
        end
587
end
588
 
589 58 mohor
 
590 27 mohor
// Line Status Register
591 37 gorban
 
592
// activation conditions
593 66 mohor
assign lsr0 = (rf_count==0 && rf_push_pulse);  // data in receiver fifo available set condition
594 37 gorban
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 45 gorban
assign lsr4 = rf_data_out[2]; // break error in the character
598 60 mohor
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 68 mohor
assign lsr7 = rf_error_bit | rf_overrun;
601 37 gorban
 
602
// lsr bit0 (receiver data available)
603 45 gorban
reg      lsr0_d;
604
 
605 27 mohor
always @(posedge clk or posedge wb_rst_i)
606 45 gorban
        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 37 gorban
        if (wb_rst_i) lsr0r <= #1 0;
611 87 gorban
        else lsr0r <= #1 (rf_count==1 && rf_pop && !rf_push_pulse || rx_reset) ? 0 : // deassert condition
612 45 gorban
                                          lsr0r || (lsr0 && ~lsr0_d); // set on rise of lsr0 and keep asserted until deasserted 
613 27 mohor
 
614 37 gorban
// lsr bit 1 (receiver overrun)
615
reg lsr1_d; // delayed
616 29 mohor
 
617 37 gorban
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 43 mohor
        if (wb_rst_i) lsr1r <= #1 0;
623 45 gorban
        else    lsr1r <= #1     lsr_mask ? 0 : lsr1r || (lsr1 && ~lsr1_d); // set on rise
624 37 gorban
 
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 44 gorban
        if (wb_rst_i) lsr2r <= #1 0;
634 45 gorban
        else lsr2r <= #1 lsr_mask ? 0 : lsr2r || (lsr2 && ~lsr2_d); // set on rise
635 37 gorban
 
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 44 gorban
        if (wb_rst_i) lsr3r <= #1 0;
645 45 gorban
        else lsr3r <= #1 lsr_mask ? 0 : lsr3r || (lsr3 && ~lsr3_d); // set on rise
646 37 gorban
 
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 44 gorban
        if (wb_rst_i) lsr4r <= #1 0;
656 45 gorban
        else lsr4r <= #1 lsr_mask ? 0 : lsr4r || (lsr4 && ~lsr4_d);
657 37 gorban
 
658
// lsr bit 5 (transmitter fifo is empty)
659
reg lsr5_d;
660
 
661
always @(posedge clk or posedge wb_rst_i)
662 45 gorban
        if (wb_rst_i) lsr5_d <= #1 1;
663 37 gorban
        else lsr5_d <= #1 lsr5;
664
 
665
always @(posedge clk or posedge wb_rst_i)
666 45 gorban
        if (wb_rst_i) lsr5r <= #1 1;
667 50 gorban
        else lsr5r <= #1 (fifo_write) ? 0 :  lsr5r || (lsr5 && ~lsr5_d);
668 37 gorban
 
669
// lsr bit 6 (transmitter empty indicator)
670
reg lsr6_d;
671
 
672
always @(posedge clk or posedge wb_rst_i)
673 45 gorban
        if (wb_rst_i) lsr6_d <= #1 1;
674 37 gorban
        else lsr6_d <= #1 lsr6;
675
 
676
always @(posedge clk or posedge wb_rst_i)
677 45 gorban
        if (wb_rst_i) lsr6r <= #1 1;
678 50 gorban
        else lsr6r <= #1 (fifo_write) ? 0 : lsr6r || (lsr6 && ~lsr6_d);
679 37 gorban
 
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 44 gorban
        if (wb_rst_i) lsr7r <= #1 0;
689 45 gorban
        else lsr7r <= #1 lsr_mask ? 0 : lsr7r || (lsr7 && ~lsr7_d);
690 37 gorban
 
691 29 mohor
// Frequency divider
692 37 gorban
always @(posedge clk or posedge wb_rst_i)
693 29 mohor
begin
694
        if (wb_rst_i)
695
                dlc <= #1 0;
696
        else
697 37 gorban
                if (start_dlc | ~ (|dlc))
698
                        dlc <= #1 dl - 1;               // preset counter
699
                else
700
                        dlc <= #1 dlc - 1;              // decrement counter
701 29 mohor
end
702
 
703 27 mohor
// 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 37 gorban
                if (|dl & ~(|dlc))     // dl>0 & dlc==0
710
                        enable <= #1 1'b1;
711
                else
712
                        enable <= #1 1'b0;
713 27 mohor
end
714
 
715 60 mohor
// 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 37 gorban
//
746
//      INTERRUPT LOGIC
747
//
748 29 mohor
 
749 37 gorban
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 40 gorban
assign thre_int = ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
752 37 gorban
assign ms_int   = ier[`UART_IE_MS] && (| msr[3:0]);
753 105 igorm
assign ti_int   = ier[`UART_IE_RDA] && (counter_t == 10'b0) && (|rf_count);
754 29 mohor
 
755 37 gorban
reg      rls_int_d;
756
reg      thre_int_d;
757
reg      ms_int_d;
758
reg      ti_int_d;
759 45 gorban
reg      rda_int_d;
760 29 mohor
 
761 37 gorban
// 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 29 mohor
 
766 37 gorban
always  @(posedge clk or posedge wb_rst_i)
767 45 gorban
        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 37 gorban
        if (wb_rst_i) thre_int_d <= #1 0;
772
        else thre_int_d <= #1 thre_int;
773 29 mohor
 
774 37 gorban
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 29 mohor
 
778 37 gorban
always  @(posedge clk or posedge wb_rst_i)
779 41 mohor
        if (wb_rst_i) ti_int_d <= #1 0;
780 37 gorban
        else ti_int_d <= #1 ti_int;
781 27 mohor
 
782 37 gorban
// 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 45 gorban
wire     rda_int_rise;
789 37 gorban
 
790 45 gorban
assign rda_int_rise    = rda_int & ~rda_int_d;
791 37 gorban
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 45 gorban
reg     rda_int_pnd;
799 37 gorban
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 45 gorban
        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 37 gorban
        if (wb_rst_i) thre_int_pnd <= #1 0;
820
        else
821 56 mohor
                thre_int_pnd <= #1 fifo_write || (iir_read & ~iir[`UART_II_IP] & iir[`UART_II_II] == `UART_II_THRE)? 0 :
822 37 gorban
                                                        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 42 mohor
        if (wb_rst_i) ti_int_pnd <= #1 0;
834 37 gorban
        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 27 mohor
always @(posedge clk or posedge wb_rst_i)
842
begin
843
        if (wb_rst_i)
844
                int_o <= #1 1'b0;
845
        else
846 37 gorban
                int_o <= #1
847
                                        rls_int_pnd             ?       ~lsr_mask                                       :
848 45 gorban
                                        rda_int_pnd             ? 1                                                             :
849 37 gorban
                                        ti_int_pnd              ? ~fifo_read                                    :
850 45 gorban
                                        thre_int_pnd    ? !(fifo_write & iir_read) :
851 37 gorban
                                        ms_int_pnd              ? ~msr_read                                             :
852
                                        0;       // if no interrupt are pending
853 27 mohor
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 37 gorban
        if (rls_int_pnd)  // interrupt is pending
863 27 mohor
        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 37 gorban
        end else // the sequence of conditions determines priority of interrupt identification
867 27 mohor
        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 37 gorban
        else if (ti_int_pnd)
873 27 mohor
        begin
874
                iir[`UART_II_II] <= #1 `UART_II_TI;
875
                iir[`UART_II_IP] <= #1 1'b0;
876
        end
877 37 gorban
        else if (thre_int_pnd)
878 27 mohor
        begin
879
                iir[`UART_II_II] <= #1 `UART_II_THRE;
880
                iir[`UART_II_IP] <= #1 1'b0;
881
        end
882 37 gorban
        else if (ms_int_pnd)
883 27 mohor
        begin
884
                iir[`UART_II_II] <= #1 `UART_II_MS;
885
                iir[`UART_II_IP] <= #1 1'b0;
886 37 gorban
        end else        // no interrupt is pending
887 27 mohor
        begin
888 40 gorban
                iir[`UART_II_II] <= #1 0;
889 27 mohor
                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.