OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [rtl/] [altera_ddr_ctrl/] [altera_ddr_phy_ddr_timing.sdc] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 xianfeng
#
2
# Legal Notice: (C)2007 Altera Corporation. All rights reserved. Your
3
# use of Altera Corporation's design tools, logic functions and other
4
# software and tools, and its AMPP partner logic functions, and any
5
# output files any of the foregoing (including device programming or
6
# simulation files), and any associated documentation or information are
7
# expressly subject to the terms and conditions of the Altera Program
8
# License Subscription Agreement or other applicable license agreement,
9
# including, without limitation, that your use is for the sole purpose
10
# of programming logic devices manufactured by Altera and sold by Altera
11
# or its authorized distributors. Please refer to the applicable
12
# agreement for further details.
13
 
14
################################################################################
15
# This file constrains the ALTMEMPHY memory interface PHY. The parameters at
16
# the top of thie file may be edited, but be warned that it it overwritten when
17
# regenerating the ALTMEMPHY Megacore Function.
18
################################################################################
19
# Generated by:9.0
20
# variation name : altera_ddr_phy
21
# family : Cyclone III
22
# speed_grade : 6
23
# local_if_drate : Full
24
# pll_ref_clk_mhz : 50.0
25
# mem_if_clk_mhz : 150.0
26
# mem_if_preset : PSC A2S56D40CTP-G5
27
# chip_or_dimm : Discrete Device
28
# mem_if_dq_per_dqs : 8
29
# ac_phase : 90
30
# ac_clk_select : 90
31
 
32
# The clock period of your memory interface. Don't modify this
33
set t(period) 6.666
34
 
35
# The worst case skew between any pair of traces which are nominally matched
36
set t(board_skew) 0.020
37
set t(min_additional_dqs_variation) 0.000
38
set t(max_additional_dqs_variation) 0.000
39
 
40
# Memory timing parameters. See Section 6 of the JEDEC spec.
41
# ----------------------------------
42
# tDS/tDH: write timing
43
set t(DS) 0.400
44
set t(DH) 0.400
45
 
46
# Data output timing for non-DQS capture
47
set t(AC) 0.700
48
 
49
# Address and command input timing
50
set t(IS) 0.600
51
set t(IH) 0.600
52
 
53
# DQS to CK input timing
54
set t(DSS) 0.2
55
set t(DSH) 0.2
56
set t(DQSS) 0.28
57
 
58
# DQ to DQS timing on read
59
set t(DQSQ) 0.400
60
set t(QHS) 0.500
61
 
62
# DQS to CK timing on reads
63
set t(DQSCK) 0.550
64
set t(capture_shift) 2.2
65
set t(HP) 3.000
66
 
67
# The maximum allowed length of the mimic path depends on the device family
68
if {$::TimeQuestInfo(family) == "Arria GX"} {
69
set t(mimic_shift) 2.200
70
} elseif {$::TimeQuestInfo(family) == "HardCopy II"} {
71
set t(mimic_shift) 2.000
72
} elseif {$::TimeQuestInfo(family) == "Cyclone III" || $::TimeQuestInfo(family) == "Cyclone III LS"} {
73
set t(mimic_shift) 2.500
74
} else {
75
set t(mimic_shift) 1.600
76
}
77
 
78
# The characterised margin loss on capture due to measurement error in the
79
# sequencer auto calibration.
80
set t(calibration_error) 1.144
81
 
82
 
83
# If the address and command paths are longer than the CK paths, put the
84
# difference in here
85
set t(additional_addresscmd_tpd) 0.000
86
 
87
# The variation name of this ALTMEMPHY
88
set corename "altera_ddr_phy"
89
 
90
# The clock period of the PLL reference clock
91
set t(inclk_period) 20.000
92
 
93
# Duty cycle distortion from the device data sheet
94
set t(DCD_total) 0.250
95
 
96
# PLL phase shift error
97
set t(PLL_PSERR) 0.000
98
 
99
 
100
################################################################################
101
# A callback to collect the results of the top level pin detection
102
################################################################################
103
proc ddr_pin {n pin pins_array_name} {
104
        upvar 1 $pins_array_name pins
105
        global pins
106
        if {![info exists pins($n)] } {
107
                post_message -type critical_warning "ddr_pin $n $pin $pins_array_name didn't recognise '$n' as a pin type"
108
        } else {
109
                lappend pins($n) $pin
110
        }
111
}
112
 
