www.pudn.com > uart_v11.zip > tx.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:       Tx.tdf                                                                                 // 
//                                                                                                       // 
//  DESCRIPTION:  AHDL File for Asynchronous Transmitter.                                                // 
//                                                                                                       // 
//  VERSION:      1.1                                                                                    // 
/////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//                                                                                                       // 
//    ========================                                                                           // 
//   | CONFIGURATION REGISTER |                                                                          // 
//    ===============================================================================================    // 
//   | 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                                               // 
//                                                                                                       // 
//////////////////////////////////////////////////////////////////////////////////////////////////////////% 
 
TITLE "Asynchronous Transmitter";  
 
 
%////////////////// 
// INCLUDE FILES // 
//////////////////% 
 
INCLUDE "lpm_dff.inc"; 
INCLUDE "lpm_mux.inc"; 
INCLUDE "lpm_counter.inc"; 
INCLUDE "clk_pdiv.inc"; 
INCLUDE "filterx.inc"; 
INCLUDE "par_gen.inc"; 
INCLUDE "shiftreg.inc"; 
 
 
%//////////////////////////// 
// USER-DEFINED PARAMETERS // 
////////////////////////////% 
 
PARAMETERS 
( 
 FILTER_DEPTH	-- Depth, (Number of Stages) in Digital Filters. 
); 
 
 
%///////////////////// 
// INPUTS & OUTPUTS // 
/////////////////////% 
 
SUBDESIGN TX 
( 
 CLK, RESET, CfgReg[6..0], TxReg[7..0], DIVISOR[16..0], TxSTART	: INPUT;	-- Controller Interface 
 TxEND, TxSTATUS												: OUTPUT; 
 
 /CTS, /DSR														: INPUT;	-- /CTS & /DSR Inputs 
 CTSf, DSRf														: OUTPUT;	-- Inverted Filtered /CTS & /DSR Inputs 
 Tx																: OUTPUT; 
) 
 
 
%////////////////////////// 
// VARIABLE DECLARATIONS // 
//////////////////////////% 
 
VARIABLE 
 
% INTERNAL VARIABLES % 
 TxCLK2										: NODE;		-- Tx Baud Rate Clock x2 
 TxCLK,			TxCkc						: NODE;		-- Tx Baud Rate Clock,			CLEAR-Input 
 TxSR,			TxSRd[7..0], TxSRe, TxSRl	: NODE;		-- Tx Data Shift Register, 		D-Inputs, ENA-Input, LOAD-Input 
				Txd							: NODE;		-- (Tx Output Flip-Flop), 		D-Input 
 				MPLXi[3..0], MPLXs[1..0]	: NODE;		-- (Tx Output Multiplexer), 	DATA-Inputs, SEL-Inputs 
 TxCNT[4..0],	TxCNTe, TxCNTc				: NODE;		-- Transmitter Bit Counter, 	ENA-Input, ACLR-Input 
 TxPar,			TxPard[7..0]				: NODE;		-- Tx Parity,					DATA-Input 
 TxENA										: NODE;		-- Tx Enable Signal 
 PARITY[1..0]								: NODE;		-- Parity Type 
 DATABITS[1..0]								: NODE;		-- Number of Data Bits 
 STOPBITS[1..0] 							: NODE;		-- Number of Stop Bits 
 HANDSHAKE									: NODE;		-- Handshaking Type 
 
% STATE MACHINES % 
 Txss	: MACHINE WITH STATES (Tx0, Tx1, Tx2, Tx3, Tx4, Tx5, Tx6, Tx7, Tx8);	-- Transmitter 
 
 
%////////////////// 
// LOGIC SECTION // 
//////////////////% 
 
BEGIN 
 
% DEFAULT VALUES % 
 DEFAULTS 
  TxCkc=GND; 
  TxSRe=GND; TxSRl=GND; 
  TxCNTe=GND; TxCNTc=GND; 
  TxEND=GND; 
 END DEFAULTS; 
 
