-------------------------------------------------------
-- XILINX_DW.VHD Version 1.0                         --
-- Xilinx HDL Synthesis Design Guide                 --
-- Ilustrates gate reduction by the use of Synopsys  --
-- Designware compnents.  This is a lower-level      --
-- module with multiple arithmetic functions         --
-- December 1997                                     --
-------------------------------------------------------


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_misc.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_components.all;

entity xilinx_dw is
    Port (CHECK  : in    STD_LOGIC;
          RST 	 : in    STD_LOGIC;
          CLK 	 : in    STD_LOGIC;
          CLK_EN : in    STD_LOGIC;
          TICK 	 : in    STD_LOGIC;
          ST	 : out   STD_LOGIC);
end xilinx_dw;

architecture BEHAV of xilinx_dw is

    signal DCNT : STD_LOGIC_VECTOR(2 downto 0);
    signal ECNT : STD_LOGIC_VECTOR(4 downto 0);
    signal ZCNT : STD_LOGIC_VECTOR(6 downto 0);
    signal E2RQ, EQ2, ECNT_E, ZCNT_E, CLREVENT,
           CLRZERO, ST_INT : STD_LOGIC;

    begin

    ST_SYNC: process (CLK, RST)
    begin
	if (RST = '0') then
            E2RQ <= '0';
            EQ2 <= '0';
            ECNT_E <= '0';
            ZCNT_E <= '0';
            CLREVENT <= '0';
            CLRZERO <= '0';
            DCNT <= "000";
            ECNT <= "00000";
            ZCNT <= "0000000";
            ST_INT <= '0';
	elsif (CLK'event and CLK='1' ) then
            if (CLK_EN = '1') then
                if (ST_INT = '0') then
               	    if (E2RQ = '0') then
               		E2RQ <= '1';
             	    end if;
             	    if (EQ2 = '1') then
               		ECNT_E <= '0';
               	    	if (TICK = '1') then
	                    DCNT <= "000";
                 	    CLREVENT <= '1';
                	    EQ2 <= '0';
                 	    E2RQ <= '0';
               	    	end if;
             	    elsif (DCNT = "100") then
               		if (TICK = '1') then
                 	    CLREVENT <= '1';
                 	    DCNT <= "000";
                 	    ECNT_E <= '0';
                 	    if (ECNT = "00000" or ECNT = "00001") then
                   		ST_INT <= '1';
                   		E2RQ <= '0';
                 	    end if;
               		end if;
             	    elsif (TICK = '1') then
               		DCNT <= unsigned(DCNT) + '1';
               		ECNT_E <= '1';
             	    else
              		ECNT_E <= '1';
             	    end if;
		elsif (ST_INT = '1') then
             	    if (DCNT = "011") then
               		if (TICK = '1') then
                 	    ZCNT_E <= '0';
                 	    ECNT_E <= '0'; 
                 	    CLREVENT <= '1';
                 	    CLRZERO <= '1';
                 	    DCNT <= "000";
                 	    if (ECNT(4) = '1' and ZCNT /= "1100100") then
                    		ST_INT <= '0';
                 	    end if;
               		end if;
               	    elsif (TICK = '1') then
                 	ZCNT_E <= '1';
                 	ECNT_E <= '1';
                 	DCNT <= unsigned(DCNT) + '1';
               	    else
                 	ZCNT_E <= '1';
                 	ECNT_E <= '1';
                    end if;
                end if;
            end if;
            if (CLK_EN = '1') then
                if (CLREVENT = '1') then
            	    ECNT <= "00000";
               	    CLREVENT <= '0';
             	elsif (CHECK = '1' and ECNT_E = '1' and ECNT /= "10000" ) then
                    ECNT <= unsigned(ECNT) + '1';
             	end if;
             	if (E2RQ = '1') then
               	    if (ECNT = "00010") then
                 	EQ2 <= '1';
               	    end if;
             	end if;
		if (CLRZERO = '1' or (CHECK = '1' and ZCNT < "1100100")) then
               	    ZCNT <= "0000000";
                    CLRZERO <= '0';
             	elsif (CHECK = '0' and ZCNT_E = '1' and ZCNT /= "1100100" ) then
               	    ZCNT <= unsigned(ZCNT) + '1';
             	end if;
            end if;
        end if;
    end process; -- End ST_SYNC

    ST <= ST_INT;

end BEHAV;
