www.pudn.com > uart_v11.zip > rx.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:       Rx.tdf                                                                                 // 
//                                                                                                       // 
//  DESCRIPTION:  AHDL File for Asynchronous Receiver.    									             // 
//                                                                                                       // 
//  VERSION:      1.1                                                                                    // 
//                                                                                                       // 
/////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//                                                                                                       // 
//    ==========================                                                                         // 
//   | 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                                               // 
//                                                                                                       // 
//////////////////////////////////////////////////////////////////////////////////////////////////////////% 
 
TITLE "Asynchronous Receiver";  
 
 
%////////////////// 
// INCLUDE FILES // 
//////////////////% 
 
INCLUDE "lpm_dff.inc"; 
INCLUDE "lpm_mux.inc"; 
INCLUDE "lpm_bustri.inc"; 
INCLUDE "lpm_counter.inc"; 
INCLUDE "filterx.inc"; 
INCLUDE "clk_pdiv.inc"; 
INCLUDE "par_gen.inc"; 
 
 
%///////////////////////// 
// CONSTANT DEFINITIONS // 
/////////////////////////% 
 
% RX STATUS FLAGS % 
 
CONSTANT DataRx	  =	B"00001";		-- Data Received 
CONSTANT StartErr =	B"00010";		-- Invalid Start Bit 
CONSTANT ParErr	  =	B"00100";		-- Parity Error 
CONSTANT FrameErr =	B"01000";		-- Invalid Stop Bit 
CONSTANT OverRun  = B"10000";		-- OverRun Error 
 
 
%//////////////////////////// 
// USER-DEFINED PARAMETERS // 
////////////////////////////% 
 
PARAMETERS 
( 
 FILTER_DEPTH	-- Depth, (Number of Stages) in Digital Filters. 
); 
 
 
%///////////////////// 
// INPUTS & OUTPUTS // 
/////////////////////% 
 
SUBDESIGN Rx 
( 
 CLK, RESET, CfgReg[6..0], DIVISOR[16..0], RxSTART 	: INPUT;	-- Controller Interface 
 RxEND, RxReg[7..0], RxStatus[4..0]					: OUTPUT; 
 /CtrlRTS, /CtrlDTR									: INPUT; 
 /RxRTS, /RxDTR										: OUTPUT; 
 /RTS, /DTR											: OUTPUT; 
 
 Rx													: INPUT;	-- COM Port 
) 
 
 
%////////////////////////// 
// VARIABLE DECLARATIONS // 
//////////////////////////% 
 
VARIABLE 
 
% INTERNAL VARIABLES % 
 RxCLK2										: NODE;		-- Rx Baud Rate Clock x2 
 RxCLK,			RxCkc						: NODE;		-- Rx Baud Rate Clock,				CLEAR-Input 
 RxSR[7..0],	RxSRe, RxSRc				: NODE;		-- Rx Data Shift Register, 			ENA-Input, ACLR-Input 
 				RxRd[7..0],	RxRe			: NODE;		-- (Rx Data Register),				D-Inputs, ENA-Input 
 Rxf										: NODE;		-- Filtered Rx Input 
 RxCNT[3..0],	RxCNTe, RxCNTc				: NODE;		-- Receiver Bit Counter, 			ENA-Input, ACLR-Input 
 RxStatus[4..0],RxSTSd[4..0], RxSTSe 		: NODE;		-- Rx Status Register (Read Only), 	D-Inputs, ENA-Input 
 				RxRTSd,	RxRTSe				: NODE;		-- Rx Local RTS Handshake Signal,	D-Input, ENA-Input 
 RxPar										: NODE;		-- Rx Parity 
 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 
 RxFlag										: NODE;		-- Status Register Rx Data Received Flag 
 
% STATE MACHINES % 
 Rxss	: MACHINE WITH STATES (Rx0, Rx1, Rx2, Rx3, Rx4, Rx5, Rx6, Rx7, Rx8, Rx9, Rx10);	-- Receiver 
 
 
%////////////////// 
// LOGIC SECTION // 
//////////////////% 
 
BEGIN 
 
% DEFAULT VALUES % 
 DEFAULTS 
  RxEND=GND; 
  RxSTSe=GND; 
  RxSRe=GND; RxSRc=GND; 
  RxCNTe=GND; RxCNTc=GND; 
  RxRTSe=GND; 
  RxCkc=GND; 
  RxRe=GND; 
 END DEFAULTS; 
 
