📄 altmemddr_phy_ddr_timing.sdc
字号:
}
# calibrated capture clock
set capture_clockname "${instname}_ddr_capture"
set capture_pattern ${instname}_alt_mem_phy_ciii_inst|dpio|dqs_group\[*\].dq\[*\].dqi|auto_generated|input_cell_*\[0\]|clk
create_clock -period $t(period) -name $capture_clockname [get_pins -compatibility_mode $capture_pattern] -add
set count 0
foreach_in_collection reg [get_pins -compatibility_mode $capture_pattern] {
set clockname "${instname}_dq_[incr count]"
create_generated_clock -name $clockname -source [get_pins -compatibility_mode $resync_clock] [get_pin_info -name $reg] -add
set_false_path -from [get_ports *] -to [get_clocks $clockname]
}
set_false_path -from [get_clocks $capture_clockname] -to [get_clocks $resync_clock]
# measure clock
set measure_clockname ${instname}_ddr_mimic
set measure_pattern ${instname}_alt_mem_phy_ciii_inst|clk|DDR_CLK_OUT\[0\].ddr_clk_out_p|auto_generated|input_cell_h\[0\]|clk
sett_collection c [get_pins -compatibility_mode $measure_pattern]
set source [get_node_info -name $c]
create_clock -period $t(period) -name $measure_clockname $source -add
set_false_path -from [get_clocks $mimic_clock] -to $measure_clockname
set_false_path -to [get_clocks $mimic_clock] -from $measure_clockname
foreach ck_clock_type_pn [array names ck_output_clocks] {
set_false_path -from [get_clocks $ck_output_clocks($ck_clock_type_pn)] -to [get_clocks $measure_clockname]
}
set scan_clock_patterns [list ${instname}_alt_mem_phy_ciii_inst|clk|scan_clk|q 2]
foreach {pattern divide_by} $scan_clock_patterns {
foreach_in_collection c [get_pins -compatibility_mode $pattern] {
set source [get_node_info -name $c]
set sys_pll_clock [get_pll_clock [list $c] "System" "" 16]
if {$sys_pll_clock != ""} {
post_sdc_message info "Creating scan clock ${source}_clock driven by $sys_pll_clock divided by $divide_by"
create_generated_clock -multiply_by 1 -divide_by $divide_by -source $sys_pll_clock -master_clock $sys_pll_clock $source -name ${source}_clock
set_max_delay -to [get_clocks $sys_pll_clock] -from [get_clocks ${source}_clock] 9.0
set_max_delay -from [get_clocks $sys_pll_clock] -to [get_clocks ${source}_clock] 9.0
set_min_delay -to [get_clocks $sys_pll_clock] -from [get_clocks ${source}_clock] -9.0
set_min_delay -from [get_clocks $sys_pll_clock] -to [get_clocks ${source}_clock] -9.0
} else {
post_message -type warning "Cannot find source clock of $source"
}
}
}
set msg_list [list]
set dqs_pll_clock_id [get_output_clock_id [get_all_dqs_pins $pins(dqsgroup)] "DQS output" msg_list]
set dq_pll_clock_id [get_output_clock_id [get_all_dq_pins $pins(dqsgroup)] "DQ output" msg_list]
if {$dqs_pll_clock_id == -1 || $dq_pll_clock_id == -1} {
foreach {msg_type msg} $msg_list {
post_message -type $msg_type "altmemddr_phy_ddr_timing.sdc: $msg"
}
post_message -type warning "altmemddr_phy_ddr_timing.sdc: Failed to find PLL clock for pins [join [get_all_dqs_pins $pins(dqsgroup)]]"
} else {
set dqsclksource [get_node_info -name $dqs_pll_clock_id]
set dqclksource [get_node_info -name $dq_pll_clock_id]
}
foreach dqsgroup $pins(dqsgroup) {
set dqspin [lindex $dqsgroup 0]
if {!$altmemddr_phy_use_high_performance_timing} {
# DQS output clock
set dqs_out_clockname "${instname}_ddr_dqsout_${dqspin}"
create_generated_clock -multiply_by 1 -source $dqsclksource -master_clock $dqsclksource $dqspin -name $dqs_out_clockname -add
}
# endif !altmemddr_phy_use_high_performance_timing
if {!$altmemddr_phy_use_high_performance_timing} {
set_output_delay -add_delay -clock $dqs_out_clockname -max [round_3dp [expr {$t(board_skew) + $t(DS) + $WR_DQS_DQ_SETUP_ERROR}]] [concat [lindex $dqsgroup 1] [lindex $dqsgroup 2]]
set_output_delay -add_delay -clock $dqs_out_clockname -min [round_3dp [expr {-$t(DH) - $t(board_skew) - $t(DCD_total) - $WR_DQS_DQ_HOLD_ERROR}]] [concat [lindex $dqsgroup 1] [lindex $dqsgroup 2]]
set_output_delay -add_delay -clock_fall -clock $dqs_out_clockname -max [round_3dp [expr {$t(board_skew) + $t(DS) + $WR_DQS_DQ_SETUP_ERROR}]] [concat [lindex $dqsgroup 1] [lindex $dqsgroup 2]]
set_output_delay -add_delay -clock_fall -clock $dqs_out_clockname -min [round_3dp [expr {-$t(DH) - $t(board_skew) - $t(DCD_total) - $WR_DQS_DQ_HOLD_ERROR}]] [concat [lindex $dqsgroup 1] [lindex $dqsgroup 2]]
}
# endif !altmemddr_phy_use_high_performance_timing
# DQS vs CK
set off_tDQSS 0
set off_tDSS 0
foreach ckclock [get_output_clocks tDQSS p] {
set_output_delay -add_delay -clock $ckclock -max [round_3dp [expr {($off_tDQSS+1-$t(DQSS)) * $t(period) + $t(board_skew) + $fpga_tDQSS_SETUP_ERROR}]] $dqspin
set_output_delay -add_delay -clock $ckclock -min [round_3dp [expr {($off_tDQSS+$t(DQSS)) * $t(period) - $t(board_skew) - $fpga_tDQSS_HOLD_ERROR}]] $dqspin
}
foreach ckclock [get_output_clocks tDQSS n] {
set_output_delay -add_delay -clock_fall -clock $ckclock -max [round_3dp [expr {($off_tDQSS+1-$t(DQSS)) * $t(period) + $t(board_skew) + $fpga_tDQSS_SETUP_ERROR}]] $dqspin
set_output_delay -add_delay -clock_fall -clock $ckclock -min [round_3dp [expr {($off_tDQSS+$t(DQSS)) * $t(period) - $t(board_skew) - $fpga_tDQSS_HOLD_ERROR}]] $dqspin
}
foreach ckclock [concat [get_output_clocks tDQSS p] [get_output_clocks tDQSS n]] {
set_false_path -to [get_clocks $ckclock] -fall_from [get_clocks $dqsclksource]
}
foreach ckclock [get_output_clocks tDSS p] {
set_output_delay -add_delay -clock $ckclock -max [round_3dp [expr {($off_tDSS+$t(DSS)) * $t(period) + $t(board_skew) + $fpga_tDSSH_SETUP_ERROR}]] $dqspin
set_output_delay -add_delay -clock $ckclock -min [round_3dp [expr {($off_tDSS-$t(DSH)) * $t(period) - $t(board_skew) - $fpga_tDSSH_HOLD_ERROR}]] $dqspin
}
foreach cknclock [get_output_clocks tDSS n] {
set_output_delay -add_delay -clock_fall -clock $cknclock -max [round_3dp [expr {($off_tDSS+$t(DSS)) * $t(period) + $t(board_skew) + $fpga_tDSSH_SETUP_ERROR}]] $dqspin
set_output_delay -add_delay -clock_fall -clock $cknclock -min [round_3dp [expr {($off_tDSS-$t(DSH)) * $t(period) - $t(board_skew) - $fpga_tDSSH_HOLD_ERROR}]] $dqspin
}
foreach ckclock [concat [get_output_clocks tDSS p] [get_output_clocks tDSS n]] {
# DSS and DSH are only for falling edge of DQS
set_false_path -to [get_clocks $ckclock] -rise_from [get_clocks $dqsclksource]
}
# Only analyze the DDIO mux select path to the DQS output
set_false_path -from [all_registers] -to [get_ports $dqspin]
}
set x [expr {$t(HP) - 2*$t(AC) - $t(calibration_error)}]
set_max_delay -from [get_all_dq_pins $pins(dqsgroup)] -to [all_registers] [round_3dp [expr {$t(capture_shift) + 0.5*$x}]]
set_min_delay -from [get_all_dq_pins $pins(dqsgroup)] -to [all_registers] [round_3dp [expr {$t(capture_shift) - 0.5*$x}]]
set capture_clock $resync_clock
set_false_path -from [get_all_dq_pins $pins(dqsgroup)] -to [get_clocks $capture_clock]
set_false_path -to [get_pins -compatibility_mode ${instname}_alt_mem_phy_ciii_inst|dpio|dqs_group\[*\].dq\[*\].dqi|auto_generated|input_*_*\[0\]|clrn]
if {$altmemddr_phy_use_high_performance_timing} {
# Cut paths to read capture registers
set dq_list [get_all_dq_pins $pins(dqsgroup)]
if {[llength $dq_list] > 0} {
set_false_path -from [concat $dq_list] -to [all_registers]
}
# Cut paths from write registers and PLL clocks-as-data
set d_dm_list [concat $dq_list [get_all_dm_pins $pins(dqsgroup)]]
if {[llength $d_dm_list] > 0} {
set_false_path -from * -to $d_dm_list
}
}
# endif altmemddr_phy_use_high_performance_timing
# Mimic Path
foreach ck $pins(ck_p) {
create_clock -period $t(period) $ck -name ${instname}_${ck}_mimic_launch_clock -add
}
set_max_delay -from [get_ports $pins(ck_p)] -to * $t(mimic_shift)
set clear_list [list \
${instname}_alt_mem_phy_ciii_inst|clk|*pll|altpll_component|auto_generated|pll_lock_sync|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|global_pre_clear|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|reset_master_ams|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|mem_pipe|ams_pipe\[*\]|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|mem_clk_pipe|ams_pipe\[*\]|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|write_clk_pipe|ams_pipe\[*\]|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|measure_clk_pipe|ams_pipe\[*\]|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|resync_clk_pipe|ams_pipe\[*\]|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|clk_div_reset_ams_n_r|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|clk_div_reset_ams_n|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|pll_reconfig_reset_ams_n_r|clrn \
${instname}_alt_mem_phy_ciii_inst|clk|pll_reconfig_reset_ams_n|clrn \
]
foreach clear $clear_list {
set clear_pins [get_pins -compatibility_mode $clear]
if {[get_collection_size $clear_pins] > 0} {
set_false_path -thru $clear_pins -to *
}
}
# Address Command
# post_message -type info "Address/Command"
set msg_list [list]
set ac_pll_clock_id [get_output_clock_id $pins(addrcmd) "Address/Command output" msg_list]
if {$ac_pll_clock_id == -1} {
foreach {msg_type msg} $msg_list {
post_message -type $msg_type "altmemddr_phy_ddr_timing.sdc: $msg"
}
post_message -type warning "altmemddr_phy_ddr_timing.sdc: Failed to find PLL clock for pins [join $pins(addrcmd)]"
} else {
set ac_pll_clock [get_node_info -name $ac_pll_clock_id]
set ded_off_rise 0
set ded_off_fall 0
set off $ded_off_fall
# Only analyze the DDIO mux select
set_false_path -from [all_registers] -to [concat $pins(addrcmd) $pins(addrcmd_2t)]
foreach ckclock [get_output_clocks ac_fall p] {
set_output_delay -add_delay -clock $ckclock -max [round_3dp [expr {$off*$t(period) + $t(IS) + $t(board_skew) + $t(DCD_total) + $fpga_tCK_ADDR_CTRL_SETUP_ERROR + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
set_output_delay -add_delay -clock $ckclock -min [round_3dp [expr {$off*$t(period) - $t(IH) - $t(board_skew) - $t(DCD_total) - $fpga_tCK_ADDR_CTRL_HOLD_ERROR + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
}
foreach ckclock [get_output_clocks ac_fall n] {
set_output_delay -add_delay -clock_fall -clock $ckclock -max [round_3dp [expr {$off*$t(period) + $t(IS) + $t(board_skew) + $t(DCD_total) + $fpga_tCK_ADDR_CTRL_SETUP_ERROR + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
set_output_delay -add_delay -clock_fall -clock $ckclock -min [round_3dp [expr {$off*$t(period) - $t(IH) - $t(board_skew) - $t(DCD_total) - $fpga_tCK_ADDR_CTRL_HOLD_ERROR + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
}
if {$ac_pll_clock_id != -1} {
foreach ckclock [concat [get_output_clocks ac_fall p] [get_output_clocks ac_fall n]] {
set_false_path -rise_from [get_clocks $ac_pll_clock] -to $ckclock
}
}
}
if { [llength $pins(addrcmd_2t)] > 0 } {
# post_message -type info "Address/Command (half rate)"
set_multicycle_path -setup -to $pins(addrcmd_2t) 2
set_multicycle_path -hold -to $pins(addrcmd_2t) 1
}
}
set instance_list [get_core_instance_list $corename]
foreach inst $instance_list {
post_sdc_message info "Adding SDC requirements for $corename instance $inst"
add_requirements_for_instance $corename $inst t $altmemddr_phy_use_high_performance_timing
add_ddr_report_command "source [list [file join [file dirname [info script]] ${corename}_report_timing.tcl]]"
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -