OpenCores
URL https://opencores.org/ocsvn/ssp_uart/ssp_uart/trunk

Subversion Repositories ssp_uart

[/] [ssp_uart/] [trunk/] [RTL/] [SSP_UART.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
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:     12:30:30 05/11/2008 
45
// Design Name:     Synchronous Serial Peripheral (SSP) Interface UART 
46
// Module Name:     ../VerilogCoponentsLib/SSP_UART/SSP_UART.v
47
// Project Name:    Verilog Components Library
48 4 MichaelA
// Target Devices:  XC3S50A-4VQG100I, XC3S200A-4VQG100I, XC3S700AN-4FFG484I 
49 2 MichaelA
// Tool versions:   ISE 10.1i SP3 
50
//
51
// Description: This module integrates the various elements of a simplified 
52
//              UART to create a UART that is efficiently supported using a 
53
//              serial interface. The module also incorporates the logic to 
54
//              support four operating modes, and controls the signal muxes 
55
//              necessary.
56
//
57
// Dependencies: re1ce.v, BRSFmnCE.v, UART_BRG.v, UART_TXSM.v, UART_RXSM.v,
58
//               UART_RTO.v, UART_INT.v, redet.v
59
//
60
// Revision History:
61
//
62
//  0.01    08E10   MAM     File Created
63
//
64
//  0.10    O8E12   MAM     Incorporated the ROMs for decoding the format
65
//                          and buad rate. Updated the interfaces to the
66
//                          BRG, TxSM, and RxSM.
67
//
68
//  0.11    08E14   MAM     Added the RTO ROM for setting the length of the
69
//                          receive timeout interval on the basis of the 
70
//                          character frame format. Modified the baud rate 
71
//                          table to remove the 300 and 600 baud entries and
72
//                          add entries for 28.8k and 14.4k baud. Reduced the
73
//                          width of the baud rate divider from 10 to 8 bits.
74
//
75
//  1.00    08G23   MAM     Modified the SSP Interface to operate with the new
76
//                          SSPx_Slv interface which uses registers for SSP_DI
77
//                          and SSP_DO. The falling edge of SCK is used for the
78
//                          latching and transfering read/write operations from
79
//                          the SCK clock domain to the Clk clock domain.
80
//
81
//  1.01    08G24   MAM     Corrected error in the TFC/RFC pulse enables that
82
//                          allowed any write to the SSP UART with 1's in these
83
//                          bit positions to generate a THR/RHR FIFO reset.
84
//
85
//  1.10    08G26   MAM     Modified to implement a multiplexed register set
86
//                          with the SPR address. Additional status registers
87
//                          added for various purposes including revision, 
88
//                          FIFO output, FIFO len, and FIFO count registers.
89
//                          Since an XC2S30 is required, and there is no other
90
//                          function required in the FPGA, increased the FIFO
91
//                          depth of the Tx FIFO to 128 words using distributed
92
//                          RAM.
93
//
94
//  1.11    08G27   MAM     Modified the organization of the SPR window status
95 4 MichaelA
//                          registers to match Table 5 in the 1700-0403C SSP
96 2 MichaelA
//                          UART specification.
97
//
98
//  1.20    08G27   MAM     Modified Tx signal path to include a FF that will 
99
//                          prevent the Tx SM from shifting until the Tx FIFO
100
//                          is loaded with the full message up to the size of
101
//                          FIFO. The bit is normally written as a 0 and ORed
102
//                          with the TF_EF. In this state, Tx SM starts the
103
//                          shift operation immediately. When the bit is set,
104
//                          then the OR with the TF_EF prevents the Tx SM from
105
//                          sending the Tx FIFO contents until HLD bit is reset
106
//
107
//  1.30    08H02   MAM     Modified the FIFOs to use the Block RAM FIFOs. 
108
//                          Updated the default parameters to set the depth to
109
//                          match the 1024 word depth of the Block RAM FIFOs.
110
//
111
//  1.40    08H09   MAM     Added Rx/Tx FIFO Threshold Resgister, reordered SPR
112
//                          sub-registers to incorporate programmable threshold
113
//                          for the FIFOs into the design. Set the default of 
114
//                          the threshold for the Rx/Tx FIFOs to half.
115
//
116
//  1.41    08H12   MAM     Registered the RxD input signal; reset State forced
117
//                          mark condition. Modified the RTFThr register so
118
//                          a logic 1 is required in SSP_DI[8] to write it.
119
//
120
//  2.00    11B06   MAM     Converted to Verilog 2001. Added an external enable
121
//                          signal, reordered the registers, and set the SPI
122
//                          interface to operate in the same manner as for the
123
//                          LTAS module.
124
//
125
//  2.01    11B08   MAM     Changed En to SSP_SSEL, and changed the SSP_DO bus
126
//                          to a tri-state bus enabled by SSP_SSEL so that the
127
//                          module can used along with other SSP-compatible
128
//                          modules in the same FPGA. Corrected minor encoding
129
//                          error for RS/TS fields.
130
//
131
//  2.10    13G10   MAM     Adjusted baud rate table to support Profibus rates
132
//                          from 3M down to 187.5k, and standard baud rates from
133
//                          1200 to 230.4k baud.
134
//
135
//  2.20    13G12   MAM     Removed baud rate table controlled by 4 bits in the
136
//                          UART control register. Replaced by a 12-bit write-
137
//                          only register mapped to the address of the read-only
138
//                          UART status register. The new Baud Rate Register re-
139
//                          places the the baud rate ROM: PS[3:0] <= BRR[11:8],
140
//                          and Div[7:0] <= BRR[7:8]. (N-1) must be loaded into
141
//                          each of these fields to set the correct divider.
142
//                          Also added parameters for default values for the 
143
//                          baud rate generator PS (Prescaler) and Div (Divider)
144
//                          values. Default values selected for 9600 bps at the
145
//                          UART operating frequency, which is 73.728 MHz for
146
//                          this application.
147
//
148
//  2.30    13G14   MAM     Changed the parameterization so module can be para-
149
//                          meterized from the instantiating module. Removed
150
//                          (commented out) Block RAM FIFO instantiations and 
151
//                          associated FIFO configuration parameters. Updated
152
//                          the Additional Comments section.
153
//
154
//  2.40    13G21   MAM     Added asynchronous reset to several functions in 
155 4 MichaelA
//                          order to correctly simulate in ISim.
156
//
157
//  2.50    13G28   MAM     Corrected issue with polling of the Receive Data
158
//                          Register. A race condition was found. Corrected by
159
//                          registering the data on the SCK clock domain and 
160
//                          by requiring that the read pulse for the receive
161
//                          FIFO is only generated if the empty flag status is
162
//                          present on the SCK clock domain. This prevents the
163
//                          same race condition as found when polling the UART
164
//                          Status Register. Examining the condition/flags of
165
//                          these registers, without polling via the SSP inter-
166
//                          face, avoids these issues. Given the limited I/O
167
//                          resources of the M16C5x, examining the condition/
168
//                          flags bits directly without polling is not a viable
169
//                          option. Therefore, corrected the race condition. If
170
//                          examining the condition/flags directly is an option,
171
//                          then that is the preferred method from a performance
172 2 MichaelA
//                          perspective.
173
//
174
// Additional Comments:
175
//
176
//  The SSP UART is defined in 1700-0403C. The following is a summary of the 
177
//  register and field definitions contained in the referenced document. If any
178
//  conflicts arise in the definitions, the implementation defined in this file
179
//  will take precedence over the document.
180
//
181
//  The UART consists of six registers:
182
// 
183
//      (1) UCR - UART Control Register     (3'b000)
184
//      (2) USR - UART Status Register      (3'b001)
185
//      (3) BRR - Baud Rate Register        (3'b001)
186
//      (3) TDR - Transmit Data Register    (3'b010)
187
//      (4) RDR - Receive Data Register     (3'b011)
188
//      (5) SPR - Scratch Pad Register      (3'b100)
189
//
190
//  The Synchronous Serial Peripheral of the ARM is configured to send 16 bits.
191
//  The result is that the 3 most significant bits are interpreted as an regis-
192 4 MichaelA
//  ter select. Bit 12, the fourth transmitted bit, sets the write/read mode of
193 2 MichaelA
//  transfer. The remaining twelve bits, bits 11...0, are data bits. In this
194
//  manner, the SSP UART minimizes the number of serial transfers required to
195
//  send and receive serial data from the SSP UART. The reads from the TDR/RDR
196
//  addresses also provide status information regarding the transmit and receive
197
//  state machines, and the FIFO-based holding registers. Thus, polling of the 
198
//  status register is not necessary in most circumstances to determine if the
199
//  FIFOs are ready to receive data from the host or have data to provide the
200
//  host.
201
//
202
//  With each SSP/SPI operation to the TDR/RDR address, the SSP UART will read
203
//  and write the receive and transmit holding registers, respectively. These
204
//  holding registers are implemented using 9-bit and 8-bit FIFOs, respective-
205
//  ly. The FIFOs are independently configured so that they can be easily
206
//  replaced with other implementations as required.
207
//
208
//  The USR implements a read-only register for the UART status bits other than
209
//  the RERR - Receiver Error, RTO - Receiver Time-Out, RRDY - Receiver Ready,
210
//  and the TRDY - Transmitter Ready status bits read out in the RDR. The USR
211
//  provides access to the UART mode and baud rate bits from the UCR. The RTSi 
212
//  and CTSi bits reflect the state of the external RTS and CTS signals in the
213
//  RS-232 modes. In the RS-485 modes, RTSi reflects the state of the external
214
//  transceiver drive enable signal, and CTSi should be read as a logic 1. The
215
//  CTSi bit is set internally to a logic 1 by the SSP UART in the RS-485 modes
216
//  because it is always ready to receive. The receiver serial input data pin 
217
//  is controlled in the RS-485 modes so that the external transceiver output
218
//  enable can always be enabled. 
219
//
220
//  UART Control Register - UCR (RA = 3'b000)
221
//
222
//  11:10 - MD  :   Mode (see table below)
223
//      9 - RTSo:   Request To Send, set to assert external RTS in Mode 0
224
//      8 - IE  :   Interrupt Enable, set to enable Xmt/Rcv interrupts
225
//    7:4 - FMT :   Format (see table below)
226
//    3:0 - Rsvd:   Reserved (previously used for Baud Rate (see table below))
227
//
228
//  UART Status Register - USR (RA = 3'b001) (Read-Only)
229
//
230
//  11:10 - MD  :   Mode (see table below)
231
//      9 - RTSi:   Request To Send In, set as discussed above
232
//      8 - CTSi:   Clear To Send In, set as discussed above
233
//    7:6 - RS  :   Receive Status:  0 - Empty, 1 < Half, 2 >= Half, 3 - Full
234
//    5:4 - TS  :   Transmit Status: 0 - Empty, 1 < Half, 2 >= Half, 3 - Full
235
//      3 - iRTO:   Receive Timeout Interrupt Flag
236
//      2 - iRDA:   Receive Data Available Interupt Flag (FIFO >= Half Full)
237
//      1 - iTHE:   Transmit FIFO Half Empty Interrupt Flag
238
//      0 - iTFE:   Transmit FIFO Empty Interrupt Flag
239
//
240
//  Buad Rate Register - BRR (RA = 3'b001) (Write-Only)
241
//
242
//   11:8 - PS  :   Baud Rate Prescaler (see table below) - load with (M - 1)
243
//    7:0 - Div :   Baud Rate Divider (see table below) - load with (N - 1)
244
//
245 4 MichaelA
//   {PS, Div}  :   Baud Rate = (Clk / 16) / ((PS + 1) * (Div + 1))
246 2 MichaelA
//
247
//  Transmit Data Register - TDR (RA = 3'b010)
248
//
249
//   11 - TFC   :   Transmit FIFO Clear, cleared at end of current cycle
250
//   10 - RFC   :   Receive FIFO Clear, cleared at end of current cycle
251
//    9 - HLD   :   Transmit Hold: 0 - normal; 1 - hold until Tx FIFO filled
252
//    8 - Rsvd  :   Reserved for Future Use
253
//  7:0 - TD    :   Transmit Data, written to Xmit FIFO when WnR is set.
254
//
255
//  Receive Data Register - RDR (RA = 3'b011)
256
//
257
//   11 - TRDY  :   Transmit Ready, set if Xmt FIFO not full
258
//   10 - RRDY  :   Receive Ready, set if Rcv FIFO has data 
259
//    9 - RTO   :   Receive Time Out, set if no data received in 3 char. times
260
//    8 - RERR  :   Receiver Error, set if current RD[7:0] has an error
261
//  7:0 - RD    :   Receive Data
262
//
263
//  Scratch Pad Register - SPR (RA = 3'b100)
264
//
265
//  11:0 - SPR  :   Scratch Pad Data, R/W location set by bits 11:9 (see below)
266
//
267
////////////////////////////////////////////////////////////////////////////////
268
//
269
//  MD[1:0] - Operating Mode
270
//
271
//   2'b00 - RS-232 without Handshaking, xRTS <= RTSi <= RTSo, CTSi <= xCTS
272
//   2'b01 - RS-232 with Handshaking, xRTS <= RTSi <= ~TxIdle, CTSi <= xCTS
273
//   2'b10 - RS-485 without Loopback, RD <= CTSi <= 1, DE <= RTSi <= ~TxIdle
274
//   2'b11 - RS-485 with Loopback, RD <= RxD, DE <= RTSi <= ~TxIdle, CTSi <= 1
275
//
276
//  FMT[3:0] - Asynchronous Serial Format
277
//
278
//   4'b0000 - 8N1, 4'b1000 - 8O2
279
//   4'b0001 - 8N1, 4'b1001 - 8E2
280
//   4'b0010 - 8O1, 4'b1010 - 8S2
281
//   4'b0011 - 8E1, 4'b1011 - 8M2
282
//   4'b0100 - 8S1, 4'b1100 - 7O1
283
//   4'b0101 - 8M1, 4'b1101 - 7E1
284
//   4'b0110 - 8N1, 4'b1110 - 7O2
285
//   4'b0111 - 8N2, 4'b1111 - 7E2
286
//
287
////////////////////////////////////////////////////////////////////////////////
288
//
289
//  SPR Sub-Addresses - Additional Status Registers
290
//
291
//      Accessed by setting SPR[11:9] to the address of the desired extended
292
//      status register. Unused bits in the status registers set to 0.
293
//      Unassigned sub-addresses default to the SPR.
294
//
295
//   1 - [7:0] Revision Register
296
//   2 - [7:0] FIFO Length: RFLen - 7:4, TFLen - 3:0; (1 << (xFLen + 4))
297
//   3 - [7:0] Rx/Tx FIFO Threshold: RFThr - 7:4, TFThr - 3:0; (xFLen >> 1)
298
//   4 - [7:0] Tx Holding Register, "peeking" into THR does not advance Tx FIFO
299
//   5 - [8:0] Rx Holding Register, "peeking" into RHR does not advance Rx FIFO
300
//   6 - [(TFLen + 4):0] Tx FIFO Count
301
//   7 - [(RFLen + 4):0] Rx FIFO Count
302
//
303
////////////////////////////////////////////////////////////////////////////////
304
 
305
module SSP_UART #(
306
    // Default BRR Settings Parameters
307
 
308
    parameter pPS_Default   = 4'h1,         // see baud rate tables below
309
    parameter pDiv_Default  = 8'hEF,        // see baud rate tables below
310
 
311
    // Default Receive Time Out Character Delay Count
312
 
313
    parameter pRTOChrDlyCnt = 3,
314
 
315
    // FIFO Configuration Parameters
316
 
317 4 MichaelA
    parameter pTF_Depth = 2,                // Tx FIFO Depth: 2**(TF_Depth + 4)
318
    parameter pRF_Depth = 2,                // Rx FIFO Depth: 2**(RF_Depth + 4)
319 2 MichaelA
    parameter pTF_Init  = "Src/UART_TF.coe",    // Tx FIFO Memory Initialization
320
    parameter pRF_Init  = "Src/UART_RF.coe"     // Rx FIFO Memory Initialization
321
)(
322
    input   Rst,                    // System Reset
323
    input   Clk,                    // System Clock
324
 
325
    //  SSP Interface
326
 
327
    input   SSP_SSEL,               // SSP Slave Select
328
 
329
    input   SSP_SCK,                // Synchronous Serial Port Serial Clock
330
    input   [2:0] SSP_RA,           // SSP Register Address
331
    input   SSP_WnR,                // SSP Command
332
    input   SSP_En,                 // SSP Start Data Transfer Phase (Bits 11:0)
333
    input   SSP_EOC,                // SSP End-Of-Cycle (Bit 0)
334
    input   [11:0] SSP_DI,          // SSP Data In
335
    output  reg [11:0] SSP_DO,      // SSP Data Out
336
 
337
    //  External UART Interface
338
 
339
    output  TxD_232,                // RS-232 Mode TxD
340
    input   RxD_232,                // RS-232 Mode RxD
341
    output  reg xRTS,               // RS-232 Mode RTS (Ready-To-Receive)
342
    input   xCTS,                   // RS-232 Mode CTS (Okay-To-Send)
343
 
344
    output  TxD_485,                // RS-485 Mode TxD
345
    input   RxD_485,                // RS-485 Mode RxD
346
    output  xDE,                    // RS-485 Mode Transceiver Drive Enable
347
 
348
    //  External Interrupt Request
349
 
350
    output  reg IRQ,                // Interrupt Request
351
 
352
    //  TxSM/RxSM Status
353
 
354
    output  TxIdle,
355
    output  RxIdle
356
);
357
 
