library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity trg_generator is generic ( cnt_width : integer := 10 ); port ( clk40 : in std_logic; rst40 : in std_logic; pt_in : in std_logic; pt_ctp : in std_logic; l0_in : in std_logic; l1_in : in std_logic; pt_to_sm : out std_logic; l0_to_sm : out std_logic; l1_to_sm : out std_logic; l0_to_ctp : out std_logic; -- configuration settings ptrg_to_l0_acc : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector( 40, cnt_width); ptrg_to_l0_send : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector( 46, cnt_width); ptrg_to_l1_acc : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector(290, cnt_width); ptrg_to_l1_send : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector(300, cnt_width); ptrg_to_idle_nol0 : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector( 60, cnt_width); ptrg_to_idle_nol1 : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector(400, cnt_width); ptrg_to_idle : in std_logic_vector(cnt_width-1 downto 0) := conv_std_logic_vector(500, cnt_width) ); end trg_generator; architecture default of trg_generator is type trg_state is (idle, sent_ptrg, wait_l0, sent_l0, wait_l1, dead_nol0, dead_nol1, dead_l1a, err); signal state_curr : trg_state; signal state_next : trg_state; signal seen_l0 : std_logic; signal seen_l1 : std_logic; signal cnt_after_ptrg : std_logic_vector(cnt_width-1 downto 0); begin -- default l0_to_ctp <= pt_ctp when state_next = idle and pt_in = '1' else '0'; process (clk40) begin -- process if (rst40 = '1') then state_curr <= idle; state_next <= idle; pt_to_sm <= '0'; l0_to_sm <= '0'; l1_to_sm <= '0'; -- l0_to_ctp <= '0'; cnt_after_ptrg <= (others => '0'); elsif rising_edge(clk40) then -- registered state output state_curr <= state_next; -- initialization pt_to_sm <= '0'; l0_to_sm <= '0'; l1_to_sm <= '0'; -- l0_to_ctp <= '0'; cnt_after_ptrg <= (others => '0'); case state_next is when idle => seen_l0 <= '0'; seen_l1 <= '1'; if (pt_in = '1') then state_next <= sent_ptrg; pt_to_sm <= '1'; -- l0_to_ctp <= pt_ctp; end if; when sent_ptrg => seen_l0 <= '0'; cnt_after_ptrg <= cnt_after_ptrg + 1; if (cnt_after_ptrg >= ptrg_to_l0_acc) then state_next <= wait_l0; end if; when wait_l0 => cnt_after_ptrg <= cnt_after_ptrg + 1; seen_l1 <= '0'; if (l0_in = '1') then seen_l0 <= '1'; end if; if (cnt_after_ptrg >= ptrg_to_l0_send) then if (l0_in = '1' or seen_l0 = '1') then l0_to_sm <= '1'; state_next <= wait_l1; else state_next <= dead_nol0; -- cnt_after_ptrg <= (others => '0'); end if; end if; when sent_l0 => cnt_after_ptrg <= cnt_after_ptrg + 1; seen_l1 <= '0'; if (cnt_after_ptrg >= ptrg_to_l1_acc) then state_next <= wait_l1; end if; when wait_l1 => cnt_after_ptrg <= cnt_after_ptrg + 1; if (l1_in = '1') then seen_l1 <= '1'; end if; if (cnt_after_ptrg >= ptrg_to_l1_send) then if (l1_in = '1' or seen_l1 = '1') then l1_to_sm <= '1'; state_next <= dead_l1a; else state_next <= dead_nol1; -- cnt_after_ptrg <= (others => '0'); end if; end if; when dead_nol0 => cnt_after_ptrg <= cnt_after_ptrg + 1; if cnt_after_ptrg >= ptrg_to_idle_nol0 then state_next <= idle; end if; when dead_nol1 => cnt_after_ptrg <= cnt_after_ptrg + 1; if cnt_after_ptrg >= ptrg_to_idle_nol1 then state_next <= idle; end if; when dead_l1a => -- dead time for operation w/o proper busy cnt_after_ptrg <= cnt_after_ptrg + 1; if (cnt_after_ptrg >= ptrg_to_idle) then state_next <= idle; end if; when others => state_next <= err; end case; end if; end process; end default;