1 |
2 |
MichaelA |
////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
//
|
3 |
|
|
// Copyright 2008-2013 by Michael A. Morris, dba M. A. Morris & Associates
|
4 |
|
|
//
|
5 |
|
|
// All rights reserved. The source code contained herein is publicly released
|
6 |
|
|
// under the terms and conditions of the GNU Lesser Public License. No part of
|
7 |
|
|
// this source code may be reproduced or transmitted in any form or by any
|
8 |
|
|
// means, electronic or mechanical, including photocopying, recording, or any
|
9 |
|
|
// information storage and retrieval system in violation of the license under
|
10 |
|
|
// which the source code is released.
|
11 |
|
|
//
|
12 |
|
|
// The source code contained herein is free; it may be redistributed and/or
|
13 |
|
|
// modified in accordance with the terms of the GNU Lesser General Public
|
14 |
|
|
// License as published by the Free Software Foundation; either version 2.1 of
|
15 |
|
|
// the GNU Lesser General Public License, or any later version.
|
16 |
|
|
//
|
17 |
|
|
// The source code contained herein is freely released WITHOUT ANY WARRANTY;
|
18 |
|
|
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
19 |
|
|
// PARTICULAR PURPOSE. (Refer to the GNU Lesser General Public License for
|
20 |
|
|
// more details.)
|
21 |
|
|
//
|
22 |
|
|
// A copy of the GNU Lesser General Public License should have been received
|
23 |
|
|
// along with the source code contained herein; if not, a copy can be obtained
|
24 |
|
|
// by writing to:
|
25 |
|
|
//
|
26 |
|
|
// Free Software Foundation, Inc.
|
27 |
|
|
// 51 Franklin Street, Fifth Floor
|
28 |
|
|
// Boston, MA 02110-1301 USA
|
29 |
|
|
//
|
30 |
|
|
// Further, no use of this source code is permitted in any form or means
|
31 |
|
|
// without inclusion of this banner prominently in any derived works.
|
32 |
|
|
//
|
33 |
|
|
// Michael A. Morris
|
34 |
|
|
// Huntsville, AL
|
35 |
|
|
//
|
36 |
|
|
////////////////////////////////////////////////////////////////////////////////
|
37 |
|
|
|
38 |
|
|
`timescale 1ns / 1ps
|
39 |
|
|
|
40 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
41 |
|
|
// Company: M. A. Morris & Associates
|
42 |
|
|
// Engineer: Michael A. Morris
|
43 |
|
|
//
|
44 |
|
|
// Create Date: 21:22:38 05/10/2008
|
45 |
|
|
// Design Name: Synchronous Serial Peripheral (SSP) Interface UART
|
46 |
|
|
// Module Name: ../VerilogCoponentsLib/SSP_UART/UART_TXSM.v
|
47 |
|
|
// Project Name: Verilog Components Library
|
48 |
|
|
// Target Devices: XC3S50A-4VQG100I, XC3S20A-4VQG100I, XC3S700AN-4FFG484I
|
49 |
|
|
// Tool versions: ISE 10.1i SP3
|
50 |
|
|
//
|
51 |
|
|
// Description: This module implements the Transmit State Machine for the SSP
|
52 |
|
|
// UART.
|
53 |
|
|
//
|
54 |
|
|
// The Baud Rate Generator implements the 16 baud rates defined
|
55 |
|
|
// in Table 3 of the SSP UART Specification.
|
56 |
|
|
//
|
57 |
|
|
// Dependencies: None
|
58 |
|
|
//
|
59 |
|
|
// Revision History:
|
60 |
|
|
//
|
61 |
|
|
// 0.01 08E10 MAM File Created
|
62 |
|
|
//
|
63 |
|
|
// 1.00 08E24 MAM Modified and tested TxSM to allow for several addi-
|
64 |
|
|
// tional conditions regarding Mode 1 - RS232 w/ Hand-
|
65 |
|
|
// shaking. In particular, TxSM goes to pStart from
|
66 |
|
|
// pShift if CTS is not asserted when the current word
|
67 |
|
|
// has been shifted.
|
68 |
|
|
//
|
69 |
|
|
// 1.10 08E28 MAM Modified to remove I/O signals best processed above
|
70 |
|
|
// this module: RTSi, RTSo, and DE. Removed from port
|
71 |
|
|
// list and moved the decoded state ouput bits to the
|
72 |
|
|
// end of the port list. Modified the TSRI and the TSR
|
73 |
|
|
// length. TSRI now only processes the two MSBs of the
|
74 |
|
|
// TSR load value. The length of TSR modified from 12
|
75 |
|
|
// to 10 bits because the logic 1 fill value and the
|
76 |
|
|
// bit counter allow the stop bits to be implicit. The
|
77 |
|
|
// result is a faster signal path.
|
78 |
|
|
//
|
79 |
|
|
// 1.20 08F08 MAM Modified TxSM to use a ROM to decode the [3:0]FMT
|
80 |
|
|
// input like the RxSM. Changed the SR implementation
|
81 |
|
|
// of the shift register into a registered multiplexer
|
82 |
|
|
// implementation. Removed the bit counter and added
|
83 |
|
|
// states to the SM to multiplex the data. Result is a
|
84 |
|
|
// SM and SR that synthesizes to a speed that matches
|
85 |
|
|
// the reported speed of the RxSM: 110+ MHz. This may
|
86 |
|
|
// indicated that this UART may be useful as a high-
|
87 |
|
|
// speed UART with an 8x over-sample instead of a 4x
|
88 |
|
|
// oversample using a 48MHz clock input and a 2x DLL.
|
89 |
|
|
//
|
90 |
|
|
// 1.21 08F12 MAM Pulled Format Decoder ROM and moved to upper level
|
91 |
|
|
// module. Added the outputs of the ROM to the port
|
92 |
|
|
// list of the module. Module now supports more format
|
93 |
|
|
// directly with the new direct inputs including com-
|
94 |
|
|
// binations not normally used. The upper level module
|
95 |
|
|
// must restrict the format inputs to those that are
|
96 |
|
|
// proper. 7-bit formats require parity, and if not
|
97 |
|
|
// set on input, then the parity generated will be
|
98 |
|
|
// that specified by the Par bits.
|
99 |
|
|
//
|
100 |
|
|
// 2.00 11B06 MAM Converted to Verilog 2001.
|
101 |
|
|
//
|
102 |
|
|
// 2.01 13G06 MAM Corrected placement of #1 delay statements. Changed
|
103 |
|
|
// combinatorial always to use @(*) instead of explicit
|
104 |
|
|
// listing of signals in sensitivity list.
|
105 |
|
|
//
|
106 |
|
|
// Additional Comments:
|
107 |
|
|
//
|
108 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
109 |
|
|
|
110 |
|
|
module UART_TXSM(
|
111 |
|
|
input Rst,
|
112 |
|
|
input Clk,
|
113 |
|
|
|
114 |
|
|
input CE_16x, // 16x Clock Enable - Baud Rate x16
|
115 |
|
|
|
116 |
|
|
input Len, // Word length: 0 - 8-bits; 1 - 7 bits
|
117 |
|
|
input NumStop, // Number Stop Bits: 0 - 1 Stop; 1 - 2 Stop
|
118 |
|
|
input ParEn, // Parity Enable
|
119 |
|
|
input [1:0] Par, // 0 - Odd; 1 - Even; 2 - Space (0); 3 - Mark (1)
|
120 |
|
|
|
121 |
|
|
input TF_EF, // Transmit THR Empty Flag
|
122 |
|
|
|
123 |
|
|
input [7:0] THR, // Transmit Holding Register
|
124 |
|
|
output reg TF_RE, // Transmit THR Read Enable Strobe
|
125 |
|
|
|
126 |
|
|
input CTSi, // RS232 Mode CTS input
|
127 |
|
|
|
128 |
|
|
output reg TxD, // Serial Data Out, LSB First, Start bit = 0
|
129 |
|
|
|
130 |
|
|
output TxIdle, // Transmit State Machine - Idle State
|
131 |
|
|
output TxStart, // Transmit State Machine - Start State - CTS wait
|
132 |
|
|
output TxShift, // Transmit State Machine - Shift State
|
133 |
|
|
output TxStop // Transmit State Machine - Stop State - RTS clear
|
134 |
|
|
);
|
135 |
|
|
|
136 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
137 |
|
|
//
|
138 |
|
|
// Module Parameters
|
139 |
|
|
//
|
140 |
|
|
|
141 |
|
|
localparam pIdle = 0; // Idle - wait for data
|
142 |
|
|
localparam pStopDelay = 1; // Stop - deassert DE/RTS after 1 bit delay
|
143 |
|
|
localparam pStartDelay = 2; // Start - assert DE/RTS, delay 1 bit & CTSi
|
144 |
|
|
localparam pUnused = 3; // Unused State
|
145 |
|
|
localparam pStartBit = 10; // Shift - transmit Start Bit
|
146 |
|
|
localparam pShift0 = 11; // Shift - transmit TSR contents (LSB)
|
147 |
|
|
localparam pShift1 = 9; // Shift - transmit TSR contents
|
148 |
|
|
localparam pShift2 = 8; // Shift - transmit TSR contents
|
149 |
|
|
localparam pShift3 = 12; // Shift - transmit TSR contents
|
150 |
|
|
localparam pShift4 = 13; // Shift - transmit TSR contents
|
151 |
|
|
localparam pShift5 = 15; // Shift - transmit TSR contents
|
152 |
|
|
localparam pShift6 = 14; // Shift - transmit TSR contents
|
153 |
|
|
localparam pShift7 = 6; // Shift - transmit TSR contents (MSB)
|
154 |
|
|
localparam pParityBit = 4; // Shift - transmit Parity Bit
|
155 |
|
|
localparam pStopBit2 = 5; // Shift - transmit Stop Bit 1
|
156 |
|
|
localparam pStopBit1 = 7; // Shift - transmit Stop Bit 2
|
157 |
|
|
|
158 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
159 |
|
|
//
|
160 |
|
|
// Local Signal Declarations
|
161 |
|
|
//
|
162 |
|
|
|
163 |
|
|
reg [3:0] Bit; // Bit Rate Divider
|
164 |
|
|
reg CE_BCnt; // CEO Bit Rate Divider
|
165 |
|
|
|
166 |
|
|
wire Odd, Evn; // Odd/Even parity signals
|
167 |
|
|
reg ParBit; // Computed/assigned Parity Bit
|
168 |
|
|
|
169 |
|
|
reg [8:0] TSR; // Transmit Shift Register
|
170 |
|
|
|
171 |
|
|
(* FSM_ENCODING="SEQUENTIAL",
|
172 |
|
|
SAFE_IMPLEMENTATION="YES",
|
173 |
|
|
SAFE_RECOVERY_STATE="4'b0" *)
|
174 |
|
|
reg [3:0] TxSM = pIdle; // Xmt State Machine
|
175 |
|
|
|
176 |
|
|
///////////////////////////////////////////////////////////////////////////////
|
177 |
|
|
//
|
178 |
|
|
// Implementation
|
179 |
|
|
//
|
180 |
|
|
|
181 |
|
|
// Set Transmit Idle Status Bit
|
182 |
|
|
|
183 |
|
|
assign TxIdle = (TxSM == pIdle); // Idle state
|
184 |
|
|
assign TxStop = (TxSM == pStopDelay); // Wait 1 bit to release line
|
185 |
|
|
assign TxStart = (TxSM == pStartDelay); // Take line and settle 1 bit
|
186 |
|
|
assign TxShift = (TxSM[3] | TxSM[2]); // Xmt Shift States
|
187 |
|
|
|
188 |
|
|
// Transmit State Machine Clock Enable
|
189 |
|
|
|
190 |
|
|
assign CE_TxSM = (TxIdle ? CE_16x : CE_BCnt);
|
191 |
|
|
|
192 |
|
|
// Shift Register Load Signal
|
193 |
|
|
|
194 |
|
|
assign Ld_TSR = CE_TxSM & ~TF_EF & CTSi
|
195 |
|
|
& ( (TxSM == pStartDelay)
|
196 |
|
|
| (TxSM == pStopBit1)
|
197 |
|
|
| (TxSM == pStopDelay) );
|
198 |
|
|
|
199 |
|
|
// Generate Transmit FIFO Read Enable
|
200 |
|
|
|
201 |
|
|
always @(posedge Clk)
|
202 |
|
|
begin
|
203 |
|
|
if(TxIdle)
|
204 |
|
|
TF_RE <= #1 1'b0;
|
205 |
|
|
else
|
206 |
|
|
TF_RE <= #1 Ld_TSR;
|
207 |
|
|
end
|
208 |
|
|
|
209 |
|
|
// Determine Load Value for Transmit Shift Register
|
210 |
|
|
|
211 |
|
|
assign Evn = ((Len) ? ^{1'b0, THR[6:0]} : ^THR);
|
212 |
|
|
assign Odd = ~Evn;
|
213 |
|
|
|
214 |
|
|
always @(*)
|
215 |
|
|
begin
|
216 |
|
|
case(Par)
|
217 |
|
|
2'b00 : ParBit <= Odd; // Odd
|
218 |
|
|
2'b01 : ParBit <= Evn; // Even
|
219 |
|
|
2'b10 : ParBit <= 0; // Space
|
220 |
|
|
2'b11 : ParBit <= 1; // Mark
|
221 |
|
|
endcase
|
222 |
|
|
end
|
223 |
|
|
|
224 |
|
|
// Transmit Shift Register
|
225 |
|
|
|
226 |
|
|
always @(posedge Clk)
|
227 |
|
|
begin
|
228 |
|
|
if(TxIdle)
|
229 |
|
|
TSR <= #1 9'b1_1111_1111;
|
230 |
|
|
else if(Ld_TSR)
|
231 |
|
|
TSR <= #1 {ParBit, THR[7:0]};
|
232 |
|
|
end
|
233 |
|
|
|
234 |
|
|
always @(posedge Clk)
|
235 |
|
|
begin
|
236 |
|
|
if(Rst)
|
237 |
|
|
#1 TxD <= 1;
|
238 |
|
|
else case(TxSM)
|
239 |
|
|
pStartBit : #1 TxD <= 0;
|
240 |
|
|
pShift0 : #1 TxD <= TSR[0];
|
241 |
|
|
pShift1 : #1 TxD <= TSR[1];
|
242 |
|
|
pShift2 : #1 TxD <= TSR[2];
|
243 |
|
|
pShift3 : #1 TxD <= TSR[3];
|
244 |
|
|
pShift4 : #1 TxD <= TSR[4];
|
245 |
|
|
pShift5 : #1 TxD <= TSR[5];
|
246 |
|
|
pShift6 : #1 TxD <= TSR[6];
|
247 |
|
|
pShift7 : #1 TxD <= TSR[7];
|
248 |
|
|
pParityBit : #1 TxD <= TSR[8];
|
249 |
|
|
default : #1 TxD <= 1;
|
250 |
|
|
endcase
|
251 |
|
|
end
|
252 |
|
|
|
253 |
|
|
// Bit Rate Divider
|
254 |
|
|
|
255 |
|
|
always @(posedge Clk)
|
256 |
|
|
begin
|
257 |
|
|
if(TxIdle)
|
258 |
|
|
Bit <= #1 4'b0;
|
259 |
|
|
else if(CE_16x)
|
260 |
|
|
Bit <= #1 Bit + 1;
|
261 |
|
|
end
|
262 |
|
|
|
263 |
|
|
always @(posedge Clk)
|
264 |
|
|
begin
|
265 |
|
|
if(TxIdle)
|
266 |
|
|
CE_BCnt <= #1 0;
|
267 |
|
|
else
|
268 |
|
|
CE_BCnt <= #1 CE_16x & (Bit == 4'b1111);
|
269 |
|
|
end
|
270 |
|
|
|
271 |
|
|
// Transmit State Machine
|
272 |
|
|
|
273 |
|
|
always @(posedge Clk)
|
274 |
|
|
begin
|
275 |
|
|
if(Rst)
|
276 |
|
|
#1 TxSM <= pIdle;
|
277 |
|
|
else if(CE_TxSM)
|
278 |
|
|
case(TxSM)
|
279 |
|
|
pIdle : TxSM <= #1 ((TF_EF) ? pIdle
|
280 |
|
|
: pStartDelay);
|
281 |
|
|
|
282 |
|
|
pStartDelay : TxSM <= #1 ((TF_EF) ? pIdle
|
283 |
|
|
: ((CTSi) ? pStartBit
|
284 |
|
|
: pStartDelay));
|
285 |
|
|
|
286 |
|
|
pStartBit : TxSM <= #1 pShift0;
|
287 |
|
|
pShift0 : TxSM <= #1 pShift1;
|
288 |
|
|
pShift1 : TxSM <= #1 pShift2;
|
289 |
|
|
pShift2 : TxSM <= #1 pShift3;
|
290 |
|
|
pShift3 : TxSM <= #1 pShift4;
|
291 |
|
|
pShift4 : TxSM <= #1 pShift5;
|
292 |
|
|
pShift5 : TxSM <= #1 pShift6;
|
293 |
|
|
pShift6 : TxSM <= #1 ((Len) ? pParityBit
|
294 |
|
|
: pShift7 );
|
295 |
|
|
pShift7 : TxSM <= #1 ((ParEn) ? pParityBit
|
296 |
|
|
: ((NumStop) ? pStopBit2
|
297 |
|
|
: pStopBit1));
|
298 |
|
|
|
299 |
|
|
pParityBit : TxSM <= #1 ((NumStop) ? pStopBit2
|
300 |
|
|
: pStopBit1);
|
301 |
|
|
|
302 |
|
|
pStopBit2 : TxSM <= #1 pStopBit1;
|
303 |
|
|
pStopBit1 : TxSM <= #1 ((TF_EF) ? pStopDelay
|
304 |
|
|
: pStartBit );
|
305 |
|
|
|
306 |
|
|
pStopDelay : TxSM <= #1 ((TF_EF) ? pIdle
|
307 |
|
|
: ((CTSi) ? pStartBit
|
308 |
|
|
: pStartDelay));
|
309 |
|
|
|
310 |
|
|
pUnused : TxSM <= #1 pIdle;
|
311 |
|
|
endcase
|
312 |
|
|
end
|
313 |
|
|
|
314 |
|
|
endmodule
|