113
################################################################################
114
# Locate the top level pins that are connected to this ALTMEMPHY instance
115
################################################################################
116
set pin_file_name "altera_ddr_phy_ddr_pins.tcl"
117
set dirname [file dirname [info script]]
118
set fn [file join $dirname $pin_file_name]
119
source $fn
120
 
121
################################################################################
122
# Add the SDC constraints for a single instantiation of this ALTMEMPHY
123
# variation. This is called multiple times if the variation has multiple
124
# instantiations.
125
################################################################################
126
proc add_requirements_for_instance {corename instance_name t_name altera_ddr_phy_use_high_performance_timing} {
127
        upvar 1 $t_name t
128
        set instname "${instance_name}|${corename}"
129
 
130
        global ck_output_clocks
131
        array unset ck_output_clocks
132
 
133
        global pins
134
        array unset pins
135
 
136
        set pins(ck_p) [list]
137
        set pins(ck_n) [list]
138
        set pins(addrcmd) [list]
139
        set pins(addrcmd_2t) [list]
140
        set pins(dqsgroup) [list]
141
        set pins(dgroup) [list]
142
 
143
################################################################################
144
# Cache the result of the automatic top level pin detection to reduce fit times
145
        global pins_cache
146
        if { [array exists pins_cache] &&  [info exists pins_cache($corename-$instance_name)] } {
147
                # post_message -type critical_warning "cache hit"
148
                array set pins $pins_cache($corename-$instance_name)
149
        } else {
150
                # post_message -type critical_warning "cache miss"
151
                get_ddr_pins $instname pins
152
                set pins_cache($corename-$instance_name) [array get pins]
153
        }
154
 
155
################################################################################
156
# Create the PLL input clock and derive clocks on the PLL outputs
157
        set msg_list [list]
158
 
159
        set ck_pll_clock_id [get_output_clock_id $pins(ck_p) "CK output" msg_list]
160
        if {$ck_pll_clock_id == -1} {
161
                foreach {msg_type msg} $msg_list {
162
                        post_message -type $msg_type "altera_ddr_phy_ddr_timing.sdc: $msg"
163
                }
164
                post_message -type warning "altera_ddr_phy_ddr_timing.sdc: Failed to find PLL clock for pins [join $pins(ck_p)]"
165
        } else {
166
                set ck_pll_clock [get_node_info -name $ck_pll_clock_id]
167
                set pll_ref_clk_id [get_input_clk_id $ck_pll_clock_id]
168
                if {$pll_ref_clk_id != -1} {
169
                        set pll_ref_clk [get_node_info -name $pll_ref_clk_id]
170
                        if {[get_collection_size [get_clocks -nowarn $pll_ref_clk]] == 0} {
171
                                create_clock -period $t(inclk_period) $pll_ref_clk
172
                        }
173
 
174
                        if {[get_collection_size [get_clocks -nowarn $ck_pll_clock]] > 0} {
175
                                # PLL clocks already derived
176
                        } else {
177
                                derive_pll_clocks
178
                        }
179
                } else {
180
                        post_message -type info "altera_ddr_phy_ddr_timing.sdc: Could not find PLL clocks for $ck_pll_clock. Creating PLL base clocks"
181
                        # Attempt to recover
182
                        derive_pll_clocks -create_base_clocks
183
                }
184
                derive_clock_uncertainty
185
        }
186
 
187
################################################################################
188
 
189
# Find the TimeQuest name for the resync clock. If it is not found, create one.
190
        set resync_clock_pattern ${instname}_alt_mem_phy_inst|clk|*|altpll_component|auto_generated|pll1|clk\[3\]
191
        set resync_clock_id ""
192
        sett_collection resync_clock_id [get_pins -compatibility_mode $resync_clock_pattern]
193
        set resync_clock [get_node_info -name $resync_clock_id]
194
        set resync_pll_ref_clk_id [get_input_clk_id $resync_clock_id]
195
 
196
        if {$resync_pll_ref_clk_id != -1} {
197
                set resync_pll_ref_clk [get_node_info -name $resync_pll_ref_clk_id]
198
                if {[get_collection_size [get_clocks -nowarn $resync_pll_ref_clk]] == 0} {
199
                        create_clock -period $t(inclk_period) $resync_pll_ref_clk
200
                }
201
        } else {
202
                post_message -type warning "altera_ddr_phy_ddr_timing.sdc: Failed to find PLL input clock pin driving $resync_clock"
203
        }
204
 
205
################################################################################
206
 
207
# Find the TimeQuest name for the mimic clock. If it is not found, create one.
208
        set mimic_clock_pattern ${instname}_alt_mem_phy_inst|clk|*|altpll_component|auto_generated|pll1|clk\[4\]
209
        set mimic_clock_pins [get_pins -nowarn -compatibility_mode $mimic_clock_pattern]
210
 
211
        if {[get_collection_size $mimic_clock_pins] == 1} {
212
                set mimic_clock_id ""
213
                sett_collection mimic_clock_id $mimic_clock_pins
214
                set mimic_clock [get_node_info -name $mimic_clock_id]
215
        } else {
216
                post_message -type error "Couldn't find mimic clock from pattern $mimic_clock_pattern"
217
                set mimic_clock ""
218
        }
219
 
220
################################################################################
221
 
222
# Find the TimeQuest name for the system clock. If it is not found, create one.
223
        set system_clock_pattern ${instname}_alt_mem_phy_inst|clk|*|altpll_component|auto_generated|pll1|clk\[1\]
224
        set system_clock_pins [get_pins -nowarn -compatibility_mode $system_clock_pattern]
225
 
226
        if {[get_collection_size $system_clock_pins] == 1} {
227
                set system_clock_id ""
228
                sett_collection system_clock_id $system_clock_pins
229
                set system_clock [get_node_info -name $system_clock_id]
230
                if {[info exists pll_ref_clk]} {
231
                        set_false_path -from $pll_ref_clk -to $system_clock
232
                        set_false_path -to $pll_ref_clk -from $system_clock
233
                        #Cut the path from the system clock to the mimic clock :
234
                        set_false_path -from $system_clock -to [get_clocks $mimic_clock]
235
                }
236
        } else {
237
                set system_clock ""
238
        }
239
 
240
 
241
################################################################################
242
# When the ALTMEMPHY is targeted for the HardCopy device family, additional
243
# clock uncertainties need to be added. These uncertainties will be provided by
244
# the HardCopy Design Centre in a file called _cu.tcl. They are
245
#  not needed for the FPGA device families, and are set to zero in that case.
246
################################################################################
247
set fpga_tREAD_CAPTURE_SETUP_ERROR 0
248
set fpga_tREAD_CAPTURE_HOLD_ERROR 0
249
set fpga_RESYNC_SETUP_ERROR 0
250
set fpga_RESYNC_HOLD_ERROR 0
251
set fpga_PA_DQS_SETUP_ERROR 0
252
set fpga_PA_DQS_HOLD_ERROR 0
253
set WR_DQS_DQ_SETUP_ERROR 0
254
set WR_DQS_DQ_HOLD_ERROR 0
255
set fpga_tCK_ADDR_CTRL_SETUP_ERROR 0
256
set fpga_tCK_ADDR_CTRL_HOLD_ERROR 0
257
set fpga_tDQSS_SETUP_ERROR 0
258
set fpga_tDQSS_HOLD_ERROR 0
259
set fpga_tDSSH_SETUP_ERROR 0
260
set fpga_tDSSH_HOLD_ERROR 0
261
################################################################################
262
# post_message -type info "Creating CK output clocks"
263
        set ck_clock_types_list [list tDSS tDQSS ac_rise ac_fall]
264
        set source $ck_pll_clock
265
 
266
        foreach ckpin [concat $pins(ck_p) $pins(ck_n)] {
267
                if { [lsearch -exact $pins(ck_p) $ckpin] != -1 } {
268
                        set invert 0
269
                        set ckpn p
270
                } elseif { [lsearch -exact $pins(ck_n) $ckpin] != -1 } {
271
                        set invert 1
272
                        set ckpn n
273
                } else {
274
                        error "Can't find pin $ckpin in $pins(ck_p) or $pins(ck_n)"
275
                }
276
 
277
                # We don't care about the tco of the memory clocks
278
                set_false_path -from * -to [get_ports $ckpin]
279
                set clocknamestub "${instname}_ck_${ckpn}_${ckpin}"
280
 
281
                foreach ck_clock_type $ck_clock_types_list {
282
                        set clockname "${clocknamestub}_${ck_clock_type}"
283
                        if { $invert } {
284
                                create_generated_clock -add -multiply_by 1 -source $source -master_clock $source -invert -name $clockname $ckpin
285
                        } else {
286
                                create_generated_clock -add -multiply_by 1 -source $source -master_clock $source -name $clockname $ckpin
287
                        }
288
                        add_output_clock $ck_clock_type $ckpn $clockname
289
                }
290
        }
291
 
292
# calibrated capture clock
293
set capture_clockname "${instname}_ddr_capture"
294
set capture_pattern ${instname}_alt_mem_phy_inst|dpio|dqs_group\[*\].dq\[*\].dqi|auto_generated|input_cell_*\[0\]|clk
295
create_clock -period $t(period) -name $capture_clockname [get_pins -compatibility_mode $capture_pattern] -add
296
set count 0
297
foreach_in_collection reg [get_pins -compatibility_mode $capture_pattern] {
298
  set clockname "${instname}_dq_[incr count]"
299
  create_generated_clock -name $clockname -source [get_pins -compatibility_mode $resync_clock] [get_pin_info -name $reg] -add
300
  set_false_path -from [get_ports *] -to [get_clocks $clockname]
301
}
302
set_false_path -from [get_clocks $capture_clockname] -to [get_clocks $resync_clock]
303
# measure clock
304
set measure_clockname ${instname}_ddr_mimic
305
set measure_pattern ${instname}_alt_mem_phy_inst|clk|DDR_CLK_OUT\[0\].ddr_clk_out_p|auto_generated|input_cell_h\[0\]|clk
306
sett_collection c [get_pins -compatibility_mode $measure_pattern]
307
set source [get_node_info -name $c]
308
create_clock -period $t(period) -name $measure_clockname $source -add
309
set_false_path -from [get_clocks $mimic_clock] -to $measure_clockname
310
set_false_path -to   [get_clocks $mimic_clock] -from $measure_clockname
311
foreach ck_clock_type_pn [array names ck_output_clocks] {
312
  set_false_path -from [get_clocks $ck_output_clocks($ck_clock_type_pn)] -to [get_clocks $measure_clockname]
313
}
314
 
315
################################################################################
316
# The scan clock provides a slow-speed clock domain to drive the PLL phase
317
# stepping interface. It is created by dividing down a PLL output phase. All
318
# transfers to and from the scan clock domain have asynchronous clock domain
319
# crossings, so the only constraint on these paths is that they have a skew
320
# less than 2 whole cycles of the scan clock. The fastest that the scan clock
321
# can run is 100MHz, so we set a +/- 9ns skew constraint across the clock
322
# domain crossing.
323
################################################################################
324
        set scan_clock_patterns [list ${instname}_alt_mem_phy_inst|clk|scan_clk|q 2]
325
        foreach {pattern divide_by} $scan_clock_patterns {
326
                foreach_in_collection c [get_pins -compatibility_mode $pattern] {
327
                        set source [get_node_info -name $c]
328
                        set sys_pll_clock [get_pll_clock [list $c] "System" "" 16]
329
                        if {$sys_pll_clock != ""} {
330
                                post_sdc_message info "Creating scan clock ${source}_clock driven by $sys_pll_clock divided by $divide_by"
331
                                create_generated_clock -multiply_by 1 -divide_by $divide_by -source $sys_pll_clock -master_clock $sys_pll_clock $source -name ${source}_clock
332
                                set_max_delay -to [get_clocks $sys_pll_clock] -from [get_clocks ${source}_clock] 9.0
333
                                set_max_delay -from [get_clocks $sys_pll_clock] -to [get_clocks ${source}_clock] 9.0
334
                                set_min_delay -to [get_clocks $sys_pll_clock] -from [get_clocks ${source}_clock] -9.0
335
                                set_min_delay -from [get_clocks $sys_pll_clock] -to [get_clocks ${source}_clock] -9.0
336
                        } else {
337
                                post_message -type warning "Cannot find source clock of $source"
338
                        }
339
                }
340
        }
341
 
342
        set msg_list [list]
343
################################################################################
344
# Locate the clocks that drive the DQ and DQS pins when writing
345
################################################################################
346
        set dqs_pll_clock_id [get_output_clock_id [get_all_dqs_pins $pins(dqsgroup)] "DQS output" msg_list]
347
        set dq_pll_clock_id [get_output_clock_id [get_all_dq_pins $pins(dqsgroup)] "DQ output" msg_list]
348
 
349
        if {$dqs_pll_clock_id == -1 || $dq_pll_clock_id == -1} {
350
                foreach {msg_type msg} $msg_list {
351
                        post_message -type $msg_type "altera_ddr_phy_ddr_timing.sdc: $msg"
352
                }
353
                post_message -type warning "altera_ddr_phy_ddr_timing.sdc: Failed to find PLL clock for pins [join [get_all_dqs_pins $pins(dqsgroup)]]"
354
        } else {
355
                set dqsclksource [get_node_info -name $dqs_pll_clock_id]
356
                set dqclksource [get_node_info -name $dq_pll_clock_id]
357
        }
358
 
359
################################################################################
360
        foreach dqsgroup $pins(dqsgroup) {
361
                set dqspin [lindex $dqsgroup 0]
362
 
363
                # If this design uses macro timing parameters, SDC constraints are not needed
364
                if {!$altera_ddr_phy_use_high_performance_timing} {
365
                        # DQS output clock
366
                        set dqs_out_clockname "${instname}_ddr_dqsout_${dqspin}"
367
                        create_generated_clock -multiply_by 1 -source $dqsclksource -master_clock $dqsclksource $dqspin -name $dqs_out_clockname -add
368
                }
369
                # endif !altera_ddr_phy_use_high_performance_timing
370
                if {!$altera_ddr_phy_use_high_performance_timing} {
371
 
372
################################################################################
373
# The write timing constrains the DQ write data with respect to the DQS strobe.
374
# An output clock is created on the DQS strobe, and we create a pair of
375
# set_output_delay assignments: one for the DQ data vs the rising edge of the
376
# DQS and the other against the falling edge.
377
# For the two max delay (setup) constraints:
378
#
379
# $t(board_skew)
380
# The worst case difference in propagation delay between the DQS strobe and any
381
# DQ pin within the same group.
382
#
383
# $t(DS)
384
# The setup requirement at the memory
385
#
386
# $WR_DQS_DQ_SETUP_ERROR
387
# An uncertainty term for HardCopy II designs, contact the HardCopy Design
388
# Centre for more information.
389
#
390
# For the two min delay (hold) constraints:
391
# - $t(board_skew)
392
# The worst case difference in propagation delay between the DQS strobe and any
393
# DQ pin within the same group.
394
#
395
# -$t(DH)
396
# The hold requirement at the memory
397
#
398
# - $t(DCD_total)
399
# Duty cycle distortion, since the launch and latch edges will be on the
400
# opposite edges
401
#
402
# - $WR_DQS_DQ_HOLD_ERROR
403
# An uncertainty term for HardCopy II designs, contact the HardCopy Design
404
# Centre for more information.
405
################################################################################
406
                        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]]
407
                        set_output_delay -add_delay -clock $dqs_out_clockname -min [round_3dp [expr {-$t(DH) - $t(board_skew) - $WR_DQS_DQ_HOLD_ERROR}]] [concat [lindex $dqsgroup 1] [lindex $dqsgroup 2]]
408
                        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]]
