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

Subversion Repositories amber

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

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

powered by: WebSVN 2.1.0

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