wiki:HardwareUsersGuides/WARPv3/Ethernet

WARP v3 User Guide: Ethernet

The WARP v3 board includes two Ethernet ports, labeled ETH A and ETH B on the board.

Ethernet PHY

Both Ethernet ports are connected a Marvell 88E1121R dual Ethernet PHY. The 88E1121R implements two tri-speed Ethernet PHY cores. Each PHY core has a dedicated MDI port, connected to the RJ-45 jack on the board, and RGMII port, connected to the FPGA.

Each PHY also has a dedicated MDIO port for exchanging configuration information with the Ethernet MAC. Each MDIO port is connected to dedicated FPGA pins for totally independent operation of the two interfaces. MDIO access requires a 5-bit address. It is important to use the correct PHY address when accessing registers via MDIO. You should not use address 0, the MDIO broadcast address, to avoid conflicts with Ethernet circuits inside the FPGA that may respond to broadcast MDIO transactions.

The hard-coded PHY addresses on WARP v3 are:

  • ETH A MDIO address: 0b00110 (0x6)
  • ETH B MDIO address: 0b00111 (0x7)

Errata note: the ETH A MDIO and MDC signal labels are swapped in the WARP v3 rev 1.1 schematics. The constraints below reflect the correct connections and have been verified in hardware.

MAC Addresses

The MAC address for each Ethernet interface is defined in user code at run-time. The API for setting the MAC address depends on your software design. If you're interacting with the Ethernet MAC directly (as in the OFDM ref design), you need to populate the source MAC address in your transmitted packets. If you're using a higher-layer API (like Xilnet in WARPLab) the MAC address is defined via a dedicated function.

Mango has a block of MAC addresses assigned by the IEEE: 40-D8-55-04-20-00 to 40-D8-55-04-2F-FF. We allocate two addresses from this range for each WARP v3 board. You can find your node's reserved addresses on a label on the back of the board. These addresses are also recorded in the board's EEPROM during manufacturing (see the EEPROM page for details).

Note: early WARP v3 kits did not include this label. These kits likewise do not have MAC addresses stored in their EEPROMs.

For boards with serial numbers lower than W3-a-00110, you can calculate your board's addresses with:

ETH A address: 40-D8-55-04-20-00 + (serial number)*2
ETH B address: 40-D8-55-04-20-00 + (serial number)*2 + 1

For example, for serial number W3-a-00050 the allocated addresses are 40-D8-55-04-20-64 and 40-D8-55-04-20-65.

We have prepared an FPGA design which will calculate these MAC addresses and store them in the EEPROM. To use it:

  1. Download WARPv3_MAC-Addr-EEPROM_Init.zip.
  2. Connect your WARP v3 kit to power, JTAG and USB-UART, configured for 57600bps.
  3. Configure the FPGA with the download.bit file in .zip archive.
  4. Watch the UART output for status messages.

For boards with serial numbers higher than W3-a-00110: these boards include the MAC address label and their EEPROMs are pre-programmed with the MAC addresses. For these newer kits there is no relation between serial number and MAC address.

Hardware Constraints

The FPGA pin constraints for the Ethernet interfaces are listed below.

#Common control - shared by PHY ports 0 and 1
NET "ETH_PHY_COMA" LOC = "C8" | IOSTANDARD = "LVCMOS25";
NET "ETH_PHY_RESETN" LOC = "L9" | IOSTANDARD = "LVCMOS25";

#88E1121R PHY 1 = ETH A on WARP v3 Board
NET "ETH_A_INT" LOC = "C10" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_MDC" LOC = "AK8" | IOSTANDARD = "LVCMOS25"; #errata: labeled MDIO in schematics, pulled up
NET "ETH_A_PD" LOC = "K9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_MDIO" LOC = "AP9" | IOSTANDARD = "LVCMOS25" | PULLUP; #errata: labeled MDC in schematics
NET "ETH_A_RX_CLK" LOC = "AC10" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_RX_CTRL" LOC = "AL9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_RXD<0>" LOC = "AK9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_RXD<1>" LOC = "AJ9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_RXD<2>" LOC = "AH8" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_RXD<3>" LOC = "AH9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_TX_CLK" LOC = "AE9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_TX_CTRL" LOC = "AG8" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_TXD<0>" LOC = "AF9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_TXD<1>" LOC = "AF10" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_TXD<2>" LOC = "AD9" | IOSTANDARD = "LVCMOS25";
NET "ETH_A_TXD<3>" LOC = "AD10" | IOSTANDARD = "LVCMOS25";

