Idelay進行時序調節

IODELAY_GROUP


# PART is virtexu xcvu440flga2892

############################################################
# Clock Period Constraints                                 #
############################################################

############################################################
# RX Clock period Constraints (per instance)               #
############################################################
# Receiver clock period constraints: please do not relax
create_clock -period 8 [get_ports rgmii_rxc]

#
####
#######
##########
#############
#################
#BLOCK CONSTRAINTS

############################################################
# Physical Interface Constraints
############################################################

############################################################
# The following are required to maximise setup/hold        #
############################################################

set_property SLEW FAST [get_ports {rgmii_txd[3] rgmii_txd[2] rgmii_txd[1] rgmii_txd[0] rgmii_tx_ctl rgmii_txc}]


############################################################
# RGMII: IODELAY Constraints
############################################################
# Please modify the value of the IDELAY_VALUE/ODELAY_VALUE
# according to your design.
# For more information on IDELAYCTRL and IODELAY, please
# refer to the User Guide.
#
# Apply the same DELAY_VALUE to all RGMII RX inputs.
# DELAY_VALUE is the time represenatation of the desired delay in ps
# This is to provide a similiar Clock Path and Data Path delay.
set_property DELAY_VALUE 900  [get_cells {rgmii_interface/delay_rgmii_rx* rgmii_interface/rxdata_bus[*].delay_rgmii_rx*}]
# Group IODELAY components
set_property IODELAY_GROUP tri_mode_ethernet_mac_iodelay_grp [get_cells {rgmii_interface/delay_rgmii_tx* rgmii_interface/txdata_out_bus[*].delay_rgmii_tx*}]
set_property IODELAY_GROUP tri_mode_ethernet_mac_iodelay_grp [get_cells {rgmii_interface/delay_rgmii_rx* rgmii_interface/rxdata_bus[*].delay_rgmii_rx*}]

//------------------------------------------------------------------------------
// File       : tri_mode_ethernet_mac_0_rgmii_v2_0_if.v
// Author     : Xilinx Inc.
// -----------------------------------------------------------------------------
// (c) Copyright 2013 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 module creates a version 2.0 Reduced Gigabit Media
//               Independent Interface (RGMII v2.0) by instantiating
//               Input/Output buffers and Input/Output double data rate
//               (DDR) flip-flops as required.
//
//               This interface is used to connect the Ethernet MAC to
//               an external Ethernet PHY.
//               This module routes the rgmii_rxc from the phy chip
//               (via a bufg) onto the rx_clk line.

//------------------------------------------------------------------------------

