--------------------------------------------------------------------------------------------------------------- -- 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; library CommonLib; use CommonLib.CommonPkg.all; entity SystemUART is port ( clk : in std_logic; enable : in std_logic; nReset : in std_logic; dIn : in std_logic_vector(15 downto 0); controlRegWEn : in std_logic; controlRegOut : out std_logic_vector(15 downto 0); dataRegWEn : in std_logic; dataRegREn : in std_logic; dataRegOut : out std_logic_vector(15 downto 0); baudRegWEn : in std_logic; baudRegOut : out std_logic_vector(15 downto 0); newDataIF : out std_logic; rxFifoFullIF : out std_logic; txFreeIF : out std_logic; serialTxOut : out std_logic; serialRxIn : in std_logic); end SystemUART; architecture General of SystemUART is signal sampleEn : std_logic; signal dataBits : SNAPTYPE_SYSUART_DATABITS; signal parity : SNAPTYPE_SYSUART_PARITY; signal stopBits : SNAPTYPE_SYSUART_STOPBITS; signal uartReset : std_logic; signal sendData : std_logic; signal txFree : std_logic; signal txBusy : std_logic; signal txData : std_logic_vector(9 downto 0); signal newData : std_logic; signal parityError : std_logic; signal rxData : std_logic_vector(9 downto 0); signal rxError : std_logic; signal baudReg : unsigned(9 downto 0); signal fifoNReset : std_logic; signal fifoDOut : std_logic_vector(9 downto 0); signal fifoFull : std_logic; signal fifoEmpty : std_logic; signal fifoFillLevel : std_logic_vector(1 downto 0); begin dataRegOut <= b"0000_00" & fifoDOut; -- Rx data comes from fifo txData <= dIn(9 downto 0); -- Tx data comes straight from data write txFree <= not txBusy; -- Tx if Free, when it's not busy sendData <= dataRegWEn and txFree; -- Only perform send if tx is free fifoNReset <= '0' when (nReset='0' or uartReset='1') else '1'; -- Fifo is reset on a programmatic UART reset or chip Reset baudRegOut <= b"0000_00" & std_logic_vector(baudReg); controlRegOut(15 downto 13) <= to_std_logic_vector(dataBits); -- Data Bits controlRegOut(12 downto 11) <= to_std_logic_vector(parity); -- Parity Bit controlRegOut(10) <= to_std_logic(stopBits); -- Stop Bit controlRegOut(9 downto 6) <= (others => '0'); -- controlRegOut(5 downto 4) <= fifoFillLevel; -- Fifo Fill Level controlRegOut(3) <= rxError; -- Rx Error controlRegOut(2) <= not fifoEmpty; -- Data Available controlRegOut(1) <= txFree; -- Tx Free controlRegOut(0) <= '0'; -- Reset -- Interrupts ------------------------------------------------------------------------------------------------- -- Create Interrupt Signals --------------------------------------------------------------------------------------------------------------- Interrupts : process(clk, fifoFull, txFree) variable full : std_logic; variable free : std_logic; begin if (clk'event and clk='1') then if (nReset='0' or uartReset='1') then full := '0'; free := '1'; elsif (enable='1') then full := fifoFull; free := txFree; end if; end if; rxFifoFullIF <= fifoFull and (not full); txFreeIF <= txFree and (not free); end process Interrupts; newDataIF <= newData; -- RegWriteControl ------------------------------------------------------------------------------------------- -- Controls writing to control register --------------------------------------------------------------------------------------------------------------- RegWriteControl : process(clk) begin if (clk'event and clk='1') then uartReset <= '0'; if (nReset='0') then dataBits <= SNAP_SYSUART_8DATABITS; parity <= SNAP_SYSUART_NO_PARITY; stopBits <= SNAP_SYSUART_1STOPBITS; rxError <= '0'; uartReset <= '0'; baudReg <= (others => '0'); elsif (enable='1') then -- Control Reg Write if (controlRegWEn = '1') then dataBits <= to_SNAPTYPE_SYSUART_DATABITS(dIn(15 downto 13)); parity <= to_SNAPTYPE_SYSUART_PARITY(dIn(12 downto 11)); stopBits <= to_SNAPTYPE_SYSUART_STOPBITS(dIn(10)); if (dIn(3)='1') then rxError <= '0'; end if; uartReset <= dIn(0); end if; if (parityError='1') then rxError <= '1'; end if; -- BaudReg Write if (baudRegWEn = '1') then baudReg <= unsigned(dIn(9 downto 0)); end if; end if; end if; end process RegWriteControl; -- SamplePulseGen --------------------------------------------------------------------------------------------- -- Generates the sample pulse divied to fit the required baud rate --------------------------------------------------------------------------------------------------------------- SampleGen : process(clk, enable) variable count : unsigned(9 downto 0); begin if (clk'event and clk='1') then if (nReset='0') then count := (others => '0'); elsif (enable='1') then if (count=b"00_0000_0000") then count := baudReg; else count := count - 1; end if; end if; end if; if (count=b"00_0000_0000") then sampleEn <= '1' and enable; else sampleEn <= '0'; end if; end process SampleGen; TxUnit : SystemUARTTx port map ( clk => clk, enable => enable, nReset => nReset, sampleEn => sampleEn, txReset => uartReset, dataBits => dataBits, parity => parity, stopBits => stopBits, sendData => sendData, txData => txData, txBusy => txBusy, serialTxOut => serialTxOut); RxUnit : SystemUARTRx port map ( clk => clk, enable => enable, nReset => nReset, sampleEn => sampleEn, rxReset => uartReset, dataBits => dataBits, parity => parity, newData => newData, parityError => parityError, rxData => rxData, serialRxIn => serialRxIn); RxFifo : Fifo generic map(dataWidth => 10) port map( clk => clk, enable => enable, nReset => fifoNReset, wEn => newData, -- WEn, newData in rxUnit rEn => dataRegREn, dIn => rxData, -- DIn, data from rxUnit dOut => fifoDOut, full => fifoFull, empty => fifoEmpty, fillLevel => fifoFillLevel); end General;