www.pudn.com > uart_v11.zip > uartctrl.tdf


%////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//                                                                                                       // 
//  PROJECT:      Programmable Universal Asynchronous Receiver/Transmitter.                              // 
//                Keith Willis                                                                           // 
//                Copyright © 1998. All Rights Reserved.                                                 // 
//                                                                                                       // 
//                You may use or distribute this module freely, provided you do not remove this          // 
//                copyright notice or modify the contents of this file.                                  // 
//                If you have questions or comments, feel free to contact me by email at                 // 
//                kcwillis@mech.eng.usyd.edu.au                                                          // 
//                                                                                                       // 
//  AUTHOR:       Keith Willis                                                                           // 
//                                                                                                       // 
//  MODULE:       UARTCTRL.tdf                                                                           // 
//                                                                                                       // 
//  DESCRIPTION:  AHDL File for UART Controller.                                                         // 
//                                                                                                       // 
//  VERSION:      1.1                                                                                    // 
//                                                                                                       // 
/////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//   ADDRESS MAP:   //                                                                                   // 
//////////////////////                                                                                   // 
//                                 ===========================================                           // 
//                                |  ADDRESS   |         REGISTER             |                          // 
//                                 ===========================================                           // 
//                                | $00 (READ) |  RECEIVED DATA REGISTER      |                          // 
//                                 -------------------------------------------                           // 
//                                | $00 (WRITE)|  TRANSMITTED DATA REGISTER   |                          // 
//                                 ===========================================                           // 
//                                | $01 (READ) |  STATUS REGISTER             |                          // 
//                                 -------------------------------------------                           // 
//                                | $01 (WRITE)|  CONFIGURATION REGISTER      |                          // 
//                                 ===========================================                           // 
//                                | $02 (WRITE)|  BAUD-RATE REGISTER          |                          // 
//                                 ===========================================                           // 
//                                | $03  (R/W) |  HANDSHAKING REGISTER        |                          // 
//                                 ===========================================                           // 
//                                                                                                       // 
//                                                                                                       // 
//                                                                                                       // 
/////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//   CPU INTEFACE:  //                                                                                   // 
//////////////////////                                                                                   // 
//                                                                                                       // 
//    Di[7..0]:  Input Data Bus. This bus may be used when embedding the UART                            // 
//               module into a larger EPLD design.                                                       // 
//                                                                                                       // 
//    Do[7..0]:  Multiplexed Output Data Bus. This bus may be used when embedding the UART               // 
//               module into a larger EPLD design.                                                       // 
//                                                                                                       // 
//    D7-D0:     8-bit Bidirectional Data Bus. This bus may also be used as the input data bus           // 
//               when embedding the UART module into a larger EPLD design.                               // 
//                                                                                                       // 
//    A1-A0:     2-bit Address Bus, decodes the internal UART registers.                                 // 
//                                                                                                       // 
//    CS:        Active-High Chip Select.                                                                // 
//                                                                                                       // 
//    RD:        Active-High Read.                                                                       // 
//                                                                                                       // 
//    WR:        Active-High Write.                                                                      // 
//                                                                                                       // 
//    RESET:     Active-High Reset.                                                                      // 
//                                                                                                       // 
//    CLK:       Master clock for UART, default=40MHz.                                                   // 
//                                                                                                       // 
//    INT:       Active High Interrupt = SENT OR RCVD.                                                   // 
//                                                                                                       // 
//    SENT:      Active-High Receiver Interrupt.                                                         // 
//                                                                                                       // 
//    RCVD:      Active-High Tranmitter Interrupt.                                                       // 
//                                                                                                       // 
//                                                                                                       // 
//                                                                                                       // 
////////////////////////////                                                                             // 
//  REGISTER BIT FIELDS:  //                                                                             // 
////////////////////////////                                                                             // 
//                                                                                                       // 
//    =================                                                                                  // 
//   | STATUS REGISTER |                                                                                 // 
//    ===============================================================================================    // 
//   |    0      |    0      |     OV     |    FE     |    PE     |    SE     |    DR     |    DT     |  // 
//    ===============================================================================================    // 
//                                                                                                       // 
//    DT:   DATA TRANSMITTED FLAG                                                                        // 
//    DR:   DATA RECEIVED FLAG                                                                           // 
//    SE:   START BIT ERROR FLAG                                                                         // 
//    PE:   PARITY ERROR FLAG                                                                            // 
//    FE:   FRAMING ERROR FLAG                                                                           // 
//    OV:   OVERUN ERROR FLAG                                                                            // 
//                                                                                                       // 
//                                                                                                       // 
//    DATA TRANSMITTED FLAG:  The data transmitted flag is set to 1 at the completion of a byte          // 
//                            transmission. It is automatically cleared to 0 when a new byte is          // 
//                            written to the Tx data register.                                           // 
//                                                                                                       // 
//    DATA RECEIVED FLAG:     The data received flag is set to 1 at the successful completion of a       // 
//                            byte receive cycle.  It is automatically cleared to 0 when the             // 
//                            Rx Data Register is read.  If a new byte is received before an             // 
//                            Rx Data Register read, the over run flag will be set to 1. If the (SR)     // 
//                            status option is set the UART will ignore all further incoming bytes       // 
//                            until the Rx Data Register has been read.                                  // 
//                                                                                                       // 
//    START BIT ERROR FLAG:   The start bit error flag is set to 1 if an invalid start bit is            // 
//                            encountered. It is automatically cleared to 0 when the Rx Data             // 
//                            Register is read.                                                          // 
//                                                                                                       // 
//    PARITY ERROR FLAG:      The parity error flag is set to 1 if an invalid parity bit is              // 
//                            encountered. It is automatically cleared to 0 when the Rx Data             // 
//                            Register is read.                                                          // 
//                                                                                                       // 
//    FRAMING ERROR FLAG:     The framing error flag is set to 1 if an invalid stop bit is               // 
//                            encountered. It is automatically cleared to 0 when the Rx Data             // 
//                            Register is read.                                                          // 
//                                                                                                       // 
//    OVERRUN ERROR FLAG:     The overrun error flag is set to 1 if a new byte is received before        // 
//                            the UART Rx Data Register has been read to clear the Rx Status flags from  // 
//                            the previous receive cycle.                                                // 
//                                                                                                       // 
//                                                                                                       // 
//                                                                                                       // 
//    ==========================                                                                         // 
//   | CONFIGURATION REGISTER 0 |                                                                        // 
//    ===============================================================================================    // 
//   | Reserved  |    HS     |    D1     |    D0     |    S1     |    S0     |    P1     |    P0     |   // 
//    ===============================================================================================    // 
//                                                                                                       // 
//    P1-P0:  PARITY TYPE           00 = NO PARITY (DEFAULT)                                             // 
//                                  01 = ODD PARITY                                                      // 
//                                  10 = EVEN PARITY                                                     // 
//                                  11 = NO PARITY                                                       // 
//                                                                                                       // 
//    S1-S0:  NUMBER OF STOP BITS   00 = 1 STOP BIT (DEFAULT)                                            // 
//                                  01 = 1.5 STOP BITS                                                   // 
//                                  10 = 2 STOP BITS                                                     // 
//                                  11 = 1 STOP BIT                                                      // 
//                                                                                                       // 
//    D1-D0:  NUMBER OF DATA BITS   00 = 5 DATA BITS                                                     // 
//                                  01 = 6 DATA BITS                                                     // 
//                                  10 = 7 DATA BITS                                                     // 
//                                  11 = 8 DATA BITS                                                     // 
//                                                                                                       // 
//    HS:   HANDSHAKING OPTION       0 = NO HANDSHAKING (CONTROLLED EXTERNALLY)                          // 
//                                   1 = LOCAL HANDSHAKING                                               // 
//                                                                                                       // 
//                                                                                                       // 
//    HANDSHAKING OPTION:     Handshaking using the /RTS, /CTS, /DTR, /DSR signals may be performed      // 
//                            locally by the UART if the handshaking option bit is set to 1. When the    // 
//                            receiver is ready to receive a byte /RTS and /DTR are held low.  After the // 
//                            first byte has been received, /RTS and /DTR remain low unless a new start  // 
//                            bit is detected, before the existing byte held in the Rx Data Register has // 
//                            been read.  If this is the case then /RTS and /DTR will be set high, and   // 
//                            the receiver will continue to receive the new incoming byte.  If the Rx    // 
//                            Data Register has not been read when the new byte has been received, then  // 
//                            the Data Overrun flag will be set, the Rx Data will be transferred to the  // 
//                            Rx Data Register, and the Rx Data Received Flag will be set.               // 
//                                                                                                       // 
//                            If the handshaking option bit is set to 0, these signals become            // 
//                            general-purpose I/O with /RTS and /DTR as outputs and /CTS and /DSR as     // 
//                            inputs.  It then becomes the responsibility of the host CPU to manage these// 
//                            signals.                                                                   // 
//                                                                                                       // 
//                                                                                                       // 
//                                                                                                       // 
//    ====================                                                                               // 
//   | BAUD-RATE REGISTER |                                                                              // 
//    ===============================================================================================    // 
//   |    B7     |    B6     |    B5     |    B4     |    B3     |    B2     |    B1     |    B0     |   // 
//    ===============================================================================================    // 
//    B7-B0:  BAUD RATE SELECTION  0000 = 1200                                                           // 
//                                 0001 = 2400                                                           // 
//                                 0010 = 4800                                                           // 
//                                 0011 = 9600                                                           // 
//                                 0100 = 14400                                                          // 
//                                 0101 = 19200                                                          // 
//                                 0110 = 28800                                                          // 
//                                 0111 = 38400                                                          // 
//                                 1000 = 57600                                                          // 
//                                 1001 = 115200                                                         // 
//                                >1001 = FCLK/(2*B[6..0] + 2)                                           // 
//                                                                                                       // 
//                                                                                                       // 
//    USER-DEFINED BAUD RATE SELECTION:   If a byte greater than H:09 is written to the baud rate        // 
//                                        selection register, this is used to directly calculate a user- // 
//                                        defined baud rate according to the following formula:          // 
//                                                                                                       // 
//                                        Fbaud = FCLK / (2 * B[6..0] + 2)                               // 
//                                        (Special Case) H:80 is invalid and will lock out the UART.     // 
//                                                                                                       // 
//                                                                                                       // 
//                                                                                                       // 
//    ======================                                                                             // 
//   | HANDSHAKING REGISTER |                                                                            // 
//    ===============================================================================================    // 
//(R)|     0     |     0     |     0     |     0     |     0     |     0     |    DSR    |    CTS    |   // 
//    -----------------------------------------------------------------------------------------------    // 
//(W)| Reserved  | Reserved  | Reserved  | Reserved  | Reserved  | Reserved  |    DTR    |    RTS    |   // 
//    ===============================================================================================    // 
//                                                                                                       // 
//                                                                                                       // 
//                                                                                                       // 
/////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//  FEATURES: //                                                                                         // 
////////////////                                                                                         // 
//                                                                                                       // 
//    - Master clock frequency(FCLK) is entered as a module parameter.                                   // 
//    - Maximum master clock frequency=50MHz for -2 grade parts.                                         // 
//    - Maximum Bit Rate=12.5MBits/s at FCLK=50MHz for -2 grade parts.                                   // 
//    - The UART may be used as an embedded module according to the "EMBEDDED" module parameter.         // 
//    - UART has separate Input & Output Data Buses for use as an embedded module in a larger design.    // 
//    - Digital Filter Depth (FILTER_DEPTH) is entered as a module parameter.                            // 
//    - Number of logic cells used approximately 385.                                                    // 
//    - All UART asynchronous inputs, (/CTS, /DSR, Rx) are digitally filtered by a 3-stage filter.       // 
//    - 5/6/7/8 Data Bits, 1/1.5/2 Stop Bits, N/O/E Parity.                                              // 
//    - Standard CPU interface.                                                                          // 
//    - Separate interrupt lines for Data Received and Data Transmitted.                                 // 
//    - A common interrupt line for all internal UART Data and Error events.                             // 
//    - 10 Standard Baud rates, from 1200 to 115200.                                                     // 
//    - 127 User Baud rates, from FCLK/4 to FCLK/256.                                                    // 
//    - Handshaking may be controlled internally by the UART or externally via the CPU.                  // 
//    - The UART handshaking signals, (/RTS, /CTS, /DTR, /DSR) are active low.                           // 
//    - 5 Error flags for Invalid Start Bit, Data OverRun, Framing Error, Parity Error, & OverRun Error. // 
//    - Transmitter enabled by new Data Write to TxReg.                                                  // 
//    - New data may be written to the TxReg during transmission.                                        // 
//    - Status Register Rx bits cleared on Rx Data Register Read.                                        // 
//    - Status Register Tx bits cleared on Tx Data Register Write.                                       // 
//    - Receiver and Transmitter Reset by Configuration Register or Baud-Rate Register Write.            // 
//    - Receiver synchronizes off the start bit.                                                         // 
//    - Receiver samples all incoming bits at the center of each bit.                                    // 
//                                                                                                       // 
//                                                                                                       // 
//   NOTE: Ignore the following compiler warnings:                                                       // 
//                                                                                                       // 
//         Group range RxSR[0..4] differs from declaration RxSR[7..0]                                    // 
//         Group range RxSR[0..5] differs from declaration RxSR[7..0]                                    // 
//         Group range RxSR[0..6] differs from declaration RxSR[7..0]                                    // 
//         Group range RxSR[0..7] differs from declaration RxSR[7..0]                                    // 
//                                                                                                       // 
//         Either aload or sload must be used together with the data[] port   	   			             // 
//         Either aload or sload must be used together with the data[] port   	   			             // 
//         Either aload or sload must be used together with the data[] port   	   			             // 
//                                                                                                       // 
//         Truncated result of division with non-zero remainder (50001200/2400).   			             // 
//         Truncated result of division with non-zero remainder (50002400/4800).   			             // 
//         Truncated result of division with non-zero remainder (50004800/9600).   			             // 
//         Truncated result of division with non-zero remainder (50009600/19200).  			             // 
//         Truncated result of division with non-zero remainder (50014400/28800).  			             // 
//         Truncated result of division with non-zero remainder (50019200/38400).  			             // 
//         Truncated result of division with non-zero remainder (50028800/57600).  			             // 
//         Truncated result of division with non-zero remainder (50038400/76800).  			             // 
//         Truncated result of division with non-zero remainder (50057600/115200). 			             // 
//         Truncated result of division with non-zero remainder (50115200/230400). 			             // 
//                                                                                                       // 
//         Symbolic name "Di7" was declared but never used                                               // 
//         Symbolic name "Di6" was declared but never used                                               // 
//         Symbolic name "Di5" was declared but never used                                               // 
//         Symbolic name "Di4" was declared but never used                                               // 
//         Symbolic name "Di3" was declared but never used                                               // 
//         Symbolic name "Di2" was declared but never used                                               // 
//         Symbolic name "Di1" was declared but never used                                               // 
//         Symbolic name "Di0" was declared but never used                                               // 
//                                                                                 			             // 
//         Warning: Flipflop '|uart:1|uart_ctrl:24|lpm_dff:249|dffs15' stuck at GND			             // 
//         Warning: Flipflop '|uart:1|uart_ctrl:24|lpm_dff:249|dffs16' stuck at GND			             // 
//                                                                                                       // 
//////////////////////////////////////////////////////////////////////////////////////////////////////////% 
 
