⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rx.tdf

📁 《FPGA嵌入式应用系统开发典型实例》-书的光盘资料
💻 TDF
字号:
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;
 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;
  RxCkc=GND;
  RxRe=GND;
 END DEFAULTS;

% IN-LINE ASSIGNMENTS %
 RxREG[]		= LPM_DFF (.Data[] = RxRd[7..0], .Clock = CLK, .Enable = RxRe, .Aclr = RESET)						-- Rx Data Register
              	  WITH (LPM_WIDTH=8)
              	  RETURNS (.q[]);
 RxStatus[4..0]	= LPM_DFF (.Data[] = RxSTSd[4..0], .Clock = CLK, .Enable = RxSTSe, .Aclr = RESET # RxSTART)			-- Rx Status Register
              	  WITH (LPM_WIDTH=5)
              	  RETURNS (.q[]);
 RxSR[]			= LPM_DFF (.Data[] = 0, .Clock = CLK, .Enable = RxSRe, .Shiftin = Rxf, .Shiften = VCC, .Aclr = RESET # RxSRc)					-- Rx Input Shift register
              	  WITH (LPM_WIDTH=8)
              	  RETURNS (.q[]);
 RxCLK2			= Clk_PDiv (.Clk = CLK, .D[] = DIVISOR[], .Reset = RESET # RxCkc)									-- Rx Baud Clock x2
              	  WITH (WIDTH=17)
              	  RETURNS (.out);
 RxCLK			= LPM_DFF (.Data[] = !RxCLK, .Clock = RxCLK2, .Aclr = 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 (.Clock = CLK, .Clk_en = RxCNTe, .Aclr = 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);

% 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

 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
    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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -