Root/lm32/logic/sakc/rtl/wb_uart/uart.v

1//-----------------------------------------------------
2// Design Name : uart
3// File Name : uart.v
4//-----------------------------------------------------
5module uart #(
6    parameter freq_hz = 100000000,
7    parameter baud = 115200
8) (
9    input reset,
10    input clk,
11    // UART lines
12    input uart_rxd,
13    output reg uart_txd,
14    //
15    output reg [7:0] rx_data,
16    output reg rx_avail,
17    output reg rx_error,
18    input rx_ack,
19    input [7:0] tx_data,
20    input tx_wr,
21    output reg tx_busy
22);
23
24parameter divisor = freq_hz/baud/16;
25
26//-----------------------------------------------------------------
27// enable16 generator
28//-----------------------------------------------------------------
29reg [15:0] enable16_counter;
30
31wire enable16;
32assign enable16 = (enable16_counter == 0);
33
34always @(posedge clk)
35begin
36    if (reset) begin
37        enable16_counter <= divisor-1;
38    end else begin
39        enable16_counter <= enable16_counter - 1;
40        if (enable16_counter == 0) begin
41            enable16_counter <= divisor-1;
42        end
43    end
44end
45
46//-----------------------------------------------------------------
47// syncronize uart_rxd
48//-----------------------------------------------------------------
49reg uart_rxd1;
50reg uart_rxd2;
51
52always @(posedge clk)
53begin
54    uart_rxd1 <= uart_rxd;
55    uart_rxd2 <= uart_rxd1;
56end
57
58//-----------------------------------------------------------------
59// UART RX Logic
60//-----------------------------------------------------------------
61reg rx_busy;
62reg [3:0] rx_count16;
63reg [3:0] rx_bitcount;
64reg [7:0] rxd_reg;
65
66always @ (posedge clk)
67begin
68    if (reset) begin
69        rx_busy <= 0;
70        rx_count16 <= 0;
71        rx_bitcount <= 0;
72        rx_avail <= 0;
73        rx_error <= 0;
74    end else begin
75        if (rx_ack) begin
76            rx_avail <= 0;
77            rx_error <= 0;
78        end
79
80        if (enable16) begin
81            if (!rx_busy) begin // look for start bit
82                if (!uart_rxd2) begin // start bit found
83                    rx_busy <= 1;
84                    rx_count16 <= 7;
85                    rx_bitcount <= 0;
86                end
87            end else begin
88                rx_count16 <= rx_count16 + 1;
89
90                if (rx_count16 == 0) begin // sample
91                    rx_bitcount <= rx_bitcount + 1;
92
93                    if (rx_bitcount == 0) begin // verify startbit
94                        if (uart_rxd2) begin
95                            rx_busy <= 0;
96                        end
97                    end else if (rx_bitcount == 9) begin // look for stop bit
98                        rx_busy <= 0;
99                        if (uart_rxd2) begin // stop bit ok
100                            rx_data <= rxd_reg;
101                            rx_avail <= 1;
102                            rx_error <= 0;
103                        end else begin // bas stop bit
104                            rx_error <= 1;
105                        end
106                    end else begin
107                        rxd_reg <= { uart_rxd2, rxd_reg[7:1] };
108                    end
109                end
110            end
111        end
112    end
113end
114
115//-----------------------------------------------------------------
116// UART TX Logic
117//-----------------------------------------------------------------
118reg [3:0] tx_bitcount;
119reg [3:0] tx_count16;
120reg [7:0] txd_reg;
121
122always @ (posedge clk)
123begin
124    if (reset) begin
125        tx_busy <= 0;
126        uart_txd <= 1;
127        tx_count16 <= 0;
128    end else begin
129        if (tx_wr && !tx_busy) begin
130            txd_reg <= tx_data;
131            tx_bitcount <= 0;
132            tx_count16 <= 0;
133            tx_busy <= 1;
134        end
135
136        if (enable16) begin
137            tx_count16 <= tx_count16 + 1;
138
139            if ((tx_count16 == 0) && tx_busy) begin
140                tx_bitcount <= tx_bitcount + 1;
141                
142                if (tx_bitcount == 0) begin
143                    uart_txd <= 'b0;
144                end else if (tx_bitcount == 9) begin
145                    uart_txd <= 'b1;
146                end else if (tx_bitcount == 10) begin
147                    tx_bitcount <= 0;
148                    tx_busy <= 0;
149                end else begin
150                    uart_txd <= txd_reg[0];
151                    txd_reg <= { 1'b0, txd_reg[7:1] };
152                end
153            end
154
155        end
156    end
157end
158
159
160endmodule
161

Archive Download this file

Branches:
master



interactive