#88E1121R PHY 0 = ETH B on WARP v3 Board
NET "ETH_B_INT" LOC = "F9" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_MDC" LOC = "AN9" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_PD" LOC = "E8" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_MDIO" LOC = "AL8" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_RX_CLK" LOC = "L10" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_RX_CTRL" LOC = "A8" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_RXD<0>" LOC = "A9" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_RXD<1>" LOC = "D9" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_RXD<2>" LOC = "C9" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_RXD<3>" LOC = "F10" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_TX_CLK" LOC = "AB10" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_TX_CTRL" LOC = "D10" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_TXD<0>" LOC = "M10" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_TXD<1>" LOC = "B8" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_TXD<2>" LOC = "AC9" | IOSTANDARD = "LVCMOS25";
NET "ETH_B_TXD<3>" LOC = "E9" | IOSTANDARD = "LVCMOS25";

Ethernet MAC

The Virtex-6 FPGA includes hard TEMAC cores which implement a tri-speed Ethernet MAC compatible with the Marvell PHY on the WARP v3 board. Each PHY requires its own TEMAC. The Virtex-6 TEMAC is fully documented in the Xilinx V6 TEMAC user guide.

The sections below detail how to properly constrain the TEMAC instances in your FPGA design. These examples are based on our reference projects built in Xilinx Platform Studio (XPS) and assume the Ethernet interfaces are connected as peripherals in a processor-based design. It is certainly possible to use the TEMAC from custom logic, bypassing any processor. The placement and timing constraints below would be valid in such a design, but the net and instance names would likely change.

The constraints below are based on the Xilinx-provided examples for implementing RGMII interfaces with the V6 TEMAC in XPS. See Xilinx Answer Record 32713 for the original Xilinx reference designs.

When using the TEMAC in XPS, you may get warnings like

Hardware Evaluation license for component <soft_temac_wrap_v2> found. The generated design will cease to function in the programmed device after operating for some period of time.

This is normal. The hardware design will actually use the hard TEMAC and will not cease functioning after a timeout. According to Xilinx the warning is a "tool limitation" and can be safely ignored.

IDELAYCTRL Instances

The reference RGMII implementation uses IDELAY and ODELAY primitives to improve timing of the RGMII signals. These primitives require an IDELAYCTRL instance in the appropriate location in the FPGA.

The Xilinx tools will automatically replicate and instantiate the proper IDELAYCTRL blocks as long as your design includes a single IDELAYCTRL instance whose location is unspecified. See Xilinx Answer Record 39966 for more details.

To use this auto-replication feature, you should configure one TEMAC wrapper to include an IDELAYCTRL but leave its location unconstrained. Then configure the second TEMAC wrapper (and any other cores which utilize I/ODELAYs) to exclude an IDELAYCTRL.

XPS_LL_TEMAC

An MHS snippet for instantiating two XPS_LL_TEMAC cores is given below. The xps_ll_temac core requires a LocalLink-equipped core to Tx/Rx packets. You can either use the SDMA port of the MPMC or the xps_ll_fifo core for direct access to packet data from the PLB. Our reference projects use the xps_ll_fifo option.

Notice the IDELAYCTRL parameters, configured to instantiate one un-located IDELAYCTRL in the ETH_A wrapper. If you only need ETH A, you can omit the ETH B instance entirely. If you only need ETH B, you should omit ETH A but change C_NUM_IDELAYCTRL to 1 for ETH B.

#Leave C_IDELAYCTRL_LOC unspecified to auto-place/replicate
BEGIN xps_ll_temac
 PARAMETER INSTANCE = ETH_A
 PARAMETER C_NUM_IDELAYCTRL = 1
