//
//     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
//     SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR
//     XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION
//     AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION
//     OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS
//     IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
//     AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
//     FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
//     WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
//     IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
//     REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
//     INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
//     FOR A PARTICULAR PURPOSE.
//     
//     (c) Copyright 2004 Xilinx, Inc.
//     All rights reserved.
//

module clocks
  (
   sys_clk,       // I
   sysace_clk,    // I
   tft_clk,       // O
   dcm_rst_n,     // I
   plb_clk,       // O
   plb_clk_n,     // O
   plb_clk90,     // O
   plb_clk270,    // O
//   clk2x,
   opb_clk,       // O
   dcr_clk,       // O
   ddr_fb_clk,    // I
   ddr_fb_clk90,  // O
   ddr_fb_clk270, // O
   dcm_locked,    // O
   sram_clk,      // O
   sram_clk_fb    // I
   );
  input  sys_clk;
  input  sysace_clk;
  output tft_clk;
  input  dcm_rst_n;
  output plb_clk;
//  output clk2x;
  output plb_clk_n;
  output plb_clk90;
  output plb_clk270;
  output opb_clk;
  output dcr_clk;
  input  ddr_fb_clk;
  output ddr_fb_clk90;
  output ddr_fb_clk270;
  output dcm_locked;
  output sram_clk;
  input  sram_clk_fb;

  wire    [3:0] por_ff;

  wire         dcm_rst = ~dcm_rst_n;
  wire         dcm1_rst;
  wire         dcm2_rst;
  wire         dcm3_rst;
