From 18c0a8e73bacd2ccbb9089d7aa220290e95dcb76 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Tue, 21 Jan 2020 15:36:05 +0300 Subject: New Alpha platform with three clocks: * 45 MHz (aka "io_clk") is the I/O clock for the FMC bus * 90 MHz (aka "sys_clk") is the system clock for all the cores * 180 MHz (aka "core_clk") is the high-speed clock for high-performance cores --- rtl/clkmgr_mmcm.v | 241 ++++++++++++++++++++++++------------------------------ 1 file changed, 109 insertions(+), 132 deletions(-) (limited to 'rtl/clkmgr_mmcm.v') diff --git a/rtl/clkmgr_mmcm.v b/rtl/clkmgr_mmcm.v index 03b0747..afb5716 100644 --- a/rtl/clkmgr_mmcm.v +++ b/rtl/clkmgr_mmcm.v @@ -1,12 +1,12 @@ //====================================================================== // // clkmgr_mmcm.v -// --------------- +// ------------- // Xilinx MMCM primitive wrapper to avoid using Clocking Wizard IP core. // // // Author: Pavel Shatov -// Copyright (c) 2016, 2018, NORDUnet A/S All rights reserved. +// 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 @@ -37,144 +37,121 @@ //====================================================================== module clkmgr_mmcm - ( - input wire gclk_in, - input wire reset_in, - - output wire gclk_out, - output wire gclk_missing_out, +( + input fmc_clk_in, + input rst_in, + + output io_clk_out, + output sys_clk_out, + output core_clk_out, + output locked_out +); - output wire clk_out, - output wire clk_valid_out - ); - - - // - // Parameters - // - parameter CLK_OUT_MUL = 12.0; // multiply factor for output clock frequency (2..64) - parameter CLK_OUT_DIV = 12.0; // divide factor for output clock frequency (1..128) - parameter CLK_OUT_PHI = 45.0; // clock phase shift (0.0..360.0) - - - // - // IBUFG - // - - (* BUFFER_TYPE="NONE" *) - wire gclk_in_ibufg; - - IBUFG IBUFG_gclk - ( - .I (gclk_in), - .O (gclk_in_ibufg) - ); - - - // - // MMCME2_ADV - // - wire mmcm_clkout0; - wire mmcm_locked; - wire mmcm_clkfbout; - wire mmcm_clkfbout_bufg; - - MMCME2_ADV # - ( - .CLKIN1_PERIOD (11.111), - .REF_JITTER1 (0.010), - - .STARTUP_WAIT ("FALSE"), - .BANDWIDTH ("OPTIMIZED"), - .COMPENSATION ("ZHOLD"), - - .DIVCLK_DIVIDE (1), - - .CLKFBOUT_MULT_F (CLK_OUT_MUL), - .CLKFBOUT_PHASE (0.000), - .CLKFBOUT_USE_FINE_PS ("FALSE"), - - .CLKOUT0_DIVIDE_F (CLK_OUT_DIV), - .CLKOUT0_PHASE (CLK_OUT_PHI), - .CLKOUT0_USE_FINE_PS ("FALSE"), - .CLKOUT0_DUTY_CYCLE (0.500), - - .CLKOUT4_CASCADE ("FALSE") - ) - MMCME2_ADV_inst - ( - .CLKIN1 (gclk_in_ibufg), - .CLKIN2 (1'b0), - .CLKINSEL (1'b1), + parameter integer CLK_CORE_MULT = 4; - .CLKFBIN (mmcm_clkfbout_bufg), - .CLKFBOUT (mmcm_clkfbout), - .CLKFBOUTB (), - - .CLKINSTOPPED (gclk_missing_out), - .CLKFBSTOPPED (), + 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; - .CLKOUT0 (mmcm_clkout0), - .CLKOUT0B (), - - .CLKOUT1 (), - .CLKOUT1B (), - - .CLKOUT2 (), - .CLKOUT2B (), - - .CLKOUT3 (), - .CLKOUT3B (), - - .CLKOUT4 (), - .CLKOUT5 (), - .CLKOUT6 (), - - .DCLK (1'b0), - .DEN (1'b0), - .DWE (1'b0), - .DADDR (7'd0), - .DI (16'h0000), - .DO (), - .DRDY (), - - .PSCLK (1'b0), - .PSEN (1'b0), - .PSINCDEC (1'b0), - .PSDONE (), - - .LOCKED (mmcm_locked), - .PWRDWN (1'b0), - .RST (reset_in) - ); + 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) + ); - // - // Mapping - // - assign gclk_out = gclk_in_ibufg; - assign clk_valid_out = mmcm_locked; - - - // - // BUFGs - // - BUFG BUFG_gclk - ( - .I (mmcm_clkout0), - .O (clk_out) + 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_feedback - ( - .I (mmcm_clkfbout), - .O (mmcm_clkfbout_bufg) - ); - - + + 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.v +// EOF clkmgr_mmcm_io.v //====================================================================== -- cgit v1.2.3