library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; use work.amc13_pack.all; use work.mydefs.all; library UNISIM; use UNISIM.VComponents.all; entity DaqLSCXG is Port ( sys_reset : in STD_LOGIC; -- active high reset of all logic but GTX sys_clk : in STD_LOGIC; sfp_pd : in array3x2; DRP_clk : in STD_LOGIC; LinkWe : in STD_LOGIC_VECTOR (2 downto 0); LinkCtrl : in STD_LOGIC_VECTOR (2 downto 0); LinkData : in array3x64; srcID : in array3x16; LinkDown : out STD_LOGIC_VECTOR (2 downto 0); LinkFull : out STD_LOGIC_VECTOR (2 downto 0); -- -- ack_cnt : out STD_LOGIC_VECTOR (2 downto 0); -- 1 ck pulse (txusrclk) indicating a received acknowledge -- pckt_cnt : out STD_LOGIC_VECTOR (2 downto 0); -- 1 ck pulse (txusrclk) indicating a transmit packet -- retransmit_cnt : out STD_LOGIC_VECTOR (2 downto 0); -- 1 ck pulse (txusrclk) indicating a retransmit packet -- event_cnt : out STD_LOGIC_VECTOR (2 downto 0); -- 1 ck pulse (sys_clk) indicating a sent event sync_loss : out STD_LOGIC_VECTOR (2 downto 0); -- goes to '1' (rxusrclk) when SERDES is out of synch status_ce : in std_logic_VECTOR (2 downto 0); -- not implemented yet status_addr : in STD_LOGIC_VECTOR (15 downto 0); -- not implemented yet status_port : out array3x64; -- first 32 bits are hard-wired -- txusrclk_o : out STD_LOGIC; -- reconstructed tx clock, to be used to clock sending circuitry rxusrclk_o : out STD_LOGIC; -- reconstructed rx clock, to be used to clock receiving circuitry -- gtx_reset : in std_logic; -- full reset of GTX only gtx_refclk : in std_logic; -- iob for refclk neg sfp_rxn : in std_logic_VECTOR (2 downto 0); -- sfp iobs sfp_rxp : in std_logic_VECTOR (2 downto 0); sfp_txn : out std_logic_VECTOR (2 downto 0); sfp_txp : out std_logic_VECTOR (2 downto 0) ); end DaqLSCXG; architecture Behavioral of DaqLSCXG is -- Local signals signal gtx_txfsmresetdone : std_logic_vector(2 downto 0); signal gtx_rxfsmresetdone : std_logic_vector(2 downto 0); signal gtx_data_valid: std_logic_vector(2 downto 0); signal sys_reset_bar : std_logic; signal txusrclk, txusrclk2 : std_logic; --signal txdll_locked, rxdll_locked, dll_reset, rxdll_reset, txdll_reset, txplllkdet, rxplllkdet: std_logic; --signal txclkfromserdes, rxclkfromserdes, rxclkfromserdes_bufg : std_logic; signal serdes_in_sync : std_logic_vector(2 downto 0); signal txdata, rxdata : array3x32; signal rxcharisk, txcharisk, rxchariscomma, gtx_rxnotintable : array3x4; --signal rxlossofsync : std_logic_vector(1 downto 0); --signal rxbufstatus : std_logic_vector(2 downto 0); signal rxbyteisaligned, rxenrealign, rxbyterealign, rxcommadet : std_logic_vector(2 downto 0); --signal gtxrefclk, drp_clk : std_logic; signal gtx_cpllfbclklost, gtx_cplllock, gtx_cpllrefclklost : std_logic; signal gtx_rxresetdone, gtx_txresetdone : std_logic_vector(2 downto 0); signal gtx_qpllrefclklost : std_logic; signal gtx_qplllock : std_logic; signal gtx_rxbyteisaligned_is_stable : std_logic_vector(2 downto 0); signal gtx_rxcdrlock : std_logic_vector(2 downto 0); signal stable_count : array3x16 ; signal data_valid_cnt : array3x9 ; signal serdes_status : array3x32 := (others => (others => '0')); COMPONENT SLINK_opt PORT( reset : IN std_logic; SYS_CLK : IN std_logic; LINKWe : IN std_logic; LINKCtrl : IN std_logic; LINKData : IN std_logic_vector(63 downto 0); src_ID : IN std_logic_vector(15 downto 0); inject_err : IN std_logic_vector(17 downto 0); read_CE : IN std_logic; Addr : IN std_logic_vector(15 downto 0); clock : IN std_logic; serdes_init : IN std_logic; clock_r : IN std_logic; SD_Data_i : IN std_logic_vector(31 downto 0); SD_Kb_i : IN std_logic_vector(3 downto 0); status_data : OUT std_logic_vector(63 downto 0); LINKDown : OUT std_logic; LINK_LFF : OUT std_logic; SD_Data_o : OUT std_logic_vector(31 downto 0); SD_Kb_o : OUT std_logic_vector(3 downto 0); Serdes_status : in std_logic_vector(31 downto 0) -- ack_cnt : OUT std_logic; -- pckt_cnt : OUT std_logic; -- retransmit : OUT std_logic; -- cnt_evt : OUT std_logic ); END COMPONENT; COMPONENT serdes5_wrapper PORT( refclk : IN std_logic; DRPclk : IN std_logic; sfp_pd : IN array3x2; txusrclk_out : OUT std_logic; qplllock : OUT std_logic; gtx_reset : IN std_logic; data_valid : IN std_logic_vector(2 downto 0); sfp_rxp : IN std_logic_vector(2 downto 0); sfp_rxn : IN std_logic_vector(2 downto 0); rxmcommaalignen : IN std_logic_vector(2 downto 0); rxpcommaalignen : IN std_logic_vector(2 downto 0); txcharisk : IN array3x4; txdata : IN array3x32; txfsmresetdone : OUT std_logic_vector(2 downto 0); rxfsmresetdone : OUT std_logic_vector(2 downto 0); rxcdrlock : OUT std_logic_vector(2 downto 0); rxnotintable : OUT array3x4; rxbyteisaligned : OUT std_logic_vector(2 downto 0); rxbyterealign : OUT std_logic_vector(2 downto 0); rxcommadet : OUT std_logic_vector(2 downto 0); rxchariscomma : OUT array3x4; rxcharisk : OUT array3x4; rxresetdone : OUT std_logic_vector(2 downto 0); txresetdone : OUT std_logic_vector(2 downto 0); rxdata : OUT array3x32; sfp_txp : OUT std_logic_vector(2 downto 0); sfp_txn : OUT std_logic_vector(2 downto 0) ); END COMPONENT; begin txusrclk2 <= txusrclk; g_SLINK_opt : for i in 0 to 2 generate Inst_SLINK_opt: SLINK_opt PORT MAP( -- FROM FED logic reset => sys_reset_bar, -- needs an active low reset SYS_CLK => sys_clk, -- DATA interface from FED LINKWe => not LinkWe(i), LINKCtrl => LinkCtrl(i), LINKData => LinkData(i), src_ID => srcID(i), inject_err => (others =>'0'), read_CE => '0', Addr => status_addr, status_data => status_port(i), LINKDown => LinkDown(i), LINK_LFF => LinkFull(i), -- SERDES interface clock => txusrclk2, -- clk tx from SERDES serdes_init => serdes_in_sync(i), -- status that comes back from GTX SD_Data_o => TXDATA(i), -- data sent to serdes (32 bit) SD_Kb_o => TXCHARISK(i), -- control K associated to SD_Data_o (4 bits) clock_r => txusrclk2, -- reconstructed clock from SERDES SD_Data_i => RXDATA(i), -- return data from SERDES 32 bit SD_Kb_i => RXCHARISK(i), -- return control K associated to SD_Data_i (4 bits) serdes_status => serdes_status(i) -- Status for user logic (to be removed later) -- ack_cnt => ack_cnt(i), -- pulse indicating a received acknoledge -- pckt_cnt => pckt_cnt(i), -- pulse indicating a transmit packet -- retransmit => retransmit_cnt(i), -- pulse indicating a retransmit packet -- cnt_evt => event_cnt(i) -- pulse indicating a sent event ); end generate; i_serdes5_wrapper: serdes5_wrapper PORT MAP( refclk => gtx_refclk, DRPclk => DRP_clk, sfp_pd => sfp_pd, txusrclk_out => txusrclk, qplllock => gtx_qplllock, gtx_reset => gtx_reset, data_valid => gtx_data_valid, sfp_rxp => sfp_rxp, sfp_rxn => sfp_rxn, txfsmresetdone => gtx_txfsmresetdone, rxfsmresetdone => gtx_rxfsmresetdone, rxcdrlock => gtx_rxcdrlock, rxnotintable => gtx_rxnotintable, rxmcommaalignen => rxenrealign, rxpcommaalignen => rxenrealign, rxbyteisaligned => rxbyteisaligned, rxbyterealign => rxbyterealign, rxcommadet => rxcommadet, rxchariscomma => rxchariscomma, rxcharisk => rxcharisk, rxresetdone => gtx_rxresetdone, txresetdone => gtx_txresetdone, txcharisk => txcharisk, txdata => txdata, rxdata => rxdata, sfp_txp => sfp_txp, sfp_txn => sfp_txn ); txusrclk_o <= txusrclk; rxusrclk_o <= txusrclk; sys_reset_bar <= not(sys_reset); process (txusrclk) begin if txusrclk='1' and txusrclk'event then for i in 0 to 2 loop if rxbyteisaligned(i)='0' then stable_count(i) <= (others => '0'); gtx_rxbyteisaligned_is_stable(i) <='0'; else stable_count(i) <= stable_count(i) + 1; if stable_count(i) = x"ffff" then gtx_rxbyteisaligned_is_stable(i) <= '1'; end if; end if; if(gtx_rxnotintable(i) /= x"0")then gtx_data_valid(i) <= '0'; data_valid_cnt(i) <= (others => '0'); else if(data_valid_cnt(i)(8) = '1')then gtx_data_valid(i) <= '1'; else data_valid_cnt(i) <= data_valid_cnt(i) + 1; end if; end if; end loop; serdes_in_sync <= gtx_rxfsmresetdone and gtx_txfsmresetdone and gtx_rxbyteisaligned_is_stable; sync_loss <= not(serdes_in_sync); rxenrealign <= not(rxbyteisaligned); end if; end process; --serdes_in_sync <= gtx_rxfsmresetdone and gtx_txfsmresetdone and gtx_rxcdrlock_is_stable; -- --sync_loss <= not(serdes_in_sync); -- --rxenrealign <= not(rxbyteisaligned); g_status : for i in 0 to 2 generate serdes_status(i)(0) <= gtx_qplllock; serdes_status(i)(1) <= gtx_qpllrefclklost; serdes_status(i)(2) <= gtx_txresetdone(i); serdes_status(i)(3) <= gtx_rxresetdone(i); serdes_status(i)(4) <= gtx_rxcdrlock(i); serdes_status(i)(5) <= rxbyteisaligned(i); serdes_status(i)(6) <= rxbyterealign(i); serdes_status(i)(7) <= rxcommadet(i); serdes_status(i)(11 downto 8) <= rxchariscomma(i); serdes_status(i)(15 downto 12) <= rxcharisk(i); serdes_status(i)(16) <= gtx_cpllfbclklost; serdes_status(i)(17) <= gtx_cplllock; serdes_status(i)(18) <= gtx_cpllrefclklost; serdes_status(i)(31 downto 19) <= (others => '0'); end generate; gtx_cpllfbclklost <= '0'; gtx_cplllock <= '1'; gtx_cpllrefclklost <= '0'; gtx_qpllrefclklost <= '0'; end Behavioral;