358
////////////////////////////////////////////////////////////////////////////////
359
//
360
//  Module Parameters
361
// 
362
 
363
localparam pVersion = 8'h23;    // Version: 2.3
364
 
365
//  Register Addresses
366
 
367
localparam pUCR = 0;            // UART Control Register
368
localparam pUSR = 1;            // UART Status Register
369
localparam pTDR = 2;            // Tx Data Register
370
localparam pRDR = 3;            // Rx Data Register
371
localparam pSPR = 4;            // Scratch Pad Register (and Aux. Status Regs)
372
 
373
//  TDR Bit Positions
374
 
375
localparam pTFC = 11;           // Tx FIFO Clear bit position
376
localparam pRFC = 10;           // Rx FIFO Clear bit position
377
localparam pHLD =  9;           // Tx SM Hold bit position
378
 
379
//  SPR Sub-Addresses
380
 
381
localparam pRev   = 1;          // Revision Reg:    {0, pVersion}
382
localparam pLen   = 2;          // Length Reg:      {0, pRF_Depth, pTF_Depth}
383
localparam pFThr  = 3;          // Rx/Tx FIFO Thres:{0, RFThr[3:0], TFThr[3:0]}
384
localparam pTHR   = 4;          // Tx Holding Reg:  {0, THR[7:0]}
385
localparam pRHR   = 5;          // Rx Holding Reg:  {0, RHR[8:0]}
386
localparam pTFCnt = 6;          // Tx Count:        {0, TFCnt[(pTF_Depth+4):0]}
387
localparam pRFCnt = 7;          // Rx Count:        {0, RFCnt[(pRF_Depth+4):0]}
388
 