`timescale 1 ps / 1 ps

//------------------------------------------------------------------------------
// The module declaration for the PHY IF design.
//------------------------------------------------------------------------------
module tri_mode_ethernet_mac_0_rgmii_v2_0_if (
    // Synchronous resets
    input            tx_reset,
    input            rx_reset,

    // The following ports are the MDIO physical interface: these will be
    // pins on the FPGA
    inout            mdio,
    output           mdc,

    // The following ports are the internal connections from IOB logic to
    // the TEMAC core for the MDIO
    output           mdio_i,
    input            mdio_o,
    input            mdio_t,
    input            mdc_i,

    // Current operating speed is 10/100
    input            speedis10100,

    // The following ports are the RGMII physical interface: these will be at
    // pins on the FPGA
    output     [3:0] rgmii_txd,
    output           rgmii_tx_ctl,
    output           rgmii_txc,
    input      [3:0] rgmii_rxd,
    input            rgmii_rx_ctl,
    input            rgmii_rxc,

    // The following signals are in the RGMII in-band status signals
    output reg       link_status,
    output reg [1:0] clock_speed,
    output reg       duplex_status,

    // The following ports are the internal GMII connections from IOB logic
    // to the TEMAC core
    input            phy_tx_enable,
    input            phy_tx_enable_falling,
    input      [7:0] txd_from_mac,
    input            tx_en_from_mac,
    input            tx_er_from_mac,
    input            tx_clk,
    input            clk_div5,
    input            clk_div5_shift,
    output     [7:0] rxd_to_mac,
    output           rx_dv_to_mac,
    output           rx_er_to_mac,

    // Receiver clock for the MAC and Client Logic
    output           rx_clk
  );


  //----------------------------------------------------------------------------
  // internal signals
  //----------------------------------------------------------------------------

  wire   [3:0] rgmii_txd_obuf;
  wire         rgmii_tx_ctl_obuf;
  wire         rgmii_txc_obuf;
  wire   [3:0] rgmii_rxd_ibuf;
  wire         rgmii_rx_ctl_ibuf;
  wire         rgmii_rxc_ibuf;
  reg    [3:0] gmii_txd_falling;             // gmii_txd signal registered on the falling edge of tx_clk.
  wire         delay_rgmii_tx_clk_out;
  wire         delay_rgmii_tx_clk_return;
  wire         rgmii_txc_odelay;             // RGMII receiver clock ODDR output.
  wire         rgmii_tx_ctl_odelay;          // RGMII control signal ODDR output.
  wire   [3:0] rgmii_txd_odelay;             // RGMII data ODDR output.
  wire         rgmii_tx_ctl_int;             // Internal RGMII transmit control signal.
  wire         rgmii_rx_ctl_delay;
  wire   [3:0] rgmii_rxd_delay;
  wire         rx_clk_int;
  wire         rx_clk_iddr;
  wire         rgmii_rx_ctl_reg;             // Internal RGMII receiver control signal.
  reg          tx_en_to_ddr;
  wire         tx_en_to_ddr_fall;
  reg          tx_en_to_ddr_lch;
  wire         gmii_rx_dv_reg;               // gmii_rx_dv registered in IOBs.
  wire         gmii_rx_er_reg;               // gmii_rx_er registered in IOBs.
  wire   [7:0] gmii_rxd_reg;                 // gmii_rxd registered in IOBs.
  wire         inband_ce;                    // RGMII inband status registers clock enable


  //----------------------------------------------------------------------------
  // Input/Output Buffers
  //----------------------------------------------------------------------------

  // MDIO
  //--------
  IOBUF mdio_iobuf (
     .I              (mdio_o),
     .IO             (mdio),
     .O              (mdio_i),
     .T              (mdio_t)
  );

   // Route through the MDC clock
  OBUF mdc_obuf_i (
     .I              (mdc_i),
     .O              (mdc)
  );


  // RGMII
  //--------
  OBUF rgmii_txc_obuf_i (
     .I              (rgmii_txc_obuf),
     .O              (rgmii_txc)
  );

  OBUF rgmii_tx_ctl_obuf_i (
     .I              (rgmii_tx_ctl_obuf),
     .O              (rgmii_tx_ctl)
  );

  genvar loopa;
  generate for (loopa=0; loopa<4; loopa=loopa+1)
    begin : obuf_data
      OBUF rgmii_txd_obuf_i (
         .I          (rgmii_txd_obuf[loopa]),
         .O          (rgmii_txd[loopa])
      );
    end
  endgenerate

  
 (* DONT_TOUCH = "yes" *) IBUF rgmii_rxc_ibuf_i (
     .I              (rgmii_rxc),
     .O              (rgmii_rxc_ibuf)
  );

 (* DONT_TOUCH = "yes" *) IBUF rgmii_rx_ctl_ibuf_i (
     .I              (rgmii_rx_ctl),
     .O              (rgmii_rx_ctl_ibuf)
  );

  genvar loopi;
  generate for (loopi=0; loopi<4; loopi=loopi+1)
    begin : ibuf_data
      IBUF rgmii_rxd_ibuf_i (
         .I          (rgmii_rxd[loopi]),
         .O          (rgmii_rxd_ibuf[loopi])
      );
    end
  endgenerate


  //----------------------------------------------------------------------------
  // Route internal signals to output ports
  //----------------------------------------------------------------------------

  assign rxd_to_mac      = gmii_rxd_reg;
  assign rx_dv_to_mac    = gmii_rx_dv_reg;
  assign rx_er_to_mac    = gmii_rx_er_reg;


  //----------------------------------------------------------------------------
  // RGMII Transmitter Clock Management
  //----------------------------------------------------------------------------

  // Delay the transmitter clock relative to the data.
  // For 1 gig operation this delay is set to produce a 90 degree phase
  // shifted clock w.r.t. gtx_clk_bufg so that the clock edges are
  // centralised within the rgmii_txd[3:0] valid window.

  // Instantiate the Output DDR primitive
  ODDRE1 #(
       
      .SRVAL         (1'b0)
  ) rgmii_txc_ddr (
      .Q             (rgmii_txc_odelay),
      .C             (tx_clk),
      .D1            (clk_div5_shift),
      .D2            (clk_div5),
      .SR            (tx_reset)
   );


   // Instantiate the Output Delay primitive (delay output by 2 ns).  In order to
   // achieve 2ns, an ODELAY is cascaded with an IDELAY from the bitslice
   // immediately below it.
 ODELAYE3 #(
      
      .DELAY_VALUE      (875),
      
      .DELAY_TYPE       ("FIXED"),
      .CASCADE          ("MASTER"),
      .REFCLK_FREQUENCY (333.333),
      .SIM_DEVICE       ("ULTRASCALE")
      
   )
   delay_rgmii_tx_clk (
      .ODATAIN          (rgmii_txc_odelay),
      .DATAOUT          (rgmii_txc_obuf),
      .CLK              (1'b0),
      .CE               (1'b0),
      .INC              (1'b0),
      .CNTVALUEIN       (9'h0),
      .CNTVALUEOUT      (),
      .LOAD             (1'b0),
      .RST              (1'b0),
      .CASC_IN          (1'b0),
      .CASC_RETURN      (delay_rgmii_tx_clk_casc_return),
      .CASC_OUT         (delay_rgmii_tx_clk_casc_out),
      .EN_VTC           (1'b1)
   );

 IDELAYE3 #(
      .DELAY_VALUE      (0),
      .DELAY_TYPE       ("FIXED"),
      .CASCADE          ("SLAVE_END"),
      .REFCLK_FREQUENCY (333.333),
      .SIM_DEVICE       ("ULTRASCALE")
      
  )
  delay_rgmii_tx_clk_casc (
      .IDATAIN          (1'b0),
      .DATAOUT          (delay_rgmii_tx_clk_casc_return),
      .DATAIN           (1'b0),
      .CLK              (1'b0),
      .CE               (1'b0),
      .INC              (1'b0),
      .CNTVALUEIN       (9'h0),
      .CNTVALUEOUT      (),
      .LOAD             (1'b0),
      .RST              (1'b0),
      .CASC_IN          (delay_rgmii_tx_clk_casc_out),
      .CASC_RETURN      (1'b0),
      .CASC_OUT         (),
      .EN_VTC           (1'b1)
  );

  

   //---------------------------------------------------------------------------
   // RGMII Transmitter Logic :
   // drive TX signals through IOBs onto RGMII interface
   //---------------------------------------------------------------------------

   // Encode rgmii ctl signal
   assign rgmii_tx_ctl_int = tx_en_from_mac ^ tx_er_from_mac;


   // Instantiate Double Data Rate Output components. Then
   // put data and control signals through ODELAY components to
   // provide similiar net delays to those seen on the clk signal.

   always @ (speedis10100, txd_from_mac)
   begin
      if (speedis10100 == 1'b0)
         gmii_txd_falling     <= txd_from_mac[7:4];
      else
         gmii_txd_falling     <= txd_from_mac[3:0];
   end


   genvar i;
   generate for (i=0; i<4; i=i+1)
     begin : txdata_out_bus
       ODDRE1 #(
       
          .SRVAL         (1'b0)
       )
       rgmii_txd_out (
          .Q             (rgmii_txd_odelay[i]),
          .C             (tx_clk),
          .D1            (txd_from_mac[i]),
          .D2            (gmii_txd_falling[i]),
          .SR            (tx_reset)
       );



      ODELAYE3 #(
          .DELAY_VALUE      (0),
          .DELAY_TYPE       ("FIXED"),
          .REFCLK_FREQUENCY (333.333),
      .SIM_DEVICE       ("ULTRASCALE")
      
       )
       delay_rgmii_txd (
          .ODATAIN       (rgmii_txd_odelay[i]),
          .DATAOUT       (rgmii_txd_obuf[i]),
          .CLK           (1'b0),
          .CE            (1'b0),
          .INC           (1'b0),
          .CNTVALUEIN    (9'h0),
          .CNTVALUEOUT   (),
          .LOAD          (1'b0),
          .RST           (1'b0),
          .CASC_IN       (1'b0),
          .CASC_RETURN   (1'b0),
          .CASC_OUT      (),
          .EN_VTC        (1'b1)
       );

     end
   endgenerate



   // when the speed switches to 10/100 tx_clk is running much faster than
   // txc and therefore the ddr needs to be controlled to prevent updates
   // occuring at tx_clk rate

   always @(posedge tx_clk)
   begin
     if(tx_reset) begin  
       tx_en_to_ddr_lch <= 1'b0;
     end  
     else begin
       if(phy_tx_enable | clk_div5) begin
         tx_en_to_ddr_lch <= tx_en_from_mac;
       end
       else if(!clk_div5 & clk_div5_shift) begin
         tx_en_to_ddr_lch <= rgmii_tx_ctl_int;
       end
       else begin
         tx_en_to_ddr_lch <= tx_en_to_ddr_lch;
       end
     end   
   end  

   always @(speedis10100 or phy_tx_enable or clk_div5 or clk_div5_shift or tx_en_from_mac or rgmii_tx_ctl_int or tx_en_to_ddr_lch)
   begin
     if( !speedis10100 | (speedis10100 & (phy_tx_enable | clk_div5)))begin
       tx_en_to_ddr = tx_en_from_mac;
     end
     else if( speedis10100 & (!clk_div5 & clk_div5_shift)) begin
       tx_en_to_ddr = rgmii_tx_ctl_int;
     end 
     else begin
       tx_en_to_ddr = tx_en_to_ddr_lch;
     end
   end  

   assign tx_en_to_ddr_fall = speedis10100 ? tx_en_to_ddr :rgmii_tx_ctl_int;


   ODDRE1 #(
       
      .SRVAL         (1'b0)
   )
   ctl_output (
      .Q             (rgmii_tx_ctl_odelay),
      .C             (tx_clk),
      .D1            (tx_en_to_ddr),
      .D2            (tx_en_to_ddr_fall),
      .SR            (tx_reset)
   );

   


   ODELAYE3 #(
      .DELAY_VALUE      (0),
      .DELAY_TYPE       ("FIXED"),
      .REFCLK_FREQUENCY (333.333),
      .SIM_DEVICE   ("ULTRASCALE")
      
   )
   delay_rgmii_tx_ctl (
      .ODATAIN       (rgmii_tx_ctl_odelay),
      .DATAOUT       (rgmii_tx_ctl_obuf),
      .CLK           (1'b0),
      .CE            (1'b0),
      .INC           (1'b0),
      .CNTVALUEIN    (9'h0),
      .CNTVALUEOUT   (),
      .LOAD          (1'b0),
      .RST           (1'b0),
      .CASC_IN       (1'b0),
      .CASC_RETURN   (1'b0),
      .CASC_OUT      (),
      .EN_VTC        (1'b1)
   );

   //---------------------------------------------------------------------------
   // RGMII Receiver Clock Logic
   //---------------------------------------------------------------------------

   // Route rgmii_rxc through a BUFG and onto clock routing
   BUFG
   bufg_rgmii_rx_clk (
      .I             (rgmii_rxc_ibuf),
      .O             (rx_clk_int)
   );

   // Route rgmii_rxc through a BUFG for connecting to IDDR components
   BUFG 
   bufg_rgmii_rx_clk_iddr (
      .I             (rgmii_rxc_ibuf),
      .O             (rx_clk_iddr)
   );


   // Assign the internal clock signal to the output port
   assign rx_clk = rx_clk_int;


   //---------------------------------------------------------------------------
   // RGMII Receiver Logic : receive signals through IOBs from RGMII interface
   //---------------------------------------------------------------------------

   // Drive input RGMII Rx signals from PADS through IODELAYS.

   // Please modify the IODELAY_VALUE according to your design.
   // For more information on IDELAYCTRL and IODELAY, please refer to
   // the User Guide.

   
  IDELAYE3 #(
      .DELAY_TYPE       ("FIXED"),
      .REFCLK_FREQUENCY (333.333),
      .SIM_DEVICE    ("ULTRASCALE")
      
   )
   delay_rgmii_rx_ctl (
      .IDATAIN       (rgmii_rx_ctl_ibuf),
      .DATAOUT       (rgmii_rx_ctl_delay),
      .DATAIN        (1'b0),
      .CLK           (1'b0),
      .CE            (1'b0),
      .INC           (1'b0),
      .CNTVALUEIN    (9'h0),
      .CNTVALUEOUT   (),
      .LOAD          (1'b0),
      .RST           (1'b0),
      .CASC_IN       (1'b0),
      .CASC_RETURN   (1'b0),
      .CASC_OUT      (),
      .EN_VTC        (1'b1)
      );
   

   genvar j;
   generate for (j=0; j<4; j=j+1)
     begin : rxdata_bus

   

       IDELAYE3 #(
          .DELAY_TYPE       ("FIXED"),
          .REFCLK_FREQUENCY (333.333),
          .SIM_DEVICE    ("ULTRASCALE")
      
       )
       delay_rgmii_rxd (
          .IDATAIN       (rgmii_rxd_ibuf[j]),
          .DATAOUT       (rgmii_rxd_delay[j]),
          .DATAIN        (1'b0),
          .CLK           (1'b0),
          .CE            (1'b0),
          .INC           (1'b0),
          .CNTVALUEIN    (9'h0),
          .CNTVALUEOUT   (),
          .LOAD          (1'b0),
          .RST           (1'b0),
          .CASC_IN       (1'b0),
          .CASC_RETURN   (1'b0),
          .CASC_OUT      (),
          .EN_VTC        (1'b1)
       );
     end
   endgenerate


   // Instantiate Double Data Rate Input flip-flops.
   // DDR_CLK_EDGE attribute specifies output data alignment from IDDR component

   genvar k;
   generate for (k=0; k<4; k=k+1)
     begin : rxdata_in_bus

       IDDRE1 #(
          .DDR_CLK_EDGE  ("SAME_EDGE_PIPELINED")
       )
       rgmii_rx_data_in (
          .Q1            (gmii_rxd_reg[k]),
          .Q2            (gmii_rxd_reg[k+4]),
          .C             (rx_clk_iddr),
          .CB            (!rx_clk_iddr),
          .D             (rgmii_rxd_delay[k]),
          .R             (1'b0)
       );
     end
   endgenerate

   IDDRE1 #(
      .DDR_CLK_EDGE  ("SAME_EDGE_PIPELINED")
   )
   rgmii_rx_ctl_in (
      .Q1            (gmii_rx_dv_reg),
      .Q2            (rgmii_rx_ctl_reg),
      .C             (rx_clk_iddr),
      .CB            (!rx_clk_iddr),
      .D             (rgmii_rx_ctl_delay),
      .R             (1'b0)
   );


   // Decode gmii_rx_er signal
   assign gmii_rx_er_reg = gmii_rx_dv_reg ^ rgmii_rx_ctl_reg;


  //----------------------------------------------------------------------------
  // RGMII Inband Status Registers
  // extract the inband status from received rgmii data
  //----------------------------------------------------------------------------

   // Enable inband status registers during Interframe Gap
   assign inband_ce = !(gmii_rx_dv_reg || gmii_rx_er_reg);

   always @ (posedge rx_clk_int)
   begin
      if (rx_reset) begin
         link_status          <= 1'b0;
         clock_speed[1:0]     <= 2'b0;
         duplex_status        <= 1'b0;
      end
      else if (inband_ce) begin
         link_status          <= gmii_rxd_reg[0];
         clock_speed[1:0]     <= gmii_rxd_reg[2:1];
         duplex_status        <= gmii_rxd_reg[3];
      end
   end



endmodule

//------------------------------------------------------------------------------
// Title      : Transmitter Clock Generator
// Project    : Tri-Mode Ethernet MAC
//------------------------------------------------------------------------------
// File       : tri_mode_ethernet_mac_0_clk_en_gen.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 module provides clock enables for the tx
//   logic and clocks to be used in the generation of rgmii_txc.
//   At 1G the enables are both set to 1 as they are not reuired, at 100M
//   the enables occur every 5th cycle for the phy interface and every 10th for
//   the client.  At 10M this changes to every 50th and every 100th respectively.
//   The clk_div5 outputs are used purely to generate the txc output and are
//   used as data inputs to the DDR logic.
//------------------------------------------------------------------------------

`timescale 1 ps/1 ps

