----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    11:57:52 03/11/2013 
-- Design Name: 
-- Module Name:    dac_clk_out_mmcm - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

Library UNISIM;
use UNISIM.vcomponents.all;

entity dac_clk_out_mmcm is
    Port ( dac_clkout_in : in  STD_LOGIC;
           dac_ctrl_reg : in  STD_LOGIC_VECTOR(32 downto 0);
			  dac_clk_sel : in  STD_LOGIC;
           dac_mmcm_lock : OUT  STD_LOGIC;
           DAC_CLK_P             : OUT std_logic ;
           DAC_CLK_N             : OUT std_logic 
			);
end dac_clk_out_mmcm;

architecture Behavioral of dac_clk_out_mmcm is



signal clk_dac_1 : std_logic;
signal clk_dac_2 : std_logic;
signal clkfbout_pll : std_logic;
signal clk_dac_bufg : std_logic;
signal clk_dac_q : std_logic;
signal dac_mmcm_reset : std_logic;

begin

	dac_mmcm_reset <= dac_ctrl_reg(32) and dac_ctrl_reg(8);

   MMCM_BASE_inst : MMCM_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",  -- Jitter programming ("HIGH","LOW","OPTIMIZED")
      CLOCK_HOLD => FALSE,       -- Hold VCO Frequency (TRUE/FALSE)
      REF_JITTER1 => 0.0,        -- Reference input jitter in UI (0.000-0.999).
      STARTUP_WAIT => FALSE,      -- Not supported. Must be set to FALSE.

      CLKIN1_PERIOD     => 8.0,

		-- 125 / 5 * 40 = 1000MHz
      CLKFBOUT_MULT_F       => 40.0,
      DIVCLK_DIVIDE         => 5,

      CLKFBOUT_PHASE        => 0.000,

      CLKOUT0_DIVIDE_F => 1.0,   -- Divide amount for CLKOUT0 (1.000-128.000).
      -- CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
      CLKOUT6_DUTY_CYCLE => 0.5,
      -- CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLKOUT6_PHASE => 0.0,
      -- CLKOUT1_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
--		CLKOUT1_DIVIDE => 2, -- DAC CLK 500MHz
		CLKOUT1_DIVIDE => 4, -- DAC CLK 250MHz
--		CLKOUT1_DIVIDE => 8, -- DAC CLK 125MHz
      CLKOUT2_DIVIDE => 2, -- DAC CLK 500MHz
--		CLKOUT2_DIVIDE => 4, -- DAC CLK 250MHz
--		CLKOUT2_DIVIDE => 8, -- DAC CLK 125MHz
      CLKOUT3_DIVIDE => 1,
      CLKOUT4_DIVIDE => 1,
      CLKOUT5_DIVIDE => 1,
      CLKOUT6_DIVIDE => 1,
      CLKOUT4_CASCADE => FALSE   -- Cascase CLKOUT4 counter with CLKOUT6 (TRUE/FALSE)
   )
   port map (
      -- Clock Outputs: 1-bit (each) output: User configurable clock outputs
      CLKOUT0 => open,     -- 1-bit output: CLKOUT0 output
      CLKOUT0B => open,   -- 1-bit output: Inverted CLKOUT0 output
      CLKOUT1 => clk_dac_1,     -- 1-bit output: CLKOUT1 output
      CLKOUT1B => open,   -- 1-bit output: Inverted CLKOUT1 output
      CLKOUT2 => clk_dac_2,     -- 1-bit output: CLKOUT2 output
      CLKOUT2B => open,   -- 1-bit output: Inverted CLKOUT2 output
      CLKOUT3 => open,     -- 1-bit output: CLKOUT3 output
      CLKOUT3B => open,   -- 1-bit output: Inverted CLKOUT3 output
      CLKOUT4 => open,     -- 1-bit output: CLKOUT4 output
      CLKOUT5 => open,     -- 1-bit output: CLKOUT5 output
      CLKOUT6 => open,     -- 1-bit output: CLKOUT6 output
      -- Feedback Clocks: 1-bit (each) output: Clock feedback ports
      CLKFBOUT => clkfbout_pll,   -- 1-bit output: Feedback clock output
      CLKFBOUTB => open, -- 1-bit output: Inverted CLKFBOUT output
      -- Status Port: 1-bit (each) output: MMCM status ports
      LOCKED => dac_mmcm_lock,       -- 1-bit output: LOCK output
      -- Clock Input: 1-bit (each) input: Clock input
      CLKIN1 => dac_clkout_in,
      -- Control Ports: 1-bit (each) input: MMCM control ports
      PWRDWN => '0',       -- 1-bit input: Power-down input
      RST => dac_mmcm_reset,             -- 1-bit input: Reset input
      -- Feedback Clocks: 1-bit (each) input: Clock feedback ports
      CLKFBIN => clkfbout_pll      -- 1-bit input: Feedback clock input
   );

--  u_bufg_clk0 : BUFG
--    port map (
--     O => clk_dac_bufg,
--     I => clk_dac_1
--     );

   u_bufg_clk : BUFGMUX
   port map (
      O => clk_dac_bufg,   -- 1-bit output: Clock buffer output
      I0 => clk_dac_1, -- 1-bit input: Clock buffer input (S=0)
      I1 => clk_dac_2, -- 1-bit input: Clock buffer input (S=1)
      S => dac_clk_sel    -- 1-bit input: Clock buffer select
   );

-- test outputs

  adc1_clk_ODDR_inst : ODDR
   generic map(
      DDR_CLK_EDGE => "OPPOSITE_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE" 
      INIT => '0',   -- Initial value for Q port ('1' or '0')
      SRTYPE => "SYNC") -- Reset Type ("ASYNC" or "SYNC")
   port map (
      Q => clk_dac_q,   -- 1-bit DDR output
      C => clk_dac_bufg,    -- 1-bit clock input
      CE => '1',  -- 1-bit clock enable input
      D1 => '1',  -- 1-bit data input (positive edge)
      D2 => '0',  -- 1-bit data input (negative edge)
      R => '0',    -- 1-bit reset input
      S => '0'     -- 1-bit set input
   );
  
    dac_clk_obufds : OBUFDS
      port map (
        I  => clk_dac_q,
        O  => DAC_CLK_P,
        OB => DAC_CLK_N
      );
end Behavioral;