TITLE "UART Controller";  
 
 
%////////////////// 
// INCLUDE FILES // 
//////////////////% 
 
INCLUDE "lpm_dff.inc"; 
INCLUDE "lpm_mux.inc"; 
INCLUDE "lpm_bustri.inc"; 
 
 
%//////////////////////////// 
// USER-DEFINED PARAMETERS // 
////////////////////////////% 
 
PARAMETERS 
( 
 FCLK,			-- Master Clock Frequency 
 EMBEDDED		-- Provide Separate Input and Output Data Buses for use as an embedded module 
); 
 
 
%///////////////////////// 
// CONSTANT DEFINITIONS // 
/////////////////////////% 
 
% DIVISOR VALUES % 
 
CONSTANT DIV1200   = (FCLK+1200)   DIV (2*1200)   - 1;		-- 1200 Baud 
CONSTANT DIV2400   = (FCLK+2400)   DIV (2*2400)   - 1;		-- 2400 Baud 
CONSTANT DIV4800   = (FCLK+4800)   DIV (2*4800)   - 1;		-- 4800 Baud 
CONSTANT DIV9600   = (FCLK+9600)   DIV (2*9600)   - 1;		-- 9600 Baud 
CONSTANT DIV14400  = (FCLK+14400)  DIV (2*14400)  - 1;		-- 14400 Baud 
CONSTANT DIV19200  = (FCLK+19200)  DIV (2*19200)  - 1;		-- 19200 Baud 
CONSTANT DIV28800  = (FCLK+28800)  DIV (2*28800)  - 1;		-- 28800 Baud 
CONSTANT DIV38400  = (FCLK+38400)  DIV (2*38400)  - 1;		-- 38400 Baud 
CONSTANT DIV57600  = (FCLK+57600)  DIV (2*57600)  - 1;		-- 57600 Baud 
CONSTANT DIV115200 = (FCLK+115200) DIV (2*115200) - 1;		-- 115200 Baud 
 
 
%///////////////////// 
// INPUTS & OUTPUTS // 
/////////////////////% 
 