# PARAMETER C_IDELAYCTRL_LOC = 
 PARAMETER C_PHY_TYPE = 3
 PARAMETER C_TEMAC1_ENABLED = 0
 PARAMETER C_BUS2CORE_CLK_RATIO = 1
 PARAMETER C_TEMAC_TYPE = 3
 PARAMETER C_TEMAC0_PHYADDR = 0b00001
 PARAMETER HW_VER = 2.03.a
 PARAMETER C_BASEADDR = 0xFFFFFFFF
 PARAMETER C_HIGHADDR = 0x00000000
 BUS_INTERFACE SPLB = mb_plb
 BUS_INTERFACE LLINK0 = ETH_A_llink0
 PORT TemacPhy_RST_n = ETH_A_TemacPhy_RST_n_pin
 PORT GTX_CLK_0 = clk_125_0000MHz
 PORT REFCLK = clk_200_0000MHz
 PORT LlinkTemac0_CLK = clk_160_0000MHz
 PORT RGMII_TXD_0 = ETH_A_RGMII_TXD_0_pin
 PORT RGMII_TX_CTL_0 = ETH_A_RGMII_TX_CTL_0_pin
 PORT RGMII_TXC_0 = ETH_A_RGMII_TXC_0_pin
 PORT RGMII_RXD_0 = ETH_A_RGMII_RXD_0_pin
 PORT RGMII_RX_CTL_0 = ETH_A_RGMII_RX_CTL_0_pin
 PORT RGMII_RXC_0 = ETH_A_RGMII_RXC_0_pin
 PORT MDC_0 = ETH_A_MDC_0_pin
 PORT MDIO_0 = ETH_A_MDIO_0_pin
END

#Let ETH_A instantiate the unconstrained IDELAYCTRL
BEGIN xps_ll_temac
 PARAMETER INSTANCE = ETH_B
 PARAMETER C_NUM_IDELAYCTRL = 0
 PARAMETER C_PHY_TYPE = 3
 PARAMETER C_TEMAC1_ENABLED = 0
 PARAMETER C_BUS2CORE_CLK_RATIO = 1
 PARAMETER C_TEMAC_TYPE = 3
 PARAMETER C_TEMAC0_PHYADDR = 0b00001
 PARAMETER HW_VER = 2.03.a
 PARAMETER C_BASEADDR = 0xFFFFFFFF
 PARAMETER C_HIGHADDR = 0x00000000
 BUS_INTERFACE SPLB = mb_plb
 BUS_INTERFACE LLINK0 = ETH_B_llink0
 PORT GTX_CLK_0 = clk_125_0000MHz
 PORT REFCLK = clk_200_0000MHz
 PORT LlinkTemac0_CLK = clk_160_0000MHz
 PORT RGMII_TXD_0 = ETH_B_RGMII_TXD_0_pin
 PORT RGMII_TX_CTL_0 = ETH_B_RGMII_TX_CTL_0_pin
 PORT RGMII_TXC_0 = ETH_B_RGMII_TXC_0_pin
 PORT RGMII_RXD_0 = ETH_B_RGMII_RXD_0_pin
 PORT RGMII_RX_CTL_0 = ETH_B_RGMII_RX_CTL_0_pin
 PORT RGMII_RXC_0 = ETH_B_RGMII_RXC_0_pin
 PORT MDC_0 = ETH_B_MDC_0_pin
 PORT MDIO_0 = ETH_B_MDIO_0_pin
END

TEMAC Locations

The two RGMII interfaces are assigned to FPGA I/O banks which optimize connections to two TEMAC cores. You should explicitly constrain the TEMAC instance locations to the optimal TEMAC for each Ethernet interface. The recommended INST/LOC constraints are listed below. The instance names in your design may be different.

#Assumes TEMAC wrapper instance name includes "ETH_A"
INST "*ETH_A*v6_emac" LOC = "TEMAC_X0Y0";

#Assumes TEMAC wrapper instance name includes "ETH_B"
INST "*ETH_B*v6_emac" LOC = "TEMAC_X0Y1";

Timing Constraints

The RGMII interface requires special timing constraints to ensure the IODELAY blocks are configured correctly. The constraints from our reference projects are included below. These are based on the Xilinx reference implementation from AR32713.

There are many "magic" numbers in the constraints below. These have been tweaked to work on the WARP v3 hardware, but may change as we refine the reference projects. In case of differences between the constraints below and those included in a reference project, trust the project's local constraints first.

###### ETH_A
###### Hard_Ethernet_MAC
# This is a RGMII system
# GTX_CLK_0 = 125MHz
# LlinkTemac0_CLK = plb_v46 clk = host clock = 100MHz from clock generator
# Rx/Tx Client clocks are Rx/Tx PHY clocks so CORE Gen PHY clock constraints propagate to Rx/Tx client clock periods
# Time domain crossing constraints (DATAPATHONLY) are set for maximum bus frequency
# allowed by IP which is the maximum option in BSB. For lower bus frequency choice in BSB,
# the constraints are over constrained. Relaxing them for your system may reduce build time.