module tri_mode_ethernet_mac_0_clk_en_gen
  (
      input             reset,
      input             speed_is_10_100,
      input             speed_is_100,
      input             clk,
      output   reg      client_tx_enable,
      output   reg      phy_tx_enable,
	  output   reg      phy_tx_enable_falling,
      output   reg      clk_div5,
      output   reg      clk_div5_shift
   );

   reg   [5:0]          counter;
   reg   [5:0]          wrap_point;
   reg   [5:0]          first_edge;
   reg   [5:0]          second_edge;
   reg                  div_2;
   wire                 speed_is_10_100_int;
   wire                 speed_is_100_int;
   reg                  clk_div5_int;
   reg                  clk_div5_shift_int;
// locally sync the speed controls

   tri_mode_ethernet_mac_0_block_sync_block txspeedis10100gen (
      .clk              (clk),
      .data_in          (speed_is_10_100),
      .data_out         (speed_is_10_100_int)
   );

   tri_mode_ethernet_mac_0_block_sync_block txspeedis100gen (
      .clk              (clk),
      .data_in          (speed_is_100),
      .data_out         (speed_is_100_int)
   );

// generate a 6 bit counter which counts to a max of 50 and then wraps
// the wrap point is dependant upon the speed setting
always @(posedge clk)
begin
   if (reset) begin
      counter                    <= 0;
   end
   else begin
      if (counter >= wrap_point) begin
         counter                 <= 0;
      end
      else begin
         counter                 <= counter + 1;
      end
   end