SUBDESIGN UARTCTRL 
( 
 Di[7..0]										: INPUT;	-- Input Data Bus 
 Do[7..0]										: OUTPUT;	-- Multiplexed Output Data Bus 
 
 CLK, RESET, RD, WR, CS, A[1..0]				: INPUT;	-- CPU Interface 
 INT, RCVD, SENT								: OUTPUT; 
 D[7..0]										: BIDIR; 
 
 TxDIVISOR[16..0], TxCfgReg[6..0], TxReg[7..0]	: OUTPUT;	-- Tx Interface 
 TxSTATUS, TxEnd, CTSf, DSRf					: INPUT;	 
 TxStart, TxReset, TxCLK						: OUTPUT; 
 
 RxSTATUS[4..0], RxReg[7..0]					: INPUT;	-- Rx Interface 
 RxDIVISOR[16..0], RxCfgReg[6..0]				: OUTPUT; 
 RxEnd, /RxRTS, /RxDTR							: INPUT; 
 RxStart, RxReset, RxCLK, /RTS, /DTR			: OUTPUT; 
) 
 
 
%////////////////////////// 
// VARIABLE DECLARATIONS // 
//////////////////////////% 
 
VARIABLE 
 
% INTERNAL VARIABLES % 
 CfgReg[6..0]			: NODE;		-- UART Configuration Register 
 BaudReg[7..0]			: NODE;		-- UART Baud Rate Register (Write Only) 
 DIVISOR[16..0]			: NODE;		-- Baud-Rate Clock Divisor 
 DOMUX[7..0]			: NODE;		-- Output Data Bus Multiplexer 
 DMXDo[3..0][7..0]		: NODE;		-- Demultiplexed Output Data Bus 
 DIVd[16..0]			: NODE;		-- D-inputs to Divisor Register 
 RTSd, RTSe, RTSc, RTSp	: NODE;		-- /RTS Output, 		D-Input, ENA-Input, ACLR-Input, PRE-Input 
 DTRd, DTRe, DTRc, DTRp	: NODE;		-- /DTR Output, 		D-Input, ENA-Input, ACLR-Input, PRE-Input 
 HANDSHAKE				: NODE;		-- Handshaking Type 
 RxReset1				: NODE;		-- Programmable Rx Reset 
 TxReset1				: NODE;		-- Programmable Tx Reset 
 
