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

Subversion Repositories amber

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

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

powered by: WebSVN 2.1.0

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