% IN-LINE ASSIGNMENTS % 
 RxREG[]		= LPM_DFF (RxRd[7..0], CLK, RxRe,,,,,, RESET,,)							-- Rx Data Register 
              	  WITH (LPM_WIDTH=8) 
              	  RETURNS (.q[]); 
 RxStatus[4..0]	= LPM_DFF (RxSTSd[4..0], CLK, RxSTSe,,,,,, RESET # RxSTART,,)			-- Rx Status Register 
              	  WITH (LPM_WIDTH=5) 
              	  RETURNS (.q[]); 
 RxSR[]			= LPM_DFF (0, CLK, RxSRe, Rxf, VCC,,,, RESET # RxSRc,,)					-- Rx Input Shift register 
              	  WITH (LPM_WIDTH=8) 
              	  RETURNS (.q[]); 
 RxCLK2			= Clk_PDiv (CLK, DIVISOR[],, RESET # RxCkc)								-- Rx Baud Clock x2 
              	  WITH (WIDTH=17) 
              	  RETURNS (.out); 
 RxCLK			= LPM_DFF (!RxCLK, RxCLK2,,,,,,, RESET # RxCkc,,)						-- Rx Baud Clock 
              	  WITH (LPM_WIDTH=1) 
              	  RETURNS (.q[]); 
 Rxf			= FILTERX (CLK, Rx,, RESET)												-- Filtered Rx Input Signal 
              	  WITH (WIDTH=1, DEPTH=FILTER_DEPTH) 
              	  RETURNS (.S_OUT[]); 
 RxCNT[]		= LPM_COUNTER (0, CLK, RxCNTe,,, RESET # RxCNTc,,,,,,,)					-- Rx Bit Counter 
              	  WITH (LPM_WIDTH=4) 
              	  RETURNS (.q[]); 
 RxPar			= Par_Gen (RxSR[7..0])													-- Rx Parity Generator 
              	  WITH (WIDTH=8) 
              	  RETURNS (.odd/even); 
 /RxRTS			= LPM_DFF (RxRTSd, CLK, RxRTSe,,,,,, RxSTART & HANDSHAKE, RESET,)		-- Rx Local RTS Handshake Signal 
              	  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]; 
 
 RxFlag=RxStatus[0];			-- Rx Data Received Flag 
 
 /RTS=/CtrlRTS;					-- /RTS, /DTR Outputs 
 /DTR=/CtrlDTR; 
 
 /RxDTR=/RxRTS; 
 
 Rxss.CLK	= CLK;				-- Rx State Machine Clock and Reset 
 Rxss.RESET	= RESET; 
 
% RECEIVER STATE MACHINE % 
 CASE Rxss IS 
 
  WHEN Rx0 => 
   RxCkc=VCC;						-- Clear Rx Clock 
   RxSRc=VCC;						-- Clear Rx Shift Register 
   RxCNTc=VCC;						-- Clear Rx Bit Counter 
   IF (!Rxf) THEN					-- Wait for First Bit 
    RxRTSe=HANDSHAKE; RxRTSd=RxFlag;-- Set Rx Local RTS Handshake Signal 
    Rxss=Rx1; 
   ELSE Rxss=Rx0; END IF; 
    
  WHEN Rx1 => 
   IF    (RxCLK & !Rxf) THEN Rxss=Rx3;						-- Check for Valid Start Bit 
   ELSIF (RxCLK & Rxf) THEN									-- Check for InValid Start Bit 
    RxSTSd[]=RxSTATUS[] # StartErr; RxSTSe=VCC; Rxss=Rx10;	-- Set Start Bit Error Flag 
   ELSE Rxss=Rx1; END IF; 
 
  WHEN Rx2 =>		-- Clock in Data Bit, Increment Rx Bit Counter 
   IF (RxCLK) THEN RxCNTe=VCC; RxSRe=VCC; Rxss=Rx3; 
   ELSE Rxss=Rx2; END IF; 
 
  WHEN Rx3 => 
   IF    (RxCNT[]==5 & DATABITS[]==0) THEN Rxss=Rx4;	-- Check If 5 Data Bits Received 
   ELSIF (RxCNT[]==6 & DATABITS[]==1) THEN Rxss=Rx4;	-- Check If 6 Data Bits Received 
   ELSIF (RxCNT[]==7 & DATABITS[]==2) THEN Rxss=Rx4;	-- Check If 7 Data Bits Received 
   ELSIF (RxCNT[]==8) THEN Rxss=Rx4;					-- Check If 8 Data Bits Received 
   ELSIF (!RxCLK) THEN Rxss=Rx2;						-- Wait for 1/2 Baud Rate Clock Cycle 
   ELSE Rxss=Rx3; END IF; 
 
  WHEN Rx4 => 
   IF (!RxCLK) THEN Rxss=Rx5;	-- Wait for 1/2 Baud Rate Clock Cycle 
   ELSE Rxss=Rx4; END IF; 
 
  WHEN Rx5 => 
   IF    (PARITY[]==0 # PARITY[]==3) THEN Rxss=Rx7;				-- Check for No Parity 
   ELSIF (RxCLK & PARITY[]==1 & (RxPar $ Rxf)) THEN Rxss=Rx6;	-- Check for Odd Parity 
   ELSIF (RxCLK & PARITY[]==2 & !(RxPar $ Rxf)) THEN Rxss=Rx6;	-- Check for Even Parity 
   ELSIF (RxCLK) THEN											-- Check for Invalid Parity 
    RxSTSd[]=RxSTATUS[] # ParErr; RxSTSe=VCC; Rxss=Rx10;		-- Set Parity Error Flag 
   ELSE Rxss=Rx5; END IF; 
 
  WHEN Rx6 => 
   IF (!RxCLK) THEN Rxss=Rx7;	-- Wait for 1/2 Baud Rate Clock Cycle 
   ELSE Rxss=Rx6; END IF; 
 
  WHEN Rx7 => 
   IF (RxCLK & Rxf & (STOPBITS[]==0 # STOPBITS[]==3)) THEN Rxss=Rx10;		-- Check for Stop Bit 1 
   ELSIF (RxCLK & Rxf & (STOPBITS[]==1 # STOPBITS[]==2)) THEN Rxss=Rx8;		-- Check if more than 1 Stop Bit 
   ELSIF (RxCLK & !Rxf) THEN												-- Check for Invalid Stop Bit 
    RxSTSd[]=RxSTATUS[] # FrameErr; RxSTSe=VCC; Rxss=Rx10;					-- Set Framing Error Flag 
   ELSE Rxss=Rx7; END IF; 
 
  WHEN Rx8 => 
   IF (!RxCLK & Rxf & STOPBITS[]==1) THEN Rxss=Rx10;		-- Check for Stop Bit 1.5 
   ELSIF (!RxCLK & Rxf & STOPBITS[]==2) THEN Rxss=Rx9;		-- Check if more than 1 Stop Bit 
   ELSIF (!RxCLK & !Rxf) THEN								-- Check for Invalid Stop Bit 
    RxSTSd[]=RxSTATUS[] # FrameErr; RxSTSe=VCC; Rxss=Rx10;	-- Set Framing Error Flag 
   ELSE Rxss=Rx8; END IF; 
 
  WHEN Rx9 => 
   IF (RxCLK & Rxf) THEN Rxss=Rx10;							-- Check for Stop Bit 2 
   ELSIF (RxCLK & !Rxf) THEN								-- Check for Invalid Stop Bit 
    RxSTSd[]=RxSTATUS[] # FrameErr; RxSTSe=VCC; Rxss=Rx10;	-- Set Framing Error Flag 
   ELSE Rxss=Rx9; END IF; 
 
  WHEN Rx10 =>  
   RxEND=VCC;														-- Set Rx End Flag 
   RxRe=VCC;														-- Load RxReg from Input Shift Register 
   RxSTSe=VCC;														-- Enable Rx Status Register 
   IF (RxFlag) THEN RxSTSd[]=RxSTATUS[] # DataRx # OverRun;			-- Set Data Received & Data Over Run Flags 
   ELSE RxSTSd[]=RxSTATUS[] # DataRx; END IF;						-- Set Data Received Flag 
   IF (DATABITS[]==0) THEN RxRd[4..0]=RxSR[0..4]; RxRd[7..5]=0;		-- Select Low 5 Data Bits 
   ELSIF (DATABITS[]==1) THEN RxRd[5..0]=RxSR[0..5]; RxRd[7..6]=0;	-- Select Low 6 Data Bits 
   ELSIF (DATABITS[]==2) THEN RxRd[6..0]=RxSR[0..6]; RxRd[7]=GND;	-- Select Low 7 Data Bits 
   ELSE RxRd[7..0]=RxSR[0..7];										-- Select Low 8 Data Bits 
   END IF; 
   Rxss=Rx0; 
 
 END CASE; 
 
END;