//  wire         clk2x_i;
  wire         clk_i;
  wire         clk;         // clk_i after BUFG
  wire         clk90_i;
  wire         clk90;       // clk90_i after BUFG
  wire         ddrclk0_i;
  wire         ddrclk0;
  wire         ddrclk90_i;
  wire         ddrclk90;
  wire         dcm1_locked;
  wire         dcm2_locked;
  wire         dcm3_locked;
  wire         tft_clk_i;

  /////////////////////////////////////////////////////////////////////////////
  // DCM 1 Instantiation
  /////////////////////////////////////////////////////////////////////////////

  DCM dcm1
    (
     .CLK0     (clk_i),       // O
     .CLK180   (),            // O
     .CLK270   (),            // O
     .CLK2X    (),            // O
     .CLK2X180 (),            // O
     .CLK90    (clk90_i),     // O
     .CLKDV    (tft_clk_i),   // O
     .CLKFB    (clk),         // I
     .CLKFX    (),            // O
     .CLKFX180 (),            // O
     .CLKIN    (sys_clk),     // I
     .DSSEN    (1'b0),        // I
     .LOCKED   (dcm1_locked), // O
     .PSCLK    (1'b0),        // I
     .PSDONE   (),            // O
     .PSEN     (1'b0),        // I
     .PSINCDEC (1'b0),        // I
     .RST      (dcm1_rst),    // I
     .STATUS   ()             // O
     );
  // synthesis attribute CLKDV_DIVIDE   of dcm1 is "4"
  // synthesis attribute DLL_FREQUENCY_MODE of dcm1 is "LOW"
  // synthesis attribute CLKIN_PERIOD of dcm1 is "10"
  // synthesis attribute DFS_FREQUENCY_MODE of dcm1 is "LOW"

/* synthesis translate_off */
// Set the clock multiplier ratio for the CPU
   defparam    dcm1.CLKDV_DIVIDE = 4;
   defparam    dcm1.DLL_FREQUENCY_MODE = "LOW";
   defparam    dcm1.CLKIN_PERIOD = 10;
   defparam    dcm1.DFS_FREQUENCY_MODE = "LOW";
/* synthesis translate_on */
  
  /////////////////////////////////////////////////////////////////////////////
  // DCM 2 Instantiation
  /////////////////////////////////////////////////////////////////////////////

  DCM dcm2
    (
     .CLK0     (ddrclk0_i),   // O
     .CLK180   (),            // O
     .CLK270   (),            // O
     .CLK2X    (),            // O
     .CLK2X180 (),            // O
     .CLK90    (ddrclk90_i),  // O
     .CLKDV    (),            // O
     .CLKFB    (ddrclk0),     // I
     .CLKFX    (),            // O
     .CLKFX180 (),            // O
     .CLKIN    (ddr_fb_clk),  // I
     .DSSEN    (1'b0),        // I
     .LOCKED   (dcm2_locked), // O
     .PSCLK    (1'b0),        // I
     .PSDONE   (),            // O
     .PSEN     (1'b0),        // I
     .PSINCDEC (1'b0),        // I
     .RST      (dcm2_rst),    // I
     .STATUS   ()             // O
     );

  // synthesis attribute DLL_FREQUENCY_MODE of dcm2 is "LOW"
  // synthesis attribute CLKOUT_PHASE_SHIFT of dcm2 is "FIXED"
  // synth esis attribute PHASE_SHIFT of dcm2 is "19"
  // synthesis attribute CLKIN_PERIOD of dcm2 is "10"

  /* synthesis translate_off */
   defparam    dcm2.DLL_FREQUENCY_MODE = "LOW";
   defparam    dcm2.CLKOUT_PHASE_SHIFT = "FIXED";
   defparam    dcm2.PHASE_SHIFT = 19;
   defparam    dcm2.CLKIN_PERIOD = 10;
  /* synthesis translate_on */

//assign dcm2_locked = 1'b1;

  /////////////////////////////////////////////////////////////////////////////
  // DCM 3 Instantiation
  /////////////////////////////////////////////////////////////////////////////

  DCM dcm3
    (
     .CLK0     (sram_clk),    // O
     .CLK180   (),            // O
     .CLK270   (),            // O
     .CLK2X    (),            // O
     .CLK2X180 (),            // O
     .CLK90    (),            // O
     .CLKDV    (),            // O
     .CLKFB    (sram_clk_fb), // I
     .CLKFX    (),            // O
     .CLKFX180 (),            // O
     .CLKIN    (clk),         // I
     .DSSEN    (1'b0),        // I
     .LOCKED   (dcm3_locked), // O
     .PSCLK    (1'b0),        // I
     .PSDONE   (),            // O
     .PSEN     (1'b0),        // I
     .PSINCDEC (1'b0),        // I
     .RST      (dcm3_rst),    // I
     .STATUS   ()             // O
     );

  // synthesis attribute DLL_FREQUENCY_MODE of dcm3 is "LOW"
  // synthesis attribute CLKIN_PERIOD of dcm3 is "10"

  /* synthesis translate_off */
   defparam    dcm3.DLL_FREQUENCY_MODE = "LOW";
   defparam    dcm3.CLKIN_PERIOD = 10;
  /* synthesis translate_on */

  /////////////////////////////////////////////////////////////////////////////
  // Global Buffers to drive clock outputs from DCM
  /////////////////////////////////////////////////////////////////////////////
  BUFG clk_bufg        (.I(clk_i),         .O(clk));
  BUFG clk90_bufg      (.I(clk90_i),       .O(clk90));
  BUFG ddrclk0_bufg    (.I(ddrclk0_i),     .O(ddrclk0));
  BUFG ddrclk90_bufg   (.I(ddrclk90_i),    .O(ddrclk90));
  BUFG tftclk_bufg     (.I(tft_clk_i),     .O(tft_clk));
//  BUFG clk2x_bufg      (.I(clk2x_i),       .O(clk2x));

  /////////////////////////////////////////////////////////////////////////////
  // Reset Logic
  /////////////////////////////////////////////////////////////////////////////

  // Use Free Running (Non-DCM controlled) clock to control logic to
  // generate a power-on reset pulse to the DCMs. This ensures a clean
  // startup reset pulse on the DCMs.
   FDP por_ff3 (.C(sysace_clk), .D(1'b0), .Q(por_ff[3]), .PRE(dcm_rst));
   FDP por_ff2 (.C(sysace_clk), .D(por_ff[3]), .Q(por_ff[2]), .PRE(dcm_rst));
   FDP por_ff1 (.C(sysace_clk), .D(por_ff[2]), .Q(por_ff[1]), .PRE(dcm_rst));
   FDP por_ff0 (.C(sysace_clk), .D(por_ff[1]), .Q(por_ff[0]), .PRE(dcm_rst));

   // synthesis attribute INIT of por_ff3 is "1"
   // synthesis attribute INIT of por_ff2 is "1"
   // synthesis attribute INIT of por_ff1 is "1"
   // synthesis attribute INIT of por_ff0 is "1"
   
   // synthesis translate_off
   defparam    por_ff3.INIT = 1'b1;
   defparam    por_ff2.INIT = 1'b1;
   defparam    por_ff1.INIT = 1'b1;
   defparam    por_ff0.INIT = 1'b1;
   // synthesis translate_on
   
  assign   dcm1_rst = por_ff[0];
  assign   dcm2_rst = por_ff[0] | ~dcm1_locked;
  assign   dcm3_rst = por_ff[0] | ~dcm1_locked;

  /////////////////////////////////////////////////////////////////////////////
  // Outputs
  /////////////////////////////////////////////////////////////////////////////

  assign   dcm_locked = dcm1_locked & dcm2_locked & dcm3_locked;
  assign   plb_clk = clk;
  assign   plb_clk_n = ~clk;
  assign   plb_clk90 = clk90;
  assign   plb_clk270 = ~clk90;
  assign   opb_clk = clk;
  assign   dcr_clk = clk;
  assign   ddr_fb_clk90 = ddrclk90;
  assign   ddr_fb_clk270 = ~ddrclk90;

endmodule // clocks