NET "*ETH_A*/hrst*" TIG;

# Locate the Tri-Mode Ethernet MAC instance
INST "*ETH_A*v6_emac" LOC = "TEMAC_X0Y0";

###############################################################################
# CLOCK CONSTRAINTS
# The following constraints are required. If you choose to not use the example
# design level of wrapper hierarchy, the net names should be translated to
# match your design.
###############################################################################

# Ethernet GTX_CLK high quality 125 MHz reference clock
NET "*/GTX_CLK_0" TNM_NET = "ref_gtx_clk";                                                 #name of signal connected to TEMAC GTX_CLK_0 input
TIMEGRP "v6_emac_v1_3_clk_ref_gtx" = "ref_gtx_clk";
TIMESPEC "TS_v6_emac_v1_3_clk_ref_gtx" = PERIOD "v6_emac_v1_3_clk_ref_gtx" 8 ns HIGH 50 %; #constant value based on constant 125 MHZ GTX clock

# Ethernet RGMII PHY-side transmit clock
# Changed NET Name - Input to bufg_tx_0
#     ___________                                         
#    |           |                 |\                     
#    | Hard Core |--- tx_clk_0_o --| >---- Tx_Cl_Clk -----
#    |___________|                 |/                     
#                                 BUFG
# 
NET "*ETH_A*/tx_cl_clk" TNM_NET = "A_phy_clk_tx";
TIMEGRP "A_v6_emac_v1_3_clk_phy_tx" = "A_phy_clk_tx";
TIMESPEC "TS_A_v6_emac_v1_3_clk_phy_tx" = PERIOD "A_v6_emac_v1_3_clk_phy_tx" 8 ns HIGH 50 %;

# Ethernet RGMII PHY-side receive clock
# Changed NET Name 
#  RGMII_RXC_0 is the name of the clock net at the TEMAC Port
#     It is the input to the IODELAY 
#        RxClientClk_0 is the name of the BUFG output clock net 
#
#                     _________      BUFR
#                    |         |      |\
#  ---RGMII_RXC_0----| IODELAY |------| >----RxClientClk_0------------
#                    |_________|      |/
#
NET "fpga_0_ETH_A_RGMII_RXC_0_pin" TNM_NET = "A_phy_clk_rx";
TIMEGRP "A_v6_emac_v1_3_clk_phy_rx" = "A_phy_clk_rx";
TIMESPEC "TS_A_v6_emac_v1_3_clk_phy_rx" = PERIOD "A_v6_emac_v1_3_clk_phy_rx" 7.5 ns HIGH 50 %;

# IDELAYCTRL 200 MHz reference clock
NET "clk_200*MHz*" TNM_NET  = "clk_ref_clk";                                              #name of signal connected to TEMAC REFCLK input    
TIMEGRP "ref_clk" = "clk_ref_clk";                                                                                                           
TIMESPEC "TS_ref_clk" = PERIOD "ref_clk" 5 ns HIGH 50 %;                                  #constant value based on constant 200 MHZ ref clock

# Constrain the DCR interface clock to an example frequency of 100 MHz
# Changed NET Name
# NET "DCREMACCLK" TNM_NET = "host_clock";
#NET "*ETH_A*/SPLB_CLK" TNM_NET = "host_clock";
#TIMEGRP "A_clk_host" = "A_host_clock";
#TIMESPEC "TS_A_clk_host" = PERIOD "A_clk_host" 10 ns HIGH 50 %;

###############################################################################
# PHYSICAL INTERFACE CONSTRAINTS
# The following constraints are necessary for proper operation, and are tuned
# for this example design. They should be modified to suit your design.
###############################################################################

# RGMII physical interface constraints
# -----------------------------------------------------------------------------

# Set the IDELAY and ODELAY values, tuned for this example design.
# These values should be modified to suit your design.
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_ctl_delay" IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d0_delay"  IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d1_delay"  IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d2_delay"  IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d3_delay"  IDELAY_VALUE = 13;

INST "*ETH_A*rgmii?rgmii_rx_ctl_delay" IDELAY_VALUE = 13;
INST "*ETH_A*rgmii?rgmii_rx_d0_delay"  IDELAY_VALUE = 13;
INST "*ETH_A*rgmii?rgmii_rx_d1_delay"  IDELAY_VALUE = 13;
INST "*ETH_A*rgmii?rgmii_rx_d2_delay"  IDELAY_VALUE = 13;
INST "*ETH_A*rgmii?rgmii_rx_d3_delay"  IDELAY_VALUE = 13;

