--------------------------------------------------------------------------------
-- CERN BE-CO-HT
--
-- https://www.ohwr.org/projects/wr2rf-vme
--------------------------------------------------------------------------------
--
-- unit name:   wr2rf_sysclks
--
-- description: Provides clean clocks for further distribution and usage
--
--------------------------------------------------------------------------------
-- Copyright CERN 2020
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

library unisim;
use unisim.vcomponents.all;

entity wr2rf_extclk is

    port (
       clk_ext_10m_i       : in  std_logic;
       clk_ext_stopped_o   : out  std_logic;       
       clk_ext_reset_i     : in  std_logic;
       clk_ext_locked_o    : out std_logic;
       clk_ext_125m_o      : out std_logic );

    attribute keep_hierarchy : string;
    attribute keep_hierarchy of wr2rf_extclk : entity is "yes";

end entity;

architecture rtl of wr2rf_extclk is

    -- Input clock buffering / unused connectors
    signal clkin1              : std_logic;
    -- Output clock buffering / unused connectors
    signal clkfbout            : std_logic;
    signal clkfbout_buf        : std_logic;
    signal clkfboutb_unused    : std_logic;
    signal clkout0             : std_logic;
    signal clkout0b_unused     : std_logic;
    signal clkout1_unused      : std_logic;
    signal clkout1b_unused     : std_logic;
    signal clkout2_unused      : std_logic;
    signal clkout2b_unused     : std_logic;
    signal clkout3_unused      : std_logic;
    signal clkout3b_unused     : std_logic;
    signal clkout4_unused      : std_logic;
    signal clkout5_unused      : std_logic;
    signal clkout6_unused      : std_logic;
    -- Dynamic programming unused signals
    signal do_unused           : std_logic_vector(15 downto 0);
    signal drdy_unused         : std_logic;
    -- Dynamic phase shift unused signals
    signal psdone_unused       : std_logic;
    -- Unused status signals
    signal clkfbstopped_unused : std_logic;

begin

    mmcm_adv_inst : MMCME2_ADV
       generic map (
          BANDWIDTH            => "OPTIMIZED",
          CLKOUT4_CASCADE      => FALSE,
          COMPENSATION         => "ZHOLD",
          STARTUP_WAIT         => FALSE,
          DIVCLK_DIVIDE        => 1,
          CLKFBOUT_MULT_F      => 62.500,
          CLKFBOUT_PHASE       => 0.000,
          CLKFBOUT_USE_FINE_PS => FALSE,
          CLKOUT0_DIVIDE_F     => 5.000,
          CLKOUT0_PHASE        => 0.000,
          CLKOUT0_DUTY_CYCLE   => 0.500,
          CLKOUT0_USE_FINE_PS  => FALSE,
          CLKIN1_PERIOD        => 100.000,
          REF_JITTER1          => 0.010)
       port map (
          -- Output clocks
          CLKFBOUT             => clkfbout,
          CLKFBOUTB            => clkfboutb_unused,
          CLKOUT0              => clkout0,
          CLKOUT0B             => clkout0b_unused,
          CLKOUT1              => clkout1_unused,
          CLKOUT1B             => clkout1b_unused,
          CLKOUT2              => clkout2_unused,
          CLKOUT2B             => clkout2b_unused,
          CLKOUT3              => clkout3_unused,
          CLKOUT3B             => clkout3b_unused,
          CLKOUT4              => clkout4_unused,
          CLKOUT5              => clkout5_unused,
          CLKOUT6              => clkout6_unused,
        -- Input clock control
          CLKFBIN              => clkfbout_buf,
          CLKIN1               => clk_ext_10m_i,
          CLKIN2               => '0',
          -- Tied to always select the primary input clock
          CLKINSEL             => '1',
          -- Ports for dynamic reconfiguration
          DADDR                => (others => '0'),
          DCLK                 => '0',
          DEN                  => '0',
          DI                   => (others => '0'),
          DO                   => do_unused,
          DRDY                 => drdy_unused,
          DWE                  => '0',
        -- Ports for dynamic phase shift
          PSCLK                => '0',
          PSEN                 => '0',
          PSINCDEC             => '0',
          PSDONE               => psdone_unused,
          -- Other control and status signals
          LOCKED               => clk_ext_locked_o,
          CLKINSTOPPED         => clk_ext_stopped_o,
          CLKFBSTOPPED         => clkfbstopped_unused,
          PWRDWN               => '0',
          RST                  => clk_ext_reset_i );
    
    clkf_buf : BUFG
       port map (
          O => clkfbout_buf,
          I => clkfbout );

    clkout1_buf : BUFG
       port map (
          O   => clk_ext_125m_o,
          I   => clkout0 );

end architecture;
