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

Subversion Repositories uart16550

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

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

powered by: WebSVN 2.1.0

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