end

always @(speed_is_10_100_int or speed_is_100_int)
begin
   if (!speed_is_10_100_int) begin
      wrap_point                 = 0;
      first_edge                 = 0;
      second_edge                = 0;
   end
   else begin
      if (speed_is_100_int) begin
         wrap_point                 = 4;
         first_edge                 = 1;
         second_edge                = 2;
      end
      else begin
         wrap_point                 = 49;
         first_edge                 = 23;
         second_edge                = 24;
      end
   end
end

// look for counter to equal wrap point - this gives the high speed
// clock enable - we want to generate a second enable every other pulse
always @(posedge clk)
begin
   if (reset) begin
      div_2                      <= 0;
   end
   else begin
      if (speed_is_10_100_int) begin
         if (counter >= wrap_point) begin
            div_2                <= !div_2;
         end
      end
      else begin
         div_2                   <= 0;
      end
   end
end

// generate the clock enables - only if speed is not 1G
always @(posedge clk)
begin
   if (reset) begin
      clk_div5_int               <= 0;
      clk_div5_shift_int         <= 0;
   end
   else begin
      if (speed_is_10_100_int) begin
         if (counter >= wrap_point) begin
            clk_div5_int         <= 1;
            clk_div5_shift_int   <= 1;
         end
         else if (counter == first_edge) begin
            clk_div5_int         <= 0;
            clk_div5_shift_int   <= 1;
         end
         else if (counter == second_edge) begin
            clk_div5_int         <= 0;
            clk_div5_shift_int   <= 0;
         end
      end
      else begin
         clk_div5_int            <= 0;
         clk_div5_shift_int      <= 1;
      end
   end