% IN-LINE ASSIGNMENTS % 
 TxCLK2		= Clk_PDiv (CLK, DIVISOR[],, RESET # TxCkc)					-- Tx Baud Clock x2 
              WITH (WIDTH=17) 
              RETURNS (.out); 
 TxCLK		= LPM_DFF (!TxCLK, TxCLK2,,,,,,, RESET # TxCkc,,)			-- Tx Baud Clock 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 Tx			= LPM_DFF (Txd, TxCLK,,,,,,,, RESET # Tx0,)					-- Tx Output Flip-Flop 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 CTSf		= FILTERX (CLK, /CTS, RESET,)								-- Inverted Filtered /CTS Input 
              WITH (WIDTH=1, DEPTH=FILTER_DEPTH) 
              RETURNS (./S_OUT[]); 
 DSRf		= FILTERX (CLK, /DSR, RESET,)								-- Inverted Filtered /DSR Input 
              WITH (WIDTH=1, DEPTH=FILTER_DEPTH) 
              RETURNS (./S_OUT[]); 
 TxSR		= ShiftReg (TxCLK, TxSRd[], RESET, TxSRl, TxSRe, GND)		-- Tx Output Shift Register 
              WITH (WIDTH=8, MSB_FIRST="NO", SHIFT_MODE="ON") 
              RETURNS (.dout); 
 Txd		= LPM_MUX (MPLXi[3..0], MPLXs[1..0],,)						-- Tx Output Multiplexer 
              WITH (LPM_WIDTH=1, LPM_SIZE=4, LPM_WIDTHS=2) 
              RETURNS (.result[]); 
 TxCNT[]	= LPM_COUNTER (0, TxCLK2,, TxCNTe,, RESET # TxCNTc,,,,,,,)	-- Tx Bit Counter 
              WITH (LPM_WIDTH=5, LPM_DIRECTION="UP") 
              RETURNS (.q[]); 
 TxPar		= Par_Gen (TxPard[7..0])									-- Tx Parity Generator 
              WITH (WIDTH=8) 
              RETURNS (.odd/even); 
 TxENA		= LPM_DFF (VCC, CLK, GND,,,,,, RESET # Tx1, TxStart,)			-- Tx Enable Signal 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 TxSTATUS	= LPM_DFF (VCC, CLK, TxEND,,,,,, RESET # TxStart,,)			-- Tx Data Transmitted Flag 
              WITH (LPM_WIDTH=1) 
              RETURNS (.q[]); 
 
% COMBINATORIAL LOGIC % 
 PARITY[]=CfgReg[1..0];			-- UART Control Bits 
 STOPBITS[]=CfgReg[3..2]; 
 DATABITS[]=CfgReg[5..4]; 
 HANDSHAKE=CfgReg[6]; 
 
 IF (DATABITS[]==0) THEN TxPard[7..5]=0; TxPard[4..0]=TxReg[4..0]; END IF;	-- Ignore High Bits in Parity Generator 
 IF (DATABITS[]==1) THEN TxPard[7..6]=0; TxPard[5..0]=TxReg[5..0]; END IF; 
 IF (DATABITS[]==2) THEN TxPard[7]=GND;  TxPard[6..0]=TxReg[6..0]; END IF; 
 IF (DATABITS[]==3) THEN                 TxPard[7..0]=TxReg[7..0]; END IF; 
 
 MPLXi[0]=VCC;			-- Assign Multilexer Inputs 
 MPLXi[1]=GND; 
 MPLXi[2]=PARITY[1] !$ TxPar; 
 MPLXi[3]=TxSR; 
 
 Txss.CLK	= CLK;		-- Tx State Machine Clock and Reset 
 Txss.RESET	= RESET; 
 
% TRANSMITTER STATE MACHINE % 
 CASE Txss IS 
 
  WHEN Tx0 => 
   MPLXs[]=0;													-- Select VCC 
   TxCkc=VCC;													-- Clear Tx Clock 
   TxCNTc=VCC;													-- Clear Tx Bit Counter 
   TxSRl=VCC;													-- Enable Load of Tx Shift Register 
   TxSRd[7..0]=TxReg[7..0];										-- Setup Data Load for Tx Shift Register 
   IF (TxENA & ((HANDSHAKE & CTSf & DSRf) # !HANDSHAKE)) THEN	-- Wait until New Tx Data and CTS/DSR 
    Txss=Tx1; 
   ELSE Txss=Tx0; END IF; 
 
  WHEN Tx1 =>	-- Clear Tx Enable Signal 
   Txss=Tx2; 
 
  WHEN Tx2 => 
   MPLXs[]=1;						-- Select GND 
   TxCNTe=VCC;						-- Enable Tx Bit Counter 
   IF (TxCNT[]==2) THEN Txss=Tx3;	-- Wait until Start Bit shifted out 
   ELSE Txss=Tx2; END IF; 
 
  WHEN Tx3 => 
   MPLXs[]=3;											-- Select Data 
   TxSRe=VCC;											-- Shift out Data 
   TxCNTe=VCC;											-- Enable Tx Bit Counter 
   IF ((DATABITS[]==0 & TxCNT[]==12) 
     # (DATABITS[]==1 & TxCNT[]==14) 
     # (DATABITS[]==2 & TxCNT[]==16) 
     # (DATABITS[]==3 & TxCNT[]==18)) THEN Txss=Tx4;	-- Wait until all Data Bits Shifted out 
   ELSE Txss=Tx3; END IF; 
 
  WHEN Tx4 => 
   TxCNTc=VCC;										-- Clear Tx Bit Counter 
   IF (PARITY[]==0 # PARITY[]==3) THEN Txss=Tx7;	-- Check if Parity Enabled 
   ELSE Txss=Tx5; END IF; 
 
  WHEN Tx5 => 
   MPLXs[]=2;						-- Select TxPar 
   TxCNTe=VCC;						-- Enable Tx Bit Counter 
   IF (TxCNT[]==2) THEN Txss=Tx6;	-- Wait until Parity Bit Shifted out 
   ELSE Txss=Tx5; END IF; 
 
  WHEN Tx6 => 
   TxCNTc=VCC;		-- Clear Tx Bit Counter 
   Txss=Tx7; 
 
  WHEN Tx7 => 
   MPLXs[]=0;														-- Select VCC 
   TxCNTe=VCC;														-- Enable Tx Bit Counter 
   IF ((STOPBITS[]==0 # STOPBITS[]==3) & TxCNT[]==2) THEN Txss=Tx8;	-- Wait until Stop Bit 1 Shifted out 
   ELSIF (STOPBITS[]==1 & TxCNT[]==3) THEN Txss=Tx8;				-- Wait until Stop Bit 1.5 Shifted out 
   ELSIF (STOPBITS[]==2 & TxCNT[]==4) THEN Txss=Tx8;				-- Wait until Stop Bit 2 Shifted out 
   ELSE Txss=Tx7; END IF; 
 
  WHEN Tx8 => 
   TxCkc=VCC;		-- Clear Tx Clock 
   TxEND=VCC;		-- Set Tx End Flag 
   Txss=Tx0; 
 
 END CASE; 
 
END;