% STATE MACHINES % 
 CFGss	: MACHINE WITH STATES (CFG0, CFG1, CFG2);					-- UART Configure 
 Ratess	: MACHINE WITH STATES (Rate0, Rate1, Rate2, Rate3);			-- Baud Rate Configure 
 RxRdss	: MACHINE WITH STATES (RxRd0, RxRd1, RxRd2);				-- Status Register Read 
 TxWrss	: MACHINE WITH STATES (TxWr0, TxWr1, TxWr2);				-- Tx Register Write 
 
 
%////////////////// 
// LOGIC SECTION // 
//////////////////% 
 
BEGIN 
 
% DEFAULT VALUES % 
 DEFAULTS 
  RxReset1=GND; 
  TxReset1=GND; 
 END DEFAULTS; 
 
% COMPILER MESSAGES % 
 ASSERT !(EMBEDDED=="YES") 
 REPORT "UART: Cannot use Bidirectional Data Bus in Embedded Mode" 
 SEVERITY WARNING; 
 
% IN-LINE ASSIGNMENTS % 
 IF (EMBEDDED!="YES") GENERATE 
  TxREG[]	= LPM_DFF (D[7..0], !WR, CS & !A0 & !A1 & !RD,,,,,, RESET,,)	-- Tx Data Register 
              WITH (LPM_WIDTH=8) 
              RETURNS (.q[]); 
  CfgReg[]	= LPM_DFF (D[6..0], !WR, CS & A0 & !A1 & !RD,,,,,, RESET,,)		-- UART Configuration Register 
              WITH (LPM_WIDTH=7) 
              RETURNS (.q[]); 
  BaudReg[]	= LPM_DFF (D[7..0], !WR, CS & !A0 & A1 & !RD,,,,,, RESET,,)		-- Baud-Rate Configuration Register 
              WITH (LPM_WIDTH=8) 
              RETURNS (.q[]); 
 ELSE GENERATE 
  TxREG[]	= LPM_DFF (Di[7..0], !WR, CS & !A0 & !A1 & !RD,,,,,, RESET,,)	-- Tx Data Register 
              WITH (LPM_WIDTH=8) 
              RETURNS (.q[]); 
  CfgReg[]	= LPM_DFF (Di[6..0], !WR, CS & A0 & !A1 & !RD,,,,,, RESET,,)	-- UART Configuration Register 
              WITH (LPM_WIDTH=7) 
              RETURNS (.q[]); 
  BaudReg[]	= LPM_DFF (Di[7..0], !WR, CS & !A0 & A1 & !RD,,,,,, RESET,,)	-- Baud-Rate Configuration Register 
              WITH (LPM_WIDTH=8) 
              RETURNS (.q[]); 
 END GENERATE; 
 DIVISOR[]	= LPM_DFF (DIVd[], CLK, Rate2,,,,,, RESET,,)					-- Baud-Rate Clock Divisor 
              WITH (LPM_WIDTH=17) 
              RETURNS (.q[]); 
 DOMUX[]	= LPM_MUX (DMXDo[3..0][7..0], A[1..0],,)						-- Output Data Bus Multiplexer 
              WITH (LPM_WIDTH=8, LPM_SIZE=4, LPM_WIDTHS=2) 
              RETURNS (.result[]); 
 IF (EMBEDDED!="YES") GENERATE 
  D[]		= LPM_BUSTRI (DOMUX[],, RD & CS & !WR)							-- Tri-State Data Bus 
              WITH (LPM_WIDTH=8) 
              RETURNS (.tridata[]); 
 END GENERATE; 
 /RTS		= LPM_DFF (RTSd, CLK, RTSe,,,,,, RTSc, RTSp,)					-- UART /RTS Handshaking Signal 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 /DTR		= LPM_DFF (DTRd, CLK, DTRe,,,,,, DTRc, DTRp,)					-- UART /DTR Handshaking Signal 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 RCVD		= LPM_DFF (RxEND, CLK,,,,,,, RESET,,)							-- Rx Interrupt 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 SENT		= LPM_DFF (TxEND, CLK,,,,,,, RESET,,)							-- Tx Interrupt 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 INT		= LPM_DFF (RxEND # TxEND, CLK,,,,,,, RESET,,)					-- Rx/Tx Common Interrupt 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 
% COMBINATORIAL LOGIC % 
 RxDIVISOR[]=DIVISOR[];	-- Common Rx/Tx Inputs 
 TxDIVISOR[]=DIVISOR[]; 
 RxCfgReg[]=CfgReg[]; 
 TxCfgReg[]=CfgReg[]; 
 RxCLK=CLK; 
 TxCLK=CLK; 
 
 HANDSHAKE=CfgReg[6]; 
 
 RTSd=/RxRTS;		-- F/F D-Input for RTS 
 RTSe=HANDSHAKE;	-- F/F ENA-Input for RTS 
 DTRd=/RxDTR;		-- F/F D-Input for DTR 
 DTRe=HANDSHAKE;	-- F/F ENA-Input for DTR 
   
 IF (EMBEDDED!="YES") GENERATE 
  RTSc=D[0] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE);							-- External CPU Asynchronous Load for RTS/DTR 
  RTSp=(!D[0] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE)) # CFG2 # Rate3 # RESET; 
  DTRc=D[1] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE); 
  DTRp=(!D[1] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE)) # CFG2 # Rate3 # RESET; 
 ELSE GENERATE 
  RTSc=Di[0] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE);							-- External CPU Asynchronous Load for RTS/DTR 
  RTSp=(!Di[0] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE)) # CFG2 # Rate3 # RESET; 
  DTRc=Di[1] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE); 
  DTRp=(!Di[1] & (CS & !RD & WR & A1 & A0 & !HANDSHAKE)) # CFG2 # Rate3 # RESET; 
 END GENERATE; 
 
 Do[]=DOMUX[];				-- Multiplexed Output Data Bus 
 
 DMXDo[0][]=RxREG[];		-- Demultiplexed Output Data Bus 
 DMXDo[1][0]=TxSTATUS; 
 DMXDo[1][5..1]=RxSTATUS[]; 
 DMXDo[1][7..6]=0; 
 DMXDo[2][]=0; 
 DMXDo[3][0]=CTSf; 
 DMXDo[3][1]=DSRf; 
 DMXDo[3][7..2]=0; 
 
 RxReset=RESET # RxReset1;	-- Rx Reset 
 TxReset=RESET # TxReset1;	-- Tx Reset 
 
