----------------------------------------------------------------------------------
-- Company:        ETH Zurich, Institute for Particle Physics
-- Engineer:       Q. Weitzel
-- 
-- Create Date:    14:09:39 07/12/2010 
-- Design Name: 
-- Module Name:    FTU_clk_gen - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description:    interface to different DCMs and clk dividers for FTU board
--                 add here more DCMs if needed
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity FTU_clk_gen is
  Port (
    clk    : IN  STD_LOGIC;
    rst    : IN  STD_LOGIC;
    clk_50 : OUT STD_LOGIC;
    clk_1  : OUT STD_LOGIC;
    ready  : OUT STD_LOGIC
  );
end FTU_clk_gen;

architecture Behavioral of FTU_clk_gen is

  component FTU_dcm_50M_to_50M
    port (
      CLKIN_IN        : in    std_logic;
      RST_IN          : in    std_logic;
      CLKFX_OUT       : out   std_logic;
      CLKIN_IBUFG_OUT : out   std_logic;
      LOCKED_OUT      : out   std_logic);
  end component;

  component Clock_Divider
    port(
      clock_in  : IN  STD_LOGIC;
      clock_out : OUT STD_LOGIC
    );
  end component;

  signal clk_1M_sig  : std_logic;
  signal clk_50M_sig : std_logic;
  
begin

  Inst_FTU_dcm_50M_to_50M : FTU_dcm_50M_to_50M
    port map(
      CLKIN_IN        => clk,
      RST_IN          => rst,
      CLKFX_OUT       => clk_50M_sig,
      CLKIN_IBUFG_OUT => open,
      LOCKED_OUT      => ready
    );

  Inst_Clock_Divider : Clock_Divider
    port map (
      clock_in  => clk_50M_sig,
      clock_out => clk_1M_sig
    );

  clk_50 <= clk_50M_sig;
  clk_1  <= clk_1M_sig;
  
end Behavioral;

----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library ftu_definitions;
USE ftu_definitions.ftu_array_types.all;
USE ftu_definitions.ftu_constants.all;

entity Clock_Divider is
  generic(
    divider : integer := INT_CLK_FREQUENCY / COUNTER_FREQUENCY
  );
  port(
    clock_in  : in  std_logic;
    clock_out : out std_logic := '0'
  );
end entity Clock_Divider;

architecture RTL of Clock_Divider is

begin
    
  process (clock_in)
    variable Z: integer range 0 to divider - 1;
  begin
    if rising_edge(clock_in) then
      if (Z < divider - 1) then
        Z := Z + 1;
      else
        Z := 0;
      end if;
      if (Z = 0) then
        clock_out <= '1';
      end if;
      if (Z = divider / 2) then
        clock_out <= '0';
      end if;
    end if;
  end process;

end architecture RTL;
