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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [system/] [uart.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  UART                                                        //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  This is a synchronous UART meaning it uses the system       //
10
//  clock rather than having its own clock. This means the      //
11
//  standard UART Baud rates are approximated and not exact.    //
12
//  However the UART tandard provides for a 10% margin on       //
13
//  baud rates and this module is much more accurate than that. //
14
//                                                              //
15
//  The Baud rate must be set before synthesis and is not       //
16
//  programmable. This keeps the UART small.                    //
17
//                                                              //
18
//  The UART uses 8 data bits, 1 stop bit and no parity bits.   //
19
//                                                              //
20
//  The UART has a 16-byte transmit and a 16-byte receive FIFO  //
21
//  These FIFOs are implemented in flipflops - FPGAs have lots  //
22
//  of flipflops!                                               //
23
//                                                              //
24
//  Author(s):                                                  //
25
//      - Conor Santifort, csantifort.amber@gmail.com           //
26
//                                                              //
27
//////////////////////////////////////////////////////////////////
28
//                                                              //
29
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
30
//                                                              //
31
// This source file may be used and distributed without         //
32
// restriction provided that this copyright statement is not    //
33
// removed from the file and that any derivative work contains  //
34
// the original copyright notice and the associated disclaimer. //
35
//                                                              //
36
// This source file is free software; you can redistribute it   //
37
// and/or modify it under the terms of the GNU Lesser General   //
38
// Public License as published by the Free Software Foundation; //
39
// either version 2.1 of the License, or (at your option) any   //
40
// later version.                                               //
41
//                                                              //
42
// This source is distributed in the hope that it will be       //
43
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
44
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
45
// PURPOSE.  See the GNU Lesser General Public License for more //
46
// details.                                                     //
47
//                                                              //
48
// You should have received a copy of the GNU Lesser General    //
49
// Public License along with this source; if not, download it   //
50
// from http://www.opencores.org/lgpl.shtml                     //
51
//                                                              //
52
//////////////////////////////////////////////////////////////////
53
 
54
`include "system_config_defines.v"
55
 
56
module uart (
57
input                       i_clk,
58
 
59
input       [31:0]          i_wb_adr,
60
input       [3:0]           i_wb_sel,
61
input                       i_wb_we,
62
output      [31:0]          o_wb_dat,
63
input       [31:0]          i_wb_dat,
64
input                       i_wb_cyc,
65
input                       i_wb_stb,
66
output                      o_wb_ack,
67
output                      o_wb_err,
68
 
69
output                      o_uart_int,
70
 
71
input                       i_uart_cts_n,   // Clear To Send
72
output                      o_uart_txd,     // Transmit data
73
output                      o_uart_rts_n,   // Request to Send
74
input                       i_uart_rxd      // Receive data
75
 
76
);
77
 
78
 
79
`include "register_addresses.v"
80
 
81
 
82
localparam [3:0] TXD_IDLE  = 4'd0,
83
                 TXD_START = 4'd1,
84
                 TXD_DATA0 = 4'd2,
85
                 TXD_DATA1 = 4'd3,
86
                 TXD_DATA2 = 4'd4,
87
                 TXD_DATA3 = 4'd5,
88
                 TXD_DATA4 = 4'd6,
89
                 TXD_DATA5 = 4'd7,
90
                 TXD_DATA6 = 4'd8,
91
                 TXD_DATA7 = 4'd9,
92
                 TXD_STOP1 = 4'd10,
93
                 TXD_STOP2 = 4'd11,
94
                 TXD_STOP3 = 4'd12;
95
 
96
localparam [3:0] RXD_IDLE      = 4'd0,
97
                 RXD_START     = 4'd1,
98
                 RXD_START_MID = 4'd2,
99
                 RXD_DATA0     = 4'd3,
100
                 RXD_DATA1     = 4'd4,
101
                 RXD_DATA2     = 4'd5,
102
                 RXD_DATA3     = 4'd6,
103
                 RXD_DATA4     = 4'd7,
104
                 RXD_DATA5     = 4'd8,
105
                 RXD_DATA6     = 4'd9,
106
                 RXD_DATA7     = 4'd10,
107
                 RXD_STOP      = 4'd11;
108
 
109
 
110
localparam RX_INTERRUPT_COUNT = 24'h3fffff;
111
 
112
 
113
// -------------------------------------------------------------------------
114
// Baud Rate Configuration
115
// -------------------------------------------------------------------------
116
 
117
`ifndef Veritak
118
localparam real UART_BAUD         = `AMBER_UART_BAUD;            // Hz
119
localparam real CLK_FREQ          = 800.0 / `AMBER_CLK_DIVIDER ; // MHz
120
localparam real UART_BIT_PERIOD   = 1000000000 / UART_BAUD;      // nS
121
localparam real UART_WORD_PERIOD  = ( UART_BIT_PERIOD * 12 );    // nS
122
localparam real CLK_PERIOD        = 1000 / CLK_FREQ;             // nS
123
localparam real CLKS_PER_WORD     = UART_WORD_PERIOD / CLK_PERIOD;
124
localparam real CLKS_PER_BIT      = CLKS_PER_WORD / 12;
125
 
126
// These are rounded to the nearest whole number
127
// i.e. 29.485960 -> 29
128
//      29.566303 -> 30    
129
localparam [9:0] TX_BITPULSE_COUNT         = CLKS_PER_BIT;
130
localparam [9:0] TX_CLKS_PER_WORD          = CLKS_PER_WORD;
131
`else
132
localparam [9:0] TX_BITPULSE_COUNT         = 30;
133
localparam [9:0] TX_CLKS_PER_WORD          = 360;
134
`endif
135
 
136
localparam [9:0] TX_BITADJUST_COUNT        = TX_CLKS_PER_WORD - 11*TX_BITPULSE_COUNT;
137
 
138
localparam [9:0] RX_BITPULSE_COUNT         = TX_BITPULSE_COUNT-2;
139
localparam [9:0] RX_HALFPULSE_COUNT        = TX_BITPULSE_COUNT/2 - 4;
140
 
141
 
142
// -------------------------------------------------------------------------
143
 
144
reg             tx_interrupt = 'd0;
145
reg             rx_interrupt = 'd0;
146
reg   [23:0]    rx_int_timer = 'd0;
147
 
148
wire            fifo_enable;
149
 
150
reg   [7:0]     tx_fifo    [0:15];
151
wire            tx_fifo_full;
152
wire            tx_fifo_empty;
153
wire            tx_fifo_half_or_less_full;
154
wire            tx_fifo_push;
155
wire            tx_fifo_push_not_full;
156
wire            tx_fifo_pop_not_empty;
157
reg   [4:0]     tx_fifo_wp = 'd0;
158
reg   [4:0]     tx_fifo_rp = 'd0;
159
reg   [4:0]     tx_fifo_count = 'd0;   // number of entries in the fifo
160
reg             tx_fifo_full_flag = 'd0;
161
 
162
reg   [7:0]     rx_fifo    [0:15];
163
reg             rx_fifo_empty = 1'd1;
164
reg             rx_fifo_full = 1'd0;
165
wire            rx_fifo_half_or_more;     // true when half full or greater
166
reg   [4:0]     rx_fifo_count = 'd0;   // number of entries in the fifo
167
wire            rx_fifo_push;
168
wire            rx_fifo_push_not_full;
169
wire            rx_fifo_pop;
170
wire            rx_fifo_pop_not_empty;
171
reg   [4:0]     rx_fifo_wp = 'd0;
172
reg   [4:0]     rx_fifo_rp = 'd0;
173
 
174
wire  [7:0]     tx_byte;
175
reg   [3:0]     txd_state = TXD_IDLE;
176
reg             txd = 1'd1;
177
reg             tx_bit_pulse = 'd0;
178
reg   [9:0]     tx_bit_pulse_count = 'd0;
179
 
180
reg   [7:0]     rx_byte = 'd0;
181
reg   [3:0]     rxd_state = RXD_IDLE;
182
wire            rx_start;
183
reg             rxen = 'd0;
184
reg   [9:0]     rx_bit_pulse_count = 'd0;
185
reg             restart_rx_bit_count = 'd0;
186
reg   [4:0]     rxd_d = 5'h1f;
187
reg   [3:0]     uart0_cts_n_d = 4'hf;
188
 
189
// Wishbone registers
190
reg  [7:0]      uart_rsr_reg = 'd0;       // Receive status, (Write) Error Clear
191
reg  [7:0]      uart_lcrh_reg = 'd0;      // Line Control High Byte
192
reg  [7:0]      uart_lcrm_reg = 'd0;      // Line Control Middle Byte
193
reg  [7:0]      uart_lcrl_reg = 'd0;      // Line Control Low Byte
194
reg  [7:0]      uart_cr_reg = 'd0;        // Control Register
195
 
196
// Wishbone interface
197
reg  [31:0]     wb_rdata = 'd0;
198
wire            wb_start_write;
199
wire            wb_start_read;
200
reg             wb_start_read_d1 = 'd0;
201
 
202
integer         i;
203
 
204
// ======================================================
205
// Wishbone Interface
206
// ======================================================
207
 
208
// Can't start a write while a read is completing. The ack for the read cycle
209
// needs to be sent first
210
assign wb_start_write = i_wb_stb && i_wb_we && !wb_start_read_d1;
211
assign wb_start_read  = i_wb_stb && !i_wb_we && !o_wb_ack;
212
 
213
always @( posedge i_clk )
214
    wb_start_read_d1 <= wb_start_read;
215
 
216
assign o_wb_dat = wb_rdata;
217
 
218
assign o_wb_err = 1'd0;
219
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
220
 
221
 
222
// ======================================================
223
// UART 0 Receive FIFO
224
// ======================================================    
225
 
226
assign rx_fifo_pop           = wb_start_read && i_wb_adr[15:0] == AMBER_UART_DR;
227
assign rx_fifo_push_not_full = rx_fifo_push && !rx_fifo_full;
228
assign rx_fifo_pop_not_empty = rx_fifo_pop && !rx_fifo_empty;
229
assign rx_fifo_half_or_more  = rx_fifo_count >= 5'd8;
230
 
231
 
232
always @ ( posedge i_clk )
233
    begin
234
    if ( fifo_enable )
235
        begin
236
        // RX FIFO Push
237
        if ( rx_fifo_push_not_full )
238
            begin
239
            rx_fifo[rx_fifo_wp[3:0]]    <= rx_byte;
240
            rx_fifo_wp                  <= rx_fifo_wp + 1'd1;
241
            end
242
 
243
        if ( rx_fifo_pop_not_empty )
244
            begin
245
            rx_fifo_rp                  <= rx_fifo_rp + 1'd1;
246
            end
247
 
248
        if ( rx_fifo_push_not_full && !rx_fifo_pop_not_empty )
249
            rx_fifo_count <= rx_fifo_count + 1'd1;
250
        else if ( rx_fifo_pop_not_empty  && !rx_fifo_push_not_full )
251
            rx_fifo_count <= rx_fifo_count - 1'd1;
252
 
253
        rx_fifo_full  <= rx_fifo_wp == {~rx_fifo_rp[4], rx_fifo_rp[3:0]};
254
        rx_fifo_empty <= rx_fifo_wp == rx_fifo_rp;
255
 
256
        if ( rx_fifo_empty || rx_fifo_pop )
257
            rx_int_timer     <= 'd0;
258
        else if ( rx_int_timer != RX_INTERRUPT_COUNT )
259
            rx_int_timer     <= rx_int_timer + 1'd1;
260
 
261
 
262
        end
263
    else    // No FIFO    
264
        begin
265
        rx_int_timer     <= 'd0;
266
 
267
        if ( rx_fifo_push )
268
            begin
269
            rx_fifo[0]         <= rx_byte;
270
            rx_fifo_empty      <= 1'd0;
271
            rx_fifo_full       <= 1'd1;
272
            end
273
        else if ( rx_fifo_pop )
274
            begin
275
            rx_fifo_empty      <= 1'd1;
276
            rx_fifo_full       <= 1'd0;
277
            end
278
        end
279
    end
280
 
281
 
282
// ======================================================
283
// Transmit Interrupts
284
// ======================================================    
285
 
286
 
287
// UART 0 Transmit Interrupt    
288
always @ ( posedge i_clk )
289
    begin
290
    // Clear the interrupt
291
    if ( wb_start_write && i_wb_adr[15:0] == AMBER_UART_ICR )
292
        tx_interrupt <= 1'd0;
293
 
294
    // Set the interrupt    
295
    else if  ( fifo_enable )
296
        // This interrupt clears automatically as bytes are pushed into the tx fifo
297
        // cr bit 5 is Transmit Interrupt Enable
298
        tx_interrupt <= tx_fifo_half_or_less_full && uart_cr_reg[5];
299
    else
300
        // This interrupt clears automatically when a byte is written to tx
301
        // cr bit 5 is Transmit Interrupt Enable
302
        tx_interrupt <= tx_fifo_empty && uart_cr_reg[5];
303
    end
304
 
305
 
306
// ======================================================
307
// Receive Interrupts
308
// ======================================================    
309
 
310
always @ ( posedge i_clk )
311
    if (fifo_enable)
312
        rx_interrupt <=  rx_fifo_half_or_more || rx_int_timer == RX_INTERRUPT_COUNT;
313
    else
314
        rx_interrupt <=  rx_fifo_full;
315
 
316
 
317
assign o_uart_int   = ( tx_interrupt & uart_cr_reg[5] )  |  // UART transmit interrupt w/ enable
318
                      ( rx_interrupt & uart_cr_reg[4] )  ;  // UART receive  interrupt w/ enable
319
 
320
assign fifo_enable = uart_lcrh_reg[4];
321
 
322
 
323
 
324
// ========================================================
325
// UART Transmit
326
// ========================================================
327
 
328
assign   o_uart_txd                 = txd;
329
 
330
assign   tx_fifo_full              = fifo_enable ? tx_fifo_count >= 5'd16 :  tx_fifo_full_flag;
331
assign   tx_fifo_empty             = fifo_enable ? tx_fifo_count == 5'd00 : !tx_fifo_full_flag;
332
assign   tx_fifo_half_or_less_full =               tx_fifo_count <= 5'd8;
333
assign   tx_byte                    = fifo_enable ? tx_fifo[tx_fifo_rp[3:0]] : tx_fifo[0] ;
334
 
335
assign   tx_fifo_push               = wb_start_write && i_wb_adr[15:0] == AMBER_UART_DR;
336
assign   tx_fifo_push_not_full      = tx_fifo_push && !tx_fifo_full;
337
assign   tx_fifo_pop_not_empty      = txd_state == TXD_STOP3 && tx_bit_pulse == 1'd1 && !tx_fifo_empty;
338
 
339
 
340
// Transmit FIFO
341
always @( posedge i_clk )
342
    begin
343
    // Use 8-entry FIFO
344
    if ( fifo_enable )
345
        begin
346
        // Push
347
        if ( tx_fifo_push_not_full )
348
            begin
349
            tx_fifo[tx_fifo_wp[3:0]] <= i_wb_dat[7:0];
350
            tx_fifo_wp <= tx_fifo_wp + 1'd1;
351
            end
352
 
353
 
354
        // Pop    
355
        if ( tx_fifo_pop_not_empty )
356
            tx_fifo_rp <= tx_fifo_rp + 1'd1;
357
 
358
        // Count up 
359
        if (tx_fifo_push_not_full && !tx_fifo_pop_not_empty)
360
            tx_fifo_count <= tx_fifo_count + 1'd1;
361
 
362
        // Count down 
363
        else if (tx_fifo_pop_not_empty  && !tx_fifo_push_not_full)
364
            tx_fifo_count <= tx_fifo_count - 1'd1;
365
        end
366
 
367
    // Do not use 8-entry FIFO, single entry register instead
368
    else
369
        begin
370
        // Clear FIFO values
371
        tx_fifo_wp    <= 'd0;
372
        tx_fifo_rp    <= 'd0;
373
        tx_fifo_count <= 'd0;
374
 
375
        // Push
376
        if ( tx_fifo_push_not_full )
377
            begin
378
            tx_fifo[0]          <= i_wb_dat[7:0];
379
            tx_fifo_full_flag   <= 1'd1;
380
            end
381
        // Pop    
382
        else if ( tx_fifo_pop_not_empty )
383
            tx_fifo_full_flag   <= 1'd0;
384
 
385
        end
386
    end
387
 
388
 
389
// ========================================================
390
// Register Clear to Send Input
391
// ========================================================
392
always @( posedge i_clk )
393
    uart0_cts_n_d <= {uart0_cts_n_d[2:0], i_uart_cts_n};
394
 
395
 
396
// ========================================================
397
// Transmit Pulse generater - matches baud rate      
398
// ========================================================
399
always @( posedge i_clk )
400
    if (( tx_bit_pulse_count == (TX_BITADJUST_COUNT-1) && txd_state == TXD_STOP2 ) ||
401
        ( tx_bit_pulse_count == (TX_BITPULSE_COUNT-1)  && txd_state != TXD_STOP2 )  )
402
        begin
403
        tx_bit_pulse_count <= 'd0;
404
        tx_bit_pulse       <= 1'd1;
405
        end
406
    else
407
        begin
408
        tx_bit_pulse_count <= tx_bit_pulse_count + 1'd1;
409
        tx_bit_pulse       <= 1'd0;
410
        end
411
 
412
 
413
// ========================================================
414
// Byte Transmitted
415
// ========================================================
416
    // Idle state, txd = 1
417
    // start bit, txd = 0
418
    // Data x 8, lsb first
419
    // stop bit, txd = 1
420
 
421
 
422
    // X = 0x58  = 01011000
423
always @( posedge i_clk )
424
    if ( tx_bit_pulse )
425
 
426
        case (txd_state)
427
 
428
            TXD_IDLE :
429
                begin
430
                txd       <= 1'd1;
431
 
432
                if ( uart0_cts_n_d[3:1] == 3'b000 && !tx_fifo_empty )
433
                    txd_state <= TXD_START;
434
                end
435
 
436
            TXD_START :
437
                begin
438
                txd       <= 1'd0;
439
                txd_state <= TXD_DATA0;
440
                end
441
 
442
            TXD_DATA0 :
443
                begin
444
                txd       <= tx_byte[0];
445
                txd_state <= TXD_DATA1;
446
                end
447
 
448
            TXD_DATA1 :
449
                begin
450
                txd       <= tx_byte[1];
451
                txd_state <= TXD_DATA2;
452
                end
453
 
454
            TXD_DATA2 :
455
                begin
456
                txd       <= tx_byte[2];
457
                txd_state <= TXD_DATA3;
458
                end
459
 
460
            TXD_DATA3 :
461
                begin
462
                txd       <= tx_byte[3];
463
                txd_state <= TXD_DATA4;
464
                end
465
 
466
            TXD_DATA4 :
467
                begin
468
                txd       <= tx_byte[4];
469
                txd_state <= TXD_DATA5;
470
                end
471
 
472
            TXD_DATA5 :
473
                begin
474
                txd       <= tx_byte[5];
475
                txd_state <= TXD_DATA6;
476
                end
477
 
478
            TXD_DATA6 :
479
                begin
480
                txd       <= tx_byte[6];
481
                txd_state <= TXD_DATA7;
482
                end
483
 
484
            TXD_DATA7 :
485
                begin
486
                txd       <= tx_byte[7];
487
                txd_state <= TXD_STOP1;
488
                end
489
 
490
            TXD_STOP1 :
491
                begin
492
                txd       <= 1'd1;
493
                txd_state <= TXD_STOP2;
494
                end
495
 
496
            TXD_STOP2 :
497
                begin
498
                txd       <= 1'd1;
499
                txd_state <= TXD_STOP3;
500
                end
501
 
502
            TXD_STOP3 :
503
                begin
504
                txd       <= 1'd1;
505
                txd_state <= TXD_IDLE;
506
                end
507
 
508
            default :
509
                begin
510
                txd       <= 1'd1;
511
                end
512
 
513
        endcase
514
 
515
 
516
 
517
 
518
// ========================================================
519
// UART Receive
520
// ========================================================
521
 
522
assign o_uart_rts_n  = ~rxen;
523
 
524
assign rx_fifo_push  = rxd_state == RXD_STOP && rx_bit_pulse_count == 10'd0;
525
 
526
// ========================================================
527
// Receive bit pulse
528
// ========================================================
529
// Pulse generater - matches baud rate      
530
always @( posedge i_clk )
531
    if ( restart_rx_bit_count )
532
        rx_bit_pulse_count <= 'd0;
533
    else
534
        rx_bit_pulse_count <= rx_bit_pulse_count + 1'd1;
535
 
536
 
537
// ========================================================
538
// Detect 1->0 transition. Filter out glitches and jaggedy transitions
539
// ========================================================
540
always @( posedge i_clk )
541
    rxd_d[4:0] <= {rxd_d[3:0], i_uart_rxd};
542
 
543
assign rx_start = rxd_d[4:3] == 2'b11 && rxd_d[1:0] == 2'b00;
544
 
545
 
546
// ========================================================
547
// Receive state machine
548
// ========================================================
549
 
550
always @( posedge i_clk )
551
    case ( rxd_state )
552
 
553
        RXD_IDLE :
554
            if ( rx_fifo_full )
555
                rxen                    <= 1'd0;
556
            else
557
                begin
558
                rxd_state               <= RXD_START;
559
                rxen                    <= 1'd1;
560
                restart_rx_bit_count    <= 1'd1;
561
                rx_byte                 <= 'd0;
562
                end
563
 
564
        RXD_START :
565
            // Filter out glitches and jaggedy transitions
566
            if ( rx_start )
567
                begin
568
                rxd_state               <= RXD_START_MID;
569
                restart_rx_bit_count    <= 1'd1;
570
                end
571
            else
572
                restart_rx_bit_count    <= 1'd0;
573
 
574
        RXD_START_MID :
575
            if ( rx_bit_pulse_count == RX_HALFPULSE_COUNT )
576
                begin
577
                rxd_state               <= RXD_DATA0;
578
                restart_rx_bit_count    <= 1'd1;
579
                end
580
            else
581
                restart_rx_bit_count    <= 1'd0;
582
 
583
        RXD_DATA0 :
584
            if ( rx_bit_pulse_count == RX_BITPULSE_COUNT )
585
                begin
586
                rxd_state               <= RXD_DATA1;
587
                restart_rx_bit_count    <= 1'd1;
588
                rx_byte[0]              <= i_uart_rxd;
589
                end
590
            else
591
                restart_rx_bit_count    <= 1'd0;
592
 
593
        RXD_DATA1 :
594
            if ( rx_bit_pulse_count == RX_BITPULSE_COUNT )
595
                begin
596
                rxd_state               <= RXD_DATA2;
597
                restart_rx_bit_count    <= 1'd1;
598
                rx_byte[1]              <= i_uart_rxd;
599
                end
600
            else
601
                restart_rx_bit_count    <= 1'd0;
602
 
603
        RXD_DATA2 :
604
            if ( rx_bit_pulse_count == RX_BITPULSE_COUNT )
605
                begin
606
                rxd_state               <= RXD_DATA3;
607
                restart_rx_bit_count    <= 1'd1;
608
                rx_byte[2]              <= i_uart_rxd;
609
                end
610
            else
611
                restart_rx_bit_count    <= 1'd0;
612
 
613
        RXD_DATA3 :
614
            if ( rx_bit_pulse_count == RX_BITPULSE_COUNT )
615
                begin
616
                rxd_state               <= RXD_DATA4;
617
                restart_rx_bit_count    <= 1'd1;
618
                rx_byte[3]              <= i_uart_rxd;
619
                end
620
            else
621
                restart_rx_bit_count    <= 1'd0;
622
 
623
        RXD_DATA4 :
624
            if ( rx_bit_pulse_count ==  RX_BITPULSE_COUNT )
625
                begin
626
                rxd_state               <= RXD_DATA5;
627
                restart_rx_bit_count    <= 1'd1;
628
                rx_byte[4]              <= i_uart_rxd;
629
                end
630
            else
631
                restart_rx_bit_count    <= 1'd0;
632
 
633
        RXD_DATA5 :
634
            if ( rx_bit_pulse_count ==  RX_BITPULSE_COUNT )
635
                begin
636
                rxd_state               <= RXD_DATA6;
637
                restart_rx_bit_count    <= 1'd1;
638
                rx_byte[5]              <= i_uart_rxd;
639
                end
640
            else
641
                restart_rx_bit_count    <= 1'd0;
642
 
643
        RXD_DATA6 :
644
            if ( rx_bit_pulse_count ==  RX_BITPULSE_COUNT )
645
                begin
646
                rxd_state               <= RXD_DATA7;
647
                restart_rx_bit_count    <= 1'd1;
648
                rx_byte[6]              <= i_uart_rxd;
649
                end
650
            else
651
                restart_rx_bit_count    <= 1'd0;
652
 
653
        RXD_DATA7 :
654
            if ( rx_bit_pulse_count ==  RX_BITPULSE_COUNT )
655
                begin
656
                rxd_state               <= RXD_STOP;
657
                restart_rx_bit_count    <= 1'd1;
658
                rx_byte[7]              <= i_uart_rxd;
659
                end
660
            else
661
                restart_rx_bit_count    <= 1'd0;
662
 
663
        RXD_STOP :
664
            if ( rx_bit_pulse_count ==  RX_BITPULSE_COUNT )  // half way through stop bit 
665
                begin
666
                rxd_state               <= RXD_IDLE;
667
                restart_rx_bit_count    <= 1'd1;
668
                end
669
            else
670
                restart_rx_bit_count    <= 1'd0;
671
 
672
        default :
673
            begin
674
            rxd_state       <= RXD_IDLE;
675
            end
676
 
677
    endcase
678
 
679
 
680
// ========================================================
681
// Register Writes
682
// ========================================================
683
always @( posedge i_clk )
684
    if ( wb_start_write )
685
        case ( i_wb_adr[15:0] )
686
            // Receive status, (Write) Error Clear
687
            AMBER_UART_RSR:  uart_rsr_reg      <= i_wb_dat[7:0];
688
            // Line Control High Byte    
689
            AMBER_UART_LCRH: uart_lcrh_reg     <= i_wb_dat[7:0];
690
            // Line Control Middle Byte    
691
            AMBER_UART_LCRM: uart_lcrm_reg     <= i_wb_dat[7:0];
692
            // Line Control Low Byte    
693
            AMBER_UART_LCRL: uart_lcrl_reg     <= i_wb_dat[7:0];
694
            // Control Register    
695
            AMBER_UART_CR:   uart_cr_reg       <= i_wb_dat[7:0];
696
        endcase
697
 
698
 
699
// ========================================================
700
// Register Reads
701
// ========================================================
702
always @( posedge i_clk )
703
    if ( wb_start_read )
704
        case ( i_wb_adr[15:0] )
705
 
706
            AMBER_UART_CID0:    wb_rdata <= 32'h0d;
707
            AMBER_UART_CID1:    wb_rdata <= 32'hf0;
708
            AMBER_UART_CID2:    wb_rdata <= 32'h05;
709
            AMBER_UART_CID3:    wb_rdata <= 32'hb1;
710
            AMBER_UART_PID0:    wb_rdata <= 32'h10;
711
            AMBER_UART_PID1:    wb_rdata <= 32'h10;
712
            AMBER_UART_PID2:    wb_rdata <= 32'h04;
713
            AMBER_UART_PID3:    wb_rdata <= 32'h00;
714
 
715
            AMBER_UART_DR:      // Rx data   
716
                    if ( fifo_enable )
717
                        wb_rdata <= {24'd0, rx_fifo[rx_fifo_rp[3:0]]};
718
                    else
719
                        wb_rdata <= {24'd0, rx_fifo[0]};
720
 
721
            AMBER_UART_RSR:     wb_rdata <= uart_rsr_reg;          // Receive status, (Write) Error Clear
722
            AMBER_UART_LCRH:    wb_rdata <= uart_lcrh_reg;         // Line Control High Byte
723
            AMBER_UART_LCRM:    wb_rdata <= uart_lcrm_reg;         // Line Control Middle Byte
724
            AMBER_UART_LCRL:    wb_rdata <= uart_lcrl_reg;         // Line Control Low Byte
725
            AMBER_UART_CR:      wb_rdata <= uart_cr_reg;           // Control Register
726
 
727
            // UART Tx/Rx Status
728
            AMBER_UART_FR:      wb_rdata <= {tx_fifo_empty,       // tx fifo empty
729
                                             rx_fifo_full,        // rx fifo full
730
                                             tx_fifo_full,        // tx fifo full
731
                                             rx_fifo_empty,       // rx fifo empty
732
                                             !tx_fifo_empty,      // uart busy
733
                                             1'd1,                 // !Data Carrier Detect
734
                                             1'd1,                 // !Data Set Ready
735
                                             !uart0_cts_n_d[3]     // !Clear to Send
736
                                             };                    // Flag Register
737
 
738
            // Interrupt Status                                                    
739
            AMBER_UART_IIR:     wb_rdata <= {5'd0,
740
                                             1'd0,                 // RTIS  - receive timeout interrupt
741
                                             tx_interrupt,         // TIS   - transmit interrupt status
742
                                             rx_interrupt,         // RIS   - receive interrupt status
743
                                             1'd0                  // Modem interrupt status
744
                                            };                     // (Write) Clear Int
745
 
746
            default:            wb_rdata <= 32'h00c0ffee;
747
 
748
        endcase
749
 
750
 
751
 
752
 
753
// =======================================================================================
754
// =======================================================================================
755
// =======================================================================================
756
// Non-synthesizable debug code
757
// =======================================================================================
758
 
759
 
760
//synopsys translate_off
761
 
762
// ========================================================
763
// Report UART Register accesses
764
// ========================================================
765
 
766
`ifndef Veritak
767
// Check in case UART approximate period
768
// is too far off
769
initial
770
    begin
771
    if ((( TX_BITPULSE_COUNT * CLK_PERIOD ) > (UART_BIT_PERIOD * 1.03) ) ||
772
        (( TX_BITPULSE_COUNT * CLK_PERIOD ) < (UART_BIT_PERIOD * 0.97) ) )
773
        begin
774
        `TB_ERROR_MESSAGE
775
        $display("UART TX bit period, %.1f, is too big. UART will not work!", TX_BITPULSE_COUNT * CLK_PERIOD);
776
        $display("Baud rate is %d, and baud bit period is %.1f", UART_BAUD, UART_BIT_PERIOD);
777
        $display("Either reduce the baud rate, or increase the system clock frequency");
778
        $display("------");
779
        end
780
    end
781
`endif
782
 
783
 
784
`ifdef AMBER_UART_DEBUG
785
wire            wb_read_ack;
786
reg             uart0_rx_int_d1 = 'd0;
787
 
788
assign wb_read_ack = i_wb_stb && !i_wb_we &&  o_wb_ack;
789
 
790
`ifndef Veritak
791
initial
792
    begin
793
    $display("%m UART period = %f nS, want %f nS, %d, %d",
794
             (TX_BITPULSE_COUNT*11 + TX_BITADJUST_COUNT) * CLK_PERIOD,
795
             UART_WORD_PERIOD,
796
             TX_BITPULSE_COUNT, TX_BITADJUST_COUNT);
797
    end
798
`endif
799
 
800
 
801
// Transmit Interrupts
802
always @ ( posedge i_clk )
803
    if ( wb_start_write && i_wb_adr[15:0] == AMBER_UART_ICR )
804
            ;
805
    else if ( fifo_enable )
806
        begin
807
        if (tx_interrupt == 1'd0 && tx_fifo_half_or_less_full && uart_cr_reg[5])
808
            $display("%m: tx_interrupt Interrupt Set with FIFO enabled");
809
        if (tx_interrupt == 1'd1 && !(tx_fifo_half_or_less_full && uart_cr_reg[5]))
810
            $display("%m: tx_interrupt Interrupt Cleared with FIFO enabled");
811
        end
812
    else
813
        begin
814
        if (tx_interrupt == 1'd0 && tx_fifo_empty && uart_cr_reg[5])
815
            $display("%m: tx_interrupt Interrupt Set with FIFO disabled");
816
        if (tx_interrupt == 1'd1 && !(tx_fifo_empty && uart_cr_reg[5]))
817
            $display("%m: tx_interrupt Interrupt Cleared with FIFO disabled");
818
        end
819
 
820
 
821
// Receive Interrupts
822
always @ ( posedge i_clk )
823
    begin
824
    uart0_rx_int_d1 <= rx_interrupt;
825
 
826
    if ( rx_interrupt && !uart0_rx_int_d1 )
827
        begin
828
        `TB_DEBUG_MESSAGE
829
        $display("rx_interrupt Interrupt fifo_enable %d, rx_fifo_full %d",
830
                 fifo_enable, rx_fifo_full);
831
        $display("rx_fifo_half_or_more %d, rx_int_timer 0x%08h, rx_fifo_count %d",
832
                 rx_fifo_half_or_more, rx_int_timer, rx_fifo_count);
833
        end
834
 
835
    if ( !rx_interrupt && uart0_rx_int_d1 )
836
        begin
837
        `TB_DEBUG_MESSAGE
838
        $display("rx_interrupt Interrupt Cleared fifo_enable %d, rx_fifo_full %d",
839
                 fifo_enable, rx_fifo_full);
840
        $display("    rx_fifo_half_or_more %d, rx_int_timer 0x%08h, rx_fifo_count %d",
841
                 rx_fifo_half_or_more, rx_int_timer, rx_fifo_count);
842
        end
843
    end
844
 
845
 
846
always @( posedge i_clk )
847
    if ( wb_read_ack || wb_start_write )
848
        begin
849
        `TB_DEBUG_MESSAGE
850
 
851
        if ( wb_start_write )
852
            $write("Write 0x%08x to   ", i_wb_dat);
853
        else
854
            $write("Read  0x%08x from ", o_wb_dat);
855
 
856
        case ( i_wb_adr[15:0] )
857
            AMBER_UART_PID0:    $write("UART PID0 register");
858
            AMBER_UART_PID1:    $write("UART PID1 register");
859
            AMBER_UART_PID2:    $write("UART PID2 register");
860
            AMBER_UART_PID3:    $write("UART PID3 register");
861
            AMBER_UART_CID0:    $write("UART CID0 register");
862
            AMBER_UART_CID1:    $write("UART CID1 register");
863
            AMBER_UART_CID2:    $write("UART CID2 register");
864
            AMBER_UART_CID3:    $write("UART CID3 register");
865
            AMBER_UART_DR:      $write("UART Tx/Rx char %c", wb_start_write ? i_wb_dat[7:0] : o_wb_dat[7:0] );
866
            AMBER_UART_RSR:     $write("UART (Read) Receive status, (Write) Error Clear");
867
            AMBER_UART_LCRH:    $write("UART Line Control High Byte");
868
            AMBER_UART_LCRM:    $write("UART Line Control Middle Byte");
869
            AMBER_UART_LCRL:    $write("UART Line Control Low Byte");
870
            AMBER_UART_CR:      $write("UART Control Register");
871
            AMBER_UART_FR:      $write("UART Flag Register");
872
            AMBER_UART_IIR:     $write("UART (Read) Interrupt Identification Register");
873
 
874
            default:
875
                begin
876
                `TB_ERROR_MESSAGE
877
                $write("Unknown UART Register region");
878
                end
879
        endcase
880
 
881
        $write(", Address 0x%08h\n", i_wb_adr);
882
        end
883
`endif
884
 
885
 
886
// ========================================================
887
// Assertions
888
// ========================================================
889
always @ ( posedge i_clk )
890
    begin
891
    if ( rx_fifo_pop  && !rx_fifo_push && rx_fifo_empty )
892
        begin
893
        `TB_WARNING_MESSAGE
894
        $write("UART rx FIFO underflow\n");
895
        end
896
    if ( !rx_fifo_pop  && rx_fifo_push && rx_fifo_full )
897
        begin
898
        `TB_WARNING_MESSAGE
899
        $write("UART rx FIFO overflow\n");
900
        end
901
 
902
    if ( tx_fifo_push && tx_fifo_full )
903
        begin
904
        `TB_WARNING_MESSAGE
905
        $display("UART tx FIFO overflow - char = %c", i_wb_dat[7:0]);
906
        end
907
    end
908
 
909
 
910
// ========================================================
911
// Debug State Machines
912
// ========================================================
913
 
914
wire    [(10*8)-1:0]    xTXD_STATE;
915
wire    [(14*8)-1:0]    xRXD_STATE;
916
 
917
 
918
assign xTXD_STATE      = txd_state == TXD_IDLE      ? "TXD_IDLE"   :
919
                         txd_state == TXD_START     ? "TXD_START"  :
920
                         txd_state == TXD_DATA0     ? "TXD_DATA0"  :
921
                         txd_state == TXD_DATA1     ? "TXD_DATA1"  :
922
                         txd_state == TXD_DATA2     ? "TXD_DATA2"  :
923
                         txd_state == TXD_DATA3     ? "TXD_DATA3"  :
924
                         txd_state == TXD_DATA4     ? "TXD_DATA4"  :
925
                         txd_state == TXD_DATA5     ? "TXD_DATA5"  :
926
                         txd_state == TXD_DATA6     ? "TXD_DATA6"  :
927
                         txd_state == TXD_DATA7     ? "TXD_DATA7"  :
928
                         txd_state == TXD_STOP1     ? "TXD_STOP1"  :
929
                         txd_state == TXD_STOP2     ? "TXD_STOP2"  :
930
                         txd_state == TXD_STOP3     ? "TXD_STOP3"  :
931
                                                      "UNKNOWN"    ;
932
 
933
assign xRXD_STATE      = rxd_state == RXD_IDLE      ? "RXD_IDLE"      :
934
                         rxd_state == RXD_START     ? "RXD_START"     :
935
                         rxd_state == RXD_START_MID ? "RXD_START_MID" :
936
                         rxd_state == RXD_DATA0     ? "RXD_DATA0"     :
937
                         rxd_state == RXD_DATA1     ? "RXD_DATA1"     :
938
                         rxd_state == RXD_DATA2     ? "RXD_DATA2"     :
939
                         rxd_state == RXD_DATA3     ? "RXD_DATA3"     :
940
                         rxd_state == RXD_DATA4     ? "RXD_DATA4"     :
941
                         rxd_state == RXD_DATA5     ? "RXD_DATA5"     :
942
                         rxd_state == RXD_DATA6     ? "RXD_DATA6"     :
943
                         rxd_state == RXD_DATA7     ? "RXD_DATA7"     :
944
                         rxd_state == RXD_STOP      ? "RXD_STOP"      :
945
                                                      "UNKNOWN"       ;
946
 
947
//synopsys translate_on
948
 
949
 
950
endmodule
951
 

powered by: WebSVN 2.1.0

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