2 // Documented Verilog UART
3 // Copyright (C) 2010 Timothy Goddard (tim@goddard.net.nz)
4 // Distributed under the MIT licence.
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 input clk, // The master clock for this module
26 input rst, // Synchronous reset.
27 input rx, // Incoming serial line
28 output tx, // Outgoing serial line
29 input transmit, // Signal to transmit
30 input [7:0] tx_byte, // Byte to transmit
31 output received, // Indicated that a byte has been received.
32 output [7:0] rx_byte, // Byte received
33 output is_receiving, // Low when receive line is idle.
34 output is_transmitting, // Low when transmit line is idle.
35 output recv_error // Indicates error in receiving packet.
38 parameter CLOCK_DIVIDE = 1302; // clock rate (50Mhz) / (baud rate (9600) * 4)
40 // States for the receiving state machine.
41 // These are just constants, not parameters to override.
42 parameter RX_IDLE = 0;
43 parameter RX_CHECK_START = 1;
44 parameter RX_READ_BITS = 2;
45 parameter RX_CHECK_STOP = 3;
46 parameter RX_DELAY_RESTART = 4;
47 parameter RX_ERROR = 5;
48 parameter RX_RECEIVED = 6;
50 // States for the transmitting state machine.
51 // Constants - do not override.
52 parameter TX_IDLE = 0;
53 parameter TX_SENDING = 1;
54 parameter TX_DELAY_RESTART = 2;
56 reg [10:0] rx_clk_divider = CLOCK_DIVIDE;
57 reg [10:0] tx_clk_divider = CLOCK_DIVIDE;
59 reg [2:0] recv_state = RX_IDLE;
60 reg [5:0] rx_countdown;
61 reg [3:0] rx_bits_remaining;
65 reg [1:0] tx_state = TX_IDLE;
66 reg [5:0] tx_countdown;
67 reg [3:0] tx_bits_remaining;
70 assign received = recv_state == RX_RECEIVED;
71 assign recv_error = recv_state == RX_ERROR;
72 assign is_receiving = recv_state != RX_IDLE;
73 assign rx_byte = rx_data;
76 assign is_transmitting = tx_state != TX_IDLE;
78 always @(posedge clk) begin
84 // The clk_divider counter counts down from
85 // the CLOCK_DIVIDE constant. Whenever it
86 // reaches 0, 1/16 of the bit period has elapsed.
87 // Countdown timers for the receiving and transmitting
88 // state machines are decremented.
89 rx_clk_divider = rx_clk_divider - 1;
90 if (!rx_clk_divider) begin
91 rx_clk_divider = CLOCK_DIVIDE;
92 rx_countdown = rx_countdown - 1;
94 tx_clk_divider = tx_clk_divider - 1;
95 if (!tx_clk_divider) begin
96 tx_clk_divider = CLOCK_DIVIDE;
97 tx_countdown = tx_countdown - 1;
100 // Receive state machine
103 // A low pulse on the receive line indicates the
106 // Wait half the period - should resume in the
107 // middle of this first pulse.
108 rx_clk_divider = CLOCK_DIVIDE;
110 recv_state = RX_CHECK_START;
113 RX_CHECK_START: begin
114 if (!rx_countdown) begin
115 // Check the pulse is still there
117 // Pulse still there - good
118 // Wait the bit period to resume half-way
119 // through the first bit.
121 rx_bits_remaining = 8;
122 recv_state = RX_READ_BITS;
124 // Pulse lasted less than half the period -
125 // not a valid transmission.
126 recv_state = RX_ERROR;
131 if (!rx_countdown) begin
132 // Should be half-way through a bit pulse here.
133 // Read this bit in, wait for the next if we
135 rx_data = {rx, rx_data[7:1]};
137 rx_bits_remaining = rx_bits_remaining - 1;
138 recv_state = rx_bits_remaining ? RX_READ_BITS : RX_CHECK_STOP;
142 if (!rx_countdown) begin
143 // Should resume half-way through the stop bit
144 // This should be high - if not, reject the
145 // transmission and signal an error.
146 recv_state = rx ? RX_RECEIVED : RX_ERROR;
149 RX_DELAY_RESTART: begin
150 // Waits a set number of cycles before accepting
151 // another transmission.
152 recv_state = rx_countdown ? RX_DELAY_RESTART : RX_IDLE;
155 // There was an error receiving.
156 // Raises the recv_error flag for one clock
157 // cycle while in this state and then waits
158 // 2 bit periods before accepting another
161 recv_state = RX_DELAY_RESTART;
164 // Successfully received a byte.
165 // Raises the received flag for one clock
166 // cycle while in this state.
167 recv_state = RX_IDLE;
171 // Transmit state machine
175 // If the transmit flag is raised in the idle
176 // state, start transmitting the current content
177 // of the tx_byte input.
179 // Send the initial, low pulse of 1 bit period
180 // to signal the start, followed by the data
181 tx_clk_divider = CLOCK_DIVIDE;
184 tx_bits_remaining = 8;
185 tx_state = TX_SENDING;
189 if (!tx_countdown) begin
190 if (tx_bits_remaining) begin
191 tx_bits_remaining = tx_bits_remaining - 1;
193 tx_data = {1'b0, tx_data[7:1]};
195 tx_state = TX_SENDING;
197 // Set delay to send out 2 stop bits.
200 tx_state = TX_DELAY_RESTART;
204 TX_DELAY_RESTART: begin
205 // Wait until tx_countdown reaches the end before
206 // we send another transmission. This covers the
208 tx_state = tx_countdown ? TX_DELAY_RESTART : TX_IDLE;