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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [rtl/] [uart16550/] [rtl/] [verilog-backup/] [uart_regs.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
//////////////////////////////////////////////////////////////////////
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
////                                                              ////
30
////  Created:        2001/05/12                                  ////
31
////  Last Updated:   (See log for the revision history           ////
32
////                                                              ////
33
////                                                              ////
34
//////////////////////////////////////////////////////////////////////
35
////                                                              ////
36
//// Copyright (C) 2000 Jacob Gorban, gorban@opencores.org        ////
37
////                                                              ////
38
//// This source file may be used and distributed without         ////
39
//// restriction provided that this copyright statement is not    ////
40
//// removed from the file and that any derivative work contains  ////
41
//// the original copyright notice and the associated disclaimer. ////
42
////                                                              ////
43
//// This source file is free software; you can redistribute it   ////
44
//// and/or modify it under the terms of the GNU Lesser General   ////
45
//// Public License as published by the Free Software Foundation; ////
46
//// either version 2.1 of the License, or (at your option) any   ////
47
//// later version.                                               ////
48
////                                                              ////
49
//// This source is distributed in the hope that it will be       ////
50
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
51
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
52
//// PURPOSE.  See the GNU Lesser General Public License for more ////
53
//// details.                                                     ////
54
////                                                              ////
55
//// You should have received a copy of the GNU Lesser General    ////
56
//// Public License along with this source; if not, download it   ////
57
//// from http://www.opencores.org/lgpl.shtml                     ////
58
////                                                              ////
59
//////////////////////////////////////////////////////////////////////
60
//
61
// CVS Revision History
62
//
63
// $Log: uart_regs.v,v $
64
// Revision 1.10  2001/06/23 11:21:48  gorban
65
// DL made 16-bit long. Fixed transmission/reception bugs.
66
//
67
// Revision 1.9  2001/05/31 20:08:01  gorban
68
// FIFO changes and other corrections.
69
//
70
// Revision 1.8  2001/05/29 20:05:04  gorban
71
// Fixed some bugs and synthesis problems.
72
//
73
// Revision 1.7  2001/05/27 17:37:49  gorban
74
// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
75
//
76
// Revision 1.6  2001/05/21 19:12:02  gorban
77
// Corrected some Linter messages.
78
//
79
// Revision 1.5  2001/05/17 18:34:18  gorban
80
// First 'stable' release. Should be sythesizable now. Also added new header.
81
//
82
// Revision 1.0  2001-05-17 21:27:11+02  jacob
83
// Initial revision
84
//
85
//
86
 
87
`include "timescale.v"
88
`include "uart_defines.v"
89
 
90
`define UART_DL1 7:0
91
`define UART_DL2 15:8
92
 
93
module uart_regs (clk,
94
        wb_rst_i, wb_addr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_re_i,
95
 
96
// additional signals
97
        modem_inputs,
98
        stx_pad_o, srx_pad_i,
99
        enable,
100
        rts_pad_o, dtr_pad_o, int_o
101
        );
102
 
103
input           clk;
104
input           wb_rst_i;
105
input   [`UART_ADDR_WIDTH-1:0]   wb_addr_i;
106
input   [7:0]    wb_dat_i;
107
output  [7:0]    wb_dat_o;
108
input           wb_we_i;
109
input   wb_re_i;
110
 
111
output          stx_pad_o;
112
input           srx_pad_i;
113
 
114
input   [3:0]    modem_inputs;
115
output          enable;
116
output          rts_pad_o;
117
output          dtr_pad_o;
118
output          int_o;
119
 
120
wire    [3:0]    modem_inputs;
121
reg             enable;
122
wire            stx_pad_o;              // received from transmitter module
123
wire            srx_pad_i;
124
 
125
reg     [7:0]    wb_dat_o;
126
 
127
wire    [`UART_ADDR_WIDTH-1:0]   wb_addr_i;
128
wire    [7:0]    wb_dat_i;
129
 
130
 
131
reg     [3:0]    ier;
132
reg     [3:0]    iir;
133
reg     [1:0]    fcr;  /// bits 7 and 6 of fcr. Other bits are ignored
134
reg     [4:0]    mcr;
135
reg     [7:0]    lcr;
136
reg     [7:0]    lsr;
137
reg     [7:0]    msr;
138
reg     [15:0]   dl;  // 32-bit divisor latch
139
reg             start_dlc; // activate dlc on writing to UART_DL1
140
reg             lsr_mask;
141
reg             msi_reset; // reset MSR 4 lower bits indicator
142
reg             threi_clear; // THRE interrupt clear flag
143
reg     [15:0]   dlc;  // 32-bit divisor latch counter
144
reg             int_o;
145
 
146
reg     [3:0]    trigger_level; // trigger level of the receiver FIFO
147
reg             rx_reset;
148
reg             tx_reset;
149
 
150
wire            dlab;                      // divisor latch access bit
151
wire            cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i; // modem status bits
152
wire            loopback;                  // loopback bit (MCR bit 4)
153
wire            cts, dsr, ri, dcd;         // effective signals (considering loopback)
154
wire            rts_pad_o, dtr_pad_o;              // modem control outputs
155
 
156
//
157
// ASSINGS
158
//
159
assign {cts_pad_i, dsr_pad_i, ri_pad_i, dcd_pad_i} = modem_inputs;
160
assign {cts, dsr, ri, dcd} = loopback ? {mcr[`UART_MC_RTS],mcr[`UART_MC_DTR],mcr[`UART_MC_OUT1],mcr[`UART_MC_OUT2]}
161
                 : ~{cts_pad_i,dsr_pad_i,ri_pad_i,dcd_pad_i};
162
 
163
assign dlab = lcr[`UART_LC_DL];
164
assign loopback = mcr[4];
165
 
166
// assign modem outputs
167
assign  rts_pad_o = mcr[`UART_MC_RTS];
168
assign  dtr_pad_o = mcr[`UART_MC_DTR];
169
 
170
// Interrupt signals
171
reg     rls_int;  // receiver line status interrupt
172
reg     rda_int;  // receiver data available interrupt
173
reg     ti_int;   // timeout indicator interrupt
174
reg     thre_int; // transmitter holding register empty interrupt
175
reg     ms_int;   // modem status interrupt
176
 
177
// FIFO signals
178
reg                             tf_push;
179
reg                             rf_pop;
180
wire    [`UART_FIFO_REC_WIDTH-1:0]       rf_data_out;
181
wire                            rf_error_bit; // an error (parity or framing) is inside the fifo
182
wire    [`UART_FIFO_COUNTER_W-1:0]       rf_count;
183
wire    [`UART_FIFO_COUNTER_W-1:0]       tf_count;
184
wire    [2:0]                    state;
185
wire    [5:0]                    counter_t;
186
wire    [3:0]                    counter_b;
187
wire            rx_lsr_mask;
188
 
189
// Transmitter Instance
190
uart_transmitter transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, state, tf_count, tx_reset);
191
 
