3 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
4 * Copyright (C) 2007 Das Labor
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, version 3 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 module uart_transceiver(
28 output reg [7:0] rx_data,
37 //-----------------------------------------------------------------
39 //-----------------------------------------------------------------
40 reg [15:0] enable16_counter;
43 assign enable16 = (enable16_counter == 16'd0);
45 always @(posedge sys_clk) begin
47 enable16_counter <= divisor - 16'b1;
49 enable16_counter <= enable16_counter - 16'd1;
51 enable16_counter <= divisor - 16'b1;
55 //-----------------------------------------------------------------
56 // Synchronize uart_rxd
57 //-----------------------------------------------------------------
61 always @(posedge sys_clk) begin
62 uart_rxd1 <= uart_rxd;
63 uart_rxd2 <= uart_rxd1;
66 //-----------------------------------------------------------------
68 //-----------------------------------------------------------------
71 reg [3:0] rx_bitcount;
74 always @(posedge sys_clk) begin
88 if(!rx_busy) begin // look for start bit
89 if(!uart_rxd2) begin // start bit found
95 rx_count16 <= rx_count16 + 4'd1;
97 if(rx_count16 == 4'd0) begin // sample
98 rx_bitcount <= rx_bitcount + 4'd1;
100 if(rx_bitcount == 4'd0) begin // verify startbit
103 end else if(rx_bitcount == 4'd9) begin // look for stop bit
105 if(uart_rxd2) begin // stop bit ok
109 end else begin // bad stop bit
113 rxd_reg <= {uart_rxd2, rxd_reg[7:1]};
121 //-----------------------------------------------------------------
123 //-----------------------------------------------------------------
124 reg [3:0] tx_bitcount;
125 reg [3:0] tx_count16;
128 always @(posedge sys_clk) begin
133 if(tx_wr && !tx_busy) begin
140 $display("UART: %c", tx_data);
142 end else if(enable16 && tx_busy) begin
143 tx_count16 <= tx_count16 + 4'd1;
145 if(tx_count16 == 4'd0) begin
146 tx_bitcount <= tx_bitcount + 4'd1;
148 if(tx_bitcount == 4'd8) begin
150 end else if(tx_bitcount == 4'd9) begin
154 uart_txd <= txd_reg[0];
155 txd_reg <= {1'b0, txd_reg[7:1]};