% STATE MACHINES % 
 CFGss.CLK = CLK;			-- State Machine's Clock and Reset 
 CFGss.RESET= RESET; 
 Ratess.CLK = CLK; 
 Ratess.RESET= RESET; 
 RxRdss.CLK = CLK; 
 RxRdss.RESET= RESET; 
 TxWrss.CLK = CLK; 
 TxWrss.RESET= RESET; 
 
 
% UART CONFIGURATION STATE MACHINE % 
 CASE CFGss	IS 
 
  WHEN CFG0 =>		-- Wait for a Write to UART Configuration Register 
   IF (CS & A0 & !A1 & WR & !Rd) THEN CFGss=CFG1;  
   ELSE CFGss=CFG0; 
   END IF; 
 
  WHEN CFG1 =>		-- Wait until UART Configuration Register Write is completed, Reset Rx and Tx State Machines 
   IF !(CS & A0 & !A1 & WR & !Rd) THEN RxReset1=VCC; TxReset1=VCC; CFGss=CFG2;  
   ELSE CFGss=CFG1; 
   END IF; 
 
  WHEN CFG2 =>		-- Reset Baud clock counters, Reset RTS/DTR 
   CFGss=CFG0; 
 
 END CASE; 
 
 
% BAUD RATE CONFIGURATION STATE MACHINE % 
 CASE Ratess	IS 
 
  WHEN Rate0 =>		-- Wait for a Write to Baud Rate Configuration Register  
   IF (CS & !A0 & A1 & WR & !Rd) THEN Ratess=Rate1;  
   ELSE Ratess=Rate0; 
   END IF; 
 
  WHEN Rate1 =>		-- Wait until Baud Rate Configuration Register Write is completed 
   IF !(CS & !A0 & A1 & WR & !Rd) THEN Ratess=Rate2;  
   ELSE Ratess=Rate1; 
   END IF; 
 
  WHEN Rate2 =>		-- Write appropriate Divisor Value to DIVISOR Register, Reset Rx and Tx State Machines 
   RxReset1=VCC; TxReset1=VCC; 
   IF    (BaudReg[] == 0) THEN DIVd[]=DIV1200;    Ratess=Rate3;		-- Baud Rate = 1200 
   ELSIF (BaudReg[] == 1) THEN DIVd[]=DIV2400;    Ratess=Rate3;		-- Baud Rate = 2400 
   ELSIF (BaudReg[] == 2) THEN DIVd[]=DIV4800;    Ratess=Rate3;		-- Baud Rate = 4800 
   ELSIF (BaudReg[] == 3) THEN DIVd[]=DIV9600;    Ratess=Rate3;		-- Baud Rate = 9600 
   ELSIF (BaudReg[] == 4) THEN DIVd[]=DIV14400;   Ratess=Rate3;		-- Baud Rate = 14400 
   ELSIF (BaudReg[] == 5) THEN DIVd[]=DIV19200;   Ratess=Rate3;		-- Baud Rate = 19200 
   ELSIF (BaudReg[] == 6) THEN DIVd[]=DIV28800;   Ratess=Rate3;		-- Baud Rate = 28800 
   ELSIF (BaudReg[] == 7) THEN DIVd[]=DIV38400;   Ratess=Rate3;		-- Baud Rate = 38400 
   ELSIF (BaudReg[] == 8) THEN DIVd[]=DIV57600;   Ratess=Rate3;		-- Baud Rate = 57600 
   ELSIF (BaudReg[] == 9) THEN DIVd[]=DIV115200;  Ratess=Rate3;		-- Baud Rate = 115200 
   ELSE DIVd[16..7]=0; DIVd[6..0]=BaudReg[6..0];  Ratess=Rate3;		-- Baud Rate = FCLK/(2*BaudReg[6..0] + 2) 
   END IF; 
 
  WHEN Rate3 =>		-- Reset Baud clock counters, Reset RTS/DTR 
   Ratess=Rate0; 
 
 END CASE; 
 
 