192
// Receiver Instance
193
uart_receiver receiver(clk, wb_rst_i, lcr, rf_pop, srx_pad_i, enable, rda_int,
194
        counter_t, counter_b, rf_count, rf_data_out, rf_error_bit, rf_overrun, rx_reset, rx_lsr_mask);
195
 
196
/*
197
always @(posedge clk or posedge wb_rst_i)   // synchrounous reading
198
begin
199
    if (wb_rst_i)
200
    begin
201
        wb_dat_o <= #1 8'b0;
202
    end
203
    else
204
    if (wb_re_i)   //if (we're not writing)
205
        case (wb_addr_i)
206
        `UART_REG_RB : if (dlab) // Receiver FIFO or DL byte 1
207
                        wb_dat_o <= #1 dl[`UART_DL1];
208
                  else
209
                        wb_dat_o <= #1 rf_data_out[9:2];
210
        `UART_REG_IE    : wb_dat_o <= #1 dlab ? dl[`UART_DL2] : ier;
211
        `UART_REG_II    : wb_dat_o <= #1 {4'b1100,iir};
212
        `UART_REG_LC    : wb_dat_o <= #1 lcr;
213
        `UART_REG_LS    : wb_dat_o <= #1 lsr;
214
        `UART_REG_MS    : wb_dat_o <= #1 msr;
215
        default:  wb_dat_o <= #1 8'b0; // ??
216
        endcase
217
    else
218
        wb_dat_o <= #1 8'b0;
219
end
220
*/
221
 
