Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / fpga / opencores / uart_transmitter.v
CommitLineData
86530b38
AT
1//////////////////////////////////////////////////////////////////////
2//// ////
3//// uart_transmitter.v ////
4//// ////
5//// ////
6//// This file is part of the "UART 16550 compatible" project ////
7//// http://www.opencores.org/cores/uart16550/ ////
8//// ////
9//// Documentation related to this project: ////
10//// - http://www.opencores.org/cores/uart16550/ ////
11//// ////
12//// Projects compatibility: ////
13//// - WISHBONE ////
14//// RS232 Protocol ////
15//// 16550D uart (mostly supported) ////
16//// ////
17//// Overview (main Features): ////
18//// UART core transmitter logic ////
19//// ////
20//// Known problems (limits): ////
21//// None known ////
22//// ////
23//// To Do: ////
24//// Thourough testing. ////
25//// ////
26//// Author(s): ////
27//// - gorban@opencores.org ////
28//// - Jacob Gorban ////
29//// - Igor Mohor (igorm@opencores.org) ////
30//// ////
31//// Created: 2001/05/12 ////
32//// Last Updated: 2001/05/17 ////
33//// (See log for the revision history) ////
34//// ////
35//// ////
36//////////////////////////////////////////////////////////////////////
37//// ////
38//// Copyright (C) 2000, 2001 Authors ////
39//// ////
40//// This source file may be used and distributed without ////
41//// restriction provided that this copyright statement is not ////
42//// removed from the file and that any derivative work contains ////
43//// the original copyright notice and the associated disclaimer. ////
44//// ////
45//// This source file is free software; you can redistribute it ////
46//// and/or modify it under the terms of the GNU Lesser General ////
47//// Public License as published by the Free Software Foundation; ////
48//// either version 2.1 of the License, or (at your option) any ////
49//// later version. ////
50//// ////
51//// This source is distributed in the hope that it will be ////
52//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
53//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
54//// PURPOSE. See the GNU Lesser General Public License for more ////
55//// details. ////
56//// ////
57//// You should have received a copy of the GNU Lesser General ////
58//// Public License along with this source; if not, download it ////
59//// from http://www.opencores.org/lgpl.shtml ////
60//// ////
61//////////////////////////////////////////////////////////////////////
62//
63// CVS Revision History
64//
65// $Log: uart_transmitter.v,v $
66// Revision 1.19 2002/07/29 21:16:18 gorban
67// The uart_defines.v file is included again in sources.
68//
69// Revision 1.18 2002/07/22 23:02:23 gorban
70// Bug Fixes:
71// * Possible loss of sync and bad reception of stop bit on slow baud rates fixed.
72// Problem reported by Kenny.Tung.
73// * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers.
74//
75// Improvements:
76// * Made FIFO's as general inferrable memory where possible.
77// So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx).
78// This saves about 1/3 of the Slice count and reduces P&R and synthesis times.
79//
80// * Added optional baudrate output (baud_o).
81// This is identical to BAUDOUT* signal on 16550 chip.
82// It outputs 16xbit_clock_rate - the divided clock.
83// It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use.
84//
85// Revision 1.16 2002/01/08 11:29:40 mohor
86// tf_pop was too wide. Now it is only 1 clk cycle width.
87//
88// Revision 1.15 2001/12/17 14:46:48 mohor
89// overrun signal was moved to separate block because many sequential lsr
90// reads were preventing data from being written to rx fifo.
91// underrun signal was not used and was removed from the project.
92//
93// Revision 1.14 2001/12/03 21:44:29 gorban
94// Updated specification documentation.
95// Added full 32-bit data bus interface, now as default.
96// Address is 5-bit wide in 32-bit data bus mode.
97// Added wb_sel_i input to the core. It's used in the 32-bit mode.
98// Added debug interface with two 32-bit read-only registers in 32-bit mode.
99// Bits 5 and 6 of LSR are now only cleared on TX FIFO write.
100// My small test bench is modified to work with 32-bit mode.
101//
102// Revision 1.13 2001/11/08 14:54:23 mohor
103// Comments in Slovene language deleted, few small fixes for better work of
104// old tools. IRQs need to be fix.
105//
106// Revision 1.12 2001/11/07 17:51:52 gorban
107// Heavily rewritten interrupt and LSR subsystems.
108// Many bugs hopefully squashed.
109//
110// Revision 1.11 2001/10/29 17:00:46 gorban
111// fixed parity sending and tx_fifo resets over- and underrun
112//
113// Revision 1.10 2001/10/20 09:58:40 gorban
114// Small synopsis fixes
115//
116// Revision 1.9 2001/08/24 21:01:12 mohor
117// Things connected to parity changed.
118// Clock devider changed.
119//
120// Revision 1.8 2001/08/23 16:05:05 mohor
121// Stop bit bug fixed.
122// Parity bug fixed.
123// WISHBONE read cycle bug fixed,
124// OE indicator (Overrun Error) bug fixed.
125// PE indicator (Parity Error) bug fixed.
126// Register read bug fixed.
127//
128// Revision 1.6 2001/06/23 11:21:48 gorban
129// DL made 16-bit long. Fixed transmission/reception bugs.
130//
131// Revision 1.5 2001/06/02 14:28:14 gorban
132// Fixed receiver and transmitter. Major bug fixed.
133//
134// Revision 1.4 2001/05/31 20:08:01 gorban
135// FIFO changes and other corrections.
136//
137// Revision 1.3 2001/05/27 17:37:49 gorban
138// Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file.
139//
140// Revision 1.2 2001/05/21 19:12:02 gorban
141// Corrected some Linter messages.
142//
143// Revision 1.1 2001/05/17 18:34:18 gorban
144// First 'stable' release. Should be sythesizable now. Also added new header.
145//
146// Revision 1.0 2001-05-17 21:27:12+02 jacob
147// Initial revision
148//
149//
150
151
152`timescale 1 ns / 10 ps
153module uart_transmitter(clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable,
154 stx_pad_o, tstate, tf_count, tx_reset, lsr_mask);
155
156 parameter s_idle = 3'b0;
157 parameter s_send_start = 3'b1;
158 parameter s_send_byte = 3'd2;
159 parameter s_send_parity = 3'd3;
160 parameter s_send_stop = 3'd4;
161 parameter s_pop_byte = 3'd5;
162
163 input clk;
164 input wb_rst_i;
165 input [7:0] lcr;
166 input tf_push;
167 input [7:0] wb_dat_i;
168 input enable;
169 input tx_reset;
170 input lsr_mask;
171 output stx_pad_o;
172 output [2:0] tstate;
173 output [(5 - 1):0] tf_count;
174
175 reg [4:0] counter;
176 reg [2:0] bit_counter;
177 reg [6:0] shift_out;
178 reg stx_o_tmp;
179 reg parity_xor;
180 reg tf_pop;
181 reg bit_out;
182 reg [(8 - 1):0] tf_data_in;
183 wire [(8 - 1):0] tf_data_out;
184 reg [2:0] tstate;
185 wire tf_overrun;
186
187 assign stx_pad_o = (lcr[6] ? 1'b0 : stx_o_tmp);
188
189 uart_tfifo fifo_tx(
190 .clk (clk),
191 .wb_rst_i (wb_rst_i),
192 .data_in (tf_data_in),
193 .data_out (tf_data_out),
194 .push (tf_push),
195 .pop (tf_pop),
196 .overrun (tf_overrun),
197 .count (tf_count),
198 .fifo_reset (tx_reset),
199 .reset_status (lsr_mask));
200
201 always @(posedge clk) tf_data_in <= wb_dat_i;
202 always @(posedge clk or posedge wb_rst_i) begin
203 if (wb_rst_i) begin
204 tstate <= #(1) s_idle;
205 stx_o_tmp <= #(1) 1'b1;
206 counter <= #(1) 5'b0;
207 shift_out <= #(1) 7'b0;
208 bit_out <= #(1) 1'b0;
209 parity_xor <= #(1) 1'b0;
210 tf_pop <= #(1) 1'b0;
211 bit_counter <= #(1) 3'b0;
212 end
213 else if (enable) begin
214 case (tstate)
215 s_idle:
216 if (~|tf_count) begin
217 tstate <= #(1) s_idle;
218 stx_o_tmp <= #(1) 1'b1;
219 end
220 else
221 begin
222 tf_pop <= #(1) 1'b0;
223 stx_o_tmp <= #(1) 1'b1;
224 tstate <= #(1) s_pop_byte;
225 end
226 s_pop_byte: begin
227 tf_pop <= #(1) 1'b1;
228 case (lcr[1:0])
229 2'b0: begin
230 bit_counter <= #(1) 3'd4;
231 parity_xor <= #(1) (^tf_data_out[4:0]);
232 end
233 2'b1: begin
234 bit_counter <= #(1) 3'd5;
235 parity_xor <= #(1) (^tf_data_out[5:0]);
236 end
237 2'b10: begin
238 bit_counter <= #(1) 3'd6;
239 parity_xor <= #(1) (^tf_data_out[6:0]);
240 end
241 2'b11: begin
242 bit_counter <= #(1) 3'd7;
243 parity_xor <= #(1) (^tf_data_out[7:0]);
244 end
245 endcase
246 {shift_out[6:0], bit_out} <= #(1) tf_data_out;
247 tstate <= #(1) s_send_start;
248 end
249 s_send_start: begin
250 tf_pop <= #(1) 1'b0;
251 if (~|counter) begin
252 counter <= #(1) 5'b01111;
253 end
254 else if (counter == 5'b1) begin
255 counter <= #(1) 0;
256 tstate <= #(1) s_send_byte;
257 end
258 else begin
259 counter <= #(1) (counter - 1'b1);
260 end
261 stx_o_tmp <= #(1) 1'b0;
262 end
263 s_send_byte: begin
264 if (~|counter) begin
265 counter <= #(1) 5'b01111;
266 end
267 else if (counter == 5'b1) begin
268 if (bit_counter > 3'b0) begin
269 bit_counter <= #(1) (bit_counter - 1'b1);
270 {shift_out[5:0], bit_out} <= #(1) {shift_out[6:1],
271 shift_out[0]};
272 tstate <= #(1) s_send_byte;
273 end
274 else if (~lcr[3]) begin
275 tstate <= #(1) s_send_stop;
276 end
277 else
278 begin
279 case ({lcr[4], lcr[5]})
280 2'b0:
281 bit_out <= #(1) (~parity_xor);
282 2'b1:
283 bit_out <= #(1) 1'b1;
284 2'b10:
285 bit_out <= #(1) parity_xor;
286 2'b11:
287 bit_out <= #(1) 1'b0;
288 endcase
289 tstate <= #(1) s_send_parity;
290 end
291 counter <= #(1) 0;
292 end
293 else begin
294 counter <= #(1) (counter - 1'b1);
295 end
296 stx_o_tmp <= #(1) bit_out;
297 end
298 s_send_parity: begin
299 if (~|counter) begin
300 counter <= #(1) 5'b01111;
301 end
302 else if (counter == 5'b1) begin
303 counter <= #(1) 4'b0;
304 tstate <= #(1) s_send_stop;
305 end
306 else begin
307 counter <= #(1) (counter - 1'b1);
308 end
309 stx_o_tmp <= #(1) bit_out;
310 end
311 s_send_stop: begin
312 if (~|counter) begin
313 casex ({lcr[2], lcr[1:0]})
314 3'b0xx:
315 counter <= #(1) 5'b01101;
316 3'd4:
317 counter <= #(1) 5'b10101;
318 default:
319 counter <= #(1) 5'b11101;
320 endcase
321 end
322 else if (counter == 5'b1) begin
323 counter <= #(1) 0;
324 tstate <= #(1) s_idle;
325 end
326 else begin
327 counter <= #(1) (counter - 1'b1);
328 end
329 stx_o_tmp <= #(1) 1'b1;
330 end
331 default:
332 tstate <= #(1) s_idle;
333 endcase
334 end
335 else begin
336 tf_pop <= #(1) 1'b0;
337 end
338 end
339endmodule