409
                        set_output_delay -add_delay -clock_fall -clock $dqs_out_clockname -min [round_3dp [expr {-$t(DH) - $t(board_skew) - $WR_DQS_DQ_HOLD_ERROR}]] [concat [lindex $dqsgroup 1] [lindex $dqsgroup 2]]
410
                }
411
                # endif !altera_ddr_phy_use_high_performance_timing
412
 
413
 
414
################################################################################
415
# The memory requires that the DQS strobes and CK clocks arrive edge aligned.
416
# For designs that generate CK/CK# from normal I/O (not recommended for
417
# HardCopy) this is just a problem for the board layout, since the DQS and CK
418
# signals are generated using the same structures from the same clocks.
419
# However, for designs that generate CK and CK# from dedicated PLL clock
420
# outputs (required for HardCopy), the CK and CK# outputs must use a different
421
# PLL clock than the slower DQS outputs to align themselves at the memory.
422
# There are two timing constraints: tDQSS says that the rising edge of DQS must
423
# align to the rising edge of ck to within 25% of a clock cycle, and tDSS/tDSH
424
# that requires the falling edge of DQS to be more than 20% of a clock cycle
425
# away from the rising edge of CK. This is automatically met if the minimum
426
# pulse width of CK is 45% (note that DDR3 has a 47/53 DCD requirement plus a
427
# separate jitter requirement).
428
# Since we need to correctly account for DCD, we must turn both of these
429
# parameters into timing constraints.
430
################################################################################
431
# DQS vs CK
432
################################################################################
433
# These offsets are only needed for designs that use a dedicated PLL output for
434
# the mem_ck pins. This design uses DDIO structures instead, so the required
435
# offset is zero.
436
################################################################################
437
                set off_tDQSS 0