INST "*ETH_A*rgmii_rxc0_delay"          IDELAY_VALUE = 0;
INST "*ETH_A*rgmii_rxc0_delay"          SIGNAL_PATTERN = CLOCK;
 
INST "*ETH_A*rgmii?rgmii_tx_clk_delay" ODELAY_VALUE = 6;
INST "*ETH_A*rgmii?rgmii_tx_clk_delay" SIGNAL_PATTERN = CLOCK;

# Group all IODELAY-related blocks to use a single IDELAYCTRL

# Change - added TNMs for trace length variations
INST "fpga_0_ETH_A_RGMII_RXD_0_pin[0]" TNM = "A_rgmii_rx_d0";
INST "fpga_0_ETH_A_RGMII_RXD_0_pin[1]" TNM = "A_rgmii_rx_d1";
INST "fpga_0_ETH_A_RGMII_RXD_0_pin[2]" TNM = "A_rgmii_rx_d2";
INST "fpga_0_ETH_A_RGMII_RXD_0_pin[3]" TNM = "A_rgmii_rx_d3";
INST "fpga_0_ETH_A_RGMII_RX_CTL_0_pin" TNM = "A_rgmii_rx_ctrl";

# Spec: 1.2ns setup time, 1.2ns hold time 
# The internal PHY delays were not used to derive the OFFSET constraints                                                                 
# Changed NET Name
#  This signal trace is longer than the clock trace, and arrives at the FPGA pin 64 ps after the clock
#  Therefore the offset in constraint must have less setup time than nominal
TIMEGRP "A_rgmii_rx_d0" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" RISING;
TIMEGRP "A_rgmii_rx_d0" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 376 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "A_rgmii_rx_d1" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" RISING;
TIMEGRP "A_rgmii_rx_d1" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 372 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "A_rgmii_rx_d2" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" RISING;
TIMEGRP "A_rgmii_rx_d2" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 115 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "A_rgmii_rx_d3" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" RISING;
TIMEGRP "A_rgmii_rx_d3" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 292 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "A_rgmii_rx_ctrl" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" RISING;
TIMEGRP "A_rgmii_rx_ctrl" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_A_RGMII_RXC_0_pin" FALLING;


NET "*ETH_A*/LlinkTemac0_CLK" TNM_NET = "A_LLCLK0"; #name of signal connected to TEMAC LlinkTemac0_CLK input
NET "*ETH_A*/SPLB_Clk" TNM_NET = "A_PLBCLK"; #name of signal connected to TEMAC SPLB_Clk input
NET "*ETH_A*/REFCLK" TNM_NET = "A_REFCLK"; #name of signal connected to TEMAC REFCLK input

TIMESPEC "TS_A_LL_CLK0_2_RX_CLIENT_CLK0"  = FROM A_LLCLK0 TO A_phy_clk_rx 8000 ps DATAPATHONLY; #constant value based on Ethernet clock                 
TIMESPEC "TS_A_LL_CLK0_2_TX_CLIENT_CLK0"  = FROM A_LLCLK0 TO A_phy_clk_tx 8000 ps DATAPATHONLY; #constant value based on Ethernet clock             
TIMESPEC "TS_A_RX_CLIENT_CLK0_2_LL_CLK0"  = FROM A_phy_clk_rx TO A_LLCLK0 8000 ps DATAPATHONLY; #varies based on period of LocalLink clock           
TIMESPEC "TS_A_TX_CLIENT_CLK0_2_LL_CLK0"  = FROM A_phy_clk_tx TO A_LLCLK0 8000 ps DATAPATHONLY; #varies based on period of LocalLink clock           

TIMESPEC "TS_A_REF_CLK_2_PLB_CLIENT_CLK"  = FROM A_REFCLK TO A_PLBCLK 8000 ps DATAPATHONLY; #varies based on period of PLB clock                        
TIMESPEC "TS_A_PLB_CLIENT_CLK_2_REF_CLK"  = FROM A_PLBCLK TO A_REFCLK 5000 ps DATAPATHONLY; #constant value based on constant 200 MHZ ref clock         

TIMESPEC "TS_A_REF_CLK_2_TX_CLIENT_CLK0"  = FROM A_REFCLK TO A_phy_clk_tx 8000 ps DATAPATHONLY; #constant value based on Ethernet clock                       
TIMESPEC "TS_A_TX_CLIENT_CLK0_2_REF_CLK"  = FROM A_phy_clk_tx TO A_REFCLK 5000 ps DATAPATHONLY; #constant value based on constant 200 MHZ ref clock           