222
always @(wb_addr_i or dlab or dl or rf_data_out or ier or iir or lcr or lsr or msr)
223
begin
224
        case (wb_addr_i)
225
        `UART_REG_RB : if (dlab) // Receiver FIFO or DL byte 1
226
                                wb_dat_o <= dl[`UART_DL1];
227
                        else
228
                                wb_dat_o <= rf_data_out[9:2];
229
        `UART_REG_IE    : wb_dat_o <= dlab ? dl[`UART_DL2] : ier;
230
        `UART_REG_II    : wb_dat_o <= {4'b1100,iir};
231
        `UART_REG_LC    : wb_dat_o <= lcr;
232
        `UART_REG_LS    : wb_dat_o <= lsr;
233
        `UART_REG_MS    : wb_dat_o <= msr;
234
        default:  wb_dat_o <= 8'b0; // ??
235
        endcase
236
end
237
 
238
// rf_pop signal handling
239
always @(posedge clk or posedge wb_rst_i)
240
begin
241
        if (wb_rst_i)
242
                rf_pop <= #1 0;
243
        else
244
        if (rf_pop)     // restore the signal to 0 after one clock cycle
245
                rf_pop <= #1 0;
246
        else
247
        if (wb_re_i && wb_addr_i == `UART_REG_RB && !dlab)
248
                rf_pop <= #1 1; // advance read pointer
249
end
250
 
251
// lsr_mask signal handling
252
always @(posedge clk or posedge wb_rst_i)
253
begin
254
        if (wb_rst_i)
255
                lsr_mask <= #1 0;
256
        else
257
        if (lsr_mask)
258
                lsr_mask <= #1 0;
259
        else
260
        if (wb_re_i && wb_addr_i == `UART_REG_LS && !dlab)
261
                lsr_mask <= #1 1; // reset bits in the Line Status Register
262
end
263
 
264
assign rx_lsr_mask = lsr_mask;
265
 
266
// msi_reset signal handling
267
always @(posedge clk or posedge wb_rst_i)
268
begin
269
        if (wb_rst_i)
270
                msi_reset <= #1 0;
271
        else
272
        if (msi_reset)
273
                msi_reset <= #1 0;
274
        else
275
        if (wb_re_i && wb_addr_i == `UART_REG_MS)
276
                msi_reset <= #1 1; // reset bits in Modem Status Register
277
end
278
 
279
// threi_clear signal handling
280
always @(posedge clk or posedge wb_rst_i)
281
begin
282
        if (wb_rst_i)
283
                threi_clear <= #1 0;
284
        else
285
        if (threi_clear && !lsr[`UART_LS_TFE] && (tf_count==0)) // reset clear flag when tx fifo clears
286
                threi_clear <= #1 0;
287
        else
288
        if (wb_re_i && wb_addr_i == `UART_REG_II)
289
                threi_clear <= #1 1; // reset bits in Modem Status Register
290
end
291
 
292
//
293
//   WRITES AND RESETS   //
294
//
295
// Line Control Register
296
always @(posedge clk or posedge wb_rst_i)
297
        if (wb_rst_i)
298
                lcr <= #1 8'b00000011; // 8n1 setting
299
        else
300
        if (wb_we_i && wb_addr_i==`UART_REG_LC)
301
                lcr <= #1 wb_dat_i;
302
 
303
// Interrupt Enable Register or UART_DL2
304
always @(posedge clk or posedge wb_rst_i)
305
        if (wb_rst_i)
306
        begin
307
                ier <= #1 4'b0000; // no interrupts after reset
308
                dl[`UART_DL2] <= #1 8'b0;
309
        end
310
        else
311
        if (wb_we_i && wb_addr_i==`UART_REG_IE)
312
                if (dlab)
313
                begin