438
                set off_tDSS 0
439
                foreach ckclock [get_output_clocks tDQSS p] {
440
                        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
441
                        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
442
                }
443
                foreach ckclock [get_output_clocks tDQSS n] {
444
                        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
445
                        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
446
                }
447
                foreach ckclock [concat [get_output_clocks tDQSS p] [get_output_clocks tDQSS n]] {
448
                        set_false_path -to [get_clocks $ckclock] -fall_from [get_clocks $dqsclksource]
449
                }
450
                foreach ckclock [get_output_clocks tDSS p] {
451
                        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
452
                        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
453
                }
454
                foreach cknclock [get_output_clocks tDSS n] {
455
                        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
456
                        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
457
                }
458
                foreach ckclock [concat [get_output_clocks tDSS p] [get_output_clocks tDSS n]] {
459
                        # DSS and DSH are only for falling edge of DQS
460
                        set_false_path -to [get_clocks $ckclock] -rise_from [get_clocks $dqsclksource]
461
                }
462
 
463
 
464
################################################################################
465
# There are three potential timing paths through a DDIO to the output pin. Two
466
# of these are from the output registers, and the third is the combinatorial
467
# path
468
# The only timing path through a DDIO that actually affects the output is the
469
# one that goes through the MUX. The timing delays through the other paths are
470
# chosen to ensure this.
471
################################################################################
472
                set_false_path -from [all_registers] -to [get_ports $dqspin]
