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,
36 //-----------------------------------------------------------------
38 //-----------------------------------------------------------------
39 reg [15:0] enable16_counter;
42 assign enable16 = (enable16_counter == 16'd0);
44 always @(posedge sys_clk) begin
46 enable16_counter <= divisor - 16'b1;
48 enable16_counter <= enable16_counter - 16'd1;
50 enable16_counter <= divisor - 16'b1;
54 //-----------------------------------------------------------------
55 // Synchronize uart_rxd
56 //-----------------------------------------------------------------
60 always @(posedge sys_clk) begin
61 uart_rxd1 <= uart_rxd;
62 uart_rxd2 <= uart_rxd1;
65 //-----------------------------------------------------------------
67 //-----------------------------------------------------------------
70 reg [3:0] rx_bitcount;
73 always @(posedge sys_clk) begin
83 if(~rx_busy) begin // look for start bit
84 if(~uart_rxd2) begin // start bit found
90 rx_count16 <= rx_count16 + 4'd1;
92 if(rx_count16 == 4'd0) begin // sample
93 rx_bitcount <= rx_bitcount + 4'd1;
95 if(rx_bitcount == 4'd0) begin // verify startbit
98 end else if(rx_bitcount == 4'd9) begin
100 if(uart_rxd2) begin // stop bit ok
103 end // ignore RX error
105 rxd_reg <= {uart_rxd2, rxd_reg[7:1]};
112 //-----------------------------------------------------------------
114 //-----------------------------------------------------------------
116 reg [3:0] tx_bitcount;
117 reg [3:0] tx_count16;
120 always @(posedge sys_clk) begin
133 $display("UART: %c", tx_data);
135 end else if(enable16 && tx_busy) begin
136 tx_count16 <= tx_count16 + 4'd1;
138 if(tx_count16 == 4'd0) begin
139 tx_bitcount <= tx_bitcount + 4'd1;
141 if(tx_bitcount == 4'd8) begin
143 end else if(tx_bitcount == 4'd9) begin
147 uart_txd <= txd_reg[0];
148 txd_reg <= {1'b0, txd_reg[7:1]};