LIBRARY ieee; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; --test firmware for the glink_Rx_test board. --version 0.0 july/2005 -- -- -- --How to use the glink_Rx_test board: -- --a/start sending the data from the TAB board through --the glink. --b/power up the glink_Rx_test board and press the "new test start" --button -- --the firmware will wait for link ready signal from the Rx --and first active DAV will start the process of parity checking -- --The following outputs are provided on the board: --1. led1 = nolock --2. led2 = nolock stored after manual reset --3. led3 = parity error --4. led4 = DAV -- --5. lemo1 = DAV as a scope trigger --6. lemo2 = nolock to an external counter -- --7. testpoint1 = recovered clock --8. testpoint2 = parity error ENTITY glink_Rx_test IS PORT( --main clock cp : IN STD_LOGIC; --signals from the glink chip strbout : IN STD_LOGIC; --clock for the glink data d : IN STD_LOGIC_VECTOR (19 downto 0);--glink data flag : IN STD_LOGIC; g_error : IN STD_LOGIC; ff : IN STD_LOGIC; cav_n : IN STD_LOGIC; dav_n : IN STD_LOGIC; linkrdy_n : IN STD_LOGIC; --signal to the glink chip flagsel : OUT STD_LOGIC; m20sel : OUT STD_LOGIC; rst_n : OUT STD_LOGIC; g1rst_n : OUT STD_LOGIC; optics_clk: OUT STD_LOGIC; div0 : OUT STD_LOGIC; div1 : OUT STD_LOGIC; --VCSEL disable sd1 : OUT STD_LOGIC; --test points tp1 : OUT STD_LOGIC; tp2 : OUT STD_LOGIC; tp3 : OUT STD_LOGIC; --with the lemo connector J1 tp4 : OUT STD_LOGIC; --with the lemo connector J2 --manual switches reset_n : IN STD_LOGIC; new_test_n: IN STD_LOGIC; --LEDs led1 : OUT STD_LOGIC; led2 : OUT STD_LOGIC; led3 : OUT STD_LOGIC; led4 : OUT STD_LOGIC; -- not used nu : OUT STD_LOGIC ); END glink_Rx_test; ARCHITECTURE rtl OF glink_Rx_test IS SIGNAL din : STD_LOGIC_VECTOR (19 downto 0); SIGNAL flag_reg : STD_LOGIC; SIGNAL error_reg : STD_LOGIC; SIGNAL ff_reg : STD_LOGIC; SIGNAL cav_reg : STD_LOGIC; SIGNAL dav_reg : STD_LOGIC; SIGNAL linkrdy_reg : STD_LOGIC; SIGNAL new_test : STD_LOGIC; SIGNAL reset : STD_LOGIC; SIGNAL parity_error : STD_LOGIC; SIGNAL nolock_stored : STD_LOGIC; SIGNAL glink_data_phase: STD_LOGIC; SIGNAL start_up_cnt : STD_LOGIC_VECTOR(15 downto 0); SIGNAL lpw_enable : STD_LOGIC; SIGNAL rst : STD_LOGIC; SIGNAL parity_d : STD_LOGIC_VECTOR(15 downto 0); SIGNAL parity : STD_LOGIC_VECTOR(15 downto 0); SIGNAL p_word_cnt : STD_LOGIC_VECTOR( 8 downto 0); SIGNAL par_error_mem : STD_LOGIC; BEGIN --send main clock to the glink optics_clk <= cp; --manual inputs PROCESS (cp) BEGIN IF rising_edge(cp) THEN reset <= not reset_n; new_test <= not new_test_n; END IF; END PROCESS; rst <= reset or new_test; --input registers PROCESS (strbout, rst) BEGIN IF rst='1' THEN din <= (others=>'0'); flag_reg <= '0'; error_reg <= '0'; ff_reg <= '0'; cav_reg <= '0'; dav_reg <= '0'; linkrdy_reg <= '0'; ELSIF rising_edge(strbout) THEN din <= d; flag_reg <= flag; error_reg <= g_error; ff_reg <= ff; cav_reg <= not cav_n; dav_reg <= not dav_n; linkrdy_reg <= not linkrdy_n; END IF; END PROCESS; --after the reset, wait 5ms for the link to enter the data phase PROCESS (cp, rst) BEGIN IF rst='1' THEN glink_data_phase <= '0'; ELSIF rising_edge(cp) THEN if start_up_cnt="0100111000100000" then --20000x25ns=5ms glink_data_phase <= '1'; else glink_data_phase <= glink_data_phase; end if; END IF; END PROCESS; --start up counter counts 5ms after the reset PROCESS (cp, rst) BEGIN IF rst='1' THEN start_up_cnt <= (others=>'0'); ELSIF rising_edge(cp) THEN if glink_data_phase = '0' then start_up_cnt <= unsigned(start_up_cnt)+1; end if; END IF; END PROCESS; --nolock stored after manual reset PROCESS (strbout, rst) BEGIN IF rst='1' THEN nolock_stored <= '0'; ELSIF rising_edge(strbout) THEN if glink_data_phase='1' then nolock_stored <= linkrdy_n or nolock_stored; end if; END IF; END PROCESS; --after glink is in the data phase wait for the first DAV --and allow to compute the longitudinal parity word process (strbout,rst) begin if rst='1' then lpw_enable <= '0'; elsif rising_edge(strbout) then lpw_enable <= (not dav_reg) or lpw_enable; end if; end process; --the longitudinal parity word: parity_d(15 downto 0) <= din(15 downto 0) xnor parity(15 downto 0) when (dav_reg='1' and lpw_enable='1') else (others=>'0'); process (strbout,dav_reg) begin if dav_reg='0' then parity <= (others=>'0'); elsif rising_edge(strbout) then parity <= parity_d; end if; end process; --check the computed parity word with the one from the data --the parity word in the data is the word#191? (make sure the glink gives --the same DAV to data response) process (strbout,dav_reg) begin if dav_reg='0' then p_word_cnt <= (others=>'0'); parity_error <= '0'; elsif rising_edge(strbout) then if lpw_enable='1' then p_word_cnt <= unsigned(p_word_cnt)+1; end if; if lpw_enable='1' and p_word_cnt=191 and parity(15 downto 0)/=din(15 downto 0) then parity_error <= '1'; end if; end if; end process; --parity error PROCESS (strbout, rst) BEGIN IF rst='1' THEN par_error_mem <= '0'; ELSIF rising_edge(strbout) THEN par_error_mem <= parity_error or par_error_mem; END IF; END PROCESS; --control signals for glink flagsel <= '0'; m20sel <= '1'; rst_n <= not reset; g1rst_n <= not rst; div0 <= '0'; div1 <= '0'; --testpoints on the board tp1 <= strbout; --recovered clock tp2 <= parity_error; --parity error --testpoints with the lemo conectors tp3 <= not dav_n; --DAV tp4 <= linkrdy_n; --nolock to an external trigger --LEDs led1 <= linkrdy_n; --nolock led2 <= nolock_stored; --nolock stored after manual reset led3 <= par_error_mem; --parity error stored after manual reset led4 <= not dav_n; --DAV --not used pins in the present firmware version nu <= din(19) or din(18) or din(17) or din(16)or error_reg or flag_reg or ff_reg or cav_reg; END rtl;