% Rx DATA REGISTER READ STATE MACHINE % 
 CASE RxRdss	IS 
 
  WHEN RxRd0 =>		-- Wait for a Read from the Rx Data Register 
   IF (CS & !A0 & !A1 & Rd & !WR) THEN RxRdss=RxRd1;  
   ELSE RxRdss=RxRd0; 
   END IF; 
 
  WHEN RxRd1 =>		-- Wait until Rx Data Register Read is completed 
   IF !(CS & !A0 & !A1 & Rd & !WR) THEN RxRdss=RxRd2;  
   ELSE RxRdss=RxRd1; 
   END IF; 
 
  WHEN RxRd2 =>		-- Clear Rx Status Register 
   RxStart=VCC; 
   RxRdss=RxRd0;  
 
 END CASE; 
 
 
% Tx DATA REGISTER WRITE STATE MACHINE % 
 CASE TxWrss	IS 
 
  WHEN TxWr0 =>		-- Wait for a Write to the Tx Data Register 
   IF (CS & !A0 & !A1 & !Rd & WR) THEN TxWrss=TxWr1;  
   ELSE TxWrss=TxWr0; 
   END IF; 
 
  WHEN TxWr1 =>		-- Wait until Tx Data Register Write is completed 
   IF !(CS & !A0 & !A1 & !Rd & WR) THEN TxWrss=TxWr2;  
   ELSE TxWrss=TxWr1; 
   END IF; 
 
  WHEN TxWr2 =>		-- Enable Tx 
   TxStart=VCC; 
   TxWrss=TxWr0; 
 
 END CASE; 
 
END;