-- -- TLU Interface -- -- Matt Warren 2014 -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library utils; use utils.pkg_types.all; library hsio; use hsio.pkg_core_globals.all; entity trig_tlu_if is -- generic( -- SIM_MODE : integer := 0 -- ); port( trig_tlu_o : out std_logic; tlu_trig_sync_i : in std_logic; -- syncronised, but not l2p --busy_i : in std_logic; busy_tlu_o : out std_logic; tlu_tclk_o : out std_logic; --tick_tclk_i : in std_logic; tog_i : in std_logic_vector(34 downto 0); trid_tlu_o : out std_logic_vector(15 downto 0); trid_valid_o : out std_logic; trid_new_o : out std_logic; -- debug_mode_i : in std_logic; debug_trig_i : in std_logic; l0id16_i : in std_logic_vector(15 downto 0); reg_tlu_ctl_i : in std_logic_vector(15 downto 0); s40 : in std_logic; --en : in std_logic; clk : in std_logic; rst : in std_logic ); -- Declarations end trig_tlu_if; -- architecture rtl of trig_tlu_if is signal en : std_logic; signal bcount : integer range 0 to 16 := 0; signal bcount_clr : std_logic; signal bcount_inc : std_logic; signal trid : std_logic_vector(15 downto 0); -- signal trid_shift : std_logic; signal trid_valid : std_logic; signal trid_new : std_logic; signal trid_clr : std_logic; signal tog_tclk : std_logic; signal tog_sel : std_logic_vector(1 downto 0); signal tlu_tclk0 : std_logic; signal tlu_tclk_en : std_logic; signal tick_tclk : std_logic; signal tlu_tclk_tick : std_logic; signal tog_tclk_q : std_logic; signal trig_tlu0 : std_logic; signal trig_in : std_logic; signal busy_tlu0 : std_logic; signal rx_delay : std_logic_vector(5 downto 0); signal rx_shiften_pipe : std_logic_vector(31 downto 0); signal rx_shiften : std_logic; signal rx_count : integer range 0 to 16 := 0; signal debug_mode : std_logic; type states is (TrigOut0, TrigOut1, WaitTrigLo, WaitTick0, WaitTick1, SendTCLKs, LastTClk, WaitRX, WaitState0, WaitState1, Start, Idle ); signal state, nstate : states; begin en <= reg_tlu_ctl_i(bTLU_ENA); debug_mode <= reg_tlu_ctl_i(bTLU_DEBUG); trig_in <= tlu_trig_sync_i when (debug_mode = '0') else debug_trig_i; -- clock it out trid_valid_o <= trid_valid when rising_edge(clk); trid_new_o <= trid_new when rising_edge(clk); trig_tlu_o <= (trig_tlu0 and not(debug_mode)) when rising_edge(clk); busy_tlu_o <= busy_tlu0 when rising_edge(clk); tlu_tclk_o <= tlu_tclk0 when rising_edge(clk); tog_sel <= reg_tlu_ctl_i(bTLU_TCLK_RATEh downto bTLU_TCLK_RATEl); --tog_sel <= reg_tlu_ctl_i(15 downto 14); with tog_sel select tog_tclk <= tog_i(T_1MHz) when "11", tog_i(T_2MHz) when "10", tog_i(T_4MHz) when "01", tog_i(T_8MHz) when others; -- "00" tog_tclk_q <= tog_tclk when rising_edge(clk); tick_tclk <= tog_tclk and not(tog_tclk_q); -- State Machine -------------------------------------------------------- prc_sync_part : process (clk) begin if rising_edge(clk) then if (rst = '1') or (en = '0') then state <= Start; else state <= nstate; end if; end if; end process; prc_async_machine : process (trig_in, tick_tclk, tog_tclk, bcount, rx_shiften, rx_count, s40, state ) begin -- defaults busy_tlu0 <= '1'; bcount_clr <= '0'; bcount_inc <= '0'; --trid_shift <= '0'; trid_valid <= '0'; trid_new <= '0'; trid_clr <= '0'; trig_tlu0 <= '0'; tlu_tclk_en <= '0'; tlu_tclk_tick <= '0'; case state is ------------------------------------------------------------- --- start same as Idle, but with trid_valid = '0' when Start => nstate <= Start; busy_tlu0 <= '0'; bcount_clr <= '1'; if (trig_in = '1') and (s40 = '1') then nstate <= TrigOut0; end if; when Idle => nstate <= Idle; busy_tlu0 <= '0'; bcount_clr <= '1'; trid_valid <= '1'; if (trig_in = '1') and (s40 = '1') then nstate <= TrigOut0; end if; when TrigOut0 => trig_tlu0 <= '1'; trid_clr <= '1'; nstate <= TrigOut1; when TrigOut1 => trig_tlu0 <= '1' after 1 ns; nstate <= WaitTrigLo; when WaitTrigLo => nstate <= WaitTrigLo; if (trig_in = '0') then nstate <= WaitTick0; end if; when WaitTick0 => nstate <= WaitTick0; if (tick_tclk = '1') then nstate <= WaitTick1; end if; when WaitTick1 => nstate <= WaitTick1; if (tick_tclk = '1') then tlu_tclk_en <= '1'; nstate <= SendTCLKs; end if; when SendTCLKs => nstate <= SendTCLKs; tlu_tclk_en <= '1'; if (tick_tclk = '1') then bcount_inc <= '1'; tlu_tclk_tick <= '1'; if (bcount = 14) then nstate <= LastTClk; end if; end if; when LastTClk => nstate <= LastTClk; tlu_tclk_en <= '1'; if (tick_tclk = '1') then tlu_tclk_tick <= '1'; tlu_tclk_en <= '0'; nstate <= WaitRX; end if; when WaitRX => nstate <= WaitRX; if (rx_count = 16) then trid_new <= '1'; nstate <= WaitState0; end if; when WaitState0 => nstate <= WaitState0; trid_valid <= '1'; if (tick_tclk = '1') then nstate <= WaitState1; end if; when WaitState1 => nstate <= WaitState1; trid_valid <= '1'; if (tick_tclk = '1') and (trig_in = '0') then nstate <= Idle; end if; end case; end process; ---------------------------------------------------------------------- prc_bcount : process (clk) begin if rising_edge(clk) then -- tclk bit counter generate if (bcount_clr = '1') then bcount <= 0; elsif (bcount_inc = '1') then bcount <= bcount + 1; end if; -- tclk generate tlu_tclk0 <= tog_tclk and tlu_tclk_en; end if; end process; rx_delay <= reg_tlu_ctl_i(bTLU_TCLK_RXDELh downto bTLU_TCLK_RXDELl); --rx_delay <= reg_tlu_ctl_i(13 downto 8); rx_shiften_pipe <= rx_shiften_pipe(30 downto 0) & tlu_tclk_tick when rising_edge(clk); rx_shiften <= rx_shiften_pipe(conv_integer(rx_delay)); prc_trid : process (clk) begin if rising_edge(clk) then if (trid_clr = '1') then --trid <= "001" & x"234"; -- good for debug mode trid <= (others => '0'); rx_count <= 0; elsif (rx_shiften = '1') then trid <= tlu_trig_sync_i & trid(15 downto 1); rx_count <= rx_count + 1; end if; end if; end process; trid_tlu_o <= trid when (debug_mode = '0') else l0id16_i; end architecture rtl;