TIMESPEC "TS_A_REF_CLK_2_RX_CLIENT_CLK0"  = FROM A_REFCLK TO A_phy_clk_rx 8000 ps DATAPATHONLY; #constant value based on Ethernet clock                
TIMESPEC "TS_A_RX_CLIENT_CLK0_2_REF_CLK"  = FROM A_phy_clk_rx TO A_REFCLK 5000 ps DATAPATHONLY; #constant value based on constant 200 MHZ ref clock    



###### ETH_B
###### Hard_Ethernet_MAC
# This is a RGMII system
# GTX_CLK_0 = 125MHz
# LlinkTemac0_CLK = plb_v46 clk = host clock = 100MHz from clock generator
# Rx/Tx Client clocks are Rx/Tx PHY clocks so CORE Gen PHY clock constraints propagate to Rx/Tx client clock periods
# Time domain crossing constraints (DATAPATHONLY) are set for maximum bus frequency
# allowed by IP which is the maximum option in BSB. For lower bus frequency choice in BSB,
# the constraints are over constrained. Relaxing them for your system may reduce build time.

NET "*ETH_B*/hrst*" TIG;

# Locate the Tri-Mode Ethernet MAC instance
INST "*ETH_B*v6_emac" LOC = "TEMAC_X0Y1";

###############################################################################
# CLOCK CONSTRAINTS
# The following constraints are required. If you choose to not use the example
# design level of wrapper hierarchy, the net names should be translated to
# match your design.
###############################################################################

# Ethernet RGMII PHY-side transmit clock
# Changed NET Name - Input to bufg_tx_0
#     ___________                                         
#    |           |                 |\                     
#    | Hard Core |--- tx_clk_0_o --| >---- Tx_Cl_Clk -----
#    |___________|                 |/                     
#                                 BUFG
# 
NET "*ETH_B*/tx_cl_clk" TNM_NET = "B_phy_clk_tx";
TIMEGRP "B_v6_emac_v1_3_clk_phy_tx" = "B_phy_clk_tx";
TIMESPEC "TS_B_v6_emac_v1_3_clk_phy_tx" = PERIOD "B_v6_emac_v1_3_clk_phy_tx" 8 ns HIGH 50 %;

# Ethernet RGMII PHY-side receive clock
# Changed NET Name 
#  RGMII_RXC_0 is the name of the clock net at the TEMAC Port
#     It is the input to the IODELAY 
#        RxClientClk_0 is the name of the BUFG output clock net 
#
#                     _________      BUFR
#                    |         |      |\
#  ---RGMII_RXC_0----| IODELAY |------| >----RxClientClk_0------------
#                    |_________|      |/
#
NET "fpga_0_ETH_B_RGMII_RXC_0_pin" TNM_NET = "B_phy_clk_rx";
TIMEGRP "B_v6_emac_v1_3_clk_phy_rx" = "B_phy_clk_rx";
TIMESPEC "TS_B_v6_emac_v1_3_clk_phy_rx" = PERIOD "B_v6_emac_v1_3_clk_phy_rx" 7.5 ns HIGH 50 %;

# Constrain the DCR interface clock to an example frequency of 100 MHz
# Changed NET Name
# NET "DCREMACCLK" TNM_NET = "host_clock";
NET "*ETH_B*/SPLB_CLK" TNM_NET = "host_clock";
TIMEGRP "B_clk_host" = "B_host_clock";
TIMESPEC "TS_B_clk_host" = PERIOD "B_clk_host" 10 ns HIGH 50 %;

###############################################################################
# PHYSICAL INTERFACE CONSTRAINTS
# The following constraints are necessary for proper operation, and are tuned
# for this example design. They should be modified to suit your design.
###############################################################################

# RGMII physical interface constraints
# -----------------------------------------------------------------------------

# Set the IDELAY and ODELAY values, tuned for this example design.
# These values should be modified to suit your design.
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_ctl_delay" IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d0_delay"  IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d1_delay"  IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d2_delay"  IDELAY_VALUE = 13;
# original assuming equal trace lengths  INST "*rgmii?rgmii_rx_d3_delay"  IDELAY_VALUE = 13;