end

// the pipeline delay between the MAC enable and the clock needs to be controlled
// to ensure the correct timing at the IO
always @(posedge clk)
begin
   if (reset) begin
      clk_div5                   <= 0;
      clk_div5_shift             <= 0;
   end
   else begin
      clk_div5                   <= clk_div5_int;
      clk_div5_shift             <= clk_div5_shift_int;
   end
end

always @(posedge clk)
begin
   if (reset) begin
      client_tx_enable           <= 0;
      phy_tx_enable              <= 0;
   end
   else begin
      if (counter >= wrap_point) begin
         phy_tx_enable           <= 1;
      end
      else begin
         phy_tx_enable           <= 0;
      end
      if (counter >= first_edge) begin
         phy_tx_enable_falling   <= 1;
      end
      else begin
         phy_tx_enable_falling   <= 0;
      end
      if ((counter >= wrap_point) & !div_2) begin
         client_tx_enable        <= 1;
      end
      else begin
         client_tx_enable        <= 0;
      end
   end
end



endmodule

------------------------------------------------------------

clock_dedicated_route backbone

  -----------------------------------------------------------

  "如果時鐘輸入引腳需要驅動不同時鐘域的CMT(MMCM/PLL)模塊,那麼約束CLOCK_DEDICATED_ROUTE=BACKBONE是必須的。 是什麼情況會導致時鐘輸入與CMT不在一個時鐘域呢?當一組外部接口時序,其時鐘信號輸入FPGA的一個I/O Bank,而相應的數據信號則在另一個I/O Bank輸入,並且此時需對時鐘信號進行分頻,分頻後的時鐘用作輸入數據的採集。"

---------------------------------------------------------------

xilinx的時鐘架構設計

 

----------------------------------------------------------------

IDELAYCTRL

 

轉載:

https://zhuanlan.zhihu.com/p/91843786

https://zhuanlan.zhihu.com/p/117290284

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章