//------------------------------------------------------------------------------
// File       : demo_tb.v
// Author     : Xilinx Inc.
//------------------------------------------------------------------------------
// (c) Copyright 2009 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. 
// 
// 
//------------------------------------------------------------------------------
// Description: This testbench will exercise the ports of the Ethernet
// 1000BASE-X PCS/PMA core's example design to perform the following
// operations:
//
//----------------
//  Configuration
//----------------
//  The core will be reset, then Auto-Negotiation (if present) will
//  be disabled and and the core will be taken out of the Isolate
//  state.
//
//----------------
//  Transmitter
//----------------
//  Four frames are generated by the Tx Stimulus and pushed into the
//  GMII transmitter.
//
//  The PHY side transmitter interface data is captured, 8B10B decoded
//  and the Tx Monitor checks that the captured data matches that
//  injected.
//
//----------------
//  Receiver
//----------------
//  Four frames are generated by the Rx Stimulus, 8B10B encoded and
//  pushed into the PHY side receiver interface.
//
//  The GMII side receiver interface data is captured and the
//  Rx Monitor checks that the captured data matches that injected.
//
//
//----------------------------------------------------------------------
//                  Demonstration Test Fixture                         |
//                                                                     |
//                                                                     |
//                  --------------------------                         |
//                  |     Example Design     |                         |
//                  |         (DUT)          |                         |
//                  |                        |                         |
//                  |                        |                         |
//                  |                        |                         |
//   Tx             |                        |  8B10B decode, Tx       |
//   Generate   ------->                  -------->           Monitor  |
//   Frames         |                        |                Frames   |
//                  |GMII                PHY |                         |
//                  | I/F                I/F |                         |
//                  |                        |                         |
//                  |                        |                         |
//                  |                        |                         |
//    Rx            |                        |  8B10B encode, Rx       |
//    Monitor  <--------                  <--------           Generate |
//    Frames        |                        |                Frames   |
//                  |                        |                         |
//                  ------------^-------------                         |
//                              |                                      |
//                              |                                      |
//                          Stimulate                                  |
//                          MDIO I/F                                   |
//                         (if present)                                |
//                                                                     |
//----------------------------------------------------------------------

`timescale 1 ps/1 ps



// This module is the demonstration testbench
module demo_tb;


  //----------------------------------------------------------------------------
  // testbench signals
  //----------------------------------------------------------------------------

  // testbench control semaphores
  reg  configuration_finished;
  wire tx_monitor_finished;
  wire rx_monitor_finished;
  wire simulation_finished;


  //----------------------------------------------------------------------------
  // DUT signals
  //----------------------------------------------------------------------------

  // An independent clock source used as the reference clock for an
  // IDELAYCTRL (if present) and for the main GT transceiver reset logic.
  // This example design assumes that this is of frequency 200MHz.
  reg  independent_clock;

  // System Reset
  reg  reset;

  // Transceiver Interface
  //----------------------
  reg  gtrefclk_p;
  reg  gtrefclk_n;
  wire txp;
  wire txn;
  wire rxp;
  wire rxn;

  // GMII Interface
  //---------------
  wire gmii_tx_clk;
  wire gmii_rx_clk;
  wire [7:0] gmii_txd;
  wire gmii_tx_en;
  wire gmii_tx_er;
  wire [7:0] gmii_rxd;
  wire gmii_rx_dv;
  wire gmii_rx_er;

  // Management: Alternative to MDIO Interface
  //------------------------------------------
  reg [4:0] configuration_vector;

  wire signal_detect;
  wire [15:0] status_vector;



  //----------------------------------------------------------------------------
  // Create clock sources
  //----------------------------------------------------------------------------

  // An independent clock source used as the reference clock for an
  // IDELAYCTRL (if present) and for the main GT transceiver reset logic.
  // This testbench uses the frequency of 200MHz.
  initial
  begin
    independent_clock <= 1'b0;
    forever
    begin
      independent_clock <= 1'b0;
      #2500;
      independent_clock <= 1'b1;
      #2500;
    end
  end



  // Create the transceiver Reference clock (125 MHz)
  initial
  begin
    gtrefclk_p <= 1'b0;
    gtrefclk_n <= 1'b1;
    forever
    begin
      gtrefclk_p <= 1'b0;
      gtrefclk_n <= 1'b1;
      #4000;
      gtrefclk_p <= 1'b1;
      gtrefclk_n <= 1'b0;
      #4000;
    end
  end



  //----------------------------------------------------------------------------
  // Wire up Device Under Test
  //----------------------------------------------------------------------------
  gige_sfp_example_design dut
     (
      .independent_clock      (independent_clock),
      .gtrefclk_p             (gtrefclk_p),
      .gtrefclk_n             (gtrefclk_n),
      .txp                    (txp),
      .txn                    (txn),
      .rxp                    (rxp),
      .rxn                    (rxn),
      .gmii_tx_clk            (gmii_tx_clk),
      .gmii_rx_clk            (gmii_rx_clk),
      .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),
      .configuration_vector   (configuration_vector),
      .status_vector          (status_vector),
      .reset                  (reset),
      .signal_detect          (signal_detect)
      );



  //----------------------------------------------------------------------------
  // Instantiate a Stimulus module for the core
  //----------------------------------------------------------------------------
  stimulus_tb stimulus
     (
      .txp                    (txp),
      .txn                    (txn),
      .rxp                    (rxp),
      .rxn                    (rxn),

      .gmii_tx_clk            (gmii_tx_clk),
      .gmii_rx_clk            (gmii_rx_clk),
      .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),

      .configuration_finished (configuration_finished),
      .tx_monitor_finished    (tx_monitor_finished),
      .rx_monitor_finished    (rx_monitor_finished)
      );



  //----------------------------------------------------------------------------
  // Simulate that PMD sublayer has detected and optical input.
  //----------------------------------------------------------------------------
  assign signal_detect = 1'b1;




  //----------------------------------------------------------------------------
  // Set the configuration for the core.  Any of the bits within
  // "configuration_vector" can be changed dynamically.
  // The core is then reset
  //----------------------------------------------------------------------------
  initial
  begin : p_configuration
    $display("** Note: Timing checks are not valid");

    configuration_finished <= 0;

    configuration_vector[1:0] <= 2'h0;   // Disable Loopback
    configuration_vector[2]   <= 1'b0;   // Disable POWERDOWN
    configuration_vector[3]   <= 1'b0;   // Disable ISOLATE
    configuration_vector[4]   <= 1'b0;   // Enable  Auto-Neg

    // reset the core
    $display("Resetting core...");
    reset <= 1'b1;
    #1000000
    reset <= 1'b0;

    // wait for core to obtain synchronisation
    wait (status_vector[1] == 1);
    #20000000

    @(posedge gtrefclk_p)

    configuration_finished <= 1;
  end // p_configuration



  //----------------------------------------------------------------------------
  // End the simulation.
  //----------------------------------------------------------------------------

  assign simulation_finished = tx_monitor_finished & rx_monitor_finished;

  initial
  begin : p_end_simulation
  fork: sim_in_progress
     @(posedge simulation_finished) disable sim_in_progress;
     #200000000                     disable sim_in_progress;
  join
  if (simulation_finished)
       #1000000
       $display("Simulation Complete.");
  else
     $display("** Error: Testbench timed out");
  $stop;
  end // p_end_simulation



endmodule

