--------------------------------------------------------------------------------------------------------------- -- 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 SystemUARTTx is port ( clk : in std_logic; enable : in std_logic; nReset : in std_logic; sampleEn : in std_logic; txReset : in std_logic; dataBits : in SNAPTYPE_SYSUART_DATABITS; parity : in SNAPTYPE_SYSUART_PARITY; stopBits : in SNAPTYPE_SYSUART_STOPBITS; sendData : in std_logic; txData : in std_logic_vector(9 downto 0); txBusy : out std_logic; serialTxOut : out std_logic); end SystemUARTTx; architecture General of SystemUARTTx is type TX_STATES is (IDLE, TX_WAIT, TX_START_BIT, TX_DATA, TX_PARITY, TX_STOP_BIT1, TX_STOP_BIT2); signal state : TX_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; signal busy : std_logic; begin txBusy <= busy; -- 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 txReset='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, dataReg, parityBit) begin case state is when IDLE => serialTxOut <= '1'; runCounter <= '0'; when TX_WAIT => serialTxOut <= '1'; runCounter <= '0'; when TX_START_BIT => serialTxOut <= '0'; runCounter <= '1'; when TX_DATA => serialTxOut <= dataReg(0); runCounter <= '1'; when TX_PARITY => serialTxOut <= parityBit; runCounter <= '1'; when TX_STOP_BIT1 => serialTxOut <= '1'; runCounter <= '1'; when TX_STOP_BIT2 => serialTxOut <= '1'; runCounter <= '1'; end case; end process StateDecode; -- StateMachine ----------------------------------------------------------------------------------------------- -- State machine controlling the receiving process --------------------------------------------------------------------------------------------------------------- StateMachine: process (clk) begin if (clk'event and clk = '1') then if (nReset='0') then parityBit <= '0'; bitCount <= (others => '0'); dataReg <= (others => '0'); busy <= '0'; state <= IDLE; elsif (enable='1') then if (txReset='1') then parityBit <= '0'; bitCount <= (others => '0'); dataReg <= (others => '0'); busy <= '0'; state <= IDLE; 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; if (sendData='1') then dataReg <= txData; busy <= '1'; if (sampleEn='1') then state <= TX_START_BIT; else state <= TX_WAIT; end if; else busy <= '0'; end if; when TX_WAIT => if (sampleEn='1') then state <= TX_START_BIT; end if; when TX_START_BIT => if (nextBit='1') then state <= TX_DATA; end if; when TX_DATA => if (nextBit='1') then parityBit <= parityBit xor dataReg(0); dataReg <= '1' & dataReg(9 downto 1); bitCount <= bitCount - 1; if (bitCount="0000") then case parity is when SNAP_SYSUART_ODD_PARITY => state <= TX_PARITY; when SNAP_SYSUART_EVEN_PARITY => state <= TX_PARITY; when SNAP_SYSUART_NO_PARITY => state <= TX_STOP_BIT1; end case; end if; end if; when TX_PARITY => if (nextBit='1') then state <= TX_STOP_BIT1; end if; when TX_STOP_BIT1 => if (nextBit='1') then case stopBits is when SNAP_SYSUART_1STOPBITS => state <= IDLE; when SNAP_SYSUART_2STOPBITS => state <= TX_STOP_BIT2; end case; end if; when TX_STOP_BIT2 => if (nextBit='1') then state <= IDLE; end if; end case; end if; end if; end if; end process StateMachine; end General;