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;