--------------------------------------------------------------------------------------------------------------- -- RISA Project -- Author: A.Greensted -- Module: -- Description: -- History: --------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------- -- RISA Project -- Author: A.Greensted -- Module: SnapLink -- Description: -- History: 1.0 (27th April 2006) --------------------------------------------------------------------------------------------------------------- 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 SnapLink 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); newDataIF : out std_logic; rxFifoFullIF : out std_logic; txFreeIF : out std_logic; linkTxOut : out std_logic; -- Serial data out linkRxIn : in std_logic; -- Serial data in linkCTSOut : out std_logic; -- Outgoing clear to send (CTS) linkCTSIn : in std_logic); -- Incoming CTS (can transmit) end SnapLink; architecture General of SnapLink is signal sampleEn : std_logic; signal dataBits : SNAPTYPE_SNAPLINK_DATABITS; signal linkReset : std_logic; signal sendData : std_logic; signal txFree : std_logic; signal txBusy : std_logic; signal txUpperBits : std_logic_vector(1 downto 0); signal txData : std_logic_vector(17 downto 0); signal newData : std_logic; signal parityError : std_logic; signal rxData : std_logic_vector(17 downto 0); signal rxError : std_logic; signal baudReg : unsigned(3 downto 0); signal fifoNReset : std_logic; signal fifoDOut : std_logic_vector(17 downto 0); signal fifoFull : std_logic; signal fifoEmpty : std_logic; signal fifoFillLevel : std_logic_vector(1 downto 0); begin dataRegOut <= fifoDOut(15 downto 0); -- Rx data comes from fifo txData <= txUpperBits & dIn; -- Tx data comes straight from data write txFree <= not txBusy and linkCTSIn; -- Tx if Free, when it's not busy, and it's clear to send sendData <= dataRegWEn and txFree; -- Only perform send if tx is free fifoNReset <= '0' when (nReset='0' or linkReset='1') else '1'; -- Fifo is reset on a programmatic link reset or chip Reset controlRegOut(15 downto 14) <= to_std_logic_vector(dataBits); -- Data Bits controlRegOut(13 downto 10) <= std_logic_vector(baudReg); -- Baud Setting controlRegOut(9 downto 8) <= txUpperBits; -- Tx Upper Bits controlRegOut(7 downto 6) <= fifoDout(17 downto 16); -- Rx Upper Bits 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 -- CTSControl ------------------------------------------------------------------------------------------------- -- Generate the Clear To Send output, dependant on RX FIFO fill level --------------------------------------------------------------------------------------------------------------- CTSControl : process(fifoFillLevel) begin case fifoFillLevel is when b"11" => linkCTSOut <= '0'; when b"10" => linkCTSOut <= '0'; when others => linkCTSOut <= '1'; end case; end process; -- 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 linkReset='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 linkReset <= '0'; if (nReset='0') then dataBits <= SNAP_SNAPLINK_16DATABITS; baudReg <= (others => '0'); txUpperBits <= (others => '0'); rxError <= '0'; linkReset <= '0'; elsif (enable='1') then -- Control Reg Write if (controlRegWEn='1') then dataBits <= to_SNAPTYPE_SNAPLINK_DATABITS(dIn(15 downto 14)); baudReg <= unsigned(dIn(13 downto 10)); txUpperBits <= dIn(9 downto 8); if (dIn(3)='1') then rxError <= '0'; end if; linkReset <= dIn(0); end if; if (parityError='1') then rxError <= '1'; 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(3 downto 0); begin if (clk'event and clk='1') then if (nReset='0') then count := (others => '0'); elsif (enable='1') then if (count=b"0000") then count := baudReg; else count := count - 1; end if; end if; end if; if (count=b"0000") then sampleEn <= '1' and enable; else sampleEn <= '0'; end if; end process SampleGen; TxUnit : SnapLinkTx port map ( clk => clk, enable => enable, nReset => nReset, sampleEn => sampleEn, txReset => linkReset, dataBits => dataBits, sendData => sendData, txData => txData, txBusy => txBusy, serialTxOut => linkTxOut); RxUnit : SnapLinkRx port map ( clk => clk, enable => enable, nReset => nReset, sampleEn => sampleEn, rxReset => linkReset, dataBits => dataBits, newData => newData, parityError => parityError, rxData => rxData, serialRxIn => linkRxIn); RxFifo : Fifo generic map(dataWidth => 18) 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;