389
//  FIFO Configuration Parameters
390
 
391
localparam pWidth = 8;          // Maximum Character width
392
localparam pxFThr = 8;          // TF/RF Half-Full Flag Theshold (%, 4 bits)
393
 
394
////////////////////////////////////////////////////////////////////////////////   
395
//
396
//  Local Signal Declarations
397
//
398
 
399
    wire    SCK;                    // Internal name for SSP_SCK
400
 
401
    wire    [2:0] RSel;             // Internal name for SSP_RA
402
    wire    Sel_TDR;                // Select - Transmit Data Register
403
    wire    Sel_RDR;                // Select - Receive Data Register
404
    wire    Sel_UCR;                // Select - UART Control Register
405
    wire    Sel_SPR;                // Select - Scratch Pad Register
406
 
407
    wire    [7:0] TD, THR;          // Transmit Data, Transmit Holding Register
408
    wire    TFC;                    // TDR: Transmit FIFO Clear
409
    reg     HLD;                    // TDR: Transmit Hold
410
    reg     TxHold;                 // Transmit Hold, synchronized to Clk
411
    wire    RE_THR;                 // Read Enable - Transmit Holding Register
412
    wire    WE_THR, ClrTHR;         // Write Enable - THR, Clear/Reset THR
413
    wire    TF_FF, TF_EF, TF_HF;    // Transmit FIFO Flags - Full, Empty, Half