INST "*ETH_B*rgmii?rgmii_rx_ctl_delay" IDELAY_VALUE = 13;
INST "*ETH_B*rgmii?rgmii_rx_d0_delay"  IDELAY_VALUE = 13;
INST "*ETH_B*rgmii?rgmii_rx_d1_delay"  IDELAY_VALUE = 13;
INST "*ETH_B*rgmii?rgmii_rx_d2_delay"  IDELAY_VALUE = 13;
INST "*ETH_B*rgmii?rgmii_rx_d3_delay"  IDELAY_VALUE = 13;

INST "*ETH_B*rgmii_rxc0_delay"          IDELAY_VALUE = 0;
INST "*ETH_B*rgmii_rxc0_delay"          SIGNAL_PATTERN = CLOCK;
 
INST "*ETH_B*rgmii?rgmii_tx_clk_delay" ODELAY_VALUE = 6;
INST "*ETH_B*rgmii?rgmii_tx_clk_delay" SIGNAL_PATTERN = CLOCK;

# Group all IODELAY-related blocks to use a single IDELAYCTRL

# Change - added TNMs for trace length variations
INST "fpga_0_ETH_B_RGMII_RXD_0_pin[0]" TNM = "B_rgmii_rx_d0";
INST "fpga_0_ETH_B_RGMII_RXD_0_pin[1]" TNM = "B_rgmii_rx_d1";
INST "fpga_0_ETH_B_RGMII_RXD_0_pin[2]" TNM = "B_rgmii_rx_d2";
INST "fpga_0_ETH_B_RGMII_RXD_0_pin[3]" TNM = "B_rgmii_rx_d3";
INST "fpga_0_ETH_B_RGMII_RX_CTL_0_pin" TNM = "B_rgmii_rx_ctrl";

# Spec: 1.2ns setup time, 1.2ns hold time 
# The internal PHY delays were not used to derive the OFFSET constraints                                                                 
# Changed NET Name
#  This signal trace is longer than the clock trace, and arrives at the FPGA pin 64 ps after the clock
#  Therefore the offset in constraint must have less setup time than nominal
TIMEGRP "B_rgmii_rx_d0" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" RISING;
TIMEGRP "B_rgmii_rx_d0" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 376 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "B_rgmii_rx_d1" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" RISING;
TIMEGRP "B_rgmii_rx_d1" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 372 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "B_rgmii_rx_d2" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" RISING;
TIMEGRP "B_rgmii_rx_d2" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 115 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "B_rgmii_rx_d3" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" RISING;
TIMEGRP "B_rgmii_rx_d3" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" FALLING;

#  This signal trace is shorter than the clock trace, and arrives at the FPGA pin 292 ps before the clock
#  Therefore the offset in constraint must have more setup time than nominal
TIMEGRP "B_rgmii_rx_ctrl" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" RISING;
TIMEGRP "B_rgmii_rx_ctrl" OFFSET = IN 1.2 ns VALID 2.4 ns BEFORE "fpga_0_ETH_B_RGMII_RXC_0_pin" FALLING;


NET "*ETH_B*/LlinkTemac0_CLK" TNM_NET = "B_LLCLK0"; #name of signal connected to TEMAC LlinkTemac0_CLK input
NET "*ETH_B*/SPLB_Clk" TNM_NET = "B_PLBCLK"; #name of signal connected to TEMAC SPLB_Clk input

TIMESPEC "TS_B_LL_CLK0_2_RX_CLIENT_CLK0"  = FROM B_LLCLK0 TO B_phy_clk_rx 8000 ps DATAPATHONLY; #constant value based on Ethernet clock                 
TIMESPEC "TS_B_LL_CLK0_2_TX_CLIENT_CLK0"  = FROM B_LLCLK0 TO B_phy_clk_tx 8000 ps DATAPATHONLY; #constant value based on Ethernet clock             
TIMESPEC "TS_B_RX_CLIENT_CLK0_2_LL_CLK0"  = FROM B_phy_clk_rx TO B_LLCLK0 8000 ps DATAPATHONLY; #varies based on period of LocalLink clock           
TIMESPEC "TS_B_TX_CLIENT_CLK0_2_LL_CLK0"  = FROM B_phy_clk_tx TO B_LLCLK0 8000 ps DATAPATHONLY; #varies based on period of LocalLink clock 
Last modified 5 years ago Last modified on Feb 5, 2014, 9:54:39 AM

Attachments (1)

Download all attachments as: .zip