473
 
474
        }
475
 
476
set x [expr {$t(HP) - 2*$t(AC) - $t(calibration_error)}]
477
set_max_delay -from [get_all_dq_pins $pins(dqsgroup)] -to [all_registers] [round_3dp [expr {$t(capture_shift) + 0.5*$x}]]
478
set_min_delay -from [get_all_dq_pins $pins(dqsgroup)] -to [all_registers] [round_3dp [expr {$t(capture_shift) - 0.5*$x}]]
479
set capture_clock $resync_clock
480
set_false_path -from [get_all_dq_pins $pins(dqsgroup)] -to [get_clocks $capture_clock]
481
set_false_path -to [get_pins -compatibility_mode ${instname}_alt_mem_phy_inst|dpio|dqs_group\[*\].dq\[*\].dqi|auto_generated|input_*_*\[0\]|clrn]
482
 
483
 
484
        if {$altera_ddr_phy_use_high_performance_timing} {
485
 
486
# Cut paths to read capture registers, since they are subject to macro timing
487
# analysis
488
                set dq_list [get_all_dq_pins $pins(dqsgroup)]
489
                if {[llength $dq_list] > 0} {
490
                        set_false_path -from [concat $dq_list] -to [all_registers]
491
                }
492
                # Cut paths from write registers and PLL clocks-as-data
493
                set d_dm_list [concat $dq_list [get_all_dm_pins $pins(dqsgroup)]]
494
                if {[llength $d_dm_list] > 0} {
495
                        set_false_path -from * -to $d_dm_list
496
                }
497
        }
