aboutsummaryrefslogblamecommitdiff
path: root/rtl/clkmgr_mmcm.v
blob: afb571634cb9a44e7a973ff9135ba7ea74488755 (plain) (tree)
1
2
3
4
5
6
7
8
9


                                                                        
                



                                                                        
                                                        





























                                                                           








                         
 
                                         
 



















                                                                   
 







                                                          
 





                         
 





































                                               
      























                          



                                                                        
                       
                                                                        
//======================================================================
//
// clkmgr_mmcm.v
// -------------
// Xilinx MMCM primitive wrapper to avoid using Clocking Wizard IP core.
//
//
// Author: Pavel Shatov
// Copyright (c) 2019, NORDUnet A/S All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in the
//   documentation and/or other materials provided with the distribution.
//
// - Neither the name of the NORDUnet nor the names of its contributors may
//   be used to endorse or promote products derived from this software
//   without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================

module clkmgr_mmcm
(
    input fmc_clk_in,
    input rst_in,
    
    output io_clk_out,
    output sys_clk_out,
    output core_clk_out,
    output locked_out
);

    parameter integer CLK_CORE_MULT = 4;

    function  integer lookup_vco_freq;
        input integer core_mult;
        case (core_mult)
            2: lookup_vco_freq =  990;
            3: lookup_vco_freq =  945;
            4: lookup_vco_freq = 1080;
            5: lookup_vco_freq =  900;
            6: lookup_vco_freq = 1080;
            7: lookup_vco_freq =  945;
            8: lookup_vco_freq = 1080;
        endcase
    endfunction
    
    localparam real FMC_CLK_PERIOD_F = 22.222;
    localparam real FB_PHASE_F       = 45.0;
    localparam real SYS_FREQ_F       = 90.0;
    
    localparam integer VCO_FREQ  = lookup_vco_freq(CLK_CORE_MULT);
    localparam integer IO_FREQ   = 45;
    localparam integer CORE_FREQ = CLK_CORE_MULT * IO_FREQ;

    localparam real VCO_FREQ_F = 1.0 * VCO_FREQ;
    localparam real FMC_FREQ_F = 1.0 * IO_FREQ;
    
    localparam real FB_MULT_F  = VCO_FREQ_F / FMC_FREQ_F;
    localparam real CLK0_DIV_F = VCO_FREQ_F / SYS_FREQ_F;
    
    localparam integer CLK1_DIV   = VCO_FREQ / IO_FREQ;
    localparam integer CLK2_DIV   = VCO_FREQ / CORE_FREQ;

    wire fmc_clk_ibufg;
    IBUFG IBUFG_fmc_clk
    (
        .I(fmc_clk_in),
        .O(fmc_clk_ibufg)
    );

    wire mmcm_clkout0;
    wire mmcm_clkout1;
    wire mmcm_clkout2;
    wire mmcm_clkfbin;
    wire mmcm_clkfbout;
    MMCME2_BASE #
    (
        .CLKIN1_PERIOD      (FMC_CLK_PERIOD_F),
        .CLKFBOUT_MULT_F    (FB_MULT_F),
        .CLKFBOUT_PHASE     (FB_PHASE_F),
        .CLKOUT0_DIVIDE_F   (CLK0_DIV_F),
        .CLKOUT1_DIVIDE     (CLK1_DIV),
        .CLKOUT2_DIVIDE     (CLK2_DIV)
    )
    MMCME2_BASE_io_clk
    (
        .CLKIN1     (fmc_clk_ibufg),
        .RST        (rst_in),
        .PWRDWN     (1'b0),

        .LOCKED     (locked_out),

      
        .CLKFBOUT   (mmcm_clkfbout),
        .CLKFBOUTB  (),
        .CLKFBIN    (mmcm_clkfbin),
      
        .CLKOUT0    (mmcm_clkout0),
        .CLKOUT0B   (),
        .CLKOUT1    (mmcm_clkout1),
        .CLKOUT1B   (),
        .CLKOUT2    (mmcm_clkout2),
        .CLKOUT2B   (),
        .CLKOUT3    (),
        .CLKOUT3B   (),
        .CLKOUT4    (),
        .CLKOUT5    (),
        .CLKOUT6    ()
    );

    BUFG BUFG_clkfb
    (
        .I(mmcm_clkfbout),
        .O(mmcm_clkfbin)
    );

    BUFG BUFG_clk_io
    (
        .I(mmcm_clkout0),
        .O(sys_clk_out)
    );
    
    BUFG BUFG_clk_sys
    (
        .I(mmcm_clkout1),
        .O(io_clk_out)
    );
    
    BUFG BUFG_clk_core
    (
        .I(mmcm_clkout2),
        .O(core_clk_out)
    );

endmodule

//======================================================================
// EOF clkmgr_mmcm_io.v
//======================================================================