414
 
415
    wire    [8:0] RD, RHR;          // Receive Data (In), Receive Holding Reg
416
    wire    RFC;                    // TDR: Receive FIFO Clear
417
    wire    WE_RHR;                 // Write Enable - RHR
418
    wire    RE_RHR, ClrRHR;         // Read Enable - RHR, Clear/Reset RHR
419
    wire    RF_FF, RF_EF, RF_HF;    // Receive FIFO Flags - Full, Empty, Half
420
    wire    [(pTF_Depth + 4):0] TFCnt;  // Tx FIFO Count
421
    wire    [(pRF_Depth + 4):0] RFCnt;  // RX FIFO Count
422
 
423
    reg     [ 7:0] TDR;             // Transmit Data Register
424
    reg     [11:0] RDR;             // Receive Data Register, UART Status Reg
425
    reg     [11:0] UCR, USR, SPR;   // UART Control, Status, & Scratch Pad Regs
426
    reg     [ 7:0] RTFThr;          // UART Rx/Tx FIFO Threshold Register
427
 
428
    wire    [1:0] MD;               // UCR: Operating Mode
429
    wire    RTSo, IE;               // UCR: RTS Output, Interrupt Enable
430
    wire    [3:0] FMT;              // UCR: Format (UCR[3:0] Reserved for Baud)
431
 
432
    reg     Len, NumStop, ParEn;    // Char Length, # Stop Bits, Parity Enable
433
    reg     [1:0] Par;              // Parity Selector
434
    reg     [3:0] PS;               // Baud Rate Prescaler
435
    reg     [7:0] Div;              // Baud Rate Divider
436
    reg     [3:0] CCntVal;          // RTO Character Length: {10 | 11 | 12} - 1
437
    wire    [3:0] RTOVal;           // RTO Character Delay Value: (N - 1)
438
 
439
    wire    RTSi, CTSi;             // USR: RTS Input, CTS Input
440
    reg     [1:0] RS, TS;           // USR: Rcv Status, Xmt Status
441
    wire    iRTO;                   // USR: Receive Timeout Interrupt
442
    wire    iRHF;                   // USR: Receive Half Full Interrupt
443
    wire    iTHE;                   // USR: Transmit Half Empty Interrupt
444
    wire    iTFE;                   // USR: Transmit FIFO Empty Interrupt
445
 
446
    reg     En;                     // delayed SSP_En (1 SCK period)
447
    wire    Clr_Int;                // Clear Interrupt Flags - read of USR
448
 
449
    wire    WE_SPR;                 // Write Enable: Scratch Pad Register
450
    wire    WE_RTFThr;              // Write Enable: Rx/Tx FIFO Threshold Reg.
451
    reg     [11:0] SPR_DO;          // SPR Output Data
452
 
453
    wire    TxD;                    // UART TxD Output (Mode Multiplexer Input)
454
    reg     RxD;                    // UART RxD Input (Mode Multiplexer Output)
455
 
456
    wire    TRDY;                   // RDR: Transmit Ready
457
    wire    RRDY;                   // RDR: Receive Ready
458
    wire    RTO;                    // RDR: Receive Timeout
459
    wire    RERR;                   // RDR: Receive Error 
460
 
461
    wire    RcvTimeout;             // Receive Timeout
462
 
463
    wire    [7:0] Version = pVersion;
464
    wire    [3:0] TFLen   = pTF_Depth;  // Len = (2**(pTF_Depth + 4))
465
    wire    [3:0] RFLen   = pRF_Depth;
466
    wire    [3:0] TFThr   = pxFThr;     // Thr = pxFThr ? pxFThr*(2**pTFLen) : 1
467
    wire    [3:0] RFThr   = pxFThr;
468
 
469
////////////////////////////////////////////////////////////////////////////////    
470
//
471
//  Implementation
472
//
473
 
474
assign SCK = SSP_SCK;
475
 
476
//  Assign SSP Read/Write Strobes
477
 
478
assign SSP_WE = SSP_SSEL &  SSP_WnR & SSP_EOC;
479
assign SSP_RE = SSP_SSEL & ~SSP_WnR & SSP_EOC;
480
 
481
//  Break out Register Select Address
482
 
483
assign RSel = SSP_RA;
484
 
485
assign Sel_TDR = (RSel == pTDR);
486
assign Sel_RDR = (RSel == pRDR);
487
assign Sel_USR = (RSel == pUSR);
488
assign Sel_UCR = (RSel == pUCR);
489
assign Sel_SPR = (RSel == pSPR);
490
 
491
//  Assign SPR Data Output based on sub-addresses: SPR[11:9]
492
 
493
always @(*)
494
begin
495
    case(SPR[11:9])