314
                        dl[`UART_DL2] <= #1 wb_dat_i;
315
                end
316
                else
317
                        ier <= #1 wb_dat_i[3:0]; // ier uses only 4 lsb
318
 
319
 
320
// FIFO Control Register and rx_reset, tx_reset signals
321
always @(posedge clk or posedge wb_rst_i)
322
        if (wb_rst_i) begin
323
                fcr <= #1 2'b11;
324
                rx_reset <= #1 0;
325
                tx_reset <= #1 0;
326
        end else
327
        if (wb_we_i && wb_addr_i==`UART_REG_FC) begin
328
                fcr <= #1 wb_dat_i[7:6];
329
                rx_reset <= #1 wb_dat_i[1];
330
                tx_reset <= #1 wb_dat_i[2];
331
        end else begin // clear rx_reset, tx_reset signals when not written to
332
                rx_reset <= #1 0;
333
                tx_reset <= #1 0;
334
        end
335
 
336
// Modem Control Register
337
always @(posedge clk or posedge wb_rst_i)
338
        if (wb_rst_i)
339
                mcr <= #1 5'b0;
340
        else
341
        if (wb_we_i && wb_addr_i==`UART_REG_MC)
342
                        mcr <= #1 wb_dat_i[4:0];
343
 
344
// TX_FIFO or UART_DL1
345
always @(posedge clk or posedge wb_rst_i)
346
        if (wb_rst_i)
347
        begin
348
                dl[`UART_DL1]  <= #1 8'b0;
349
                tf_push   <= #1 1'b0;
350
                start_dlc <= #1 1'b0;
351
        end
352
        else
353
        if (wb_we_i && wb_addr_i==`UART_REG_TR)
354
                if (dlab)
355
                begin
356
                        dl[`UART_DL1] <= #1 wb_dat_i;
357
                        start_dlc <= #1 1'b1; // enable DL counter
358
                        tf_push <= #1 1'b0;
359
                end
360
                else
361
                begin
362
                        tf_push   <= #1 1'b1;
363
                        start_dlc <= #1 1'b0;
364
                end
365
        else
366
        begin
367
                start_dlc <= #1 1'b0;
368
                tf_push   <= #1 1'b0;
369
        end
370
 
371
// Receiver FIFO trigger level selection logic (asynchronous mux)
372
always @(fcr[`UART_FC_TL])
373
        case (fcr[`UART_FC_TL])
374
                2'b00 : trigger_level = 1;
375
                2'b01 : trigger_level = 4;
376
                2'b10 : trigger_level = 8;
377
                2'b11 : trigger_level = 14;
378
        endcase
379
 
380
//
381
//  STATUS REGISTERS  //
382
//
383
 
384
// Modem Status Register
385
always @(posedge clk or posedge wb_rst_i)
386
begin
387
        if (wb_rst_i)
388
                msr <= #1 0;
389
        else begin
390
                msr[`UART_MS_DDCD:`UART_MS_DCTS] <= #1 msi_reset ? 4'b0 :
391
                        msr[`UART_MS_DDCD:`UART_MS_DCTS] | ({dcd, ri, dsr, cts} ^ msr[`UART_MS_CDCD:`UART_MS_CCTS]);
392
                msr[`UART_MS_CDCD:`UART_MS_CCTS] <= #1 {dcd, ri, dsr, cts};
393
        end
394
end
395
 
396
// Line Status Register
397
always @(posedge clk or posedge wb_rst_i)
398
begin
399
        if (wb_rst_i)
400
                lsr <= #1 8'b01100000;
401
        else
402
        if (lsr_mask)
403
                lsr <= #1 lsr & 8'b00000001;
404
        else
405
        begin
406
                lsr[0] <= #1 (rf_count!=4'b0);  // data in receiver fifo available
407
                lsr[1] <= #1 rf_overrun;     // Receiver overrun error
408
                lsr[2] <= #1 rf_data_out[1]; // parity error bit
409
                lsr[3] <= #1 rf_data_out[0]; // framing error bit
410
                lsr[4] <= #1 (counter_b==4'b0); // break counter reached 0
411
                lsr[5] <= #1 (tf_count==5'b0);  // transmitter fifo is empty
412
                lsr[6] <= #1 (tf_count==5'b0 && (state == /*`S_IDLE */ 0)); // transmitter empty
413
                lsr[7] <= #1 rf_error_bit;
