1 |
15 |
dgisselq |
////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// Filename: rxuartlite.v
|
4 |
|
|
//
|
5 |
|
|
// Project: wbuart32, a full featured UART with simulator
|
6 |
|
|
//
|
7 |
|
|
// Purpose: Receive and decode inputs from a single UART line.
|
8 |
|
|
//
|
9 |
|
|
//
|
10 |
|
|
// To interface with this module, connect it to your system clock,
|
11 |
|
|
// and a UART input. Set the parameter to the number of clocks per
|
12 |
|
|
// baud. When data becomes available, the o_wr line will be asserted
|
13 |
|
|
// for one clock cycle.
|
14 |
|
|
//
|
15 |
|
|
// This interface only handles 8N1 serial port communications. It does
|
16 |
|
|
// not handle the break, parity, or frame error conditions.
|
17 |
|
|
//
|
18 |
|
|
//
|
19 |
|
|
// Creator: Dan Gisselquist, Ph.D.
|
20 |
|
|
// Gisselquist Technology, LLC
|
21 |
|
|
//
|
22 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
23 |
|
|
//
|
24 |
|
|
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
|
25 |
|
|
//
|
26 |
|
|
// This program is free software (firmware): you can redistribute it and/or
|
27 |
|
|
// modify it under the terms of the GNU General Public License as published
|
28 |
|
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
29 |
|
|
// your option) any later version.
|
30 |
|
|
//
|
31 |
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
32 |
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
33 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
34 |
|
|
// for more details.
|
35 |
|
|
//
|
36 |
|
|
// You should have received a copy of the GNU General Public License along
|
37 |
|
|
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
|
38 |
|
|
// target there if the PDF file isn't present.) If not, see
|
39 |
|
|
// <http://www.gnu.org/licenses/> for a copy.
|
40 |
|
|
//
|
41 |
|
|
// License: GPL, v3, as defined and found on www.gnu.org,
|
42 |
|
|
// http://www.gnu.org/licenses/gpl.html
|
43 |
|
|
//
|
44 |
|
|
//
|
45 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
46 |
|
|
//
|
47 |
|
|
//
|
48 |
|
|
`define RXU_BIT_ZERO 4'h0
|
49 |
|
|
`define RXU_BIT_ONE 4'h1
|
50 |
|
|
`define RXU_BIT_TWO 4'h2
|
51 |
|
|
`define RXU_BIT_THREE 4'h3
|
52 |
|
|
`define RXU_BIT_FOUR 4'h4
|
53 |
|
|
`define RXU_BIT_FIVE 4'h5
|
54 |
|
|
`define RXU_BIT_SIX 4'h6
|
55 |
|
|
`define RXU_BIT_SEVEN 4'h7
|
56 |
|
|
// `define RXU_PARITY 4'h8 // Unused in RXUARTLITE
|
57 |
|
|
`define RXU_STOP 4'h8
|
58 |
|
|
// `define RXU_SECOND_STOP 4'ha // Unused in RXUARTLITE
|
59 |
|
|
// Unused 4'hb
|
60 |
|
|
// Unused 4'hc
|
61 |
|
|
// `define RXU_BREAK 4'hd // Unused in RXUARTLITE
|
62 |
|
|
// `define RXU_RESET_IDLE 4'he // Unused in RXUARTLITE
|
63 |
|
|
`define RXU_IDLE 4'hf
|
64 |
|
|
|
65 |
|
|
module rxuartlite(i_clk, i_uart_rx, o_wr, o_data);
|
66 |
|
|
parameter [23:0] CLOCKS_PER_BAUD = 24'd868;
|
67 |
|
|
input i_clk;
|
68 |
|
|
input i_uart_rx;
|
69 |
|
|
output reg o_wr;
|
70 |
|
|
output reg [7:0] o_data;
|
71 |
|
|
|
72 |
|
|
|
73 |
|
|
wire [23:0] clocks_per_baud, half_baud;
|
74 |
|
|
reg [3:0] state;
|
75 |
|
|
|
76 |
|
|
assign half_baud = { 1'b0, CLOCKS_PER_BAUD[23:1] } - 24'h1;
|
77 |
|
|
reg [23:0] baud_counter;
|
78 |
|
|
reg zero_baud_counter;
|
79 |
|
|
|
80 |
|
|
|
81 |
|
|
// Since this is an asynchronous receiver, we need to register our
|
82 |
|
|
// input a couple of clocks over to avoid any problems with
|
83 |
|
|
// metastability. We do that here, and then ignore all but the
|
84 |
|
|
// ck_uart wire.
|
85 |
|
|
reg q_uart, qq_uart, ck_uart;
|
86 |
|
|
initial q_uart = 1'b0;
|
87 |
|
|
initial qq_uart = 1'b0;
|
88 |
|
|
initial ck_uart = 1'b0;
|
89 |
|
|
always @(posedge i_clk)
|
90 |
|
|
begin
|
91 |
|
|
q_uart <= i_uart_rx;
|
92 |
|
|
qq_uart <= q_uart;
|
93 |
|
|
ck_uart <= qq_uart;
|
94 |
|
|
end
|
95 |
|
|
|
96 |
|
|
// Keep track of the number of clocks since the last change.
|
97 |
|
|
//
|
98 |
|
|
// This is used to determine if we are in either a break or an idle
|
99 |
|
|
// condition, as discussed further below.
|
100 |
|
|
reg [23:0] chg_counter;
|
101 |
|
|
initial chg_counter = 24'h00;
|
102 |
|
|
always @(posedge i_clk)
|
103 |
|
|
if (qq_uart != ck_uart)
|
104 |
|
|
chg_counter <= 24'h00;
|
105 |
|
|
else
|
106 |
|
|
chg_counter <= chg_counter + 1;
|
107 |
|
|
|
108 |
|
|
// Are we in the middle of a baud iterval? Specifically, are we
|
109 |
|
|
// in the middle of a start bit? Set this to high if so. We'll use
|
110 |
|
|
// this within our state machine to transition out of the IDLE
|
111 |
|
|
// state.
|
112 |
|
|
reg half_baud_time;
|
113 |
|
|
initial half_baud_time = 0;
|
114 |
|
|
always @(posedge i_clk)
|
115 |
|
|
half_baud_time <= (~ck_uart)&&(chg_counter >= half_baud);
|
116 |
|
|
|
117 |
|
|
|
118 |
|
|
initial state = `RXU_IDLE;
|
119 |
|
|
always @(posedge i_clk)
|
120 |
|
|
begin
|
121 |
|
|
if (state == `RXU_IDLE)
|
122 |
|
|
begin // Idle state, independent of baud counter
|
123 |
|
|
// By default, just stay in the IDLE state
|
124 |
|
|
state <= `RXU_IDLE;
|
125 |
|
|
if ((~ck_uart)&&(half_baud_time))
|
126 |
|
|
// UNLESS: We are in the center of a valid
|
127 |
|
|
// start bit
|
128 |
|
|
state <= `RXU_BIT_ZERO;
|
129 |
|
|
end else if (zero_baud_counter)
|
130 |
|
|
begin
|
131 |
|
|
if (state < `RXU_STOP)
|
132 |
|
|
// Data arrives least significant bit first.
|
133 |
|
|
// By the time this is clocked in, it's what
|
134 |
|
|
// you'll have.
|
135 |
|
|
state <= state + 1;
|
136 |
|
|
else // Wait for the next character
|
137 |
|
|
state <= `RXU_IDLE;
|
138 |
|
|
end
|
139 |
|
|
end
|
140 |
|
|
|
141 |
|
|
// Data bit capture logic.
|
142 |
|
|
//
|
143 |
|
|
// This is drastically simplified from the state machine above, based
|
144 |
|
|
// upon: 1) it doesn't matter what it is until the end of a captured
|
145 |
|
|
// byte, and 2) the data register will flush itself of any invalid
|
146 |
|
|
// data in all other cases. Hence, let's keep it real simple.
|
147 |
|
|
reg [7:0] data_reg;
|
148 |
|
|
always @(posedge i_clk)
|
149 |
|
|
if (zero_baud_counter)
|
150 |
|
|
data_reg <= { ck_uart, data_reg[7:1] };
|
151 |
|
|
|
152 |
|
|
// Our data bit logic doesn't need nearly the complexity of all that
|
153 |
|
|
// work above. Indeed, we only need to know if we are at the end of
|
154 |
|
|
// a stop bit, in which case we copy the data_reg into our output
|
155 |
|
|
// data register, o_data, and tell others (for one clock) that data is
|
156 |
|
|
// available.
|
157 |
|
|
//
|
158 |
|
|
initial o_data = 8'h00;
|
159 |
|
|
reg pre_wr;
|
160 |
|
|
initial pre_wr = 1'b0;
|
161 |
|
|
always @(posedge i_clk)
|
162 |
|
|
if ((zero_baud_counter)&&(state == `RXU_STOP))
|
163 |
|
|
begin
|
164 |
|
|
o_wr <= 1'b1;
|
165 |
|
|
o_data <= data_reg;
|
166 |
|
|
end else
|
167 |
|
|
o_wr <= 1'b0;
|
168 |
|
|
|
169 |
|
|
// The baud counter
|
170 |
|
|
//
|
171 |
|
|
// This is used as a "clock divider" if you will, but the clock needs
|
172 |
|
|
// to be reset before any byte can be decoded. In all other respects,
|
173 |
|
|
// we set ourselves up for clocks_per_baud counts between baud
|
174 |
|
|
// intervals.
|
175 |
|
|
always @(posedge i_clk)
|
176 |
|
|
if ((zero_baud_counter)|||(state == `RXU_IDLE))
|
177 |
|
|
baud_counter <= CLOCKS_PER_BAUD-1'b1;
|
178 |
|
|
else
|
179 |
|
|
baud_counter <= baud_counter-1'b1;
|
180 |
|
|
|
181 |
|
|
// zero_baud_counter
|
182 |
|
|
//
|
183 |
|
|
// Rather than testing whether or not (baud_counter == 0) within our
|
184 |
|
|
// (already too complicated) state transition tables, we use
|
185 |
|
|
// zero_baud_counter to pre-charge that test on the clock
|
186 |
|
|
// before--cleaning up some otherwise difficult timing dependencies.
|
187 |
|
|
initial zero_baud_counter = 1'b0;
|
188 |
|
|
always @(posedge i_clk)
|
189 |
|
|
if (state == `RXU_IDLE)
|
190 |
|
|
zero_baud_counter <= 1'b0;
|
191 |
|
|
else
|
192 |
|
|
zero_baud_counter <= (baud_counter == 24'h01);
|
193 |
|
|
|
194 |
|
|
|
195 |
|
|
endmodule
|
196 |
|
|
|
197 |
|
|
|