## Copyright (C) 1991-2011 Altera Corporation
## Your use of Altera Corporation's design tools, logic functions
## and other software and tools, and its AMPP partner logic
## functions, and any output files any of the foregoing
## (including device programming or simulation files), and any
## associated documentation or information are expressly subject
## to the terms and conditions of the Altera Program License
## Subscription Agreement, Altera MegaCore Function License
## Agreement, or other applicable license agreement, including,
## without limitation, that your use is for the sole purpose of
## programming logic devices manufactured by Altera and sold by
## Altera or its authorized distributors. Please refer to the
## applicable agreement for further details.
# This script is intended to be a guide. It is highly possible
# that due how the design is instantiated and other designs
# in your project may require some edits to this script especially
# clock name in order to ensure proper timing constraints.
#
# Reference
# AN 433: Constraining and Analyzing Source-Synchronous Interfaces.pdf
# *************************************************************
# The sdc below is based on the System Approach - Same Edge Capture Center Align
# *************************************************************
#**************************************************************
# Time Information
#**************************************************************
set_time_format -unit ns -decimal_places 3
# Input Clock to the PLL
set IN_CLK_PERIOD 10
# 1000MHz: Period = 8ns | 100MHz: Period = 40ns | 10MHz: Period = 400ns
set RX_CLK_125M_PERIOD 8
set RX_CLK_25M_PERIOD 40
set RX_CLK_2_5M_PERIOD 400
# 1000MHz: Period = 8ns | 100MHz: Period = 40ns | 10MHz: Period = 400ns
set TX_CLK_125M_PERIOD 8
set TX_CLK_25M_PERIOD 40
set TX_CLK_2_5M_PERIOD 400
# Default Frequency: 100MHz (Up to 125MHz)
set MM_CLK_PERIOD 10
# set FF_TX_CLK_PERIOD 10
# set FF_RX_CLK_PERIOD 10
# Change the name of the TSE(RGMII) core clocks on top level
set clk_in "CLK"
set mm_clk "mm_clk"
# set ff_tx_clk "ff_tx_clk"
# set ff_rx_clk "ff_rx_clk"
# Change the other clock name on the top level
set rgmii_rx_125M_virtualclk "rgmii_rx_125M_virtualclk"
set rgmii_rx_25M_virtualclk "rgmii_rx_25M_virtualclk"
set rgmii_rx_2_5M_virtualclk "rgmii_rx_2_5M_virtualclk"
set rgmii_rx_125M_clk "rgmii_rx_125M_clk"
set rgmii_rx_25M_clk "rgmii_rx_25M_clk"
set rgmii_rx_2_5M_clk "rgmii_rx_2_5M_clk"
# Change the name of rgmii interface on the top level
set rgmii_tx_clk "RGMII_TX_CLK"
set rgmii_out "RGMII_OUT"
set rgmii_tx_control "RGMII_TX_CONTROL"
set rgmii_rx_clk "RGMII_RX_CLK"
set rgmii_in "RGMII_IN"
set rgmii_rx_control "RGMII_RX_CONTROL"
**************************************************************
# Board and External PHY
#**************************************************************
# Board Delay
# Assume trace delay, pin capacitance, and rise/fall time differences between data and\
clock are negligible.
set data_delay_max 0
set data_delay_min 0
set clk_delay_max 0
set clk_delay_min 0
# External PHY Parameter (Refer to MarvelPHY 88EE1111)
set tsu 1.0
set th 0.8
set tco_max 0.5
set tco_min -0.5
#**************************************************************
# Create Clock
#**************************************************************
create_clock -name altera_tse_$clk_in -period $IN_CLK_PERIOD [get_ports $clk_in]
# create_clock -name altera_tse_$mm_clk -period $MM_CLK_PERIOD [get_ports $mm_clk]
# Create clock with 90 degree shift for center align
create_clock -name $rgmii_rx_125M_clk -period $RX_CLK_125M_PERIOD \
-waveform "[expr 0.25*$RX_CLK_125M_PERIOD] [expr 0.75*$RX_CLK_125M_PERIOD]" \
[get_ports $rgmii_rx_clk]
create_clock -name $rgmii_rx_25M_clk -period $RX_CLK_25M_PERIOD \
-waveform "[expr 0.25*$RX_CLK_25M_PERIOD] [expr 0.75*$RX_CLK_25M_PERIOD]" \
[get_ports $rgmii_rx_clk] \
-add
create_clock -name $rgmii_rx_2_5M_clk -period $RX_CLK_2_5M_PERIOD \
-waveform "[expr 0.25*$RX_CLK_2_5M_PERIOD] [expr 0.75*$RX_CLK_2_5M_PERIOD]" \
[get_ports $rgmii_rx_clk] \
-add
# create_clock -name altera_tse_$ff_tx_clk -period $FF_TX_CLK_PERIOD [get_ports $ff_tx_clk]
# create_clock -name altera_tse_$ff_rx_clk -period $FF_RX_CLK_PERIOD [get_ports $ff_rx_clk]
#**************************************************************
# Virtual Clock
#**************************************************************
# Virtual Clock is the clock outside the FPGA. It is also used
# to differentiate the clock uncertainty between
# Input to Register, Register to Register and Output to Register
create_clock -name $rgmii_rx_125M_virtualclk -period $RX_CLK_125M_PERIOD
create_clock -name $rgmii_rx_25M_virtualclk -period $RX_CLK_25M_PERIOD
create_clock -name $rgmii_rx_2_5M_virtualclk -period $RX_CLK_2_5M_PERIOD
#**************************************************************
# Create Generated Clock
#**************************************************************
# Tx PLL
#**************************************************************
create_generated_clock -name clk_125M_0deg \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|inclk[0]}] \
[get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[0]}] \
-divide_by 4 \
-multiply_by 5
create_generated_clock -name clk_25M_0deg \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|inclk[0]}] \
[get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[1]}] \
-divide_by 4
create_generated_clock -name clk_2_5M_0deg \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|inclk[0]}] \
[get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[2]}] \
-divide_by 40
create_generated_clock -name $mm_clk \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|inclk[0]}] \
[get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[3]}] \
-divide_by 1 \
-multiply_by 1
#**************************************************************
# RGMII TX CLOCK
#**************************************************************
# It doesn't use virtual clock as to include the delay generated by
# in the timing analysis
# -phase 90:Tells timing analysis that there is a phase-shift externaly.
# It have no effect inside the FPGA
create_generated_clock -name rgmii_125_tx_clk \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[0]}] \
-master_clock clk_125M_0deg \
-phase 90 \
[get_ports $rgmii_tx_clk]
create_generated_clock -name rgmii_25_tx_clk \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[1]}] \
-master_clock clk_25M_0deg \
[get_ports $rgmii_tx_clk] \
-phase 90 \
-add
create_generated_clock -name rgmii_2_5_tx_clk \
-source [get_pins {pll_inst|altpll_component|auto_generated|pll1|clk[2]}] \
-master_clock clk_2_5M_0deg \
-phase 90 \
[get_ports $rgmii_tx_clk] \
-add
#**************************************************************
#**************************************************************
# Set Clock Groups / Set False Path
#**************************************************************
# select_reg (selector of mux) is not the path propagate to RGMII interface. So, it is set to be false path.
set_false_path -from {CLKCRL:clkctrl_inst|CLKCRL_altclkctrl_5ke:CLKCRL_altclkctrl_5ke_component|select_reg*} -to {RGMII_OUT*}
set_false_path -from {CLKCRL:clkctrl_inst|CLKCRL_altclkctrl_5ke:CLKCRL_altclkctrl_5ke_component|select_reg*} -to {RGMII_TX_CONTROL}
# Each group will be analyzed with its clock domain within the group
set_clock_groups -exclusive \
-group "clk_125M_0deg rgmii_125_tx_clk $rgmii_rx_125M_clk $rgmii_rx_125M_virtualclk" \
-group "clk_25M_0deg rgmii_25_tx_clk $rgmii_rx_25M_clk $rgmii_rx_25M_virtualclk" \
-group "clk_2_5M_0deg rgmii_2_5_tx_clk $rgmii_rx_2_5M_clk $rgmii_rx_2_5M_virtualclk"
# Set false path to the design with different domain clock
set_clock_groups -asynchronous \
-group {clk_125M_0deg clk_25M_0deg clk_2_5M_0deg} \
-group "altera_tse_$clk_in" \
-group "mm_clk" \
-group "$rgmii_rx_125M_clk $rgmii_rx_25M_clk $rgmii_rx_2_5M_clk"
#**************************************************************
# Derive Clock Uncertainty
#**************************************************************
derive_clock_uncertainty -add
#**************************************************************
# Transmit Side (External PHY Delay is Turn On)
#**************************************************************
# Same Edge Capture Center Align: launch at positive edge and latch at positive edge
# Determine the desired setup and hold relationship in order to
# let TimeQuest analyze only the correct pair of launch-latch setup and hold relationship
set_false_path \
-fall_from [get_clocks "clk_125M_0deg clk_25M_0deg clk_2_5M_0deg"] \
-rise_to [get_clocks "rgmii_125_tx_clk rgmii_25_tx_clk rgmii_2_5_tx_clk"] \
-setup
set_false_path \
-rise_from [get_clocks "clk_125M_0deg clk_25M_0deg clk_2_5M_0deg"] \
-fall_to [get_clocks "rgmii_125_tx_clk rgmii_25_tx_clk rgmii_2_5_tx_clk"] \
-setup
set_false_path \
-fall_from [get_clocks "clk_125M_0deg clk_25M_0deg clk_2_5M_0deg"] \
-fall_to [get_clocks "rgmii_125_tx_clk rgmii_25_tx_clk rgmii_2_5_tx_clk"] \
-hold
set_false_path \
-rise_from [get_clocks "clk_125M_0deg clk_25M_0deg clk_2_5M_0deg"] \
-rise_to [get_clocks "rgmii_125_tx_clk rgmii_25_tx_clk rgmii_2_5_tx_clk"] \
-hold
# --------------------------------------------------------
# Take setup and hold time of External Phy and path delay difference
# between data and clock into timing analysis consideration for 125M clock
# The formula to calculate the output delay is provided in AN433
# Set Output Deday
set_output_delay -clock rgmii_125_tx_clk \
-max [expr $data_delay_max + $tsu - $clk_delay_min] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-add_delay
set_output_delay -clock rgmii_125_tx_clk \
-max [expr $data_delay_max + $tsu - $clk_delay_min] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-clock_fall \
-add_delay
set_output_delay -clock rgmii_125_tx_clk \
-min [expr $data_delay_min - $th - $clk_delay_max] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-add_delay
set_output_delay -clock rgmii_125_tx_clk \
-min [expr $data_delay_min - $th - $clk_delay_max] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-clock_fall \
-add_delay
# --------------------------------------------------------
# Take setup and hold time of External Phy and path delay difference
# between data and clock into timing analysis consideration for 25M clock
set_output_delay -clock rgmii_25_tx_clk \
-max [expr $data_delay_max + $tsu - $clk_delay_min] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-add_delay
set_output_delay -clock rgmii_25_tx_clk \
-max [expr $data_delay_max + $tsu - $clk_delay_min] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-clock_fall \
-add_delay
set_output_delay -clock rgmii_25_tx_clk \
-min [expr $data_delay_min - $th - $clk_delay_max] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-add_delay
set_output_delay -clock rgmii_25_tx_clk \
-min [expr $data_delay_min - $th - $clk_delay_max] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-clock_fall \
-add_delay
# --------------------------------------------------------
# Take setup and hold time of External Phy and path delay difference
# between data and clock into timing analysis consideration for 2.5M clock
set_output_delay -clock rgmii_2_5_tx_clk \
-max [expr $data_delay_max + $tsu - $clk_delay_min] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-add_delay
set_output_delay -clock rgmii_2_5_tx_clk \
-max [expr $data_delay_max + $tsu - $clk_delay_min] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-clock_fall \
-add_delay
set_output_delay -clock rgmii_2_5_tx_clk \
-min [expr $data_delay_min - $th - $clk_delay_max] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-add_delay
set_output_delay -clock rgmii_2_5_tx_clk \
-min [expr $data_delay_min - $th - $clk_delay_max] \
[get_ports "$rgmii_out* $rgmii_tx_control"] \
-clock_fall \
-add_delay
#**************************************************************
# Receiver Side (External PHY Delay is Turn On)
#**************************************************************
# Same Edge Capture Center Align: launch at positive edge and latch at positive edge
# Determine the desired setup and hold relationship in order to
# let TimeQuest analyze only the correct pair of launch-latch setup and hold relationship
set_false_path \
-fall_from [get_clocks "$rgmii_rx_125M_virtualclk $rgmii_rx_25M_virtualclk $rgmii_rx_2_5M_virtualclk"] \
-rise_to [get_clocks "$rgmii_rx_125M_clk $rgmii_rx_25M_clk $rgmii_rx_2_5M_clk"] \
-setup
set_false_path \
-rise_from [get_clocks "$rgmii_rx_125M_virtualclk $rgmii_rx_25M_virtualclk $rgmii_rx_2_5M_virtualclk"] \
-fall_to [get_clocks "$rgmii_rx_125M_clk $rgmii_rx_25M_clk $rgmii_rx_2_5M_clk"] \
-setup
set_false_path \
-fall_from [get_clocks "$rgmii_rx_125M_virtualclk $rgmii_rx_25M_virtualclk $rgmii_rx_2_5M_virtualclk"] \
-fall_to [get_clocks "$rgmii_rx_125M_clk $rgmii_rx_25M_clk $rgmii_rx_2_5M_clk"] \
-hold
set_false_path \
-rise_from [get_clocks "$rgmii_rx_125M_virtualclk $rgmii_rx_25M_virtualclk $rgmii_rx_2_5M_virtualclk"] \
-rise_to [get_clocks "$rgmii_rx_125M_clk $rgmii_rx_25M_clk $rgmii_rx_2_5M_clk"] \
-hold
# --------------------------------------------------------
# Take tco of External Phy and path delay difference between
# data and clock into timing analysis consideration for 125M clock
# The formula to calculate the input delay is provided in AN433
# Set Input Deday
set_input_delay -clock [get_clocks $rgmii_rx_125M_virtualclk] \
-max [expr $data_delay_max + $tco_max - $clk_delay_min] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_125M_virtualclk] \
-max [expr $data_delay_max + $tco_max - $clk_delay_min] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-clock_fall \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_125M_virtualclk] \
-min [expr $data_delay_min + $tco_min - $clk_delay_max] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_125M_virtualclk] \
-min [expr $data_delay_min + $tco_min - $clk_delay_max] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-clock_fall \
-add_delay
# --------------------------------------------------------
# Take tco of External Phy and path delay difference between
# data and clock into timing analysis consideration for 25M clock
set_input_delay -clock [get_clocks $rgmii_rx_25M_virtualclk] \
-max [expr $data_delay_max + $tco_max - $clk_delay_min] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_25M_virtualclk] \
-max [expr $data_delay_max + $tco_max - $clk_delay_min] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-clock_fall \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_25M_virtualclk] \
-min [expr $data_delay_min + $tco_min - $clk_delay_max] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_25M_virtualclk] \
-min [expr $data_delay_min + $tco_min - $clk_delay_max] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-clock_fall \
-add_delay
# --------------------------------------------------------
# Take tco of External Phy and path delay difference between
# data and clock into timing analysis consideration for 2.5M clock
set_input_delay -clock [get_clocks $rgmii_rx_2_5M_virtualclk] \
-max [expr $data_delay_max + $tco_max - $clk_delay_min] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_2_5M_virtualclk] \
-max [expr $data_delay_max + $tco_max - $clk_delay_min] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-clock_fall \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_2_5M_virtualclk] \
-min [expr $data_delay_min + $tco_min - $clk_delay_max] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-add_delay
set_input_delay -clock [get_clocks $rgmii_rx_2_5M_virtualclk] \
-min [expr $data_delay_min + $tco_min - $clk_delay_max] \
[get_ports "$rgmii_in* $rgmii_rx_control"] \
-clock_fall \
-add_delay