📄 rx.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 + -