module one_gig_eth_pcs_pma_clocking
   (
      input            txoutclk,                  // txoutclk from GT transceiver.
      input            rxoutclk,                  // rxoutclk from GT transceiver.
      input            mmcm_reset,                // MMCM Reset
      output  wire     mmcm_locked,               // MMCM locked

      output           userclk,                   // for GT PMA reference clock
      output           userclk2,                  // 125MHz clock for core reference clock.
      output           rxuserclk,                 // for GT PMA reference clock
      output           rxuserclk2                 // 125MHz clock for core reference clock.
   );

   wire         clkout0;                  // MMCM output clock
   wire         clkout1;                  // MMCM output clock
   wire         clkfbout;                 // MMCM Feedback clock
// Route txoutclk input through a BUFG
   wire txoutclk_bufg;
   wire userclk_i;
   wire rxoutclk_buf;

   //---------------------------------------------------------------------------
   // Transceiver Clock Management
   //---------------------------------------------------------------------------

   // Route txoutclk input through a BUFG
   BUFG  bufg_txoutclk (
      .I         (txoutclk),
      .O         (txoutclk_bufg)
   );

  // The GT transceiver provides a 62.5MHz clock to the FPGA fabrix.  This is
  // routed to an MMCM module where it is used to create phase and frequency
  // related 62.5MHz and 125MHz clock sources
  MMCME2_ADV # (
    .BANDWIDTH            ("OPTIMIZED"),
    .CLKOUT4_CASCADE      ("FALSE"),
    .COMPENSATION         ("ZHOLD"),
    .STARTUP_WAIT         ("FALSE"),
    .DIVCLK_DIVIDE        (1),
    .CLKFBOUT_PHASE       (0.000),
    .CLKFBOUT_USE_FINE_PS ("FALSE"),
    .CLKOUT0_PHASE        (0.000),
    .CLKOUT0_DUTY_CYCLE   (0.5),
    .CLKOUT0_USE_FINE_PS  ("FALSE"),
    .CLKOUT1_PHASE        (0.000),
    .CLKOUT1_DUTY_CYCLE   (0.5),
    .CLKOUT1_USE_FINE_PS  ("FALSE"),
    .CLKIN1_PERIOD        (16.0),
    .CLKFBOUT_MULT_F      (16.000),
    .CLKOUT0_DIVIDE_F     (8.000),
    .CLKOUT1_DIVIDE       (16),

    .REF_JITTER1          (0.010)
  ) mmcm_adv_inst (
    // Output clocks
    .CLKFBOUT             (clkfbout),
    .CLKFBOUTB            (),
    .CLKOUT0              (clkout0),
    .CLKOUT0B             (),
    .CLKOUT1              (clkout1),
    .CLKOUT1B             (),
    .CLKOUT2              (),
    .CLKOUT2B             (),
    .CLKOUT3              (),
    .CLKOUT3B             (),
    .CLKOUT4              (),
    .CLKOUT5              (),
    .CLKOUT6              (),
    // Input clock control
    .CLKFBIN              (clkfbout),
    .CLKIN1               (txoutclk_bufg),
    .CLKIN2               (1'b0),
    // Tied to always select the primary input clock
    .CLKINSEL             (1'b1),
    // Ports for dynamic reconfiguration
    .DADDR                (7'h0),
    .DCLK                 (1'b0),
    .DEN                  (1'b0),
    .DI                   (16'h0),
    .DO                   (),
    .DRDY                 (),
    .DWE                  (1'b0),
    // Ports for dynamic phase shift
    .PSCLK                (1'b0),
    .PSEN                 (1'b0),
    .PSINCDEC             (1'b0),
    .PSDONE               (),
    // Other control and status signals
    .LOCKED               (mmcm_locked),
    .CLKINSTOPPED         (),
    .CLKFBSTOPPED         (),
    .PWRDWN               (1'b0),
    .RST                  (mmcm_reset)
   );
  // This 62.5MHz clock is placed onto global clock routing and is then used
   // for tranceiver TXUSRCLK/RXUSRCLK.
   BUFG bufg_userclk (
      .I     (clkout1),
      .O     (userclk_i)
   );


   // This 125MHz clock is placed onto global clock routing and is then used
   // to clock all Ethernet core logic.
   BUFG bufg_userclk2 (
      .I     (clkout0),
      .O     (userclk2)
   );



assign userclk = userclk_i;


   // Place the Rx recovered clock on a Global Clock Buffer (it may be possible
   // to switch this for a BUFHCE/BUFR and BUFMR combination)
   BUFG rxrecclkbufg (
      .I   (rxoutclk),
      .O   (rxoutclk_buf)
   );

  assign rxuserclk2 = rxoutclk_buf;
  assign rxuserclk  = rxoutclk_buf;

endmodule // one_gig_eth_pcs_pma_clocking