498
        # endif altera_ddr_phy_use_high_performance_timing
499
 
500
#False path the read and write latency values from the sequencer, as these will be static when being used :
501
set rd_wr_latency_ops [get_pins -compatibility_mode ${instname}_alt_mem_phy_inst|*seq_wrapper|*seq_inst|*dgrb|?d_lat*|clk]
502
set_false_path -from $rd_wr_latency_ops
503
#False path the sequencer memory clock disable signal from the sequencer, as this will be static when being used :
504
set_false_path -from [get_pins -compatibility_mode  ${instname}_alt_mem_phy_inst|*seq_wrapper|*seq_inst|seq_mem_clk_disable*]
505
 
506
################################################################################
507
# The mimic path consists of a register on a dedicated PLL clock phase that is
508
# set up to capture an echo of the outgoing CK clocks.
509
# The sequencer measures the arrival time of the echo of the CK clock by
510
# sweeping the dedicated PLL phase that is used to clock the mimic path
511
# register. By taking a reference measurement of this phase during calibration
512
# and comparing that with a similar measurement during operation, variations in
513
# timing due to voltage and temperature can be tracked.
514
# The mimic path register needs to be placed close to the IOE in order that the
515
# changes in the length of the routing from the IOE to the mimic path register
516
# doesn't distort the measurements.
517
################################################################################
518
foreach ck $pins(ck_p) {
519
  create_clock -period $t(period) $ck -name ${instname}_${ck}_mimic_launch_clock -add
520
}
521
set_max_delay -from [get_clocks ${instname}_${ck}_mimic_launch_clock] -to  [get_clocks *ddr_mimic]  $t(mimic_shift)
522
 
