------------------------------------------------------------------------------- -- Company: EDF Boston University -- Engineer: Shouxiang Wu -- -- Create Date: 14:53:20 05/24/2010 -- Design Name: -- Module Name: TTC_decoder - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- -- TTC Hamming encoding -- hmg[0] = d[0]^d[1]^d[2]^d[3]; -- hmg[1] = d[0]^d[4]^d[5]^d[6]; -- hmg[2] = d[1]^d[2]^d[4]^d[5]^d[7]; -- hmg[3] = d[1]^d[3]^d[4]^d[6]^d[7]; -- hmg[4] = d[0]^d[2]^d[3]^d[5]^d[6]^d[7]; -- -- As no detailed timing of TTCrx chip is available, L1A may need to add -- several clocks of delay pending test results -- May 27 2010 -- -- Mods: -- 24 Oct 2013, esh/jmm - add delay pipeline on TTC input ------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.std_logic_misc.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity TTC_decoder is port ( TTC_data_p : in std_logic; TTC_data_n : in std_logic; Clock40 : in std_logic; clock200 : in std_logic; TTCready : out std_logic; L1Accept : out std_logic; BCntRes : out std_logic; EvCntRes : out std_logic; SinErrStr : out std_logic; DbErrStr : out std_logic; BrcstStr : out std_logic; Brcst : out std_logic_vector (7 downto 2) ); end TTC_decoder; architecture Behavioral of TTC_decoder is constant Coarse_Delay : std_logic_vector(3 downto 0) := x"0"; signal TTC_CLK_in : std_logic := '0'; signal TTC_CLK : std_logic := '0'; signal CLKFB : std_logic := '0'; signal TTC_data_in : std_logic := '0'; signal TTC_data_dl : std_logic := '0'; signal TTC_data_dl2 : std_logic := '0'; signal TTC_data : std_logic_vector(1 downto 0) := (others => '0'); signal L1A : std_logic := '0'; signal sr : std_logic_vector(38 downto 0) := (others => '0'); signal rec_cntr : std_logic_vector(5 downto 0) := (others => '0'); signal rec_cmd : std_logic := '0'; signal FMT : std_logic := '0'; signal brcst_str : std_logic_vector(3 downto 0) := (others => '0'); signal brcst_data : std_logic_vector(7 downto 0) := (others => '0'); signal indiv_data : std_logic_vector(31 downto 0) := (others => '0'); signal indiv_str : std_logic_vector(1 downto 0) := (others => '0'); signal syndrome : std_logic_vector(6 downto 0) := (others => '0'); signal brcst_i : std_logic_vector(7 downto 2) := (others => '0'); signal one : std_logic := '0'; signal frame_err : std_logic := '0'; signal single_err : std_logic := '0'; signal double_err : std_logic := '0'; signal EvCntReset : std_logic := '0'; signal BCntReset : std_logic := '0'; signal idelay_valid : std_logic := '0'; signal indiv_SinErrStr : std_logic; signal indiv_DbErrStr : std_logic; signal Str : std_logic; signal E : std_logic; signal Debug : std_logic_vector (40 downto 0); signal TTCrxADDR : std_logic_vector (13 downto 0); signal SubADDR : std_logic_vector (7 downto 0); signal Data : std_logic_vector (7 downto 0); -- shift register for delay esh/jmm signal InputDelaySR : std_logic_vector(11 downto 0); signal rst_n : std_logic; begin -- no reset for non-simulation esh/jmm rst_n <= '1'; TTC_CLK <= clock40; Brcst <= Brcst_i; --TTC_data_dl <= TTC_data_in; TTCready <= '1'; --TTC_lock <= '1'; -- cdceOut1Ibufds2Gtxe2: ibufds_gte2 -- port map ( -- O => TTC_CLK_in, --cdce out U1 LHC CLK -- ODIV2 => open, -- CEB => '0', -- I => TTC_CLK_p, -- IB => TTC_CLK_n -- ); i_TTC_data_in : ibufds generic map(DIFF_TERM => true, IOSTANDARD => "LVDS_25") port map(i => TTC_data_p, ib => TTC_data_n, o => TTC_data_in); -- i_TTC_CLK_buf : bufg port map(i => TTC_CLK_in, o => TTC_CLK); -- IDELAYCTRL_inst : IDELAYCTRL -- port map ( -- RDY => idelay_valid, -- 1-bit output indicates validity of the REFCLK -- REFCLK => clock200, -- 1-bit reference clock input -- RST => '0' ); -- 1-bit reset input --IDELAYE2_inst : IDELAYE2 --generic map ( -- CINVCTRL_SEL => "FALSE", -- Enable dynamic clock inversion (FALSE, TRUE) -- DELAY_SRC => "DATAIN", -- Delay input (IDATAIN, DATAIN) -- HIGH_PERFORMANCE_MODE => "TRUE", -- Reduced jitter ("TRUE"), Reduced power ("FALSE") -- IDELAY_TYPE => "FIXED", -- IDELAY_VALUE => 31, -- PIPE_SEL => "FALSE", -- REFCLK_FREQUENCY => 200.0, -- SIGNAL_PATTERN => "DATA" --) --port map ( ---- CNTVALUEOUT => CNTVALUEOUT, -- 5-bit output: Counter value output -- DATAOUT => TTC_data_dl, -- C =>clock200, -- CE =>'1', -- CINVCTRL => '0', -- CNTVALUEIN => (others=>'0'), -- DATAIN => TTC_data_in, -- IDATAIN => TTC_data_in, -- INC => '1', -- LD => '0', -- LDPIPEEN => '0', -- REGRST => '0' --); TTC_data_dl <= TTC_data_in; i_TTC_data : IDDR generic map ( DDR_CLK_EDGE => "SAME_EDGE_PIPELINED", -- "OPPOSITE_EDGE", "SAME_EDGE" -- or "SAME_EDGE_PIPELINED" INIT_Q1 => '0', -- Initial value of Q1: '0' or '1' INIT_Q2 => '0', -- Initial value of Q2: '0' or '1' SRTYPE => "SYNC") -- Set/Reset type: "SYNC" or "ASYNC" port map ( Q1 => TTC_data(1), -- 1-bit output for positive edge of clock Q2 => TTC_data(0), -- 1-bit output for negative edge of clock C => TTC_CLK, -- 1-bit clock input CE => '1', -- 1-bit clock enable input D => TTC_data_dl, -- 1-bit DDR data input -- D => TTC_data_in, -- 1-bit DDR data input R => '0', -- 1-bit reset S => '0' -- 1-bit set ); process(TTC_CLK) begin if(TTC_CLK'event and TTC_CLK = '1')then L1A <= TTC_data(0); if(rec_cmd = '0')then rec_cntr <= (others => '0'); else rec_cntr <= rec_cntr + 1; end if; if(rec_cntr(5 downto 3) = "101" or (FMT = '0' and rec_cntr(3 downto 0) = x"d"))then rec_cmd <= '0'; elsif(TTC_data(1) = '0')then rec_cmd <= '1'; end if; if(or_reduce(rec_cntr) = '0')then FMT <= TTC_data(1); end if; sr <= sr(37 downto 0) & TTC_data(1); if(FMT = '0' and rec_cntr(3 downto 0) = x"e")then brcst_data <= sr(12 downto 5); syndrome(0) <= sr(0) xor sr(5) xor sr(6) xor sr(7) xor sr(8); syndrome(1) <= sr(1) xor sr(5) xor sr(9) xor sr(10) xor sr(11); syndrome(2) <= sr(2) xor sr(6) xor sr(7) xor sr(9) xor sr(10) xor sr(12); syndrome(3) <= sr(3) xor sr(6) xor sr(8) xor sr(9) xor sr(11) xor sr(12); syndrome(4) <= xor_reduce(sr(12 downto 0)); frame_err <= not TTC_data(1); brcst_str(0) <= '1'; syndrome(6 downto 5) <= "00"; elsif(FMT = '1' and rec_cntr = "101000")then indiv_data <= sr(38 downto 7); syndrome(0) <= sr(0) xor sr(7) xor sr(8) xor sr(9) xor sr(10) xor sr(11) xor sr(12); syndrome(1) <= sr(1) xor sr(13) xor sr(14) xor sr(15) xor sr(16) xor sr(17) xor sr(18) xor sr(19) xor sr(20) xor sr(21) xor sr(22) xor sr(23) xor sr(24) xor sr(25) xor sr(26) xor sr(27); syndrome(2) <= sr(2) xor sr(13) xor sr(14) xor sr(15) xor sr(16) xor sr(17) xor sr(18) xor sr(19) xor sr(20) xor sr(28) xor sr(29) xor sr(30) xor sr(31) xor sr(32) xor sr(33) xor sr(34); syndrome(3) <= sr(3) xor sr(7) xor sr(8) xor sr(9) xor sr(13) xor sr(14) xor sr(15) xor sr(16) xor sr(21) xor sr(22) xor sr(23) xor sr(24) xor sr(28) xor sr(29) xor sr(30) xor sr(31) xor sr(35) xor sr(36) xor sr(37); syndrome(4) <= sr(4) xor sr(7) xor sr(10) xor sr(11) xor sr(13) xor sr(14) xor sr(17) xor sr(18) xor sr(21) xor sr(22) xor sr(25) xor sr(26) xor sr(28) xor sr(29) xor sr(32) xor sr(33) xor sr(35) xor sr(36) xor sr(38); syndrome(5) <= sr(5) xor sr(8) xor sr(10) xor sr(12) xor sr(13) xor sr(15) xor sr(17) xor sr(19) xor sr(21) xor sr(23) xor sr(25) xor sr(27) xor sr(28) xor sr(30) xor sr(32) xor sr(34) xor sr(35) xor sr(37) xor sr(38); syndrome(6) <= xor_reduce(sr); frame_err <= not TTC_data(1); indiv_str(0) <= '1'; else brcst_str(0) <= '0'; indiv_str(0) <= '0'; end if; single_err <= xor_reduce(syndrome) and not frame_err; if((or_reduce(syndrome) = '1' and xor_reduce(syndrome) = '0') or frame_err = '1')then double_err <= '1'; else double_err <= '0'; end if; SinErrStr <= single_err and brcst_str(1); DbErrStr <= double_err and brcst_str(1); indiv_SinErrStr <= single_err and indiv_str(1); indiv_DbErrStr <= (double_err or not one) and indiv_str(1); brcst_str(2) <= brcst_str(1) and not double_err; Str <= indiv_str(1) and not double_err and one; if(syndrome(3 downto 0) = x"c")then Brcst_i(7) <= not brcst_data(7); else Brcst_i(7) <= brcst_data(7); end if; if(syndrome(3 downto 0) = x"a")then Brcst_i(6) <= not brcst_data(6); else Brcst_i(6) <= brcst_data(6); end if; if(syndrome(3 downto 0) = x"6")then Brcst_i(5) <= not brcst_data(5); else Brcst_i(5) <= brcst_data(5); end if; if(syndrome(3 downto 0) = x"e")then Brcst_i(4) <= not brcst_data(4); else Brcst_i(4) <= brcst_data(4); end if; if(syndrome(3 downto 0) = x"9")then Brcst_i(3) <= not brcst_data(3); else Brcst_i(3) <= brcst_data(3); end if; if(syndrome(3 downto 0) = x"5")then Brcst_i(2) <= not brcst_data(2); else Brcst_i(2) <= brcst_data(2); end if; if(syndrome(3 downto 0) = x"d")then EvCntReset <= not brcst_data(1); else EvCntReset <= brcst_data(1); end if; if(syndrome(3 downto 0) = x"3")then BCntReset <= not brcst_data(0); else BCntReset <= brcst_data(0); end if; BCntRes <= brcst_str(3) and BCntReset; EvCntRes <= brcst_str(3) and EvCntReset; BrcstStr <= brcst_str(3) and or_reduce(Brcst_i); if(syndrome(5 downto 0) = "110000")then TTCrxADDR(13) <= not indiv_data(31); else TTCrxADDR(13) <= indiv_data(31); end if; if(syndrome(5 downto 0) = "101000")then TTCrxADDR(12) <= not indiv_data(30); else TTCrxADDR(12) <= indiv_data(30); end if; if(syndrome(5 downto 0) = "011000")then TTCrxADDR(11) <= not indiv_data(29); else TTCrxADDR(11) <= indiv_data(29); end if; if(syndrome(5 downto 0) = "111000")then TTCrxADDR(10) <= not indiv_data(28); else TTCrxADDR(10) <= indiv_data(28); end if; if(syndrome(5 downto 0) = "100100")then TTCrxADDR(9) <= not indiv_data(27); else TTCrxADDR(9) <= indiv_data(27); end if; if(syndrome(5 downto 0) = "010100")then TTCrxADDR(8) <= not indiv_data(26); else TTCrxADDR(8) <= indiv_data(26); end if; if(syndrome(5 downto 0) = "110100")then TTCrxADDR(7) <= not indiv_data(25); else TTCrxADDR(7) <= indiv_data(25); end if; if(syndrome(5 downto 0) = "001100")then TTCrxADDR(6) <= not indiv_data(24); else TTCrxADDR(6) <= indiv_data(24); end if; if(syndrome(5 downto 0) = "101100")then TTCrxADDR(5) <= not indiv_data(23); else TTCrxADDR(5) <= indiv_data(23); end if; if(syndrome(5 downto 0) = "011100")then TTCrxADDR(4) <= not indiv_data(22); else TTCrxADDR(4) <= indiv_data(22); end if; if(syndrome(5 downto 0) = "111100")then TTCrxADDR(3) <= not indiv_data(21); else TTCrxADDR(3) <= indiv_data(21); end if; if(syndrome(5 downto 0) = "100010")then TTCrxADDR(2) <= not indiv_data(20); else TTCrxADDR(2) <= indiv_data(20); end if; if(syndrome(5 downto 0) = "010010")then TTCrxADDR(1) <= not indiv_data(19); else TTCrxADDR(1) <= indiv_data(19); end if; if(syndrome(5 downto 0) = "110010")then TTCrxADDR(0) <= not indiv_data(18); else TTCrxADDR(0) <= indiv_data(18); end if; if(syndrome(5 downto 0) = "001010")then E <= not indiv_data(17); else E <= indiv_data(17); end if; if(syndrome(5 downto 0) = "101010")then one <= not indiv_data(16); else one <= indiv_data(16); end if; if(syndrome(5 downto 0) = "011010")then subaddr(7) <= not indiv_data(15); else subaddr(7) <= indiv_data(15); end if; if(syndrome(5 downto 0) = "111010")then subaddr(6) <= not indiv_data(14); else subaddr(6) <= indiv_data(14); end if; if(syndrome(5 downto 0) = "000110")then subaddr(5) <= not indiv_data(13); else subaddr(5) <= indiv_data(13); end if; if(syndrome(5 downto 0) = "100110")then subaddr(4) <= not indiv_data(12); else subaddr(4) <= indiv_data(12); end if; if(syndrome(5 downto 0) = "010110")then subaddr(3) <= not indiv_data(11); else subaddr(3) <= indiv_data(11); end if; if(syndrome(5 downto 0) = "110110")then subaddr(2) <= not indiv_data(10); else subaddr(2) <= indiv_data(10); end if; if(syndrome(5 downto 0) = "001110")then subaddr(1) <= not indiv_data(9); else subaddr(1) <= indiv_data(9); end if; if(syndrome(5 downto 0) = "101110")then subaddr(0) <= not indiv_data(8); else subaddr(0) <= indiv_data(8); end if; if(syndrome(5 downto 0) = "011110")then data(7) <= not indiv_data(7); else data(7) <= indiv_data(7); end if; if(syndrome(5 downto 0) = "111110")then data(6) <= not indiv_data(6); else data(6) <= indiv_data(6); end if; if(syndrome(5 downto 0) = "100001")then data(5) <= not indiv_data(5); else data(5) <= indiv_data(5); end if; if(syndrome(5 downto 0) = "010001")then data(4) <= not indiv_data(4); else data(4) <= indiv_data(4); end if; if(syndrome(5 downto 0) = "110001")then data(3) <= not indiv_data(3); else data(3) <= indiv_data(3); end if; if(syndrome(5 downto 0) = "001001")then data(2) <= not indiv_data(2); else data(2) <= indiv_data(2); end if; if(syndrome(5 downto 0) = "101001")then data(1) <= not indiv_data(1); else data(1) <= indiv_data(1); end if; if(syndrome(5 downto 0) = "011001")then data(0) <= not indiv_data(0); else data(0) <= indiv_data(0); end if; end if; end process; i_L1Accept : SRL16E port map ( Q => L1Accept, -- SRL data output A0 => Coarse_Delay(0), -- Select[0] input A1 => Coarse_Delay(1), -- Select[1] input A2 => Coarse_Delay(2), -- Select[2] input A3 => Coarse_Delay(3), -- Select[3] input CE => '1', -- Clock enable input CLK => TTC_CLK, -- Clock input D => L1A -- SRL data input ); i_brcst_str1 : SRL16E port map ( Q => brcst_str(1), -- SRL data output A0 => '0', -- Select[0] input A1 => '1', -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => '1', -- Clock enable input CLK => TTC_CLK, -- Clock input D => brcst_str(0) -- SRL data input ); i_brcst_str3 : SRL16E port map ( Q => brcst_str(3), -- SRL data output A0 => Coarse_Delay(0), -- Select[0] input A1 => Coarse_Delay(1), -- Select[1] input A2 => Coarse_Delay(2), -- Select[2] input A3 => Coarse_Delay(3), -- Select[3] input CE => '1', -- Clock enable input CLK => TTC_CLK, -- Clock input D => brcst_str(2) -- SRL data input ); i_indiv_str1 : SRL16E port map ( Q => indiv_str(1), -- SRL data output A0 => '0', -- Select[0] input A1 => '1', -- Select[1] input A2 => '0', -- Select[2] input A3 => '0', -- Select[3] input CE => '1', -- Clock enable input CLK => TTC_CLK, -- Clock input D => indiv_str(0) -- SRL data input ); end Behavioral;