
module gige_phy
  (input reset, 
   input independent_clock,
//   input ETH_CLK_p, input ETH_CLK_n,
   input sfp_clk,
   input SFP_RX_p, input SFP_RX_n,
   output SFP_TX_p, output SFP_TX_n,
   output gmii_clk,
   input  [7:0] gmii_txd, input gmii_tx_en, input gmii_tx_er,
   output [7:0] gmii_rxd, output gmii_rx_dv, output gmii_rx_er,
   output [31:0] misc_debug,
   output [15:0] int_data,
   output [15:0] status_vector);

//   wire   sfp_clk;
   wire   mmcm_locked, mmcm_reset, resetdone, clkfbout;
   wire   userclk, userclk2;
   wire   txoutclk, txoutclk_bufg;
   assign gmii_clk = userclk2; // 125 MHz
   
//   IBUFDS_GTE2 clk_sfp_pin (.O(sfp_clk),.I(ETH_CLK_p),.IB(ETH_CLK_n), .CEB(1'b0));

   // Route txoutclk input through a BUFG
   // FIXME is this really necessary?  It seems wasteful.
   BUFG  bufg_txoutclk (.I (txoutclk), .O (txoutclk_bufg));

   // 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));

   // 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));

   // The GT transceiver provides a 62.5MHz clock to the FPGA fabric.  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_MULT_F      (16.000),
      .CLKFBOUT_PHASE       (0.000),
      .CLKFBOUT_USE_FINE_PS ("FALSE"),
      .CLKOUT0_DIVIDE_F     (8.000),
      .CLKOUT0_PHASE        (0.000),
      .CLKOUT0_DUTY_CYCLE   (0.5),
      .CLKOUT0_USE_FINE_PS  ("FALSE"),
      .CLKOUT1_DIVIDE       (16),
      .CLKOUT1_PHASE        (0.000),
      .CLKOUT1_DUTY_CYCLE   (0.5),
      .CLKOUT1_USE_FINE_PS  ("FALSE"),
      .CLKIN1_PERIOD        (16.0),
      .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)
	);

   assign mmcm_reset = reset | ~resetdone;

   gige_sfp_block gige_sfp_block
     (.gtrefclk(sfp_clk), .txp(SFP_TX_p), .txn(SFP_TX_n), .rxp(SFP_RX_p), .rxn(SFP_RX_n),
      .txoutclk(txoutclk), .resetdone(resetdone), .mmcm_locked(mmcm_locked), .userclk(userclk), .userclk2(userclk2),
      .independent_clock_bufg(independent_clock),
      .pma_reset(reset),
      .gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er),
      .gmii_rxd(gmii_rxd), .gmii_rx_dv(gmii_rx_dv), .gmii_rx_er(gmii_rx_er),
      .gmii_isolate(),  // unused

      .configuration_vector(5'b00000),
      .status_vector(status_vector), .reset(reset), .signal_detect(1'b1),
      .misc_debug(misc_debug),
      .int_data(int_data));

endmodule // gige_phy
