|
|
@@ -1,867 +0,0 @@
|
|
|
-//-------------------------------------------------------------------------------------------
|
|
|
-// ____ ____
|
|
|
-// / /\/ /
|
|
|
-// /___/ \ /
|
|
|
-// \ \ \/ � Copyright 2019 Xilinx, Inc. All rights reserved.
|
|
|
-// \ \ This file contains confidential and proprietary information of Xilinx, Inc.
|
|
|
-// / / and is protected under U.S. and international copyright and other
|
|
|
-// /___/ /\ intellectual property laws.
|
|
|
-// \ \ / \
|
|
|
-// \___\/\___\
|
|
|
-//
|
|
|
-//-------------------------------------------------------------------------------------------
|
|
|
-// Device: 7_Series
|
|
|
-// Author: Tatsukawa, Kruger, Ribbing, Defossez
|
|
|
-// Entity Name: mmcme2_drp
|
|
|
-// Purpose: This calls the DRP register calculation functions and
|
|
|
-// provides a state machine to perform MMCM reconfiguration
|
|
|
-// based on the calculated values stored in a initialized
|
|
|
-// ROM.
|
|
|
-// 7-Series MMCM is called: MMCME2
|
|
|
-// Ultrascale MMCM is called: MMCME3
|
|
|
-// UltrascalePlus MMCM is called: MMCME4
|
|
|
-// MMCME3 attributes
|
|
|
-// CLKINx_PERIOD: 0.968 to 100.000 (x = 1 or 2)
|
|
|
-// REF_JITTERx: 0.001 to 0.999 (x = 1 or 2)
|
|
|
-// BANDWIDTH: LOW, HIGH, OPTIMIZED and POSTCRC
|
|
|
-// COMPENSATION: AUTO, ZHOLD, EXTERNAL, INTERNAL and BUF_IN
|
|
|
-// DIVCLK_DIVIDE: 1 to 106
|
|
|
-// CLKFBOUT_MULT_F: 2 to 64
|
|
|
-// CLKFBOUT_PHASE: -360 to 360
|
|
|
-// CLKOUTn_DIVIDE: 1 to 128 (n = 0 to 6)
|
|
|
-// CLKOUTn_PHASE: -360 to 360 (n = 0 to 6)
|
|
|
-// CLKOUTn_DUTY_CYCLE: 0.01 to 0.99 (n = 0 to 6)
|
|
|
-//
|
|
|
-// Tools: Vivado_2019.1 or newer
|
|
|
-// Limitations: None
|
|
|
-//
|
|
|
-// Vendor: Xilinx Inc.
|
|
|
-// Version: 1.40
|
|
|
-// Filename: mmcme3_drp.v
|
|
|
-// Date Created: 22-Oct-2014
|
|
|
-// Date Last Modified: 25-Jun-2019
|
|
|
-//-------------------------------------------------------------------------------------------
|
|
|
-// Disclaimer:
|
|
|
-// This disclaimer is not a license and does not grant any rights to the materials
|
|
|
-// distributed herewith. Except as otherwise provided in a valid license issued to you
|
|
|
-// by Xilinx, and to the maximum extent permitted by applicable law: (1) THESE MATERIALS
|
|
|
-// ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL
|
|
|
-// WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED
|
|
|
-// TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR
|
|
|
-// PURPOSE; and (2) Xilinx shall not be liable (whether in contract or tort, including
|
|
|
-// negligence, or under any other theory of liability) for any loss or damage of any
|
|
|
-// kind or nature related to, arising under or in connection with these materials,
|
|
|
-// including for any direct, or any indirect, special, incidental, or consequential
|
|
|
-// loss or damage (including loss of data, profits, goodwill, or any type of loss or
|
|
|
-// damage suffered as a result of any action brought by a third party) even if such
|
|
|
-// damage or loss was reasonably foreseeable or Xilinx had been advised of the
|
|
|
-// possibility of the same.
|
|
|
-//
|
|
|
-// CRITICAL APPLICATIONS
|
|
|
-// Xilinx products are not designed or intended to be fail-safe, or for use in any
|
|
|
-// application requiring fail-safe performance, such as life-support or safety devices
|
|
|
-// or systems, Class III medical devices, nuclear facilities, applications related to
|
|
|
-// the deployment of airbags, or any other applications that could lead to death,
|
|
|
-// personal injury, or severe property or environmental damage (individually and
|
|
|
-// collectively, "Critical Applications"). Customer assumes the sole risk and
|
|
|
-// liability of any use of Xilinx products in Critical Applications, subject only to
|
|
|
-// applicable laws and regulations governing limitations on product liability.
|
|
|
-//
|
|
|
-// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
|
|
|
-//
|
|
|
-// Contact: e-mail hotline@xilinx.com phone + 1 800 255 7778
|
|
|
-//-------------------------------------------------------------------------------------------
|
|
|
-// Revision History:
|
|
|
-// Rev: 13-Jan-2011 - Tatsukawa
|
|
|
-// Updated ROM[18,41] LOCKED bitmask to 16'HFC00
|
|
|
-// Rev: 30-May-2013 - Tatsukawa
|
|
|
-// Adding Fractional support for CLKFBOUT_MULT_F, CLKOUT0_DIVIDE_F
|
|
|
-// Rev: 30-Apr-2014 - Tatsukawa
|
|
|
-// For fractional multiply changed order to enable fractional
|
|
|
-// before the multiply is applied to prevent false VCO DRCs
|
|
|
-// (e.g. DADDR 7'h15 must be set before updating 7'h14)
|
|
|
-// Rev: 24-Oct-2014 - Ribbing
|
|
|
-// Parameters have been added to clarify Reg1/Reg2/Shared registers
|
|
|
-// Rev: 08-Jun-2015 - Kruger
|
|
|
-// WAIT_LOCK update
|
|
|
-// Rev: 02-May-2016 - Kruger
|
|
|
-// Reordering FRAC_EN bits DADDR(7'h09, 7'h15)
|
|
|
-// Registers before frac settings (7'h08, 7'h14)
|
|
|
-// Rev: 19-Sep-2018 - Defossez
|
|
|
-// Updated comments of BANDWIDTH.
|
|
|
-// Corrected some typos.
|
|
|
-// Rev: 25-Jun-2019 - Defossez
|
|
|
-// Adding registering possibility for LOCKE signal.
|
|
|
-//-------------------------------------------------------------------------------------------
|
|
|
-//
|
|
|
-`timescale 1ps/1ps
|
|
|
-//
|
|
|
-module mmcme2_drp
|
|
|
- #(
|
|
|
- // Register the LOCKED signal with teh MMCME3_ADV input clock.
|
|
|
- // The LOCKED_IN (LOCKED from the MMCME3_ADV) is fed into a register and then
|
|
|
- // passed the LOCKED_OUT when REGISTER_LOCKED is set to "Reg" or when set to
|
|
|
- // "NoReg" LOCKED_IN is just passed on to LOCKED_OUT without being registered.
|
|
|
- parameter REGISTER_LOCKED = "Reg",
|
|
|
- // Use the registered LOCKED signal from the MMCME3 also for the DRP state machine.
|
|
|
- parameter USE_REG_LOCKED = "No",
|
|
|
- // Possible/allowed combinations of above two parameters:
|
|
|
- // | REGISTER_LOCKED | USE_REG_LOCKED | |
|
|
|
- // |-----------------|----------------|--------------------------------------------|
|
|
|
- // | "NoReg" | "No" | LOCKED is just passed through mmcme3_drp |
|
|
|
- // | | | and is used as is with the state machine |
|
|
|
- // | "NoReg" | "Yes" | NOT ALLOWED |
|
|
|
- // | "Reg" | "No" | LOCKED is registered but the unregistered |
|
|
|
- // | | | version is used for the state machine. |
|
|
|
- // | "Reg" | "Yes" | LOCKED is registered and the registered |
|
|
|
- // | | | version is also used by the state machine. |
|
|
|
- //
|
|
|
- //***********************************************************************
|
|
|
- // State 1 Parameters - These are for the first reconfiguration state.
|
|
|
- //***********************************************************************
|
|
|
- //
|
|
|
- // These parameters have an effect on the feedback path. A change on
|
|
|
- // these parameters will effect all of the clock outputs.
|
|
|
- //
|
|
|
- // The parameters are composed of:
|
|
|
- // _MULT: This can be from 2 to 64. It has an effect on the VCO
|
|
|
- // frequency which consequently, effects all of the clock
|
|
|
- // outputs.
|
|
|
- // _PHASE: This is the phase multiplied by 1000. For example if
|
|
|
- // a phase of 24.567 deg was desired the input value would be
|
|
|
- // 24567. The range for the phase is from -360000 to 360000.
|
|
|
- // _FRAC: This can be from 0 to 875. This represents the fractional
|
|
|
- // divide multiplied by 1000.
|
|
|
- // M = _MULT + _FRAC / 1000
|
|
|
- // e.g. M=8.125
|
|
|
- // _MULT = 8
|
|
|
- // _FRAC = 125
|
|
|
- // _FRAC_EN: This indicates fractional divide has been enabled. If 1
|
|
|
- // then the fractional divide algorithm will be used to calculate
|
|
|
- // register settings. If 0 then default calculation to be used.
|
|
|
- parameter S1_CLKFBOUT_MULT = 13,
|
|
|
- parameter S1_CLKFBOUT_PHASE = 0,
|
|
|
- parameter S1_CLKFBOUT_FRAC = 125,
|
|
|
- parameter S1_CLKFBOUT_FRAC_EN = 1,
|
|
|
- //
|
|
|
- // The bandwidth parameter effects the phase error and the jitter filter
|
|
|
- // capability of the MMCM. For more information on this parameter see the
|
|
|
- // Device user guide.
|
|
|
- // Possible values are: "LOW", "LOW_SS", "HIGH" and "OPTIMIZED"
|
|
|
- parameter S1_BANDWIDTH = "LOW",
|
|
|
- //
|
|
|
- // The divclk parameter allows the input clock to be divided before it
|
|
|
- // reaches the phase and frequency comparator. This can be set between
|
|
|
- // 1 and 128.
|
|
|
- parameter S1_DIVCLK_DIVIDE = 1,
|
|
|
-
|
|
|
- // The following parameters describe the configuration that each clock
|
|
|
- // output should have once the reconfiguration for state one has
|
|
|
- // completed.
|
|
|
- //
|
|
|
- // The parameters are composed of:
|
|
|
- // _DIVIDE: This can be from 1 to 128
|
|
|
- // _PHASE: This is the phase multiplied by 1000. For example if
|
|
|
- // a phase of 24.567 deg was desired the input value would be
|
|
|
- // 24567. The range for the phase is from -360000 to 360000.
|
|
|
- // _DUTY: This is the duty cycle multiplied by 100,000. For example if
|
|
|
- // a duty cycle of .24567 was desired the input would be
|
|
|
- // 24567.
|
|
|
- //
|
|
|
- parameter S1_CLKOUT0_DIVIDE = 2,
|
|
|
- parameter S1_CLKOUT0_PHASE = 0,
|
|
|
- parameter S1_CLKOUT0_DUTY = 50000,
|
|
|
- parameter S1_CLKOUT0_FRAC = 125,
|
|
|
- parameter S1_CLKOUT0_FRAC_EN = 1,
|
|
|
- //
|
|
|
- parameter S1_CLKOUT1_DIVIDE = 1,
|
|
|
- parameter S1_CLKOUT1_PHASE = 0,
|
|
|
- parameter S1_CLKOUT1_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S1_CLKOUT2_DIVIDE = 1,
|
|
|
- parameter S1_CLKOUT2_PHASE = 0,
|
|
|
- parameter S1_CLKOUT2_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S1_CLKOUT3_DIVIDE = 1,
|
|
|
- parameter S1_CLKOUT3_PHASE = 0,
|
|
|
- parameter S1_CLKOUT3_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S1_CLKOUT4_DIVIDE = 1,
|
|
|
- parameter S1_CLKOUT4_PHASE = 0,
|
|
|
- parameter S1_CLKOUT4_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S1_CLKOUT5_DIVIDE = 1,
|
|
|
- parameter S1_CLKOUT5_PHASE = 0,
|
|
|
- parameter S1_CLKOUT5_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S1_CLKOUT6_DIVIDE = 1,
|
|
|
- parameter S1_CLKOUT6_PHASE = 0,
|
|
|
- parameter S1_CLKOUT6_DUTY = 50000,
|
|
|
- //
|
|
|
- //***********************************************************************
|
|
|
- // State 2 Parameters - These are for the second reconfiguration state.
|
|
|
- //***********************************************************************
|
|
|
- //
|
|
|
- // These parameters have an effect on the feedback path. A change on
|
|
|
- // these parameters will effect all of the clock outputs.
|
|
|
- //
|
|
|
- // The parameters are composed of:
|
|
|
- // _MULT: This can be from 2 to 64. It has an effect on the VCO
|
|
|
- // frequency which consequently, effects all of the clock
|
|
|
- // outputs.
|
|
|
- // _PHASE: This is the phase multiplied by 1000. For example if
|
|
|
- // a phase of 24.567 deg was desired the input value would be
|
|
|
- // 24567. The range for the phase is from -360000 to 360000.
|
|
|
- // _FRAC: This can be from 0 to 875. This represents the fractional
|
|
|
- // divide multiplied by 1000.
|
|
|
- // M = _MULT + _FRAC / 1000
|
|
|
- // e.g. M=8.125
|
|
|
- // _MULT = 8
|
|
|
- // _FRAC = 125
|
|
|
- // _FRAC_EN: This indicates fractional divide has been enabled. If 1
|
|
|
- // then the fractional divide algorithm will be used to calculate
|
|
|
- // register settings. If 0 then default calculation to be used.
|
|
|
- parameter S2_CLKFBOUT_MULT = 1,
|
|
|
- parameter S2_CLKFBOUT_PHASE = 0,
|
|
|
- parameter S2_CLKFBOUT_FRAC = 125,
|
|
|
- parameter S2_CLKFBOUT_FRAC_EN = 1,
|
|
|
- //
|
|
|
- // The bandwidth parameter effects the phase error and the jitter filter
|
|
|
- // capability of the MMCM. For more information on this parameter see the
|
|
|
- // Device user guide.
|
|
|
- // Possible values are: "LOW", "LOW_SS", "HIGH" and "OPTIMIZED"
|
|
|
- parameter S2_BANDWIDTH = "LOW",
|
|
|
- //
|
|
|
- // The divclk parameter allows the input clock to be divided before it
|
|
|
- // reaches the phase and frequency comparator. This can be set between
|
|
|
- // 1 and 128.
|
|
|
- parameter S2_DIVCLK_DIVIDE = 1,
|
|
|
- //
|
|
|
- // The following parameters describe the configuration that each clock
|
|
|
- // output should have once the reconfiguration for state one has
|
|
|
- // completed.
|
|
|
- //
|
|
|
- // The parameters are composed of:
|
|
|
- // _DIVIDE: This can be from 1 to 128
|
|
|
- // _PHASE: This is the phase multiplied by 1000. For example if
|
|
|
- // a phase of 24.567 deg was desired the input value would be
|
|
|
- // 24567. The range for the phase is from -360000 to 360000
|
|
|
- // _DUTY: This is the duty cycle multiplied by 100,000. For example if
|
|
|
- // a duty cycle of .24567 was desired the input would be
|
|
|
- // 24567.
|
|
|
- //
|
|
|
- parameter S2_CLKOUT0_DIVIDE = 1,
|
|
|
- parameter S2_CLKOUT0_PHASE = 0,
|
|
|
- parameter S2_CLKOUT0_DUTY = 50000,
|
|
|
- parameter S2_CLKOUT0_FRAC = 125,
|
|
|
- parameter S2_CLKOUT0_FRAC_EN = 1,
|
|
|
- //
|
|
|
- parameter S2_CLKOUT1_DIVIDE = 2,
|
|
|
- parameter S2_CLKOUT1_PHASE = 0,
|
|
|
- parameter S2_CLKOUT1_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S2_CLKOUT2_DIVIDE = 3,
|
|
|
- parameter S2_CLKOUT2_PHASE = 0,
|
|
|
- parameter S2_CLKOUT2_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S2_CLKOUT3_DIVIDE = 4,
|
|
|
- parameter S2_CLKOUT3_PHASE = 0,
|
|
|
- parameter S2_CLKOUT3_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S2_CLKOUT4_DIVIDE = 5,
|
|
|
- parameter S2_CLKOUT4_PHASE = 0,
|
|
|
- parameter S2_CLKOUT4_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S2_CLKOUT5_DIVIDE = 5,
|
|
|
- parameter S2_CLKOUT5_PHASE = 0,
|
|
|
- parameter S2_CLKOUT5_DUTY = 50000,
|
|
|
- //
|
|
|
- parameter S2_CLKOUT6_DIVIDE = 5,
|
|
|
- parameter S2_CLKOUT6_PHASE = -90,
|
|
|
- parameter S2_CLKOUT6_DUTY = 50000
|
|
|
- ) (
|
|
|
- // These signals are controlled by user logic interface and are covered
|
|
|
- // in more detail within the XAPP.
|
|
|
- input SADDR,
|
|
|
- input SEN,
|
|
|
- input SCLK,
|
|
|
- input RST,
|
|
|
- output reg SRDY,
|
|
|
-
|
|
|
-
|
|
|
- // input [7:0] ClkDiv1_i,
|
|
|
- // input [7:0] ClkDiv2_i,
|
|
|
- // input [7:0] ClkDiv3_i,
|
|
|
- // input [7:0] ClkDiv4_i,
|
|
|
- // input [7:0] ClkDiv5_i,
|
|
|
- // input [7:0] ClkDiv6_i,
|
|
|
- // input [7:0] ClkDiv7_i,
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- //
|
|
|
- // These signals are to be connected to the MMCM_ADV by port name.
|
|
|
- // Their use matches the MMCM port description in the Device User Guide.
|
|
|
- input [15:0] DO,
|
|
|
- input DRDY,
|
|
|
- input LOCK_REG_CLK_IN,
|
|
|
- input LOCKED_IN,
|
|
|
- output reg DWE,
|
|
|
- output reg DEN,
|
|
|
- output reg [6:0] DADDR,
|
|
|
- output reg [15:0] DI,
|
|
|
- output DCLK,
|
|
|
- output reg RST_MMCM,
|
|
|
- output LOCKED_OUT
|
|
|
- );
|
|
|
-//----------------------------------------------------------------------------------------
|
|
|
- //
|
|
|
- wire IntLocked;
|
|
|
- wire IntRstMmcm;
|
|
|
- wire [15:0] clkVal;
|
|
|
- wire [15:0] fracPart;
|
|
|
- assign clkVal = 16'h208;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- //
|
|
|
- // 100 ps delay for behavioral simulations
|
|
|
- localparam TCQ = 100;
|
|
|
-
|
|
|
- // Make sure the memory is implemented as distributed
|
|
|
- (* rom_style = "distributed" *)
|
|
|
- //
|
|
|
- // ROM of: 39 bit word 64 words deep
|
|
|
- reg [38:0] rom [63:0];
|
|
|
- reg [5:0] rom_addr;
|
|
|
- reg [38:0] rom_do;
|
|
|
- reg next_srdy;
|
|
|
- reg [5:0] next_rom_addr;
|
|
|
- reg [6:0] next_daddr;
|
|
|
- reg next_dwe;
|
|
|
- reg next_den;
|
|
|
- reg next_rst_mmcm;
|
|
|
- reg [15:0] next_di;
|
|
|
- //
|
|
|
- // Insert a register in LOCKED or not depending on the value given to the parameters
|
|
|
- // REGISTER_LOCKED. When REGISTER_LOCKED is set to "Reg" insert a register, when set
|
|
|
- // to "NoReg" don't insert a register but just pass the LOCKED signal from input to
|
|
|
- // output.
|
|
|
- // Use or not, under USE_REG_LOCKED parameter control, the registered version of the
|
|
|
- // LOCKED signal for the DRP state machine.
|
|
|
- // Possible/allowed combinations of the two LOCKED related parameters:
|
|
|
- //
|
|
|
- // | REGISTER_LOCKED | USE_REG_LOCKED | |
|
|
|
- // |-----------------|----------------|--------------------------------------------|
|
|
|
- // | "NoReg" | "No" | LOCKED is just passed through mmcme3_drp |
|
|
|
- // | | | and is used as is with the state machine |
|
|
|
- // | "NoReg" | "Yes" | NOT ALLOWED |
|
|
|
- // | "Reg" | "No" | LOCKED is registered but the unregistered |
|
|
|
- // | | | version is used for the state machine. |
|
|
|
- // | "Reg" | "Yes" | LOCKED is registered and the registered |
|
|
|
- // | | | version is also used by the state machine. |
|
|
|
- //
|
|
|
- generate
|
|
|
- if (REGISTER_LOCKED == "NoReg" && USE_REG_LOCKED == "No") begin
|
|
|
- assign LOCKED_OUT = LOCKED_IN;
|
|
|
- assign IntLocked = LOCKED_IN;
|
|
|
- end else if (REGISTER_LOCKED == "Reg" && USE_REG_LOCKED == "No") begin
|
|
|
- FDRE #(
|
|
|
- .INIT (0),
|
|
|
- .IS_C_INVERTED (0),
|
|
|
- .IS_D_INVERTED (0),
|
|
|
- .IS_R_INVERTED (0)
|
|
|
- ) mmcme3_drp_I_Fdrp (
|
|
|
- .D (LOCKED_IN),
|
|
|
- .CE (1'b1),
|
|
|
- .R (IntRstMmcm),
|
|
|
- .C (LOCK_REG_CLK_IN),
|
|
|
- .Q (LOCKED_OUT)
|
|
|
- );
|
|
|
- //
|
|
|
- assign IntLocked = LOCKED_IN;
|
|
|
- end else if (REGISTER_LOCKED == "Reg" && USE_REG_LOCKED == "Yes") begin
|
|
|
- FDRE #(
|
|
|
- .INIT (0),
|
|
|
- .IS_C_INVERTED (0),
|
|
|
- .IS_D_INVERTED (0),
|
|
|
- .IS_R_INVERTED (0)
|
|
|
- ) mmcme3_drp_I_Fdrp (
|
|
|
- .D (LOCKED_IN),
|
|
|
- .CE (1'b1),
|
|
|
- .R (IntRstMmcm),
|
|
|
- .C (LOCK_REG_CLK_IN),
|
|
|
- .Q (LOCKED_OUT)
|
|
|
- );
|
|
|
- //
|
|
|
- assign IntLocked = LOCKED_OUT;
|
|
|
- end
|
|
|
- endgenerate
|
|
|
-
|
|
|
- // Integer used to initialize remainder of unused ROM
|
|
|
- integer ii;
|
|
|
-
|
|
|
- // Pass SCLK to DCLK for the MMCM
|
|
|
- assign DCLK = SCLK;
|
|
|
- assign IntRstMmcm = RST_MMCM;
|
|
|
-
|
|
|
- // Include the MMCM reconfiguration functions. This contains the constant
|
|
|
- // functions that are used in the calculations below. This file is
|
|
|
- // required.
|
|
|
- `include "mmcme2_drp_func.h"
|
|
|
-
|
|
|
- //**************************************************************************
|
|
|
- // State 1 Calculations
|
|
|
- //**************************************************************************
|
|
|
- // Please see header for information.
|
|
|
- localparam [37:0] S1_CLKFBOUT =
|
|
|
- mmcm_count_calc(S1_CLKFBOUT_MULT, S1_CLKFBOUT_PHASE, 50000);
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKFBOUT_FRAC_CALC =
|
|
|
- mmcm_frac_count_calc(S1_CLKFBOUT_MULT, S1_CLKFBOUT_PHASE, 50000, S1_CLKFBOUT_FRAC);
|
|
|
-
|
|
|
- localparam [9:0] S1_DIGITAL_FILT =
|
|
|
- mmcm_filter_lookup(S1_CLKFBOUT_MULT, S1_BANDWIDTH);
|
|
|
-
|
|
|
- localparam [39:0] S1_LOCK =
|
|
|
- mmcm_lock_lookup(S1_CLKFBOUT_MULT);
|
|
|
-
|
|
|
- localparam [37:0] S1_DIVCLK =
|
|
|
- mmcm_count_calc(S1_DIVCLK_DIVIDE, 0, 50000);
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT0 =
|
|
|
- mmcm_count_calc(S1_CLKOUT0_DIVIDE, S1_CLKOUT0_PHASE, S1_CLKOUT0_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT0_REG1 = S1_CLKOUT0[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT0_REG2 = S1_CLKOUT0[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT0_FRAC_CALC =
|
|
|
- mmcm_frac_count_calc(S1_CLKOUT0_DIVIDE, S1_CLKOUT0_PHASE, 50000, S1_CLKOUT0_FRAC);
|
|
|
- localparam [15:0] S1_CLKOUT0_FRAC_REG1 = S1_CLKOUT0_FRAC_CALC[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT0_FRAC_REG2 = S1_CLKOUT0_FRAC_CALC[31:16]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [5:0] S1_CLKOUT0_FRAC_REGSHARED = S1_CLKOUT0_FRAC_CALC[37:32]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT1 =
|
|
|
- mmcm_count_calc(S1_CLKOUT1_DIVIDE, S1_CLKOUT1_PHASE, S1_CLKOUT1_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT1_REG1 = S1_CLKOUT1[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT1_REG2 = S1_CLKOUT1[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT2 =
|
|
|
- mmcm_count_calc(S1_CLKOUT2_DIVIDE, S1_CLKOUT2_PHASE, S1_CLKOUT2_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT2_REG1 = S1_CLKOUT2[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT2_REG2 = S1_CLKOUT2[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT3 =
|
|
|
- mmcm_count_calc(S1_CLKOUT3_DIVIDE, S1_CLKOUT3_PHASE, S1_CLKOUT3_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT3_REG1 = S1_CLKOUT3[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT3_REG2 = S1_CLKOUT3[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT4 =
|
|
|
- mmcm_count_calc(S1_CLKOUT4_DIVIDE, S1_CLKOUT4_PHASE, S1_CLKOUT4_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT4_REG1 = S1_CLKOUT4[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT4_REG2 = S1_CLKOUT4[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT5 =
|
|
|
- mmcm_count_calc(S1_CLKOUT5_DIVIDE, S1_CLKOUT5_PHASE, S1_CLKOUT5_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT5_REG1 = S1_CLKOUT5[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT5_REG2 = S1_CLKOUT5[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S1_CLKOUT6 =
|
|
|
- mmcm_count_calc(S1_CLKOUT6_DIVIDE, S1_CLKOUT6_PHASE, S1_CLKOUT6_DUTY);
|
|
|
- localparam [15:0] S1_CLKOUT6_REG1 = S1_CLKOUT6[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S1_CLKOUT6_REG2 = S1_CLKOUT6[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- //**************************************************************************
|
|
|
- // State 2 Calculations
|
|
|
- //**************************************************************************
|
|
|
- localparam [37:0] S2_CLKFBOUT =
|
|
|
- mmcm_count_calc(S2_CLKFBOUT_MULT, S2_CLKFBOUT_PHASE, 50000);
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKFBOUT_FRAC_CALC =
|
|
|
- mmcm_frac_count_calc(S2_CLKFBOUT_MULT, S2_CLKFBOUT_PHASE, 50000, S2_CLKFBOUT_FRAC);
|
|
|
-
|
|
|
- localparam [9:0] S2_DIGITAL_FILT =
|
|
|
- mmcm_filter_lookup(S2_CLKFBOUT_MULT, S2_BANDWIDTH);
|
|
|
-
|
|
|
- localparam [39:0] S2_LOCK =
|
|
|
- mmcm_lock_lookup(S2_CLKFBOUT_MULT);
|
|
|
-
|
|
|
- localparam [37:0] S2_DIVCLK =
|
|
|
- mmcm_count_calc(S2_DIVCLK_DIVIDE, 0, 50000);
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT0 =
|
|
|
- mmcm_count_calc(S2_CLKOUT0_DIVIDE, S2_CLKOUT0_PHASE, S2_CLKOUT0_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT0_REG1 = S2_CLKOUT0[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT0_REG2 = S2_CLKOUT0[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT0_FRAC_CALC =
|
|
|
- mmcm_frac_count_calc(S2_CLKOUT0_DIVIDE, S2_CLKOUT0_PHASE, 50000, S2_CLKOUT0_FRAC);
|
|
|
- localparam [15:0] S2_CLKOUT0_FRAC_CALC_REG1 = S2_CLKOUT0_FRAC_CALC[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT0_FRAC_CALC_REG2 = S2_CLKOUT0_FRAC_CALC[31:16]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT0_FRAC_CALC_REGSHARED = S2_CLKOUT0_FRAC_CALC[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT1 =
|
|
|
- mmcm_count_calc(S2_CLKOUT1_DIVIDE, S2_CLKOUT1_PHASE, S2_CLKOUT1_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT1_REG1 = S2_CLKOUT1[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT1_REG2 = S2_CLKOUT1[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT2 =
|
|
|
- mmcm_count_calc(S2_CLKOUT2_DIVIDE, S2_CLKOUT2_PHASE, S2_CLKOUT2_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT2_REG1 = S2_CLKOUT2[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT2_REG2 = S2_CLKOUT2[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT3 =
|
|
|
- mmcm_count_calc(S2_CLKOUT3_DIVIDE, S2_CLKOUT3_PHASE, S2_CLKOUT3_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT3_REG1 = S2_CLKOUT3[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT3_REG2 = S2_CLKOUT3[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT4 =
|
|
|
- mmcm_count_calc(S2_CLKOUT4_DIVIDE, S2_CLKOUT4_PHASE, S2_CLKOUT4_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT4_REG1 = S2_CLKOUT4[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT4_REG2 = S2_CLKOUT4[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT5 =
|
|
|
- mmcm_count_calc(S2_CLKOUT5_DIVIDE, S2_CLKOUT5_PHASE, S2_CLKOUT5_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT5_REG1 = S2_CLKOUT5[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT5_REG2 = S2_CLKOUT5[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- localparam [37:0] S2_CLKOUT6 =
|
|
|
- mmcm_count_calc(S2_CLKOUT6_DIVIDE, S2_CLKOUT6_PHASE, S2_CLKOUT6_DUTY);
|
|
|
- localparam [15:0] S2_CLKOUT6_REG1 = S2_CLKOUT6[15:0]; //See log file for 16 bit reporting of the register
|
|
|
- localparam [15:0] S2_CLKOUT6_REG2 = S2_CLKOUT6[31:16]; //See log file for 16 bit reporting of the register
|
|
|
-
|
|
|
- initial begin
|
|
|
- // rom entries contain (in order) the address, a bitmask, and a bitset
|
|
|
- //***********************************************************************
|
|
|
- // State 1 Initialization
|
|
|
- //***********************************************************************
|
|
|
-
|
|
|
- // Store the power bits
|
|
|
- rom[0] = {7'h28, 16'h0000, 16'hFFFF};
|
|
|
-
|
|
|
- // Store CLKOUT0 divide and phase
|
|
|
- rom[1] = (S1_CLKOUT0_FRAC_EN == 0) ?
|
|
|
- {7'h09, 16'h8000, 16'h0480}:
|
|
|
- {7'h09, 16'h8000, 16'h0480};
|
|
|
- rom[2] = (S1_CLKOUT0_FRAC_EN == 0) ?
|
|
|
- {7'h08, 16'h1000, clkVal}:
|
|
|
- {7'h08, 16'h1000, clkVal};
|
|
|
-
|
|
|
- // Store CLKOUT1 divide and phase
|
|
|
- rom[3] = {7'h0A, 16'h1000, S1_CLKOUT1[15:0]};
|
|
|
- rom[4] = {7'h0B, 16'hFC00, S1_CLKOUT1[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT2 divide and phase
|
|
|
- rom[5] = {7'h0C, 16'h1000, S1_CLKOUT2[15:0]};
|
|
|
- rom[6] = {7'h0D, 16'hFC00, S1_CLKOUT2[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT3 divide and phase
|
|
|
- rom[7] = {7'h0E, 16'h1000, S1_CLKOUT3[15:0]};
|
|
|
- rom[8] = {7'h0F, 16'hFC00, S1_CLKOUT3[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT4 divide and phase
|
|
|
- rom[9] = {7'h10, 16'h1000, S1_CLKOUT4[15:0]};
|
|
|
- rom[10] = {7'h11, 16'hFC00, S1_CLKOUT4[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT5 divide and phase
|
|
|
- rom[11] = {7'h06, 16'h1000, S1_CLKOUT5[15:0]};
|
|
|
- rom[12] = (S1_CLKOUT0_FRAC_EN == 0) ?
|
|
|
- {7'h07, 16'hC000, S1_CLKOUT5[31:16]}:
|
|
|
- {7'h07, 16'hC000, S1_CLKOUT5[31:30], S1_CLKOUT0_FRAC_CALC[35:32],S1_CLKOUT5[25:16]};
|
|
|
-
|
|
|
- // Store CLKOUT6 divide and phase
|
|
|
- rom[13] = {7'h12, 16'h1000, S1_CLKOUT6[15:0]};
|
|
|
- rom[14] = (S1_CLKFBOUT_FRAC_EN == 0) ?
|
|
|
- {7'h13, 16'hC000, S1_CLKOUT6[31:16]}:
|
|
|
- {7'h13, 16'hC000, S1_CLKOUT6[31:30], S1_CLKFBOUT_FRAC_CALC[35:32],S1_CLKOUT6[25:16]};
|
|
|
-
|
|
|
- // Store the input divider
|
|
|
- rom[15] = {7'h16, 16'hC000, {2'h0, S1_DIVCLK[23:22], S1_DIVCLK[11:0]} };
|
|
|
-
|
|
|
- // Store the feedback divide and phase
|
|
|
- rom[16] = (S1_CLKFBOUT_FRAC_EN == 0) ?
|
|
|
- {7'h14, 16'h1000, S1_CLKFBOUT[15:0]}:
|
|
|
- {7'h14, 16'h1000, S1_CLKFBOUT_FRAC_CALC[15:0]};
|
|
|
- rom[17] = (S1_CLKFBOUT_FRAC_EN == 0) ?
|
|
|
- {7'h15, 16'h8000, S1_CLKFBOUT[31:16]}:
|
|
|
- {7'h15, 16'h8000, S1_CLKFBOUT_FRAC_CALC[31:16]};
|
|
|
-
|
|
|
- // Store the lock settings
|
|
|
- rom[18] = {7'h18, 16'hFC00, {6'h00, S1_LOCK[29:20]} };
|
|
|
- rom[19] = {7'h19, 16'h8000, {1'b0 , S1_LOCK[34:30], S1_LOCK[9:0]} };
|
|
|
- rom[20] = {7'h1A, 16'h8000, {1'b0 , S1_LOCK[39:35], S1_LOCK[19:10]} };
|
|
|
-
|
|
|
- // Store the filter settings
|
|
|
- rom[21] = {7'h4E, 16'h66FF,
|
|
|
- S1_DIGITAL_FILT[9], 2'h0, S1_DIGITAL_FILT[8:7], 2'h0,
|
|
|
- S1_DIGITAL_FILT[6], 8'h00 };
|
|
|
- rom[22] = {7'h4F, 16'h666F,
|
|
|
- S1_DIGITAL_FILT[5], 2'h0, S1_DIGITAL_FILT[4:3], 2'h0,
|
|
|
- S1_DIGITAL_FILT[2:1], 2'h0, S1_DIGITAL_FILT[0], 4'h0 };
|
|
|
-
|
|
|
- //***********************************************************************
|
|
|
- // State 2 Initialization
|
|
|
- //***********************************************************************
|
|
|
-
|
|
|
- // Store the power bits
|
|
|
- rom[23] = {7'h28, 16'h0000, 16'hFFFF};
|
|
|
-
|
|
|
- // Store CLKOUT0 divide and phase
|
|
|
- rom[24] = (S2_CLKOUT0_FRAC_EN == 0) ?
|
|
|
- {7'h09, 16'h8000, 16'h0480}:
|
|
|
- {7'h09, 16'h8000, 16'h0480};
|
|
|
- rom[25] = (S2_CLKOUT0_FRAC_EN == 0) ?
|
|
|
- {7'h08, 16'h1000, clkVal}:
|
|
|
- {7'h08, 16'h1000, clkVal};
|
|
|
-
|
|
|
- // Store CLKOUT1 divide and phase
|
|
|
- rom[26] = {7'h0A, 16'h1000, S2_CLKOUT1[15:0]};
|
|
|
- rom[27] = {7'h0B, 16'hFC00, S2_CLKOUT1[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT2 divide and phase
|
|
|
- rom[28] = {7'h0C, 16'h1000, S2_CLKOUT2[15:0]};
|
|
|
- rom[29] = {7'h0D, 16'hFC00, S2_CLKOUT2[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT3 divide and phase
|
|
|
- rom[30] = {7'h0E, 16'h1000, S2_CLKOUT3[15:0]};
|
|
|
- rom[31] = {7'h0F, 16'hFC00, S2_CLKOUT3[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT4 divide and phase
|
|
|
- rom[32] = {7'h10, 16'h1000, S2_CLKOUT4[15:0]};
|
|
|
- rom[33] = {7'h11, 16'hFC00, S2_CLKOUT4[31:16]};
|
|
|
-
|
|
|
- // Store CLKOUT5 divide and phase
|
|
|
- rom[34] = {7'h06, 16'h1000, S2_CLKOUT5[15:0]};
|
|
|
- rom[35] = (S2_CLKOUT0_FRAC_EN == 0) ?
|
|
|
- {7'h07, 16'hC000, S2_CLKOUT5[31:16]}:
|
|
|
- {7'h07, 16'hC000, S2_CLKOUT5[31:30], S2_CLKOUT0_FRAC_CALC[35:32],S2_CLKOUT5[25:16]};
|
|
|
-
|
|
|
- // Store CLKOUT6 divide and phase
|
|
|
- rom[36] = {7'h12, 16'h1000, S2_CLKOUT6[15:0]};
|
|
|
- rom[37] = (S2_CLKFBOUT_FRAC_EN == 0) ?
|
|
|
- {7'h13, 16'hC000, S2_CLKOUT6[31:16]}:
|
|
|
- {7'h13, 16'hC000, S2_CLKOUT6[31:30], S2_CLKFBOUT_FRAC_CALC[35:32],S2_CLKOUT6[25:16]};
|
|
|
-
|
|
|
- // Store the input divider
|
|
|
- rom[38] = {7'h16, 16'hC000, {2'h0, S2_DIVCLK[23:22], S2_DIVCLK[11:0]} };
|
|
|
-
|
|
|
- // Store the feedback divide and phase
|
|
|
- rom[39] = (S2_CLKFBOUT_FRAC_EN == 0) ?
|
|
|
- {7'h14, 16'h1000, S2_CLKFBOUT[15:0]}:
|
|
|
- {7'h14, 16'h1000, S2_CLKFBOUT_FRAC_CALC[15:0]};
|
|
|
- rom[40] = (S2_CLKFBOUT_FRAC_EN == 0) ?
|
|
|
- {7'h15, 16'h8000, S2_CLKFBOUT[31:16]}:
|
|
|
- {7'h15, 16'h8000, S2_CLKFBOUT_FRAC_CALC[31:16]};
|
|
|
-
|
|
|
- // Store the lock settings
|
|
|
- rom[41] = {7'h18, 16'hFC00, {6'h00, S2_LOCK[29:20]} };
|
|
|
- rom[42] = {7'h19, 16'h8000, {1'b0 , S2_LOCK[34:30], S2_LOCK[9:0]} };
|
|
|
- rom[43] = {7'h1A, 16'h8000, {1'b0 , S2_LOCK[39:35], S2_LOCK[19:10]} };
|
|
|
-
|
|
|
- // Store the filter settings
|
|
|
- rom[44] = {7'h4E, 16'h66FF,
|
|
|
- S2_DIGITAL_FILT[9], 2'h0, S2_DIGITAL_FILT[8:7], 2'h0,
|
|
|
- S2_DIGITAL_FILT[6], 8'h00 };
|
|
|
- rom[45] = {7'h4F, 16'h666F,
|
|
|
- S2_DIGITAL_FILT[5], 2'h0, S2_DIGITAL_FILT[4:3], 2'h0,
|
|
|
- S2_DIGITAL_FILT[2:1], 2'h0, S2_DIGITAL_FILT[0], 4'h0 };
|
|
|
-
|
|
|
- // Initialize the rest of the ROM
|
|
|
- rom[46] = {7'h28,32'h0000_0000};
|
|
|
- for(ii = 47; ii < 64; ii = ii +1) begin
|
|
|
- rom[ii] = 0;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- // Output the initialized rom value based on rom_addr each clock cycle
|
|
|
- always @(posedge SCLK) begin
|
|
|
- rom_do<= #TCQ rom[rom_addr];
|
|
|
- end
|
|
|
-
|
|
|
- //**************************************************************************
|
|
|
- // Everything below is associated whith the state machine that is used to
|
|
|
- // Read/Modify/Write to the MMCM.
|
|
|
- //**************************************************************************
|
|
|
-
|
|
|
- // State Definitions
|
|
|
- localparam RESTART = 4'h1;
|
|
|
- localparam WAIT_LOCK = 4'h2;
|
|
|
- localparam WAIT_SEN = 4'h3;
|
|
|
- localparam ADDRESS = 4'h4;
|
|
|
- localparam WAIT_A_DRDY = 4'h5;
|
|
|
- localparam BITMASK = 4'h6;
|
|
|
- localparam BITSET = 4'h7;
|
|
|
- localparam WRITE = 4'h8;
|
|
|
- localparam WAIT_DRDY = 4'h9;
|
|
|
-
|
|
|
- // State sync
|
|
|
- reg [3:0] current_state = RESTART;
|
|
|
- reg [3:0] next_state = RESTART;
|
|
|
-
|
|
|
- // These variables are used to keep track of the number of iterations that
|
|
|
- // each state takes to reconfigure.
|
|
|
- // STATE_COUNT_CONST is used to reset the counters and should match the
|
|
|
- // number of registers necessary to reconfigure each state.
|
|
|
- localparam STATE_COUNT_CONST = 4;
|
|
|
- reg [4:0] state_count = STATE_COUNT_CONST;
|
|
|
- reg [4:0] next_state_count = STATE_COUNT_CONST;
|
|
|
-
|
|
|
- // This block assigns the next register value from the state machine below
|
|
|
- always @(posedge SCLK) begin
|
|
|
- DADDR <= #TCQ next_daddr;
|
|
|
- DWE <= #TCQ next_dwe;
|
|
|
- DEN <= #TCQ next_den;
|
|
|
- RST_MMCM <= #TCQ next_rst_mmcm;
|
|
|
- DI <= #TCQ next_di;
|
|
|
-
|
|
|
- SRDY <= #TCQ next_srdy;
|
|
|
-
|
|
|
- rom_addr <= #TCQ next_rom_addr;
|
|
|
- state_count <= #TCQ next_state_count;
|
|
|
- end
|
|
|
-
|
|
|
- // This block assigns the next state, reset is syncronous.
|
|
|
- always @(posedge SCLK) begin
|
|
|
- if(RST) begin
|
|
|
- current_state <= #TCQ RESTART;
|
|
|
- end else begin
|
|
|
- current_state <= #TCQ next_state;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- always @* begin
|
|
|
- // Setup the default values
|
|
|
- next_srdy = 1'b0;
|
|
|
- next_daddr = DADDR;
|
|
|
- next_dwe = 1'b0;
|
|
|
- next_den = 1'b0;
|
|
|
- next_rst_mmcm = RST_MMCM;
|
|
|
- next_di = DI;
|
|
|
- next_rom_addr = rom_addr;
|
|
|
- next_state_count = state_count;
|
|
|
-
|
|
|
- case (current_state)
|
|
|
- // If RST is asserted reset the machine
|
|
|
- RESTART: begin
|
|
|
- next_daddr = 7'h00;
|
|
|
- next_di = 16'h0000;
|
|
|
- next_rom_addr = 6'h00;
|
|
|
- next_rst_mmcm = 1'b1;
|
|
|
- next_state = WAIT_LOCK;
|
|
|
- end
|
|
|
-
|
|
|
- // Waits for the MMCM to assert IntLocked - once it does asserts SRDY
|
|
|
- WAIT_LOCK: begin
|
|
|
- // Make sure reset is de-asserted
|
|
|
- next_rst_mmcm = 1'b0;
|
|
|
- // Reset the number of registers left to write for the next
|
|
|
- // reconfiguration event.
|
|
|
- next_state_count = STATE_COUNT_CONST ;
|
|
|
- next_rom_addr = SADDR ? STATE_COUNT_CONST : 8'h00;
|
|
|
-
|
|
|
- if(IntLocked) begin
|
|
|
- // MMCM is IntLocked, go on to wait for the SEN signal
|
|
|
- next_state = WAIT_SEN;
|
|
|
- // Assert SRDY to indicate that the reconfiguration module is
|
|
|
- // ready
|
|
|
- next_srdy = 1'b1;
|
|
|
- end else begin
|
|
|
- // Keep waiting, IntLocked has not asserted yet
|
|
|
- next_state = WAIT_LOCK;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- // Wait for the next SEN pulse and set the ROM addr appropriately
|
|
|
- // based on SADDR
|
|
|
- WAIT_SEN: begin
|
|
|
- next_rom_addr = SADDR ? STATE_COUNT_CONST : 8'h00;
|
|
|
- if (SEN) begin
|
|
|
- next_rom_addr = SADDR ? STATE_COUNT_CONST : 8'h00;
|
|
|
- // Go on to address the MMCM
|
|
|
- next_state = ADDRESS;
|
|
|
- end else begin
|
|
|
- // Keep waiting for SEN to be asserted
|
|
|
- next_state = WAIT_SEN;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- // Set the address on the MMCM and assert DEN to read the value
|
|
|
- ADDRESS: begin
|
|
|
- // Reset the DCM through the reconfiguration
|
|
|
- next_rst_mmcm = 1'b1;
|
|
|
- // Enable a read from the MMCM and set the MMCM address
|
|
|
- next_den = 1'b1;
|
|
|
- next_daddr = rom_do[38:32];
|
|
|
-
|
|
|
- // Wait for the data to be ready
|
|
|
- next_state = WAIT_A_DRDY;
|
|
|
- end
|
|
|
-
|
|
|
- // Wait for DRDY to assert after addressing the MMCM
|
|
|
- WAIT_A_DRDY: begin
|
|
|
- if (DRDY) begin
|
|
|
- // Data is ready, mask out the bits to save
|
|
|
- next_state = BITMASK;
|
|
|
- end else begin
|
|
|
- // Keep waiting till data is ready
|
|
|
- next_state = WAIT_A_DRDY;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- // Zero out the bits that are not set in the mask stored in rom
|
|
|
- BITMASK: begin
|
|
|
- // Do the mask
|
|
|
- next_di = rom_do[31:16] & DO;
|
|
|
- // Go on to set the bits
|
|
|
- next_state = BITSET;
|
|
|
- end
|
|
|
-
|
|
|
- // After the input is masked, OR the bits with calculated value in rom
|
|
|
- BITSET: begin
|
|
|
- // Set the bits that need to be assigned
|
|
|
- next_di = rom_do[15:0] | DI;
|
|
|
- // Set the next address to read from ROM
|
|
|
- next_rom_addr = rom_addr + 1'b1;
|
|
|
- // Go on to write the data to the MMCM
|
|
|
- next_state = WRITE;
|
|
|
- end
|
|
|
-
|
|
|
- // DI is setup so assert DWE, DEN, and RST_MMCM. Subtract one from the
|
|
|
- // state count and go to wait for DRDY.
|
|
|
- WRITE: begin
|
|
|
- // Set WE and EN on MMCM
|
|
|
- next_dwe = 1'b1;
|
|
|
- next_den = 1'b1;
|
|
|
-
|
|
|
- // Decrement the number of registers left to write
|
|
|
- next_state_count = state_count - 1'b1;
|
|
|
- // Wait for the write to complete
|
|
|
- next_state = WAIT_DRDY;
|
|
|
- end
|
|
|
-
|
|
|
- // Wait for DRDY to assert from the MMCM. If the state count is not 0
|
|
|
- // jump to ADDRESS (continue reconfiguration). If state count is
|
|
|
- // 0 wait for lock.
|
|
|
- WAIT_DRDY: begin
|
|
|
- if(DRDY) begin
|
|
|
- // Write is complete
|
|
|
- if(state_count > 0) begin
|
|
|
- // If there are more registers to write keep going
|
|
|
- next_state = ADDRESS;
|
|
|
- end else begin
|
|
|
- // There are no more registers to write so wait for the MMCM
|
|
|
- // to lock
|
|
|
- next_state = WAIT_LOCK;
|
|
|
- end
|
|
|
- end else begin
|
|
|
- // Keep waiting for write to complete
|
|
|
- next_state = WAIT_DRDY;
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- // If in an unknown state reset the machine
|
|
|
- default: begin
|
|
|
- next_state = RESTART;
|
|
|
- end
|
|
|
- endcase
|
|
|
- end
|
|
|
-endmodule
|