414
        end
415
end
416
 
417
// Enable signal generation logic
418
always @(posedge clk or posedge wb_rst_i)
419
begin
420
        if (wb_rst_i)
421
        begin
422
                dlc    <= #1 0;
423
                enable <= #1 1'b0;
424
        end
425
        else
426
        begin
427
                if (start_dlc)
428
                begin
429
                        enable <= #1 1'b0;
430
                        dlc    <= #1 dl;
431
                end
432
                else
433
                begin
434
                        if (dl!=0)
435
                        begin
436
                                if ( (dlc-1)==0 )
437
                                begin
438
                                        enable <= #1 1'b1;
439
                                        dlc <= #1 dl;
440
                                end
441
                                else
442
                                begin
443
                                        enable <= #1 1'b0;
444
                                        dlc <= #1 dlc - 1;
445
                                end
446
                        end
447
                        else
448
                        begin
449
                                dlc <= #1 0;
450
                                enable <= #1 1'b0;
451
                        end
452
                end
453
        end
454
end
455
 
456
//
457
//      INTERRUPT LOGIC
458
//
459
always @(posedge clk or posedge wb_rst_i)
460
begin
461
        if (wb_rst_i)
462
        begin
463
                rls_int  <= #1 1'b0;
464
                rda_int  <= #1 1'b0;
465
                ti_int   <= #1 1'b0;
466
                thre_int <= #1 1'b0;
467
                ms_int   <= #1 1'b0;
468
        end
469
        else
470
        begin
471
                rls_int  <= #1 ier[`UART_IE_RLS] && (lsr[`UART_LS_OE] || lsr[`UART_LS_PE] || lsr[`UART_LS_FE] || lsr[`UART_LS_BI]);
472
                rda_int  <= #1 ier[`UART_IE_RDA] && (rf_count >= {1'b0,trigger_level});
473
                thre_int <= #1 threi_clear ? 0 : ier[`UART_IE_THRE] && lsr[`UART_LS_TFE];
474
                ms_int   <= #1 ier[`UART_IE_MS] && (| msr[3:0]);
475
                ti_int   <= #1 ier[`UART_IE_RDA] && (counter_t == 6'b0);
476
        end
477
end
478
 
479
always @(posedge clk or posedge wb_rst_i)
480
begin
481
        if (wb_rst_i)
482
                int_o <= #1 1'b0;
483
        else
484
                if (| {rls_int,rda_int,thre_int,ms_int,ti_int})
485
                        int_o <= #1 1'b1;
486
                else
487
                        int_o <= #1 1'b0;
488
end
489
 
490
 
491
// Interrupt Identification register
492
always @(posedge clk or posedge wb_rst_i)
493
begin
494
        if (wb_rst_i)
495
                iir <= #1 1;
496
        else
497
        if (rls_int)  // interrupt occured and is enabled  (not masked)
498
        begin
499
                iir[`UART_II_II] <= #1 `UART_II_RLS;    // set identification register to correct value
500
                iir[`UART_II_IP] <= #1 1'b0;            // and clear the IIR bit 0 (interrupt pending)
501
        end
502
        else
503
        if (rda_int)
504
        begin
505
                iir[`UART_II_II] <= #1 `UART_II_RDA;
506
                iir[`UART_II_IP] <= #1 1'b0;
507
        end
508
        else
509
        if (ti_int)
510
        begin
511
                iir[`UART_II_II] <= #1 `UART_II_TI;
512
                iir[`UART_II_IP] <= #1 1'b0;
513
        end
514
        else
515
        if (thre_int)
516
        begin
517
                iir[`UART_II_II] <= #1 `UART_II_THRE;
518
                iir[`UART_II_IP] <= #1 1'b0;
519
        end
520
        else
521
        if (ms_int)
522
        begin
523
                iir[`UART_II_II] <= #1 `UART_II_MS;
524
                iir[`UART_II_IP] <= #1 1'b0;
525
        end
526
        else    // no interrupt is pending
527
        begin
528
                iir[`UART_II_IP] <= #1 1'b1;
529
        end
530
end
531
 
532
endmodule

powered by: WebSVN 2.1.0

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