523
# Cut asynchronous reset paths for clock domain crossing in the clocking and
524
# reset block
525
 
526
#  - clk|global_pre_clear|clrn: The master reset flop, driven by the PLL locked
527
# output and the soft_reset_n and global_reset_n signals
528
 
529
#  - clk|reset_master_ams|clrn: Synchronises the PLL locked reset to the
530
# global_pre_clear reset
531
 
532
#  - clk|mem_pipe|ams_pipe\[*\]|clrn: Transfers the master reset to the mem
533
# clock domain
534
 
535
#  - clk|mem_clk_pipe|ams_pipe\[*\]|clrn: Transfers the master reset to the mem
536
# clock domain
537
 
538
#  - clk|write_clk_pipe|ams_pipe\[*\]|clrn: Transfers the master reset to the
539
# write clock domain
540
 
541
#  - clk|measure_clk_pipe|ams_pipe\[*\]|clrn: Transfers the master reset to the
542
# measure clock domain
543
 
544
#  - clk|resync_clk_pipe|ams_pipe\[*\]|clrn: Transfers the master reset to the
545
# resync clock domain
546
#  - clk|clk_div_reset_ams_n_r|clrn: Master reset clock domain crossing
547
#  - clk|clk_div_reset_ams_n|clrn: Master reset clock domain crossing
548
 
549
#  - clk|pll_reconfig_reset_ams_n_r|clrn: Master reset clock domain crossing to
550
# the PLL reconfig block
551
 
552
#  - clk|pll_reconfig_reset_ams_n|clrn: Master reset clock domain crossing to
553
# the PLL reconfig block
554
        set clear_list [list \
555
                ${instname}_alt_mem_phy_inst|clk|*pll|altpll_component|auto_generated|pll_lock_sync|clrn \
556
                ${instname}_alt_mem_phy_inst|clk|global_pre_clear|clrn \
557
                ${instname}_alt_mem_phy_inst|clk|reset_master_ams|clrn \
558
                ${instname}_alt_mem_phy_inst|clk|mem_pipe|ams_pipe\[*\]|clrn \
559
                ${instname}_alt_mem_phy_inst|clk|mem_clk_pipe|ams_pipe\[*\]|clrn \
560
                ${instname}_alt_mem_phy_inst|clk|write_clk_pipe|ams_pipe\[*\]|clrn \
561
                ${instname}_alt_mem_phy_inst|clk|measure_clk_pipe|ams_pipe\[*\]|clrn \
562
                ${instname}_alt_mem_phy_inst|clk|resync_clk_pipe|ams_pipe\[*\]|clrn \
563
                ${instname}_alt_mem_phy_inst|clk|clk_div_reset_ams_n_r|clrn \
564
                ${instname}_alt_mem_phy_inst|clk|clk_div_reset_ams_n|clrn \
565
                ${instname}_alt_mem_phy_inst|clk|pll_reconfig_reset_ams_n_r|clrn \
566
                ${instname}_alt_mem_phy_inst|clk|pll_reconfig_reset_ams_n|clrn \
567
        ]
568
 
569
        foreach clear $clear_list {
570
                set clear_pins [get_pins -nowarn -compatibility_mode $clear]
571
                if {[get_collection_size $clear_pins] > 0} {
572
                        set_false_path -thru $clear_pins -to *
573
                }
574
        }
575
 
576
 
