--------------------------------------------------------------------------------------------------------------- -- RISA Project -- Author: A.Greensted -- Module: -- Description: -- History: --------------------------------------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library SnapLib; use SnapLib.SnapPkg.all; entity SystemUARTRx is port ( clk : in std_logic; enable : in std_logic; nReset : in std_logic; sampleEn : in std_logic; rxReset : in std_logic; dataBits : in SNAPTYPE_SYSUART_DATABITS; parity : in SNAPTYPE_SYSUART_PARITY; newData : out std_logic; parityError : out std_logic; rxData : out std_logic_vector(9 downto 0); serialRxIn : in std_logic); end SystemUARTRx; architecture General of SystemUARTRx is signal decoderReg : std_logic_vector(0 to 6); signal bitValue : std_logic; signal validStartBit : std_logic; type RX_STATES is (IDLE, RX_WAIT, RX_DATA, RX_PARITY, RX_STOP_BIT); signal state : RX_STATES; signal parityBit : std_logic; signal bitCount : unsigned(3 downto 0); signal dataReg : std_logic_vector(9 downto 0); signal runCounter : std_logic; signal delayCount : unsigned(2 downto 0); signal nextBit : std_logic; begin rxData <= dataReg; -- Decoder ---------------------------------------------------------------------------------------------------- -- High rate data sampling, detects start bit and performs vote in each data bit --------------------------------------------------------------------------------------------------------------- Decoder : process(clk) begin if (clk'event and clk='1') then if (nReset='0') then decoderReg <= (others => '1'); elsif (enable='1') then if (rxReset='1') then decoderReg <= (others => '1'); elsif (sampleEn='1') then decoderReg <= decoderReg(1 to 6) & serialRxIn; end if; end if; end if; end process; bitValue <= (decoderReg(4) and decoderReg(5)) or (decoderReg(5) and decoderReg(6)) or (decoderReg(4) and decoderReg(6)); validStartBit <= decoderReg(0) and not (decoderReg(1)) and (not bitValue); -- DelayCounter ----------------------------------------------------------------------------------------------- -- Times the delay between packet bits (8 sampleEn pulses) --------------------------------------------------------------------------------------------------------------- DelayCounter : process (clk) begin if (clk'event and clk = '1') then if (nReset='0') then delayCount <= b"000"; elsif (enable='1') then if (runCounter = '0' or rxReset='1') then delayCount <= b"000"; elsif (sampleEn = '1') then delayCount <= delayCount + 1; end if; end if; end if; end process DelayCounter; nextBit <= '1' when (delayCount=b"111" and sampleEn='1' and runCounter='1') else '0'; -- StateDecode ------------------------------------------------------------------------------------------------ -- Generates various signals that are derived from the state machine's state --------------------------------------------------------------------------------------------------------------- StateDecode : process(state) begin case state is when IDLE => runCounter <= '0'; when RX_WAIT => runCounter <= '0'; when RX_DATA => runCounter <= '1'; when RX_PARITY => runCounter <= '1'; when RX_STOP_BIT => runCounter <= '1'; end case; end process StateDecode; -- StateMachine ----------------------------------------------------------------------------------------------- -- State machine controlling the receiving process --------------------------------------------------------------------------------------------------------------- StateMachine: process (clk) variable newData_var : std_logic; variable parityError_var : std_logic; begin if (clk'event and clk = '1') then if (nReset='0') then parityBit <= '0'; bitCount <= (others => '0'); dataReg <= (others => '0'); state <= IDLE; parityError_var := '0'; newData_var := '0'; elsif (enable='1') then if (rxReset = '1') then parityBit <= '0'; bitCount <= (others => '0'); dataReg <= (others => '0'); state <= IDLE; parityError_var := '0'; newData_var := '0'; else case state is when IDLE => case parity is when SNAP_SYSUART_EVEN_PARITY => parityBit <= '0'; when SNAP_SYSUART_ODD_PARITY => parityBit <= '1'; when SNAP_SYSUART_NO_PARITY => parityBit <= '0'; end case; case dataBits is when SNAP_SYSUART_5DATABITS => bitCount <= "0100"; when SNAP_SYSUART_6DATABITS => bitCount <= "0101"; when SNAP_SYSUART_7DATABITS => bitCount <= "0110"; when SNAP_SYSUART_8DATABITS => bitCount <= "0111"; when SNAP_SYSUART_9DATABITS => bitCount <= "1000"; when SNAP_SYSUART_10DATABITS => bitCount <= "1001"; end case; parityError_var := '0'; newData_var := '0'; if (validStartBit='1') then if (sampleEn='1') then state <= RX_DATA; else state <= RX_WAIT; end if; end if; when RX_WAIT => if (sampleEn='1') then state <= RX_DATA; end if; when RX_DATA => if (nextBit='1') then case dataBits is when SNAP_SYSUART_5DATABITS => dataReg(9 downto 5) <= (others => '0'); dataReg(4) <= bitValue; dataReg(3) <= dataReg(4); when SNAP_SYSUART_6DATABITS => dataReg(9 downto 6) <= (others => '0'); dataReg(5) <= bitValue; dataReg(4 downto 3) <= dataReg(5 downto 4); when SNAP_SYSUART_7DATABITS => dataReg(9 downto 7) <= (others => '0'); dataReg(6) <= bitValue; dataReg(5 downto 3) <= dataReg(6 downto 4); when SNAP_SYSUART_8DATABITS => dataReg(9 downto 8) <= (others => '0'); dataReg(7) <= bitValue; dataReg(6 downto 3) <= dataReg(7 downto 4); when SNAP_SYSUART_9DATABITS => dataReg(9) <= '0'; dataReg(8) <= bitValue; dataReg(7 downto 3) <= dataReg(8 downto 4); when SNAP_SYSUART_10DATABITS => dataReg(9) <= bitValue; dataReg(8 downto 3) <= dataReg(9 downto 4); end case; dataReg(2 downto 0) <= dataReg(3 downto 1); parityBit <= parityBit xor bitValue; bitCount <= bitCount - 1; if (bitCount="0000") then case parity is when SNAP_SYSUART_ODD_PARITY => state <= RX_PARITY; when SNAP_SYSUART_EVEN_PARITY => state <= RX_PARITY; when SNAP_SYSUART_NO_PARITY => state <= RX_STOP_BIT; end case; end if; end if; when RX_PARITY => if (nextBit='1') then if (bitValue /= parityBit) then -- Check for parity error parityError_var := '1'; end if; state <= RX_STOP_BIT; end if; when RX_STOP_BIT => if (nextBit='1') then if (bitValue = '1') then -- Check for valid stop bit newData_var := '1'; end if; state <= IDLE; end if; end case; end if; end if; end if; parityError <= parityError_var; newData <= newData_var; end process StateMachine; end General;