496
        pRev    : SPR_DO <= {4'b0, Version[7:0]};
497
        pLen    : SPR_DO <= {4'b0, pRF_Depth[3:0], pTF_Depth[3:0]};
498
        pFThr   : SPR_DO <= {4'b0, RTFThr};
499
        pTHR    : SPR_DO <= {4'b0, THR};
500
        pRHR    : SPR_DO <= {3'b0, RHR};
501
        pTFCnt  : SPR_DO <= {1'b0, TFCnt[(pTF_Depth + 4):0]};
502
        pRFCnt  : SPR_DO <= {1'b0, RFCnt[(pRF_Depth + 4):0]};
503
        default : SPR_DO <= SPR;
504
    endcase
505
end
506
 
507
//  Drive SSP Output Data Bus
508
 
509
always @(*)
510
begin
511
    case(RSel)
512
        pUCR    : SSP_DO <= ((SSP_SSEL) ? UCR                              : 0);
513
        pUSR    : SSP_DO <= ((SSP_SSEL) ? USR                              : 0);
514
        pTDR    : SSP_DO <= ((SSP_SSEL) ? TDR                              : 0);
515
        pRDR    : SSP_DO <= ((SSP_SSEL) ? RDR                              : 0);
516
        pSPR    : SSP_DO <= ((SSP_SSEL) ? SPR_DO                           : 0);
517
        default : SSP_DO <= ((SSP_SSEL) ? {1'b0, RFCnt[(pRF_Depth+4) : 0]} : 0);
518
    endcase
519
end
520
 
521
//  Assert IRQ when IE is set
522
 
523
assign Rst_IRQ = Rst | Clr_Int;
524
 
525
always @(posedge Clk)
526
begin
527
    if(Rst_IRQ)
528
        IRQ <= 0;
529
    else if(~IRQ)
530
        IRQ <= #1 IE & (iTFE | iTHE | iRHF | iRTO);
531
end
532
 
533
////////////////////////////////////////////////////////////////////////////////
534
//
535
//  Write UART Control Register
536
//
537
 
538
always @(negedge SCK or posedge Rst)
539
begin
540
    if(Rst)
541
        UCR <= #1 0;
542
    else if(Sel_UCR)
543
        UCR <= #1 ((SSP_WE) ? SSP_DI : USR);
544
end
545
 
546
//  Assign UCR Fields
547
 
548
assign MD   = UCR[11:10];
549
assign RTSo = UCR[9];
550
assign IE   = UCR[8];
551
assign FMT  = UCR[7:4];
552
 
553
//  Format Decode
554
 
555
always @(FMT)
556
case(FMT)
557
    4'b0000 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00};   // 8N1
558
    4'b0001 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00};   // 8N1
559
    4'b0010 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b00};   // 8O1
560
    4'b0011 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b01};   // 8E1
561
    4'b0100 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b10};   // 8S1
562
    4'b0101 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b1, 2'b11};   // 8M1
563
    4'b0110 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b0, 1'b0, 2'b00};   // 8N1
564
    4'b0111 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b0, 2'b00};   // 8N2
565
    4'b1000 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b00};   // 8O2
566
    4'b1001 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b01};   // 8E2
567
    4'b1010 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b10};   // 8S2
568
    4'b1011 : {Len, NumStop, ParEn, Par} <= {1'b0, 1'b1, 1'b1, 2'b11};   // 8M2
569
    4'b1100 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b0, 1'b1, 2'b00};   // 7O1
570
    4'b1101 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b0, 1'b1, 2'b01};   // 7E1
571
    4'b1110 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b1, 1'b1, 2'b00};   // 7O2
572
    4'b1111 : {Len, NumStop, ParEn, Par} <= {1'b1, 1'b1, 1'b1, 2'b01};   // 7E2
573
endcase
574
 
575
//  Baud Rate Generator's PS and Div for defined Baud Rates (48 MHz Osc)
576
//
577
//  Profibus Baud Rates
578 4 MichaelA
//
579 2 MichaelA
//  {PS, Div} <= {4'h0, 8'h00}; // PS= 1; Div=  1; BR=3.0M
580
//  {PS, Div} <= {4'h0, 8'h01}; // PS= 1; Div=  2; BR=1.5M
581
//  {PS, Div} <= {4'h0, 8'h05}; // PS= 1; Div=  6; BR=500.0k
582
//  {PS, Div} <= {4'h0, 8'h0F}; // PS= 1; Div= 16; BR=187.5k
583 4 MichaelA
//
584 2 MichaelA
//  Standard Baud Rates
585 4 MichaelA
//
586 2 MichaelA
//  {PS, Div} <= {4'hC, 8'h00}; // PS=13; Div=  1; BR=230.4k
587
//  {PS, Div} <= {4'hC, 8'h01}; // PS=13; Div=  2; BR=115.2k
588
//  {PS, Div} <= {4'hC, 8'h02}; // PS=13; Div=  3; BR= 76.8k
589
//  {PS, Div} <= {4'hC, 8'h03}; // PS=13; Div=  4; BR= 57.6k
590
//  {PS, Div} <= {4'hC, 8'h05}; // PS=13; Div=  6; BR= 38.4k
591
//  {PS, Div} <= {4'hC, 8'h07}; // PS=13; Div=  8; BR= 28.8k
592
//  {PS, Div} <= {4'hC, 8'h0B}; // PS=13; Div= 12; BR= 19.2k
593
//  {PS, Div} <= {4'hC, 8'h0F}; // PS=13; Div= 16; BR= 14.4k
594
//  {PS, Div} <= {4'hC, 8'h17}; // PS=13; Div= 24; BR=  9.6k
595
//  {PS, Div} <= {4'hC, 8'h2F}; // PS=13; Div= 48; BR=  4.8k
596
//  {PS, Div} <= {4'hC, 8'h5F}; // PS=13; Div= 96; BR=  2.4k
597
//  {PS, Div} <= {4'hC, 8'hBF}; // PS=13; Div=192; BR=  1.2k
598
//
599
//  Baud Rate Generator's PS and Div for defined Baud Rates (29.4912 MHz)
600
//
601 4 MichaelA
//  Extended Baud Rates
602
//
603 2 MichaelA
//  {PS, Div} <= {4'h0, 8'h00}; // PS= 1; Div=  1; BR=1843.2k
604 4 MichaelA
//  {PS, Div} <= {4'h0, 8'h01}; // PS= 1; Div=  2; BR= 921.6k
605 2 MichaelA
//  {PS, Div} <= {4'h0, 8'h02}; // PS= 1; Div=  3; BR= 614.4k
606
//  {PS, Div} <= {4'h0, 8'h03}; // PS= 1; Div=  4; BR= 460.8k
607
//  {PS, Div} <= {4'h0, 8'h05}; // PS= 1; Div=  6; BR= 307.2k
608 4 MichaelA
//  {PS, Div} <= {4'h0, 8'h07}; // PS= 1; Div=  8; BR= 230.4k
609 2 MichaelA
//  {PS, Div} <= {4'h0, 8'h0B}; // PS= 1; Div= 12; BR= 153.6k
610
//
611
//  Standard Baud Rates
612
//
613
//  {PS, Div} <= {4'h0, 8'h0F}; // PS= 1; Div= 16; BR= 115.2k
614
//  {PS, Div} <= {4'h0, 8'h17}; // PS= 1; Div= 24; BR=  76.8k
615 4 MichaelA
//  {PS, Div} <= {4'h0, 8'h1F}; // PS= 1; Div= 32; BR=  57.6k
616 2 MichaelA
//  {PS, Div} <= {4'h0, 8'h2F}; // PS= 1; Div= 48; BR=  38.4k
617
//  {PS, Div} <= {4'h0, 8'h3F}; // PS= 1; Div= 64; BR=  28.8k
618
//  {PS, Div} <= {4'h0, 8'h5F}; // PS= 1; Div= 96; BR=  19.2k
619
//  {PS, Div} <= {4'h0, 8'h7F}; // PS= 1; Div=128; BR=  14.4k
620
//  {PS, Div} <= {4'h0, 8'hBF}; // PS= 1; Div=192; BR=   9.6k
621
//  {PS, Div} <= {4'h0, 8'hFF}; // PS= 1; Div=256; BR=   7.2k
622
//  {PS, Div} <= {4'h1, 8'hBF}; // PS= 2; Div=192; BR=   4.8k
623
//  {PS, Div} <= {4'h1, 8'hFF}; // PS= 3; Div=256; BR=   3.6k
624
//  {PS, Div} <= {4'h3, 8'hBF}; // PS= 4; Div=192; BR=   2.4k
625
//  {PS, Div} <= {4'h3, 8'hFF}; // PS= 4; Div=256; BR=   1.8k
626
//  {PS, Div} <= {4'h7, 8'hBF}; // PS= 8; Div=192; BR=   1.2k
627
//  {PS, Div} <= {4'h7, 8'hFF}; // PS= 8; Div=256; BR=   0.9k
628
//  {PS, Div} <= {4'hF, 8'hBF}; // PS=16; Div=192; BR=   0.6k
629
//  {PS, Div} <= {4'hF, 8'hFF}; // PS=16; Div=256; BR=   0.45k
630
 
631
//  Receive Timeout Character Frame Length
632
 
633
always @(FMT)
634
case(FMT)
635
    4'b0000 : CCntVal <= 4'h9;   // 8N1,  9 <= 10 - 1
636
    4'b0001 : CCntVal <= 4'h9;   // 8N1,  9 <= 10 - 1
637
    4'b0010 : CCntVal <= 4'hA;   // 8O1, 10 <= 11 - 1
638
    4'b0011 : CCntVal <= 4'hA;   // 8E1, 10 <= 11 - 1
639
    4'b0100 : CCntVal <= 4'hA;   // 8S1, 10 <= 11 - 1
640
    4'b0101 : CCntVal <= 4'hA;   // 8M1, 10 <= 11 - 1
641
    4'b0110 : CCntVal <= 4'h9;   // 8N1,  9 <= 10 - 1
642
    4'b0111 : CCntVal <= 4'hA;   // 8N2, 10 <= 11 - 1
643
    4'b1000 : CCntVal <= 4'hB;   // 8O2, 11 <= 12 - 1
644
    4'b1001 : CCntVal <= 4'hB;   // 8E2, 11 <= 12 - 1
645
    4'b1010 : CCntVal <= 4'hB;   // 8S2, 11 <= 12 - 1
646
    4'b1011 : CCntVal <= 4'hB;   // 8M2, 11 <= 12 - 1
647
    4'b1100 : CCntVal <= 4'h9;   // 7O1,  9 <= 10 - 1
648
    4'b1101 : CCntVal <= 4'h9;   // 7E1,  9 <= 10 - 1
649
    4'b1110 : CCntVal <= 4'h9;   // 7O2,  9 <= 10 - 1
650
    4'b1111 : CCntVal <= 4'h9;   // 7E2,  9 <= 10 - 1
651
endcase
652
 
653
assign RTOVal = (pRTOChrDlyCnt - 1);    // Set RTO Character Delay Count
654
 
655
////////////////////////////////////////////////////////////////////////////////
656
//
657
//  USR Register and Operations
658
//
659
 
660
always @(*)
661
begin
662
    case({RF_FF, RF_HF, RF_EF})
663
        3'b000 : RS <= 2'b01;   // Not Empty, < Half Full
664
        3'b001 : RS <= 2'b00;   // Empty
665
        3'b010 : RS <= 2'b10;   // > Half Full, < Full
666
        3'b011 : RS <= 2'b00;   // Not Possible/Not Allowed
667
        3'b100 : RS <= 2'b00;   // Not Possible/Not Allowed
668
        3'b101 : RS <= 2'b00;   // Not Possible/Not Allowed
669
        3'b110 : RS <= 2'b11;   // Full
670
        3'b111 : RS <= 2'b00;   // Not Possible/Not Allowed
671
    endcase
672
end
673
 
674
always @(*)
675
begin
676
    case({TF_FF, TF_HF, TxIdle})
677
        3'b000 : TS <= 2'b01;   // Not Empty, < Half Full
678
        3'b001 : TS <= 2'b00;   // Empty
679
        3'b010 : TS <= 2'b10;   // > Half Full, < Full
680
        3'b011 : TS <= 2'b00;   // Not Possible/Not Allowed
681
        3'b100 : TS <= 2'b00;   // Not Possible/Not Allowed
682
        3'b101 : TS <= 2'b00;   // Not Possible/Not Allowed
683
        3'b110 : TS <= 2'b11;   // Full
684
        3'b111 : TS <= 2'b00;   // Not Possible/Not Allowed
685
    endcase
686
end
687
 
688
always @(posedge SCK or posedge Rst)
689
begin
690
    if(Rst)
691
        USR <= #1 0;
692
    else
693
        USR <= #1 {MD, RTSi, CTSi, RS, TS, iRTO, iRHF, iTHE, iTFE};
694
end
695
 
696
//  Read UART Status Register
697
 
698
always @(posedge SCK or posedge Rst)
699
begin
700
    if(Rst)
701
        En <= #1 0;
702
    else
703
        En <= #1 SSP_En;
704
end
705
 
706
//  Generate Clr_Int on rising edge of SSP_En if Sel_USR asserted
707
//      and rising edge on SSP_En and any interrupt flags set in USR
708
//      change clock domains from SCK to Clk (UART)
709
 
710
re1ce   RED1 (
711
            .den(Sel_USR & (SSP_En & ~En) & |USR[3:0]),
712
            .din(SCK),
713
            .clk(Clk),
714
            .rst(Rst),
715
            .trg(),
716
            .pls(Clr_Int)
717
        );
718
 
719
////////////////////////////////////////////////////////////////////////////////
720
//
721
//  BRR - Baud Rate Register
722
//
723
 
724
always @(posedge SCK or posedge Rst)
725
begin
726
    if(Rst)
727
        {PS, Div} <= #1 {pPS_Default, pDiv_Default};        // Default: 9600 bps
728
    else if(Sel_USR)
729
        {PS, Div} <= #1 ((SSP_WE) ? SSP_DI : {PS, Div});
730
end
731
 
732
////////////////////////////////////////////////////////////////////////////////
733
//
734
//  TDR/RDR Registers and Operations
735
//
736
 
737
//  Write Transmit Data Register
738
 
739
assign WE_TDR = SSP_WE & Sel_TDR & TRDY;
740
 
741
always @(posedge SCK or posedge Rst)
742
begin
743
    if(Rst)
744
        TDR <= #1 8'b0;
745
    else if(WE_TDR)
746
        TDR <= #1 SSP_DI[7:0];
747
end
748
 
749
assign TD = TDR;
750
 
751
//  Clear Transmit Holding Register
752
 
753
assign TFC = SSP_DI[pTFC] & WE_TDR;
754
 
755
re1ce   RED2 (
756
            .den(TFC),
757
            .din(SCK),
758
            .clk(Clk),
759
            .rst(Rst),
760
            .trg(),
761
            .pls(ClrTHR)
762
        );
763
 
764
//  Clear Receive Holding Register
765
 
766
assign RFC = SSP_DI[pRFC] & WE_TDR;
767
 
768
re1ce   RED3 (
769
            .den(RFC),
770
            .din(SCK),
771
            .clk(Clk),
772
            .rst(Rst),
773
            .trg(),
774
            .pls(ClrRHR)
775
        );
776
 
777
//  Latch/Register the Transmit Hold Bit on writes to TDR
778
 
779
always @(posedge SCK or posedge Rst)
780
begin
781
    if(Rst)
782
        HLD <= #1 0;
783
    else if(WE_TDR)
784
        HLD <= #1 SSP_DI[pHLD];
785
end
786
 
787
//  Write Transmit Holding Register (FIFO)
788
 
789
re1ce   RED4 (
790
            .den(WE_TDR),
791
            .din(SCK),
792
            .clk(Clk),
793
            .rst(Rst),
794
            .trg(),
795
            .pls(WE_THR)
796
        );
797
 
798
//  Set TxHold when the THR is written
799
 
800
always @(posedge Clk)
801
begin
802
    if(Rst)
803
        TxHold <= #1 0;
804
    else if(WE_THR)
805
        TxHold <= #1 HLD;
806
end
807
 
808
//  Read Receive Data Register
809
 
810
assign TRDY = ~TF_FF;
811
assign RRDY = ~RF_EF;
812
assign RTO  = RcvTimeout;
813 4 MichaelA
assign RERR = RHR[8];
814
 
815 2 MichaelA
//  Capture and Hold Receive Data Register on SCK clock domain
816
 
817 4 MichaelA
always @(posedge SCK or posedge Rst)
818
begin
819
    if(Rst)
820
        RDR <= #1 0;
821
    else if(~SSP_En)
822
        RDR <= #1 {TRDY, RRDY, RTO, RERR, RHR[7:0]};
823
end
824 2 MichaelA
 
825 4 MichaelA
//  Read Receive Holding Register
826
//      Generate RE_RHR read pulse only when the captured value indicates that
827 2 MichaelA
//      RDR contains data because there is data in the Receive FIFO, i.e. RHR.
828
 
829
assign RE_RDR = Sel_RDR & ~SSP_WnR & (SSP_En & ~En) & RDR[10];
830
 
831
re1ce   RED5 (
832
            .den(RE_RDR),
833
            .din(SCK),
834
            .clk(Clk),
835
            .rst(Rst),
836
            .trg(),
837
            .pls(RE_RHR)
838
        );
839
 
840
////////////////////////////////////////////////////////////////////////////////
841
//
842
//  Write Scratch Pad Register
843
//
844
 
845
assign WE_SPR = SSP_WE & Sel_SPR;
846
 
847
always @(posedge SCK or posedge Rst)
848
begin
849
    if(Rst)
850
        SPR <= #1 0;
851
    else if(WE_SPR)
852
        SPR <= #1 SSP_DI;
853
end
854
 
855
assign WE_RTFThr = SSP_WE & Sel_SPR & (SSP_DI[11:9] == pFThr) & SSP_DI[8];
856
 
857
always @(posedge SCK or posedge Rst)
858
begin
859
    if(Rst)
860
        RTFThr <= #1 {RFThr, TFThr};
861
    else if(WE_RTFThr)
862
        RTFThr <= #1 SSP_DI;
863
end
864
 
865
////////////////////////////////////////////////////////////////////////////////
866
//
867
//  Xmt/Rcv Holding Register Instantiations - Dual-Port Synchronous FIFOs
868
//
869
//  THR FIFO - 2**(pTFLen + 4) x pWidth FIFO
870
 
871
DPSFnmCE    #(
872
                .addr((pTF_Depth + 4)),
873
                .width(pWidth),
874
                .init(pTF_Init)
875
            ) TF1 (
876
                .Rst(Rst | ClrTHR),
877
                .Clk(Clk),
878
                .WE(WE_THR),
879
                .RE(RE_THR),
880
                .DI(TD),
881
                .DO(THR),
882
                .FF(TF_FF),
883
                .HF(TF_HF),
884
                .EF(TF_EF),
885
                .Cnt(TFCnt)
886
            );
887
 
888
//  RHR FIFO - 2**(pRFLen + 4) x (pWidth + 1) FIFO
889
 
890
DPSFnmCE    #(
891
                .addr((pRF_Depth + 4)),
892
                .width((pWidth + 1)),
893
                .init(pRF_Init)
894
            ) RF1 (
895
                .Rst(Rst | ClrRHR),
896
                .Clk(Clk),
897
                .WE(WE_RHR),
898
                .RE(RE_RHR),
899
                .DI(RD),
900
                .DO(RHR),
901
                .FF(RF_FF),
902
                .HF(RF_HF),
903
                .EF(RF_EF),
904
                .Cnt(RFCnt)
905
            );
906
 
907
////////////////////////////////////////////////////////////////////////////////
908
//
909
//  Configure external/internal serial port signals according to MD[1:0]
910
//      MD[1:0] = 0,1 - RS-233; 2,3 - RS-485
911
 
912
assign RS232 = ~MD[1];
913
assign RS485 =  MD[1];
914
 
915
//  Set RS-232/Rs-485 TxD
916
 
917
assign TxD_232 = (RS232 ? TxD : 1);
918
assign TxD_485 = (RS485 ? TxD : 1);
919
 
920
//  Assert DE in the RS-485 modes whenever the TxSM is not idle, and deassert
921
//      whenever the RS-485 modes are not selected
922
 
923
assign xDE = (RS485 ? ~TxIdle : 0);
924
 
925
//  Connect the UART's RxD serial input to the appropriate external RxD input
926
//      Hold RxD to logic 1 when in the RS-485 w/o Loopback mode and the TxSM
927
//      is transmitting data. In this manner, the external xOE signal to the 
928
//      RS-485 transceiver can always be asserted.
929
 
930
always @(posedge Clk or posedge Rst)
931
begin
932
    if(Rst)
933
        RxD <= #1 1;
934
    else
935
        case(MD)
936
            2'b00 : RxD <= #1 RxD_232;
937
            2'b01 : RxD <= #1 RxD_232;
938
            2'b10 : RxD <= #1 (TxIdle ? RxD_485 : 1);
939
            2'b11 : RxD <= #1 RxD_485;
940
        endcase
941
end
942
 
943
// RS-232 auto-Handshaking is implemented as Ready-To-Receive (RTR) based on
944
//      the Rcv FIFO flag settings. xRTS, which should connect to the receiving
945
//      side's xCTS, is asserted whenever the local receive FIFO is less than 
946
//      half full. If a similar UART with hardware handshaking is connected,
947
//      then that transmitter should stop sending until the local FIFO is read
948
//      so that it is below the HF mark. Since local reads of the receive FIFO
949
//      are expected to be much faster than the RS-232 baud rate, it is not 
950
//      expected that hysteresis will be required to prevent rapid assertion
951
//      and deassertion of RTS.
952
//
953
//      This handshaking mechanism was selected for the automatic handshaking
954
//      mode because it prevents (or attempts to prevent) receive FIFO over-
955
//      flow in the receiver. Furthermore, it reduces the software workload in
956
//      the transmitter's send routines.
957
//
958
//      For all other modes, the CTSi control signal to the UART_TXSM is held
959
//      at logic one. This effectively disables the TxSM's handshaking logic,
960
//      and allows the transmitter to send data as soon as data is written to
961
//      Xmt FIFO.
962
 
963
always @(*)
964
begin
965
    case(MD)
966
        2'b00 : xRTS <= RTSo;
967
        2'b01 : xRTS <= ~RF_HF;
968
        2'b10 : xRTS <= 0;
969
        2'b11 : xRTS <= 0;
970
    endcase
971
end
972
 
973
assign RTSi = ((RS232) ? xRTS : xDE);
974
assign CTSi = ((MD == 1) ? xCTS : 1);
975
 
976
////////////////////////////////////////////////////////////////////////////////
977
//
978
//  UART Baud Rate Generator Instantiation
979
//
980
 
981
UART_BRG    BRG (
982
                .Rst(Rst),
983
                .Clk(Clk),
984
                .PS(PS),
985
                .Div(Div),
986
                .CE_16x(CE_16x)
987
            );
988
 
989
////////////////////////////////////////////////////////////////////////////////
990
//
991
//  UART Transmitter State Machine & Shift Register Instantiation
992
//
993
 
994
UART_TXSM   XMT (
995
                .Rst(Rst),
996
                .Clk(Clk),
997
 
998
                .CE_16x(CE_16x),
999
 
1000
                .Len(Len),
1001
                .NumStop(NumStop),
1002
                .ParEn(ParEn),
1003
                .Par(Par),
1004
 
1005
                .TF_RE(RE_THR),
1006
                .THR(THR),
1007
                .TF_EF(TF_EF | TxHold),
1008
 
1009
                .TxD(TxD),
1010
                .CTSi(CTSi),
1011
 
1012
                .TxIdle(TxIdle),
1013
                .TxStart(),
1014
                .TxShift(),
1015
                .TxStop()
1016
            );
1017
 
1018
////////////////////////////////////////////////////////////////////////////////
1019
//
1020
//  UART Receiver State Machine & Shift Register Instantiation
1021
//
1022
 
1023
UART_RXSM   RCV (
1024
                .Rst(Rst),
1025
                .Clk(Clk),
1026
 
1027
                .CE_16x(CE_16x),
1028
 
1029
                .Len(Len),
1030
                .NumStop(NumStop),
1031
                .ParEn(ParEn),
1032
                .Par(Par),
1033
 
1034
                .RxD(RxD),
1035
 
1036
                .RD(RD),
1037
                .WE_RHR(WE_RHR),
1038
 
1039
                .RxWait(),
1040
                .RxIdle(RxIdle),
1041
                .RxStart(),
1042
                .RxShift(),
1043
                .RxParity(),
1044
                .RxStop(),
1045
                .RxError()
1046
            );
1047
 
1048
////////////////////////////////////////////////////////////////////////////////
1049
//
1050
//  UART Receive Timeout Module Instantiation
1051
//
1052
 
1053
UART_RTO    TMR (
1054
                .Rst(Rst),
1055
                .Clk(Clk),
1056
 
1057
                .CE_16x(CE_16x),
1058
 
1059
                .WE_RHR(WE_RHR),
1060
                .RE_RHR(RE_RHR),
1061
 
1062
                .CCntVal(CCntVal),
1063
                .RTOVal(RTOVal),
1064
 
1065
                .RcvTimeout(RcvTimeout)
1066
            );
1067
 
1068
////////////////////////////////////////////////////////////////////////////////
1069
//
1070
//  UART Interrupt Generator Instantiation
1071
//
1072
 
1073
UART_INT    INT (
1074
                .Rst(Rst),
1075
                .Clk(Clk),
1076
 
1077
                .TF_HF(TF_HF),
1078
                .TF_EF(TF_EF),
1079
                .RF_HF(RF_HF),
1080
                .RF_EF(RF_EF),
1081
 
1082
                .RTO(RTO),
1083
 
1084
                .Clr_Int(Clr_Int),
1085
                .USR(USR[3:0]),
1086
 
1087
                .iTFE(iTFE),
1088
                .iTHE(iTHE),
1089
                .iRHF(iRHF),
1090
                .iRTO(iRTO)
1091
            );
1092
 
1093
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.