577
################################################################################
578
# Timing constrain the Address/command outputs. Note that ALTMEMPHY uses a DDIO
579
# structure to generate the output, even though the output is single data rate
580
# (or half data rate for the non-chip-select pins, when in half rate mode). It
581
# does this by controlling the input to the DDIO such that the same data is
582
# driven out on the rising and falling edges, or on the falling edge and the
583
# subsequent rising edge. This is used to provide a 180 degree phase shift to
584
# the output when the address/command phase in the wizard is set to 90 degree
585
# or 180 degrees, which are inverted versions of the 270 degree write clock or
586
# 0 degree DQS clock.
587
#
588
# The transitions on the select signal driving the DDIO output MUX control the
589
# timing, so we have to cut the paths coming from the registers to the IO pin
590
# with a set_false_path -from [all_registers] assignment.
591
#
592
# We also have to tell TimeQuest that only the rising (or falling) edge of the
593
# address/command clock generates a transition on the output. This is done with
594
# a set_false_path -rise_from (or -fall_from) assignment.
595
#
596
# When the core is in half-rate mode, which is the default and needed to
597
# achieve the maximum possible frequency, all the address/command pins except
598
# the chip select (cs) pin are driven out a whole cycle early. This improves
599
# timing when the address bus has a greater load than the Chip Select signal.
600
# It is simply a set_multicycle_path assignment to all the 2t address/command
601
# pins.
602
################################################################################
603
################################################################################
604
# Address/Command
605
################################################################################
606
        set msg_list [list]
607
        set ac_pll_clock_id [get_output_clock_id $pins(addrcmd) "Address/Command output" msg_list]
608
        if {$ac_pll_clock_id == -1} {
609
                foreach {msg_type msg} $msg_list {
610
                        post_message -type $msg_type "altera_ddr_phy_ddr_timing.sdc: $msg"
611
                }
612
                post_message -type warning "altera_ddr_phy_ddr_timing.sdc: Failed to find PLL clock for pins [join $pins(addrcmd)]"
613
        } else {
614
                set ac_pll_clock [get_node_info -name $ac_pll_clock_id]
615
 
616
################################################################################
617
# These offset parameters are needed for designs that have the 'Use Dedicated
618
# PLL clock outputs' set. They are not needed in this case, and are set to
619
# zero.
620
################################################################################
621
                set ded_off_rise 0
622
                set ded_off_fall 0
623
                set off $ded_off_fall
624
                # Only analyze the DDIO mux select
625
                set_false_path -from [all_registers] -to [concat $pins(addrcmd) $pins(addrcmd_2t)]
626
                foreach ckclock [get_output_clocks ac_fall p] {
627
                        set_output_delay -add_delay -clock $ckclock -max [round_3dp [expr {$off*$t(period) + $t(IS) + $t(board_skew) + $fpga_tCK_ADDR_CTRL_SETUP_ERROR + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
628
                        set_output_delay -add_delay -clock $ckclock -min [round_3dp [expr {$off*$t(period) - $t(IH) - $t(board_skew) - $fpga_tCK_ADDR_CTRL_HOLD_ERROR  + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
629
                }
630
                foreach ckclock [get_output_clocks ac_fall n] {
631
                        set_output_delay -add_delay -clock_fall -clock $ckclock -max [round_3dp [expr {$off*$t(period) + $t(IS) + $t(board_skew) + $fpga_tCK_ADDR_CTRL_SETUP_ERROR + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
632
                        set_output_delay -add_delay -clock_fall -clock $ckclock -min [round_3dp [expr {$off*$t(period) - $t(IH) - $t(board_skew) - $fpga_tCK_ADDR_CTRL_HOLD_ERROR  + $t(additional_addresscmd_tpd)}]] [concat $pins(addrcmd) $pins(addrcmd_2t)]
633
                }
634
                if {$ac_pll_clock_id != -1} {
635
                        foreach ckclock [concat [get_output_clocks ac_fall p] [get_output_clocks ac_fall n]] {
636
                                set_false_path -rise_from [get_clocks $ac_pll_clock] -to $ckclock
637
                        }
638
                }
639
        }
640
        if { [llength $pins(addrcmd_2t)] > 0 } {
641
                # post_message -type info "Address/Command (half rate)"
642
                set_multicycle_path -setup -to $pins(addrcmd_2t) 2
643
                set_multicycle_path -hold -to $pins(addrcmd_2t) 1
644
        }
645
 
646
}
647
 
648
################################################################################
649
 
650
 
651
# Apply the timing constraints to every instantiation of this ALTMEMPHY
652
# variation within the design.
653
set instance_list [get_core_instance_list $corename]
654
foreach inst $instance_list {
655
        post_sdc_message info "Adding SDC requirements for $corename instance $inst"
656
        add_requirements_for_instance $corename $inst t $altera_ddr_phy_use_high_performance_timing
657
        add_ddr_report_command "source [list [file join [file dirname [info script]] ${corename}_report_timing.tcl]]"
658
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.