OpenCores
URL https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk

Subversion Repositories pcie_ds_dma

[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source_artix7/] [cl_a7pcie_x4_pipe_clock.v] - Rev 48

Go to most recent revision | Compare with Previous | Blame | View Log

//-----------------------------------------------------------------------------
//
// (c) Copyright 2010-2011 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.
//
// 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.
//
//-----------------------------------------------------------------------------
// Project    : Series-7 Integrated Block for PCI Express
// File       : cl_a7pcie_x4_pipe_clock.v
// Version    : 1.10
//------------------------------------------------------------------------------
//  Filename     :  pipe_clock.v
//  Description  :  PIPE Clock Module for 7 Series Transceiver
//  Version      :  15.3
//------------------------------------------------------------------------------
 
 
 
`timescale 1ns / 1ps
 
 
 
//---------- PIPE Clock Module -------------------------------------------------
module cl_a7pcie_x4_pipe_clock #
(
 
    parameter PCIE_ASYNC_EN      = "FALSE",                 // PCIe async enable
    parameter PCIE_TXBUF_EN      = "FALSE",                 // PCIe TX buffer enable for Gen1/Gen2 only
    parameter PCIE_LANE          = 1,                       // PCIe number of lanes
    parameter PCIE_LINK_SPEED    = 3,                       // PCIe link speed 
    parameter PCIE_REFCLK_FREQ   = 0,                       // PCIe reference clock frequency
    parameter PCIE_USERCLK1_FREQ = 2,                       // PCIe user clock 1 frequency
    parameter PCIE_USERCLK2_FREQ = 2,                       // PCIe user clock 2 frequency
    parameter PCIE_OOBCLK_MODE   = 1,                       // PCIe oob clock mode
    parameter PCIE_DEBUG_MODE    = 0                        // PCIe Debug mode
 
)
 
(
 
    //---------- Input -------------------------------------
    input                       CLK_CLK,
    input                       CLK_TXOUTCLK,
    input       [PCIE_LANE-1:0] CLK_RXOUTCLK_IN,
    input                       CLK_RST_N,
    input       [PCIE_LANE-1:0] CLK_PCLK_SEL,
    input                       CLK_GEN3,       
 
    //---------- Output ------------------------------------
    output                      CLK_PCLK,
    output                      CLK_RXUSRCLK,
    output      [PCIE_LANE-1:0] CLK_RXOUTCLK_OUT,
    output                      CLK_DCLK,
    output                      CLK_OOBCLK,
    output                      CLK_USERCLK1,
    output                      CLK_USERCLK2,
    output                      CLK_MMCM_LOCK
 
);
 
    //---------- Select Clock Divider ----------------------
    localparam          DIVCLK_DIVIDE    = (PCIE_REFCLK_FREQ == 2) ? 1 :
                                           (PCIE_REFCLK_FREQ == 1) ? 1 : 1;
 
    localparam          CLKFBOUT_MULT_F  = (PCIE_REFCLK_FREQ == 2) ? 4 :
                                           (PCIE_REFCLK_FREQ == 1) ? 8 : 10;
 
    localparam          CLKIN1_PERIOD    = (PCIE_REFCLK_FREQ == 2) ? 4 :
                                           (PCIE_REFCLK_FREQ == 1) ? 8 : 10;
 
    localparam          CLKOUT0_DIVIDE_F = 8;
 
    localparam          CLKOUT1_DIVIDE   = 4;
 
    localparam          CLKOUT2_DIVIDE   = (PCIE_USERCLK1_FREQ == 5) ?  2 : 
                                           (PCIE_USERCLK1_FREQ == 4) ?  4 :
                                           (PCIE_USERCLK1_FREQ == 3) ?  8 :
                                           (PCIE_USERCLK1_FREQ == 1) ? 32 : 16;
 
    localparam          CLKOUT3_DIVIDE   = (PCIE_USERCLK2_FREQ == 5) ?  2 : 
                                           (PCIE_USERCLK2_FREQ == 4) ?  4 :
                                           (PCIE_USERCLK2_FREQ == 3) ?  8 :
                                           (PCIE_USERCLK2_FREQ == 1) ? 32 : 16;
 
    localparam          CLKOUT4_DIVIDE   = 20;
 
    //---------- Select Reference Clock --------------------                                       
    localparam          REFCLK_SEL = ((PCIE_TXBUF_EN == "TRUE") && (PCIE_LINK_SPEED != 3)) ? 1'd1 : 1'd0;                                       
 
    //---------- Input Registers ---------------------------
(* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *)    reg         [PCIE_LANE-1:0] pclk_sel_reg1 = {PCIE_LANE{1'd0}};
(* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *)    reg                         gen3_reg1     = 1'd0;
 
(* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *)    reg         [PCIE_LANE-1:0] pclk_sel_reg2 = {PCIE_LANE{1'd0}};
(* ASYNC_REG = "TRUE", SHIFT_EXTRACT = "NO" *)    reg                         gen3_reg2     = 1'd0;   
 
    //---------- Internal Signals -------------------------- 
    wire                        refclk;
    wire                        mmcm_fb;
    wire                        clk_125mhz;
    wire                        clk_125mhz_buf;
    wire                        clk_250mhz;
    wire                        userclk1;
    wire                        userclk2;
    wire                        oobclk;
    reg                         pclk_sel = 1'd0;
 
    //---------- Output Registers --------------------------
    wire                        pclk_1;
    wire                        pclk;
    wire                        userclk1_1;
    wire                        userclk2_1;
    wire                        mmcm_lock;
 
    //---------- Generate Per-Lane Signals -----------------
    genvar              i;                                  // Index for per-lane signals
 
 
 
//---------- Input FF ----------------------------------------------------------
always @ (posedge pclk)
begin
 
    if (!CLK_RST_N)
        begin
        //---------- 1st Stage FF --------------------------
        pclk_sel_reg1 <= {PCIE_LANE{1'd0}};
        gen3_reg1     <= 1'd0;
        //---------- 2nd Stage FF --------------------------
        pclk_sel_reg2 <= {PCIE_LANE{1'd0}};
        gen3_reg2     <= 1'd0;
        end
    else
        begin  
        //---------- 1st Stage FF --------------------------
        pclk_sel_reg1 <= CLK_PCLK_SEL;
        gen3_reg1     <= CLK_GEN3;
        //---------- 2nd Stage FF --------------------------
        pclk_sel_reg2 <= pclk_sel_reg1;
        gen3_reg2     <= gen3_reg1;
        end
 
end
 
 
 
//---------- Select Reference clock or TXOUTCLK --------------------------------   
generate if ((PCIE_TXBUF_EN == "TRUE") && (PCIE_LINK_SPEED != 3))
 
    begin : refclk_i
 
    //---------- Select Reference Clock ----------------------------------------
    BUFG refclk_i
    (
 
        //---------- Input -------------------------------------
        .I                          (CLK_CLK),
        //---------- Output ------------------------------------
        .O                          (refclk)
 
    );
 
    end
 
else
 
    begin : txoutclk_i
 
    //---------- Select TXOUTCLK -----------------------------------------------
    BUFG txoutclk_i
    (
 
        //---------- Input -------------------------------------
        .I                          (CLK_TXOUTCLK),
        //---------- Output ------------------------------------
        .O                          (refclk)
 
    );
 
    end
 
endgenerate
 
 
 
//---------- MMCM --------------------------------------------------------------
MMCME2_ADV #
(
 
    .BANDWIDTH                  ("OPTIMIZED"),
    .CLKOUT4_CASCADE            ("FALSE"),
    .COMPENSATION               ("ZHOLD"),
    .STARTUP_WAIT               ("FALSE"),
    .DIVCLK_DIVIDE              (DIVCLK_DIVIDE),
    .CLKFBOUT_MULT_F            (CLKFBOUT_MULT_F),  
    .CLKFBOUT_PHASE             (0.000),
    .CLKFBOUT_USE_FINE_PS       ("FALSE"),
    .CLKOUT0_DIVIDE_F           (CLKOUT0_DIVIDE_F),                    
    .CLKOUT0_PHASE              (0.000),
    .CLKOUT0_DUTY_CYCLE         (0.500),
    .CLKOUT0_USE_FINE_PS        ("FALSE"),
    .CLKOUT1_DIVIDE             (CLKOUT1_DIVIDE),                    
    .CLKOUT1_PHASE              (0.000),
    .CLKOUT1_DUTY_CYCLE         (0.500),
    .CLKOUT1_USE_FINE_PS        ("FALSE"),
    .CLKOUT2_DIVIDE             (CLKOUT2_DIVIDE),                  
    .CLKOUT2_PHASE              (0.000),
    .CLKOUT2_DUTY_CYCLE         (0.500),
    .CLKOUT2_USE_FINE_PS        ("FALSE"),
    .CLKOUT3_DIVIDE             (CLKOUT3_DIVIDE),                  
    .CLKOUT3_PHASE              (0.000),
    .CLKOUT3_DUTY_CYCLE         (0.500),
    .CLKOUT3_USE_FINE_PS        ("FALSE"),
    .CLKOUT4_DIVIDE             (CLKOUT4_DIVIDE),                  
    .CLKOUT4_PHASE              (0.000),
    .CLKOUT4_DUTY_CYCLE         (0.500),
    .CLKOUT4_USE_FINE_PS        ("FALSE"),
    .CLKIN1_PERIOD              (CLKIN1_PERIOD),                   
    .REF_JITTER1                (0.010)
 
)
mmcm_i
(
 
     //---------- Input ------------------------------------
    .CLKIN1                     (refclk),
  //.CLKIN2                     (1'd0),                     // not used, comment out CLKIN2 if it cause implementation issues
  //.CLKIN2                     (refclk),                   // not used, comment out CLKIN2 if it cause implementation issues
    .CLKINSEL                   (1'd1),
    .CLKFBIN                    (mmcm_fb),
    .RST                        (!CLK_RST_N),
    .PWRDWN                     (1'd0), 
 
    //---------- Output ------------------------------------
    .CLKFBOUT                   (mmcm_fb),
    .CLKFBOUTB                  (),
    .CLKOUT0                    (clk_125mhz),
    .CLKOUT0B                   (),
    .CLKOUT1                    (clk_250mhz),
    .CLKOUT1B                   (),
    .CLKOUT2                    (userclk1),
    .CLKOUT2B                   (),
    .CLKOUT3                    (userclk2),
    .CLKOUT3B                   (),
    .CLKOUT4                    (oobclk),
    .CLKOUT5                    (),
    .CLKOUT6                    (),
    .LOCKED                     (mmcm_lock),
 
    //---------- Dynamic Reconfiguration -------------------
    .DCLK                       ( 1'd0),
    .DADDR                      ( 7'd0),
    .DEN                        ( 1'd0),
    .DWE                        ( 1'd0),
    .DI                         (16'd0),
    .DO                         (),
    .DRDY                       (),
 
    //---------- Dynamic Phase Shift -----------------------
    .PSCLK                      (1'd0),
    .PSEN                       (1'd0),
    .PSINCDEC                   (1'd0),
    .PSDONE                     (),
 
    //---------- Status ------------------------------------
    .CLKINSTOPPED               (),
    .CLKFBSTOPPED               ()  
 
); 
 
 
 
//---------- Select PCLK MUX ---------------------------------------------------
generate if (PCIE_LINK_SPEED != 1) 
 
    begin : pclk_i1_bufgctrl
    //---------- PCLK Mux ----------------------------------
    BUFGCTRL pclk_i1
    (
        //---------- Input ---------------------------------
        .CE0                        (1'd1),         
        .CE1                        (1'd1),        
        .I0                         (clk_125mhz),   
        .I1                         (clk_250mhz),   
        .IGNORE0                    (1'd0),        
        .IGNORE1                    (1'd0),        
        .S0                         (~pclk_sel),    
        .S1                         ( pclk_sel),    
        //---------- Output --------------------------------
        .O                          (pclk_1)
    );
    end
 
else 
 
    //---------- Select PCLK Buffer ------------------------
    begin : pclk_i1_bufg
    //---------- PCLK Buffer -------------------------------
    BUFG pclk_i1
    (
        //---------- Input ---------------------------------
        .I                          (clk_125mhz), 
        //---------- Output --------------------------------
        .O                          (clk_125mhz_buf)
    );
    assign pclk_1 = clk_125mhz_buf;
    end 
 
endgenerate
 
 
 
//---------- Generate RXOUTCLK Buffer for Debug --------------------------------
generate if ((PCIE_DEBUG_MODE == 1) || (PCIE_ASYNC_EN == "TRUE"))
 
    begin : rxoutclk_per_lane
    //---------- Generate per Lane -------------------------
    for (i=0; i<PCIE_LANE; i=i+1) 
 
        begin : rxoutclk_i
        //---------- RXOUTCLK Buffer -----------------------
        BUFG rxoutclk_i
        (
            //---------- Input -----------------------------
            .I                          (CLK_RXOUTCLK_IN[i]), 
            //---------- Output ----------------------------
            .O                          (CLK_RXOUTCLK_OUT[i])
        );
        end
 
    end 
 
else
 
    //---------- Disable RXOUTCLK Buffer for Normal Operation 
    begin : rxoutclk_i_disable
    assign CLK_RXOUTCLK_OUT = {PCIE_LANE{1'd0}};
    end       
 
endgenerate 
 
 
//---------- Generate DCLK Buffer ----------------------------------------------
generate if (PCIE_LINK_SPEED != 1)
 
    begin : dclk_i_bufg
    //---------- DCLK Buffer -------------------------------
    BUFG dclk_i
    (
        //---------- Input ---------------------------------
        .I                          (clk_125mhz), 
        //---------- Output --------------------------------
        .O                          (CLK_DCLK)
    );
    end
 
else
 
    //---------- Disable DCLK Buffer -----------------------
    begin : dclk_i
    assign CLK_DCLK = clk_125mhz_buf;                       // always 125 MHz in Gen1
    end
 
endgenerate
 
 
 
//---------- Generate USERCLK1 Buffer ------------------------------------------
generate if (PCIE_USERCLK1_FREQ != 0) 
 
    begin : userclk1_i1
    //---------- USERCLK1 Buffer ---------------------------
    BUFG usrclk1_i1
    (
        //---------- Input ---------------------------------
        .I                          (userclk1),
        //---------- Output --------------------------------
        .O                          (userclk1_1)
    );
    end 
 
else 
 
    //---------- Disable USERCLK1 Buffer -------------------
    begin : disable_userclk1_i1
    assign userclk1_1 = 1'd0;
    end 
 
endgenerate 
 
 
 
//---------- Generate USERCLK2 Buffer ------------------------------------------
generate if (PCIE_USERCLK2_FREQ != 0) 
 
    begin : userclk2_i1
    //---------- USERCLK2 Buffer ---------------------------
    BUFG usrclk2_i1
    (
        //---------- Input ---------------------------------
        .I                          (userclk2),
        //---------- Output --------------------------------
        .O                          (userclk2_1)
    );
    end
 
else 
 
    //---------- Disable USERCLK2 Buffer -------------------
    begin : userclk2_i1_disable
    assign userclk2_1 = 1'd0;
    end  
 
endgenerate 
 
 
 
//---------- Generate OOBCLK Buffer --------------------------------------------
generate if (PCIE_OOBCLK_MODE == 2) 
 
    begin : oobclk_i1
    //---------- OOBCLK Buffer -----------------------------
    BUFG oobclk_i1
    (
        //---------- Input ---------------------------------
        .I                          (oobclk),
        //---------- Output --------------------------------
        .O                          (CLK_OOBCLK)
    );
    end
 
else 
 
    //---------- Disable OOBCLK Buffer ---------------------
    begin : oobclk_i1_disable
    assign CLK_OOBCLK = pclk;
    end  
 
endgenerate 
 
 
 
//---------- Generate 2nd Stage Buffers ----------------------------------------
generate if ((PCIE_LINK_SPEED == 3) && (PCIE_ASYNC_EN == "TRUE")) 
 
    begin : second_stage_buf
 
    //---------- PCLK Buffer ---------------------------------------------------
    BUFG pclk_i2
    (
        //---------- Input -------------------------------------
        .I                          (pclk_1),  
        //---------- Output ------------------------------------
        .O                          (pclk)
    );
 
 
 
    //---------- RXUSRCLK Mux --------------------------------------------------
    BUFGCTRL rxusrclk_i2
    (
        //---------- Input ---------------------------------
        .CE0                        (1'b1),              
        .CE1                        (1'b1),              
        .I0                         (pclk_1),            
        .I1                         (CLK_RXOUTCLK_IN[0]),   
        .IGNORE0                    (1'b0),               
        .IGNORE1                    (1'b0),               
        .S0                         (~gen3_reg2),        
        .S1                         ( gen3_reg2),           
        //---------- Output --------------------------------
        .O                          (CLK_RXUSRCLK)
    );
 
 
 
    //---------- Generate USERCLK1 Buffer --------------------------------------
    if (PCIE_USERCLK1_FREQ != 0) 
 
        begin : userclk1_i2
        //---------- USERCLK1 Buffer -----------------------
        BUFG usrclk1_i2
        (
            //---------- Input -----------------------------
            .I                          (userclk1_1),
            //---------- Output ----------------------------
            .O                          (CLK_USERCLK1)
        );
        end
 
    else 
 
        //---------- Disable USERCLK1 Buffer ---------------
        begin : userclk1_i2_disable
        assign CLK_USERCLK1 = userclk1_1;
        end
 
 
 
    //---------- Generate USERCLK2 Buffer --------------------------------------
    if (PCIE_USERCLK2_FREQ != 0) 
 
        begin : userclk2_i2
        //---------- USERCLK2 Buffer -----------------------
        BUFG usrclk2_i2
        (
            //---------- Input -----------------------------
            .I                          (userclk2_1),
            //---------- Output ----------------------------
            .O                          (CLK_USERCLK2)
        );
        end
 
    else 
 
        //---------- Disable USERCLK2 Buffer ---------------
        begin : userclk2_i2_disable
        assign CLK_USERCLK2 = userclk2_1;
        end
 
    end  
 
else 
 
    //---------- Disable 2nd Stage Buffer --------------------------------------
    begin : second_stage_buf_disable 
    assign pclk         = pclk_1;
    assign CLK_RXUSRCLK = pclk_1;
    assign CLK_USERCLK1 = userclk1_1;
    assign CLK_USERCLK2 = userclk2_1;
    end 
 
endgenerate 
 
 
 
//---------- Select PCLK -------------------------------------------------------
always @ (posedge pclk)
begin
 
    if (!CLK_RST_N)
        pclk_sel <= 1'd0;
    else
        begin 
        //---------- Select 250 MHz ------------------------
        if (&pclk_sel_reg2)
            pclk_sel <= 1'd1;
        //---------- Select 125 MHz ------------------------  
        else if (&(~pclk_sel_reg2))
            pclk_sel <= 1'd0;  
        //---------- Hold PCLK -----------------------------
        else
            pclk_sel <= pclk_sel;
        end
 
end        
 
 
 
//---------- PIPE Clock Output -------------------------------------------------
assign CLK_PCLK      = pclk;
assign CLK_MMCM_LOCK = mmcm_lock;
 
 
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.