-- -- Multi channel IODELAY2 delay programme -- -- 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 iodelay2_prog is port( reg_i : in std_logic_vector (15 downto 0); reg_wr_i : in std_logic; idelay_ctl_o : out t_idelay_ctl; idelay_cal_o : out std_logic; idelay_busy_i : in std_logic; rst : in std_logic; clk : in std_logic ); -- Declarations end iodelay2_prog; -- architecture rtl of iodelay2_prog is signal selected_hs : integer range 0 to 71; signal address : std_logic_vector(6 downto 0); signal delayval : std_logic_vector(7 downto 0); signal counter : std_logic_vector(7 downto 0); signal count_en : std_logic; signal idelay_cal : std_logic; --signal inc : std_logic; signal ce : std_logic_vector(71 downto 0); signal zero : std_logic_vector(71 downto 0); signal strm_swap : std_logic_vector (71 downto 0); signal strm_loop : std_logic_vector (71 downto 0); type states is (Reset, IssueCal0, IssueCal1, CalWaitBusy, ZeroDelay, ZDWaitBusy, CheckCounter, IncDelay, WaitBusy, Idle); signal state, nstate : states; begin idelay_ctl_o.ce <= ce(71 downto 0); idelay_ctl_o.zero <= zero(71 downto 0); idelay_ctl_o.inc <= '1'; -- we always inc idelay_ctl_o.strm_loop <= strm_loop(71 downto 0); idelay_ctl_o.strm_swap <= strm_swap(71 downto 0); selected_hs <= conv_integer(address); address <= reg_i(14 downto 8); delayval <= reg_i(7 downto 0); prc_store : process (clk) begin if rising_edge(clk) then -- if (rst = '1') then -- counter <= (others => '0'); -- else -- defaults strm_swap <= (others => '0'); strm_loop <= (others => '0'); --strm_swap (conv_integer(reg_i(14 downto 8))) <= reg_i(); strm_loop (conv_integer(reg_i(14 downto 8))) <= reg_i(15); if (reg_wr_i = '1') then counter <= delayval; else if (count_en = '1') then counter <= counter - '1'; end if; end if; -- end if; end if; end process; -- State Machine -------------------------------------------------------- prc_sm_clocked : process (clk) begin if rising_edge(clk) then if (rst = '1') then state <= Reset; else state <= nstate; end if; end if; end process; prc_sm_async : process (state, reg_wr_i, counter, selected_hs, idelay_busy_i) begin --defaults nstate <= Idle; ce <= (others => '0'); zero <= (others => '0'); count_en <= '0'; idelay_cal <= '0'; case state is when Reset => nstate <= Reset; if (idelay_busy_i = '0') then nstate <= IssueCal0; end if; when IssueCal0 => nstate <= IssueCal1; when IssueCal1 => idelay_cal <= '1'; nstate <= CalWaitBusy; when CalWaitBusy => nstate <= CalWaitBusy; if (idelay_busy_i = '0') then nstate <= Idle; end if; ----------------------------------------------------------- when Idle => nstate <= Idle; if (idelay_busy_i = '0') then if (reg_wr_i = '1') then nstate <= ZeroDelay; end if; end if; when ZeroDelay => zero(selected_hs) <= '1'; nstate <= ZDWaitBusy; when ZDWaitBusy => nstate <= ZDWaitBusy; if (idelay_busy_i = '0') then nstate <= CheckCounter; end if; ---------------------------------------------------------------- when CheckCounter => if (counter = "00000000") then nstate <= Idle; else nstate <= IncDelay; end if; when IncDelay => ce(selected_hs) <= '1'; count_en <= '1'; nstate <= WaitBusy; when WaitBusy => nstate <= WaitBusy; if (idelay_busy_i = '0') then nstate <= CheckCounter; end if; end case; end process; idelay_cal_o <= idelay_cal when rising_edge(clk); end architecture rtl;