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

Subversion Repositories spacewiresystemc

[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [hps_sdram_p0_pin_map.tcl] - Blame information for rev 40

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 32 redbear
# (C) 2001-2017 Intel Corporation. All rights reserved.
2
# Your use of Intel Corporation's design tools, logic functions and other 
3
# software and tools, and its AMPP partner logic functions, and any output 
4 40 redbear
# files from any of the foregoing (including device programming or simulation 
5 32 redbear
# files), and any associated documentation or information are expressly subject 
6
# to the terms and conditions of the Intel Program License Subscription 
7 40 redbear
# Agreement, Intel FPGA IP License Agreement, or other applicable 
8 32 redbear
# license agreement, including, without limitation, that your use is for the 
9
# sole purpose of programming logic devices manufactured by Intel and sold by 
10
# Intel or its authorized distributors.  Please refer to the applicable 
11
# agreement for further details.
12
 
13
 
14
#####################################################################
15
#
16
# THIS IS AN AUTO-GENERATED FILE!
17
# -------------------------------
18
# If you modify this files, all your changes will be lost if you
19
# regenerate the core!
20
#
21
# FILE DESCRIPTION
22
# ----------------
23
# This file contains the traversal routines that are used by both
24
# hps_sdram_p0_pin_assignments.tcl and hps_sdram_p0.sdc scripts. 
25
#
26
# These routines are only meant to support these two scripts. 
27
# Trying to using them in a different context can have unexpected 
28
# results.
29
 
30
set script_dir [file dirname [info script]]
31
 
32
source [file join $script_dir hps_sdram_p0_parameters.tcl]
33
load_package sdc_ext
34
 
35
proc hps_sdram_p0_find_all_pins { mystring } {
36
        set allpins [get_pins -compatibility_mode $mystring ]
37
 
38
        foreach_in_collection pin $allpins {
39
                set pinname [ get_pin_info -name $pin ]
40
 
41
                puts "$pinname"
42
        }
43
}
44
 
45
 
46
proc hps_sdram_p0_index_in_collection { col j } {
47
        set i 0
48
        foreach_in_collection path $col {
49
                if {$i == $j} {
50
                        return $path
51
                }
52
                set i [expr $i + 1]
53
        }
54
        return ""
55
}
56
 
57
 
58
proc hps_sdram_p0_get_clock_to_pin_name_mapping {} {
59
        set result [list]
60
        set clocks_collection [get_clocks]
61
        foreach_in_collection clock $clocks_collection {
62
                set clock_name [get_clock_info -name $clock]
63
                set clock_target [get_clock_info -targets $clock]
64
                set first_index [hps_sdram_p0_index_in_collection $clock_target 0]
65
                set catch_exception [catch {get_pin_info -name $first_index} pin_name]
66
                if {$catch_exception == 0} {
67
                        lappend result [list $clock_name $pin_name]
68
                }
69
        }
70
        return $result
71
}
72
 
73
 
74
proc hps_sdram_p0_get_clock_name_from_pin_name { pin_name } {
75
        set table [hps_sdram_p0_get_clock_to_pin_name_mapping]
76
        foreach entry $table {
77
                if {[string compare [lindex [lindex [split $entry] 1] 0] $pin_name] == 0} {
78
                        return [lindex $entry 0]
79
                }
80
        }
81
        return ""
82
}
83
 
84
 
85
proc hps_sdram_p0_get_clock_name_from_pin_name_vseries {pin_name suffix} {
86
        set name [hps_sdram_p0_get_clock_name_from_pin_name $pin_name]
87
        if {[string compare -nocase $name ""] == 0} {
88
                set pll_clock $pin_name
89
                regsub {[^\|]+$} $pll_clock {} pll_clock
90
                set pll_clock "${pll_clock}pll_${suffix}"
91
        } else {
92
                set pll_clock $name
93
        }
94
        return $pll_clock
95
}
96
 
97
 
98
proc hps_sdram_p0_get_clock_name_from_pin_name_pre_vseries {pin_name suffix} {
99
        set name [hps_sdram_p0_get_clock_name_from_pin_name $pin_name]
100
        if {[string compare -nocase $name ""] == 0} {
101
                set pll_clock $pin_name
102
                regsub {upll_memphy\|auto_generated\|pll1\|clk\[[0-9]+\]$} $pll_clock "pll" pll_clock
103
                set pll_clock "${pll_clock}_${suffix}"
104
        } else {
105
                set pll_clock $name
106
        }
107
        return $pll_clock
108
}
109
 
110
proc hps_sdram_p0_get_or_add_clock_vseries_from_virtual_refclk {args} {
111
        array set opts { /
112
                -suffix "" /
113
                -target "" /
114
                -period "" /
115
                -phase 0 }
116
 
117
        array set opts $args
118
 
119
        set clock_name [hps_sdram_p0_get_clock_name_from_pin_name $opts(-target)]
120
 
121
 
122
        if {[string compare -nocase $clock_name ""] == 0} {
123
                set clock_name $opts(-target)
124
                set suffix $opts(-suffix)
125
 
126
                regsub {~PLL_OUTPUT_COUNTER\|divclk$} $clock_name "" clock_name
127
                regsub {_phy$} $clock_name "" clock_name
128
                regsub {[0-9]+$} $clock_name "" clock_name
129
                set clock_name "${clock_name}_${suffix}"
130
                set re [expr $opts(-period) * $opts(-phase)/360]
131
                set fe [expr $opts(-period) * $opts(-phase)/360 + $opts(-period)/2]
132
 
133
                create_clock \
134
                        -name $clock_name \
135
                        -period $opts(-period) \
136
                        -waveform [ list $re $fe ] \
137
                        $opts(-target)
138
        }
139
 
140
        return $clock_name
141
}
142
 
143
proc hps_sdram_p0_get_or_add_clock_vseries {args} {
144
        array set opts { /
145
                -suffix "" /
146
                -target "" /
147
                -source "" /
148
                -multiply_by 1 /
149
                -divide_by 1 /
150
                -phase 0 }
151
 
152
        array set opts $args
153
        set target $opts(-target)
154
 
155
        set clock_name [hps_sdram_p0_get_clock_name_from_pin_name $opts(-target)]
156
 
157
        if {[string compare -nocase $clock_name ""] == 0} {
158
                set clock_name $opts(-target)
159
                set suffix $opts(-suffix)
160
 
161
                regsub {~PLL_OUTPUT_COUNTER\|divclk$} $clock_name "" clock_name
162
                regsub {_phy$} $clock_name "" clock_name
163
                regsub {[0-9]+$} $clock_name "" clock_name
164
                regsub -all {\\} $clock_name "" clock_name
165
                set clock_name "${clock_name}_${suffix}"
166
                set source_name "\{$opts(-source)\}"
167
 
168
                create_generated_clock \
169
                        -name ${clock_name} \
170
                        -source ${source_name} \
171
                        -multiply_by $opts(-multiply_by) \
172
                        -divide_by $opts(-divide_by) \
173
                        -phase $opts(-phase) \
174
                        $target
175
        }
176
 
177
        return $clock_name
178
}
179
 
180
proc hps_sdram_p0_get_or_add_clock_pre_vseries {args} {
181
        array set opts { /
182
                -suffix "" /
183
                -target "" /
184
                -source "" /
185
                -multiply_by 1 /
186
                -divide_by 1 /
187
                -phase 0 }
188
 
189
        array set opts $args
190
 
191
        set clock_name [hps_sdram_p0_get_clock_name_from_pin_name $opts(-target)]
192
 
193
        if {[string compare -nocase $clock_name ""] == 0} {
194
                set clock_name $opts(-target)
195
                set suffix $opts(-suffix)
196
 
197
                regsub {upll_memphy\|auto_generated\|pll1\|clk\[[0-9]+\]$} $clock_name "pll" clock_name
198
                set clock_name "${clock_name}_${suffix}"
199
 
200
                create_generated_clock \
201
                        -name $clock_name \
202
                        -source $opts(-source) \
203
                        -multiply_by $opts(-multiply_by) \
204
                        -divide_by $opts(-divide_by) \
205
                        -phase $opts(-phase) \
206
                        $opts(-target)
207
        }
208
 
209
        return $clock_name
210
}
211
 
212
 
213
proc hps_sdram_p0_get_source_clock_pin_name {node_name} {
214
 
215
        set nodename ""
216
        set nodes [get_nodes $node_name]
217
        hps_sdram_p0_traverse_fanin_up_to_depth [hps_sdram_p0_index_in_collection $nodes 0] hps_sdram_p0_is_node_type_pll_clk clock results_array 10
218
        if {[array size results_array] == 1} {
219
                set pin_id [lindex [array names results_array] 0]
220
                if {[string compare -nocase $pin_id ""] != 0} {
221
                        set nodename [get_node_info -name $pin_id]
222
                }
223
        }
224
        return $nodename
225
}
226
 
227
 
228
proc hps_sdram_p0_find_all_keepers { mystring } {
229
        set allkeepers [get_keepers $mystring ]
230
 
231
        foreach_in_collection keeper $allkeepers {
232
                set keepername [ get_node_info -name $keeper ]
233
 
234
                puts "$keepername"
235
        }
236
}
237
 
238
proc hps_sdram_p0_round_3dp { x } {
239
        return [expr { round($x * 1000) / 1000.0  } ]
240
}
241
 
242
proc hps_sdram_p0_get_timequest_name {hier_name} {
243
        set sta_name ""
244
        for {set inst_start [string first ":" $hier_name]} {$inst_start != -1} {} {
245
                incr inst_start
246
                set inst_end [string first "|" $hier_name $inst_start]
247
                if {$inst_end == -1} {
248
                        append sta_name [string range $hier_name $inst_start end]
249
                        set inst_start -1
250
                } else {
251
                        append sta_name [string range $hier_name $inst_start $inst_end]
252
                        set inst_start [string first ":" $hier_name $inst_end]
253
                }
254
        }
255
        return $sta_name
256
}
257
 
258
proc hps_sdram_p0_are_entity_names_on { } {
259
        set entity_names_on 1
260
 
261
 
262
        return [set_project_mode -is_show_entity]
263
}
264
 
265
proc hps_sdram_p0_get_core_instance_list {corename} {
266
        set full_instance_list [hps_sdram_p0_get_core_full_instance_list $corename]
267
        set instance_list [list]
268
 
269
        foreach inst $full_instance_list {
270
                set sta_name [hps_sdram_p0_get_timequest_name $inst]
271
                if {[lsearch $instance_list [escape_brackets $sta_name]] == -1} {
272
                        lappend instance_list $sta_name
273
                }
274
        }
275
        return $instance_list
276
}
277
 
278
proc hps_sdram_p0_get_core_full_instance_list {corename} {
279
        set allkeepers [get_keepers * ]
280
 
281
        set_project_mode -always_show_entity_name on
282
 
283
        set instance_list [list]
284
 
285
        set inst_regexp {(^.*}
286
        append inst_regexp {:[A-Za-z0-9\.\\_\[\]\-\$():]+)\|}
287
        append inst_regexp ${corename}
288
        append inst_regexp {:[A-Za-z0-9\.\\_\[\]\-\$():]+\|}
289
        append inst_regexp "${corename}_acv_hard_memphy"
290
        append inst_regexp {:umemphy}
291
 
292
        foreach_in_collection keeper $allkeepers {
293
                set name [ get_node_info -name $keeper ]
294
 
295
                if {[regexp -- $inst_regexp $name -> hier_name] == 1} {
296
                        if {[lsearch $instance_list [escape_brackets $hier_name]] == -1} {
297
                                lappend instance_list $hier_name
298
                        }
299
                }
300
        }
301
 
302
        set_project_mode -always_show_entity_name qsf
303
 
304
        if {[ llength $instance_list ] == 0} {
305
                post_message -type error "The auto-constraining script was not able to detect any instance for core < $corename >"
306
                post_message -type error "Verify the following:"
307
                post_message -type error " The core < $corename > is instantiated within another component (wrapper)"
308
                post_message -type error " The core is not the top-level of the project"
309
                post_message -type error " The memory interface pins are exported to the top-level of the project"
310
                post_message -type error "Alternatively, if you are no longer instantiating core < $corename >,"
311
                post_message -type error " clean up any stale SDC_FILE references from the QSF/QIP files."
312
        }
313
 
314
        return $instance_list
315
}
316
 
317
 
318
proc hps_sdram_p0_traverse_fanin_up_to_depth { node_id match_command edge_type results_array_name depth} {
319
        upvar 1 $results_array_name results
320
 
321
        if {$depth < 0} {
322
                error "Internal error: Bad timing netlist search depth"
323
        }
324
        set fanin_edges [get_node_info -${edge_type}_edges $node_id]
325
        set number_of_fanin_edges [llength $fanin_edges]
326
        for {set i 0} {$i != $number_of_fanin_edges} {incr i} {
327
                set fanin_edge [lindex $fanin_edges $i]
328
                set fanin_id [get_edge_info -src $fanin_edge]
329
                if {$match_command == "" || [eval $match_command $fanin_id] != 0} {
330
                        set results($fanin_id) 1
331
                } elseif {$depth == 0} {
332
                } else {
333
                        hps_sdram_p0_traverse_fanin_up_to_depth $fanin_id $match_command $edge_type results [expr {$depth - 1}]
334
                }
335
        }
336
}
337
proc hps_sdram_p0_is_node_type_pll_inclk { node_id } {
338
        set cell_id [get_node_info -cell $node_id]
339
 
340
        if {$cell_id == ""} {
341
                set result 0
342
        } else {
343
                set atom_type [get_cell_info -atom_type $cell_id]
344
                if {$atom_type == "FRACTIONAL_PLL"} {
345
                        set node_name [get_node_info -name $node_id]
346
                        set fanin_edges [get_node_info -clock_edges $node_id]
347
                        if {([string match "*|refclkin" $node_name] || [string match "*|refclkin\\\[0\\\]" $node_name]) && [llength $fanin_edges] > 0} {
348
                                set result 1
349
                        } else {
350
                                set result 0
351
                        }
352
                } elseif {$atom_type == "HPS_SDRAM_PLL"} {
353
                        set node_name [get_node_info -name $node_id]
354
                        set fanin_edges [get_node_info -clock_edges $node_id]
355
                        if {[string match "*|ref_clk" $node_name] && [llength $fanin_edges] > 0} {
356
                                set result 1
357
                        } else {
358
                                set result 0
359
                        }
360
                } elseif {$atom_type == "PLL"} {
361
                        set node_name [get_node_info -name $node_id]
362
                        set fanin_edges [get_node_info -clock_edges $node_id]
363
                        if {([string match "*|refclk" $node_name] || [string match "*|refclk\\\[0\\\]" $node_name]) && [llength $fanin_edges] > 0} {
364
                                set result 1
365
                        } else {
366
                                set result 0
367
                        }
368
                } else {
369
                        set result 0
370
                }
371
        }
372
        return $result
373
}
374
 
375
proc hps_sdram_p0_is_node_type_pin { node_id } {
376
        set node_type [get_node_info -type $node_id]
377
        if {$node_type == "port"} {
378
                set result 1
379
        } else {
380
                set result 0
381
        }
382
        return $result
383
}
384
 
385
proc hps_sdram_p0_get_input_clk_id { pll_output_node_id } {
386
        if {[hps_sdram_p0_is_node_type_pll_clk $pll_output_node_id]} {
387
                array set results_array [list]
388
                hps_sdram_p0_traverse_fanin_up_to_depth $pll_output_node_id hps_sdram_p0_is_node_type_pll_inclk clock results_array 2
389
                if {[array size results_array] == 1} {
390
                        # Found PLL inclk, now find the input pin
391
                        set pll_inclk_id [lindex [array names results_array] 0]
392
                        set result [get_node_info -name $pll_inclk_id]
393
                } else {
394
                        post_message -type critical_warning "Could not find PLL clock for [get_node_info -name $pll_output_node_id]"
395
                        set result -1
396
                }
397
        } else {
398
                error "Internal error: hps_sdram_p0_get_input_clk_id only works on PLL output clocks"
399
        }
400
        return $result
401
}
402
 
403
proc hps_sdram_p0_is_node_type_pll_clk { node_id } {
404
        set cell_id [get_node_info -cell $node_id]
405
 
406
        if {$cell_id == ""} {
407
                set result 0
408
        } else {
409
                set atom_type [get_cell_info -atom_type $cell_id]
410
                if {$atom_type == "PLL_OUTPUT_COUNTER"} {
411
                        set node_name [get_node_info -name $node_id]
412
                        if {[string match "*|pll*~PLL_OUTPUT_COUNTER*|divclk" $node_name]} {
413
                                set result 1
414
                        } else {
415
                                set result 0
416
                        }
417
                } elseif {$atom_type == "HPS_SDRAM_PLL"} {
418
                        set node_name [get_node_info -name $node_id]
419
                        if {[string match "*|*pll|*_clk" $node_name]} {
420
                                set result 1
421
                        } else {
422
                                set result 0
423
                        }
424
                } elseif {$atom_type == "PLL"} {
425
                        set node_name [get_node_info -name $node_id]
426
                        if {[string match "*|pll*|divclk" $node_name]} {
427
                                set result 1
428
                        } else {
429
                                set result 0
430
                        }
431
                } else {
432
                        set result 0
433
                }
434
        }
435
        return $result
436
}
437
 
438
proc hps_sdram_p0_get_pll_clock { dest_id_list node_type clock_id_name search_depth} {
439
        if {$clock_id_name != ""} {
440
                upvar 1 $clock_id_name clock_id
441
        }
442
        set clock_id -1
443
 
444
        array set clk_array [list]
445
        foreach node_id $dest_id_list {
446
                hps_sdram_p0_traverse_fanin_up_to_depth $node_id hps_sdram_p0_is_node_type_pll_clk clock clk_array $search_depth
447
        }
448
        if {[array size clk_array] == 1} {
449
                set clock_id [lindex [array names clk_array] 0]
450
                set clk [get_node_info -name $clock_id]
451
        } elseif {[array size clk_array] > 1} {
452
                puts "Found more than 1 clock driving the $node_type"
453
                set clk ""
454
        } else {
455
                set clk ""
456
        }
457
 
458
        return $clk
459
}
460
 
461
proc hps_sdram_p0_get_pll_clock_name { clock_id } {
462
        set clock_name [get_node_info -name $clock_id]
463
 
464
        return $clock_name
465
}
466
 
467
proc hps_sdram_p0_get_pll_clock_name_for_acf { clock_id pll_output_wire_name } {
468
        set clock_name [get_node_info -name $clock_id]
469
        regexp {(.*)\|pll\d+\~PLL_OUTPUT_COUNTER} $clock_name matched clock_name
470
        regexp {(.*)\|pll\d+_phy\~PLL_OUTPUT_COUNTER} $clock_name matched clock_name
471
        set clock_name "$clock_name|$pll_output_wire_name"
472
        return $clock_name
473
}
474
 
475
proc hps_sdram_p0_get_output_clock_id { ddio_output_pin_list pin_type msg_list_name {max_search_depth 20} } {
476
        upvar 1 $msg_list_name msg_list
477
        set output_clock_id -1
478
 
479
        set output_id_list [list]
480
        set pin_collection [get_keepers -no_duplicates $ddio_output_pin_list]
481
        if {[get_collection_size $pin_collection] == [llength $ddio_output_pin_list]} {
482
                foreach_in_collection id $pin_collection {
483
                        lappend output_id_list $id
484
                }
485
        } elseif {[get_collection_size $pin_collection] == 0} {
486
                lappend msg_list "warning" "Could not find any $pin_type pins"
487
        } else {
488
                lappend msg_list "warning" "Could not find all $pin_type pins"
489
        }
490
        hps_sdram_p0_get_pll_clock $output_id_list $pin_type output_clock_id $max_search_depth
491
        return $output_clock_id
492
}
493
 
494
proc hps_sdram_p0_get_output_clock_id2 { ddio_output_pin_list pin_type msg_list_name {max_search_depth 20} } {
495
        upvar 1 $msg_list_name msg_list
496
        set output_clock_id -1
497
 
498
        set output_id_list [list]
499
        set pin_collection [get_pins -no_duplicates $ddio_output_pin_list]
500
        if {[get_collection_size $pin_collection] == [llength $ddio_output_pin_list]} {
501
                foreach_in_collection id $pin_collection {
502
                        lappend output_id_list $id
503
                }
504
        } elseif {[get_collection_size $pin_collection] == 0} {
505
                lappend msg_list "warning" "Could not find any $pin_type pins"
506
        } else {
507
                lappend msg_list "warning" "Could not find all $pin_type pins"
508
        }
509
        hps_sdram_p0_get_pll_clock $output_id_list $pin_type output_clock_id $max_search_depth
510
        return $output_clock_id
511
}
512
 
513
proc hps_sdram_p0_is_node_type_clkbuf { node_id } {
514
        set cell_id [get_node_info -cell $node_id]
515
        if {$cell_id == ""} {
516
                set result 0
517
        } else {
518
                set atom_type [get_cell_info -atom_type $cell_id]
519
                if {$atom_type == "CLKBUF" || $atom_type == "PHY_CLKBUF"} {
520
                        set result 1
521
                } else {
522
                        set result 0
523
                }
524
        }
525
        return $result
526
}
527
 
528
proc hps_sdram_p0_get_clkbuf_clock { dest_id_list node_type clock_id_name search_depth} {
529
        if {$clock_id_name != ""} {
530
                upvar 1 $clock_id_name clock_id
531
        }
532
        set clock_id -1
533
 
534
        array set clk_array [list]
535
        foreach node_id $dest_id_list {
536
                hps_sdram_p0_traverse_fanin_up_to_depth $node_id hps_sdram_p0_is_node_type_clkbuf clock clk_array $search_depth
537
        }
538
        if {[array size clk_array] == 1} {
539
                set clock_id [lindex [array names clk_array] 0]
540
                set clk [get_node_info -name $clock_id]
541
        } elseif {[array size clk_array] > 1} {
542
                set clk ""
543
        } else {
544
                set clk ""
545
        }
546
 
547
        return $clk
548
}
549
 
550
proc hps_sdram_p0_get_output_clock_clkbuf_id { ddio_output_pin_list pin_type msg_list_name {max_search_depth 20} } {
551
        upvar 1 $msg_list_name msg_list
552
        set output_clock_id -1
553
 
554
        set output_id_list [list]
555
        set pin_collection [get_keepers -no_duplicates $ddio_output_pin_list]
556
        if {[get_collection_size $pin_collection] == [llength $ddio_output_pin_list]} {
557
                foreach_in_collection id $pin_collection {
558
                        lappend output_id_list $id
559
                }
560
        } elseif {[get_collection_size $pin_collection] == 0} {
561
                lappend msg_list "warning" "Could not find any $pin_type pins"
562
        } else {
563
                lappend msg_list "warning" "Could not find all $pin_type pins"
564
        }
565
        hps_sdram_p0_get_clkbuf_clock $output_id_list $pin_type output_clock_id $max_search_depth
566
        return $output_clock_id
567
}
568
 
569
 
570
proc hps_sdram_p0_is_node_type_clk_phase_select { node_id } {
571
        set cell_id [get_node_info -cell $node_id]
572
        if {$cell_id == ""} {
573
                set result 0
574
        } else {
575
                set atom_type [get_cell_info -atom_type $cell_id]
576
                if {$atom_type == "CLK_PHASE_SELECT"} {
577
                        set result 1
578
                } else {
579
                        set result 0
580
                }
581
        }
582
        return $result
583
}
584
 
585
proc hps_sdram_p0_get_clk_phase_select_clock { dest_id_list node_type clock_id_name search_depth} {
586
        if {$clock_id_name != ""} {
587
                upvar 1 $clock_id_name clock_id
588
        }
589
        set clock_id -1
590
 
591
        array set clk_array [list]
592
        foreach node_id $dest_id_list {
593
                hps_sdram_p0_traverse_fanin_up_to_depth $node_id hps_sdram_p0_is_node_type_clk_phase_select clock clk_array $search_depth
594
        }
595
        if {[array size clk_array] == 1} {
596
                set clock_id [lindex [array names clk_array] 0]
597
                set clk [get_node_info -name $clock_id]
598
        } elseif {[array size clk_array] > 1} {
599
                set clk ""
600
        } else {
601
                set clk ""
602
        }
603
 
604
        return $clk
605
}
606
 
607
proc hps_sdram_p0_get_output_clock_clk_phase_select_id { ddio_output_pin_list pin_type msg_list_name {max_search_depth 20} } {
608
        upvar 1 $msg_list_name msg_list
609
        set output_clock_id -1
610
 
611
        set output_id_list [list]
612
        set pin_collection [get_keepers -no_duplicates $ddio_output_pin_list]
613
        if {[get_collection_size $pin_collection] == [llength $ddio_output_pin_list]} {
614
                foreach_in_collection id $pin_collection {
615
                        lappend output_id_list $id
616
                }
617
        } elseif {[get_collection_size $pin_collection] == 0} {
618
                lappend msg_list "warning" "Could not find any $pin_type pins"
619
        } else {
620
                lappend msg_list "warning" "Could not find all $pin_type pins"
621
        }
622
        hps_sdram_p0_get_clk_phase_select_clock $output_id_list $pin_type output_clock_id $max_search_depth
623
        return $output_clock_id
624
}
625
 
626
proc post_sdc_message {msg_type msg} {
627
        if { $::TimeQuestInfo(nameofexecutable) != "quartus_fit"} {
628
                post_message -type $msg_type $msg
629
        }
630
}
631
 
632
proc hps_sdram_p0_get_names_in_collection { col } {
633
        set res [list]
634
        foreach_in_collection node $col {
635
                lappend res [ get_node_info -name $node ]
636
        }
637
        return $res
638
}
639
 
640
proc hps_sdram_p0_static_map_expand_list { FH listname pinname } {
641
        upvar $listname local_list
642
 
643
        puts $FH ""
644
        puts $FH "   # $pinname"
645
        puts $FH "   set pins($pinname) \[ list \]"
646
        foreach pin $local_list($pinname) {
647
                puts $FH "   lappend pins($pinname) $pin"
648
        }
649
}
650
 
651
proc hps_sdram_p0_static_map_expand_list_of_list { FH listname pinname } {
652
        upvar $listname local_list
653
 
654
        puts $FH ""
655
        puts $FH "   # $pinname"
656
        puts $FH "   set pins($pinname) \[ list \]"
657
        set count_groups 0
658
        foreach sublist $local_list($pinname) {
659
                puts $FH ""
660
                puts $FH "   # GROUP - ${count_groups}"
661
                puts $FH "   set group_${count_groups} \[ list \]"
662
                foreach pin $sublist {
663
                        puts $FH "   lappend group_${count_groups} $pin"
664
                }
665
                puts $FH ""
666
                puts $FH "   lappend pins($pinname) \$group_${count_groups}"
667
 
668
                incr count_groups
669
        }
670
}
671
 
672
proc hps_sdram_p0_static_map_expand_string { FH stringname pinname } {
673
        upvar $stringname local_string
674
 
675
        puts $FH ""
676
        puts $FH "   # $pinname"
677
        puts $FH "   set pins($pinname) $local_string($pinname)"
678
}
679
 
680
proc hps_sdram_p0_format_3dp { x } {
681
        return [format %.3f $x]
682
}
683
 
684
proc hps_sdram_p0_get_colours { x y } {
685
 
686
        set fcolour [list "black"]
687
        if {$x < 0} {
688
                lappend fcolour "red"
689
        } else {
690
                lappend fcolour "blue"
691
        }
692
        if {$y < 0} {
693
                lappend fcolour "red"
694
        } else {
695
                lappend fcolour "blue"
696
        }
697
 
698
        return $fcolour
699
}
700
 
701
proc min { a b } {
702
        if { $a == "" } {
703
                return $b
704
        } elseif { $a < $b } {
705
                return $a
706
        } else {
707
                return $b
708
        }
709
}
710
 
711
proc max { a b } {
712
        if { $a == "" } {
713
                return $b
714
        } elseif { $a > $b } {
715
                return $a
716
        } else {
717
                return $b
718
        }
719
}
720
 
721
proc hps_sdram_p0_max_in_collection { col attribute } {
722
        set i 0
723
        set max 0
724
        foreach_in_collection path $col {
725
                if {$i == 0} {
726
                        set max [get_path_info $path -${attribute}]
727
                } else {
728
                        set temp [get_path_info $path -${attribute}]
729
                        if {$temp > $max} {
730
                                set max $temp
731
                        }
732
                }
733
                set i [expr $i + 1]
734
        }
735
        return $max
736
}
737
 
738
proc hps_sdram_p0_min_in_collection { col attribute } {
739
        set i 0
740
        set min 0
741
        foreach_in_collection path $col {
742
                if {$i == 0} {
743
                        set min [get_path_info $path -${attribute}]
744
                } else {
745
                        set temp [get_path_info $path -${attribute}]
746
                        if {$temp < $min} {
747
                                set min $temp
748
                        }
749
                }
750
                set i [expr $i + 1]
751
        }
752
        return $min
753
}
754
 
755
proc hps_sdram_p0_min_in_collection_to_name { col attribute name } {
756
        set i 0
757
        set min 0
758
        foreach_in_collection path $col {
759
                if {[get_node_info -name [get_path_info $path -to]] == $name} {
760
                        if {$i == 0} {
761
                                set min [get_path_info $path -${attribute}]
762
                        } else {
763
                                set temp [get_path_info $path -${attribute}]
764
                                if {$temp < $min} {
765
                                        set min $temp
766
                                }
767
                        }
768
                        set i [expr $i + 1]
769
                }
770
        }
771
        return $min
772
}
773
 
774
proc hps_sdram_p0_min_in_collection_from_name { col attribute name } {
775
        set i 0
776
        set min 0
777
        foreach_in_collection path $col {
778
                if {[get_node_info -name [get_path_info $path -from]] == $name} {
779
                        if {$i == 0} {
780
                                set min [get_path_info $path -${attribute}]
781
                        } else {
782
                                set temp [get_path_info $path -${attribute}]
783
                                if {$temp < $min} {
784
                                        set min $temp
785
                                }
786
                        }
787
                        set i [expr $i + 1]
788
                }
789
        }
790
        return $min
791
}
792
 
793
proc hps_sdram_p0_max_in_collection_to_name { col attribute name } {
794
        set i 0
795
        set max 0
796
        foreach_in_collection path $col {
797
                if {[get_node_info -name [get_path_info $path -to]] == $name} {
798
                        if {$i == 0} {
799
                                set max [get_path_info $path -${attribute}]
800
                        } else {
801
                                set temp [get_path_info $path -${attribute}]
802
                                if {$temp > $max} {
803
                                        set max $temp
804
                                }
805
                        }
806
                        set i [expr $i + 1]
807
                }
808
        }
809
        return $max
810
}
811
 
812
proc hps_sdram_p0_max_in_collection_from_name { col attribute name } {
813
        set i 0
814
        set max 0
815
        foreach_in_collection path $col {
816
                if {[get_node_info -name [get_path_info $path -from]] == $name} {
817
                        if {$i == 0} {
818
                                set max [get_path_info $path -${attribute}]
819
                        } else {
820
                                set temp [get_path_info $path -${attribute}]
821
                                if {$temp > $max} {
822
                                        set max $temp
823
                                }
824
                        }
825
                        set i [expr $i + 1]
826
                }
827
        }
828
        return $max
829
}
830
 
831
 
832
proc hps_sdram_p0_min_in_collection_to_name2 { col attribute name } {
833
        set i 0
834
        set min 0
835
        foreach_in_collection path $col {
836
                if {[regexp $name [get_node_info -name [get_path_info $path -to]]]} {
837
                        if {$i == 0} {
838
                                set min [get_path_info $path -${attribute}]
839
                        } else {
840
                                set temp [get_path_info $path -${attribute}]
841
                                if {$temp < $min} {
842
                                        set min $temp
843
                                }
844
                        }
845
                        set i [expr $i + 1]
846
                }
847
        }
848
        return $min
849
}
850
 
851
proc hps_sdram_p0_min_in_collection_from_name2 { col attribute name } {
852
        set i 0
853
        set min 0
854
        foreach_in_collection path $col {
855
                if {[regexp $name [get_node_info -name [get_path_info $path -from]]]} {
856
                        if {$i == 0} {
857
                                set min [get_path_info $path -${attribute}]
858
                        } else {
859
                                set temp [get_path_info $path -${attribute}]
860
                                if {$temp < $min} {
861
                                        set min $temp
862
                                }
863
                        }
864
                        set i [expr $i + 1]
865
                }
866
        }
867
        return $min
868
}
869
 
870
proc hps_sdram_p0_max_in_collection_to_name2 { col attribute name } {
871
        set i 0
872
        set max 0
873
        foreach_in_collection path $col {
874
                if {[regexp $name [get_node_info -name [get_path_info $path -to]]]} {
875
                        if {$i == 0} {
876
                                set max [get_path_info $path -${attribute}]
877
                        } else {
878
                                set temp [get_path_info $path -${attribute}]
879
                                if {$temp > $max} {
880
                                        set max $temp
881
                                }
882
                        }
883
                        set i [expr $i + 1]
884
                }
885
        }
886
        return $max
887
}
888
 
889
proc hps_sdram_p0_max_in_collection_from_name2 { col attribute name } {
890
        set i 0
891
        set max 0
892
        foreach_in_collection path $col {
893
                if {[regexp $name [get_node_info -name [get_path_info $path -from]]]} {
894
                        if {$i == 0} {
895
                                set max [get_path_info $path -${attribute}]
896
                        } else {
897
                                set temp [get_path_info $path -${attribute}]
898
                                if {$temp > $max} {
899
                                        set max $temp
900
                                }
901
                        }
902
                        set i [expr $i + 1]
903
                }
904
        }
905
        return $max
906
}
907
 
908
 
909
proc hps_sdram_p0_get_max_clock_path_delay_through_clock_node {from through to} {
910
        set init 0
911
        set max_delay 0
912
        set paths [get_path -rise_from $through -rise_to $to]
913
        foreach_in_collection path1 $paths {
914
                set delay [get_path_info $path1 -arrival_time]
915
                set clock_node [get_node_info -name [get_path_info $path1 -from]]
916
 
917
                set paths2 [get_path -rise_from $from -rise_to $clock_node]
918
                foreach_in_collection path2 $paths2 {
919
                        set total_delay [expr $delay + [get_path_info $path2 -arrival_time]]
920
                        if {$init == 0 || $total_delay > $max_delay} {
921
                                set init 1
922
                                set max_delay $total_delay
923
                        }
924
                }
925
        }
926
        return $max_delay
927
}
928
 
929
proc hps_sdram_p0_get_min_clock_path_delay_through_clock_node {from through to} {
930
        set init 0
931
        set min_delay 0
932
        set paths [get_path -rise_from $through -rise_to $to -min_path]
933
        foreach_in_collection path1 $paths {
934
                set delay [get_path_info $path1 -arrival_time]
935
                set clock_node [get_node_info -name [get_path_info $path1 -from]]
936
 
937
                set paths2 [get_path -rise_from $from -rise_to $clock_node -min_path]
938
                foreach_in_collection path2 $paths2 {
939
                        set total_delay [expr $delay + [get_path_info $path2 -arrival_time]]
940
                        if {$init == 0 || $total_delay < $min_delay} {
941
                                set init 1
942
                                set min_delay $total_delay
943
                        }
944
                }
945
        }
946
        return $min_delay
947
}
948
 
949
proc hps_sdram_p0_get_model_corner {} {
950
 
951
        set operating_conditions [get_operating_conditions]
952
        set return_value [list]
953
        if {[regexp {^([0-9])_H([0-9])_([a-z]+)_([a-z0-9_\-]+)} $operating_conditions matched speedgrade transceiver model corner]} {
954
 
955
        } elseif {[regexp {^([A-Z0-9]+)_([a-z]+)_([a-z0-9_\-]+)} $operating_conditions matched speedgrade model corner]} {
956
 
957
        }
958
        regsub {\-} $corner "n" corner
959
        set return_value [list $model $corner]
960
        return $return_value
961
}
962
 
963
proc hps_sdram_p0_get_min_aiot_delay {pinname} {
964
 
965
        set atom_id [get_atom_node_by_name -name $pinname]
966
        set sin_pin [create_pin_object -atom $atom_id]
967
        set results [get_simulation_results -pin $sin_pin -aiot]
968
 
969
        set rise 0
970
        set fall 0
971
        foreach { key value } $results {
972
                if {$key == "Absolute Rise Delay to Far-end"} {
973
                        set rise $value
974
                } elseif {$key == "Absolute Fall Delay to Far-end"} {
975
                        set fall $value
976
                }
977
        }
978
        return [min $rise $fall]
979
}
980
 
981
proc hps_sdram_p0_get_rise_aiot_delay {pinname} {
982
 
983
        set atom_id [get_atom_node_by_name -name $pinname]
984
        set sin_pin [create_pin_object -atom $atom_id]
985
        set results [get_simulation_results -pin $sin_pin -aiot]
986
 
987
        set rise 0
988
        foreach { key value } $results {
989
            if {$key == "Absolute Rise Delay to Far-end"} {
990
               set rise $value
991
            }
992
        }
993
        return $rise
994
}
995
 
996
proc hps_sdram_p0_get_fall_aiot_delay {pinname} {
997
 
998
        set atom_id [get_atom_node_by_name -name $pinname]
999
        set sin_pin [create_pin_object -atom $atom_id]
1000
        set results [get_simulation_results -pin $sin_pin -aiot]
1001
 
1002
        set fall 0
1003
        foreach { key value } $results {
1004
            if {$key == "Absolute Fall Delay to Far-end"} {
1005
               set fall $value
1006
            }
1007
        }
1008
        return $fall
1009
}
1010
 
1011
 
1012
proc hps_sdram_p0_get_aiot_attr {pinname attr} {
1013
 
1014
        set atom_id [get_atom_node_by_name -name $pinname]
1015
        set sin_pin [create_pin_object -atom $atom_id]
1016
        set results [get_simulation_results -pin $sin_pin -aiot]
1017
 
1018
        set value 0
1019
        foreach { key value } $results {
1020
                if {$key == $attr} {
1021
                        return $value
1022
                }
1023
        }
1024
        return $value
1025
}
1026
 
1027
proc hps_sdram_p0_get_pll_phase_shift {output_counter_name} {
1028
        load_package atoms
1029
        read_atom_netlist
1030
        set phase_shift ""
1031
 
1032
        # Remove possible "|divclk" at the end of the name
1033
        regsub {\|divclk$} $output_counter_name "" output_counter_name
1034
 
1035
        # Get all PLL output counters
1036
        set pll_output_counter_atoms [get_atom_nodes -type PLL_OUTPUT_COUNTER]
1037
 
1038
        # Go through the output counters and find the one that matches the above and return the phase
1039
        foreach_in_collection atom $pll_output_counter_atoms {
1040
                set name [get_atom_node_info -key name -node $atom]
1041
                regsub {^[^\:]+\:} $name "" name
1042
                regsub -all {\|[^\:]+\:} $name "|" name
1043
 
1044
                # If the name matches return the phase shift
1045
                if {$name == $output_counter_name} {
1046
                        set phase_shift [get_atom_node_info -key TIME_PHASE_SHIFT -node $atom]
1047
                        regsub { ps} $phase_shift "" phase_shift
1048
                        break
1049
                }
1050
        }
1051
        return $phase_shift
1052
}
1053
 
1054
# ----------------------------------------------------------------
1055
#
1056
proc hps_sdram_p0_get_io_standard {target_pin} {
1057
#
1058
# Description: Gets the I/O standard of the given memory interface pin
1059
#              This function assumes the fitter has already completed and the
1060
#              compiler report has been loaded.
1061
#
1062
# ----------------------------------------------------------------
1063
        # Look through the pin report
1064
        set io_std [hps_sdram_p0_get_fitter_report_pin_info $target_pin "I/O Standard" -1]
1065
        if {$io_std == ""} {
1066
                return "UNKNOWN"
1067
        }
1068
        set result ""
1069
        switch -exact -- $io_std {
1070
                "SSTL-2 Class I" {set result "SSTL_2_I"}
1071
                "Differential 2.5-V SSTL Class I" {set result "DIFF_SSTL_2_I"}
1072
                "SSTL-2 Class II" {set result "SSTL_2_II"}
1073
                "Differential 2.5-V SSTL Class II" {set result "DIFF_SSTL_2_II"}
1074
                "SSTL-18 Class I" {set result "SSTL_18_I"}
1075
                "Differential 1.8-V SSTL Class I" {set result "DIFF_SSTL_18_I"}
1076
                "SSTL-18 Class II" {set result "SSTL_18_II"}
1077
                "Differential 1.8-V SSTL Class II" {set result "DIFF_SSTL_18_II"}
1078
                "SSTL-15 Class I" {set result "SSTL_15_I"}
1079
                "Differential 1.5-V SSTL Class I" {set result "DIFF_SSTL_15_I"}
1080
                "SSTL-15 Class II" {set result "SSTL_15_II"}
1081
                "Differential 1.5-V SSTL Class II" {set result "DIFF_SSTL_15_II"}
1082
                "1.8-V HSTL Class I" {set result "HSTL_18_I"}
1083
                "Differential 1.8-V HSTL Class I" {set result "DIFF_HSTL_18_I"}
1084
                "1.8-V HSTL Class II" {set result "HSTL_18_II"}
1085
                "Differential 1.8-V HSTL Class II" {set result "DIFF_HSTL_18_II"}
1086
                "1.5-V HSTL Class I" {set result "HSTL_I"}
1087
                "Differential 1.5-V HSTL Class I" {set result "DIFF_HSTL"}
1088
                "1.5-V HSTL Class II" {set result "HSTL_II"}
1089
                "Differential 1.5-V HSTL Class II" {set result "DIFF_HSTL_II"}
1090
                "1.2-V HSTL Class I" {set result "SSTL_125"}
1091
                "Differential 1.2-V HSTL Class I" {set result "DIFF_SSTL_125"}
1092
                "1.2-V HSTL Class II" {set result "SSTL_125"}
1093
                "Differential 1.2-V HSTL Class II" {set result "DIFF_SSTL_125"}
1094
                "SSTL-15" {set result "SSTL_15"}
1095
                "Differential 1.5-V SSTL" {set result "DIFF_SSTL_15"}
1096
                "SSTL-135" {set result "SSTL_135"}
1097
                "Differential 1.35-V SSTL" {set result "DIFF_SSTL_135"}
1098
                "SSTL-125" {set result "SSTL_125"}
1099
                "Differential 1.25-V SSTL" {set result "DIFF_SSTL_125"}
1100
                "SSTL-12" {set result "DIFF_SSTL_125"}
1101
                "Differential 1.2-V HSUL" {set result "DIFF_HSUL_12"}
1102
                default {
1103
                        post_message -type error "Found unsupported Memory I/O standard $io_std on pin $target_pin"
1104
                        set result "UNKNOWN"
1105
                }
1106
        }
1107
        return $result
1108
}
1109
 
1110
# Routine to find the termination pins
1111
proc hps_sdram_p0_get_rzq_pins { instname all_rzq_pins } {
1112
        upvar $all_rzq_pins rzqpins
1113
        load_package atoms
1114
        read_atom_netlist
1115
        set rzq_pins [ list ]
1116
        set entity_names_on [ hps_sdram_p0_are_entity_names_on ]
1117
 
1118
        # Get all termination atoms, to which rzqpin should be attached
1119
        set_project_mode -always_show_entity_name off
1120
        set instance ${instname}*
1121
        set atoms [get_atom_nodes -type TERMINATION -matching [escape_brackets $instance] ]
1122
        post_message -type info "Number of Termination Atoms are [get_collection_size $atoms]"
1123
        foreach_in_collection term_atom $atoms {
1124
                set rzq_pin ""
1125
                set atom $term_atom
1126
                set term_atom_name [get_atom_node_info -key name -node $term_atom]
1127
                post_message -type info "Found Termination Atom $term_atom_name"
1128
                set type [get_atom_node_info -key type -node $term_atom]
1129
 
1130
                # Check until you traverse to an IO_PAD for the RZQ Pin
1131
                while { ![regexp IO_PAD $type ] } {
1132
                        set name [get_atom_node_info -key name -node $atom]
1133
                        set iterms [get_atom_iports -node $atom]
1134
                        set iterm_size [llength $iterms]
1135
                        # Check for Multiple Inputs
1136
                        if { $iterm_size > 1 } {
1137
                                post_message -type error " Multiple inputs to a node:$name attached to a  Termination_Atom:$term_atom_name "
1138
                                break
1139
 
1140
                        }
1141
 
1142
                        foreach iterm $iterms {
1143
                                set fanin       [get_atom_port_info -node $atom -type iport -port_id $iterm -key fanin]
1144
                                set atom [lindex $fanin 0]
1145
                                set type [get_atom_node_info -key type -node $atom]
1146
                                set rzq_pin [get_atom_node_info -key name -node $atom]
1147
                        }
1148
                }
1149
 
1150
                lappend rzq_pins [ join $rzq_pin ]
1151
        }
1152
 
1153
        set_project_mode -always_show_entity_name qsf
1154
        set rzqpins $rzq_pins
1155
}
1156
 
1157
 
1158
proc hps_sdram_p0_get_acv_read_offset { period dqs_phase dqs_period } {
1159
 
1160
        set offset [expr abs(90/360.0*$period - $dqs_phase/360.0*$dqs_period)]
1161
        if {$offset != 0} {
1162
                set part_period [expr $dqs_phase/360.0*$dqs_period - 0.469/2.0 - 0.12]
1163
                set offset [max 0.120 $part_period]
1164
        }
1165
 
1166
        return $offset
1167
}
1168
# (C) 2001-2017 Intel Corporation. All rights reserved.
1169
# Your use of Intel Corporation's design tools, logic functions and other 
1170
# software and tools, and its AMPP partner logic functions, and any output 
1171 40 redbear
# files from any of the foregoing (including device programming or simulation 
1172 32 redbear
# files), and any associated documentation or information are expressly subject 
1173
# to the terms and conditions of the Intel Program License Subscription 
1174 40 redbear
# Agreement, Intel FPGA IP License Agreement, or other applicable 
1175 32 redbear
# license agreement, including, without limitation, that your use is for the 
1176
# sole purpose of programming logic devices manufactured by Intel and sold by 
1177
# Intel or its authorized distributors.  Please refer to the applicable 
1178
# agreement for further details.
1179
 
1180
 
1181
proc hps_sdram_p0_sort_proc {a b} {
1182
        set idxs [list 1 2 0]
1183
        foreach i $idxs {
1184
                set ai [lindex $a $i]
1185
                set bi [lindex $b $i]
1186
                if {$ai > $bi} {
1187
                        return 1
1188
                } elseif { $ai < $bi } {
1189
                        return -1
1190
                }
1191
        }
1192
        return 0
1193
}
1194
 
1195
proc hps_sdram_p0_traverse_atom_path {atom_id atom_oport_id path} {
1196
        # Return list of {atom oterm_id} pairs by tracing the atom netlist starting from the given atom_id through the given path
1197
        # Path consists of list of {atom_type fanin|fanout|end <port_type> <-optional>}
1198
        set result [list]
1199
        if {[llength $path] > 0} {
1200
                set path_point [lindex $path 0]
1201
                set atom_type [lindex $path_point 0]
1202
                set next_direction [lindex $path_point 1]
1203
                set port_type [lindex $path_point 2]
1204
                set atom_optional [lindex $path_point 3]
1205
                if {[get_atom_node_info -key type -node $atom_id] == $atom_type} {
1206
                        if {$next_direction == "end"} {
1207
                                if {[get_atom_port_info -key type -node $atom_id -port_id $atom_oport_id -type oport] == $port_type} {
1208
                                        lappend result [list $atom_id $atom_oport_id]
1209
                                }
1210
                        } elseif {$next_direction == "atom"} {
1211
                                lappend result [list $atom_id]
1212
                        } elseif {$next_direction == "fanin"} {
1213
                                set atom_iport [get_atom_iport_by_type -node $atom_id -type $port_type]
1214
                                if {$atom_iport != -1} {
1215
                                        set iport_fanin [get_atom_port_info -key fanin -node $atom_id -port_id $atom_iport -type iport]
1216
                                        set source_atom [lindex $iport_fanin 0]
1217
                                        set source_oterm [lindex $iport_fanin 1]
1218
                                        set result [hps_sdram_p0_traverse_atom_path $source_atom $source_oterm [lrange $path 1 end]]
1219
                                } elseif {$atom_optional == "-optional"} {
1220
                                        set result [hps_sdram_p0_traverse_atom_path $atom_id $atom_oport_id [lrange $path 1 end]]
1221
                                }
1222
                        } elseif {$next_direction == "fanout"} {
1223
                                set atom_oport [get_atom_oport_by_type -node $atom_id -type $port_type]
1224
                                if {$atom_oport != -1} {
1225
                                        set oport_fanout [get_atom_port_info -key fanout -node $atom_id -port_id $atom_oport -type oport]
1226
                                        foreach dest $oport_fanout {
1227
                                                set dest_atom [lindex $dest 0]
1228
                                                set dest_iterm [lindex $dest 1]
1229
                                                set fanout_result_list [hps_sdram_p0_traverse_atom_path $dest_atom -1 [lrange $path 1 end]]
1230
                                                foreach fanout_result $fanout_result_list {
1231
                                                        if {[lsearch $result $fanout_result] == -1} {
1232
                                                                lappend result $fanout_result
1233
                                                        }
1234
                                                }
1235
                                        }
1236
                                }
1237
                        } else {
1238
                                error "Unexpected path"
1239
                        }
1240
                } elseif {$atom_optional == "-optional"} {
1241
                        set result [hps_sdram_p0_traverse_atom_path $atom_id $atom_oport_id [lrange $path 1 end]]
1242
                }
1243
        }
1244
        return $result
1245
}
1246
 
1247
# Get the fitter name of the PLL output driving the given pin
1248
proc hps_sdram_p0_traverse_to_ddio_out_pll_clock {pin msg_list_name} {
1249
        upvar 1 $msg_list_name msg_list
1250
        set result ""
1251
        if {$pin != ""} {
1252
                set pin_id [get_atom_node_by_name -name $pin]
1253
                set pin_to_pll_path [list {IO_PAD fanin PADIN} {IO_OBUF fanin I} {PSEUDO_DIFF_OUT fanin I -optional} {DELAY_CHAIN fanin DATAIN -optional} {DELAY_CHAIN fanin DATAIN -optional} {DDIO_OUT fanin CLKHI -optional} {OUTPUT_PHASE_ALIGNMENT fanin CLK -optional} {CLKBUF fanin INCLK -optional} {PLL end CLK}]
1254
                set pll_id_list [hps_sdram_p0_traverse_atom_path $pin_id -1 $pin_to_pll_path]
1255
                if {[llength $pll_id_list] == 1} {
1256
                        set atom_oterm_pair [lindex $pll_id_list 0]
1257
                        set result [get_atom_port_info -key name -node [lindex $atom_oterm_pair 0] -port_id [lindex $atom_oterm_pair 1] -type oport]
1258
                } else {
1259
                        lappend msg_list "Error: PLL clock not found for $pin"
1260
                }
1261
        }
1262
        return $result
1263
}
1264
 
1265
proc hps_sdram_p0_traverse_to_leveling_delay_chain {pin msg_list_name} {
1266
        upvar 1 $msg_list_name msg_list
1267
        set result ""
1268
        if {$pin != ""} {
1269
                set pin_id [get_atom_node_by_name -name $pin]
1270
                set pin_to_leveling_path [list {IO_PAD fanin PADIN} {IO_OBUF fanin I} {PSEUDO_DIFF_OUT fanin I -optional} {DELAY_CHAIN fanin DATAIN -optional} {DELAY_CHAIN fanin DATAIN -optional} {DDIO_OUT fanin CLK -optional} {FF fanin CLK -optional} {DDIO_OUT fanin CLKHI -optional} {CLK_PHASE_SELECT fanin CLKIN -optional} {LEVELING_DELAY_CHAIN end CLKOUT} ]
1271
                set leveling_id_list [hps_sdram_p0_traverse_atom_path $pin_id -1 $pin_to_leveling_path]
1272
                if {[llength $leveling_id_list] == 1} {
1273
                        set atom_oterm_pair [lindex $leveling_id_list 0]
1274
                        set result [get_atom_node_info -key name -node [lindex $atom_oterm_pair 0]]
1275
                } else {
1276
                        lappend msg_list "Error: Leveling delay chain not found for $pin"
1277
                }
1278
        }
1279
 
1280
        regsub {^[^\:]+\:} $result "" result
1281
        regsub -all {\|[^\:]+\:} $result "|" result
1282
 
1283
        return $result
1284
}
1285
 
1286
proc hps_sdram_p0_traverse_to_clock_phase_select {pin msg_list_name} {
1287
        upvar 1 $msg_list_name msg_list
1288
        set result ""
1289
        if {$pin != ""} {
1290
                set pin_id [get_atom_node_by_name -name $pin]
1291
                set pin_to_cps_path [list {IO_PAD fanin PADIN} {IO_OBUF fanin I} {PSEUDO_DIFF_OUT fanin I -optional} {DELAY_CHAIN fanin DATAIN -optional} {DELAY_CHAIN fanin DATAIN -optional} {DDIO_OUT fanin CLK -optional} {FF fanin CLK -optional} {DDIO_OUT fanin CLKHI -optional} {CLK_PHASE_SELECT end CLKOUT}  ]
1292
                set cps_id_list [hps_sdram_p0_traverse_atom_path $pin_id -1 $pin_to_cps_path]
1293
                if {[llength $cps_id_list] == 1} {
1294
                        set atom_oterm_pair [lindex $cps_id_list 0]
1295
                        set result [get_atom_node_info -key name -node [lindex $atom_oterm_pair 0]]
1296
                } else {
1297
                        lappend msg_list "Error: Clock phase select not found for $pin"
1298
                }
1299
        }
1300
 
1301
        regsub {^[^\:]+\:} $result "" result
1302
        regsub -all {\|[^\:]+\:} $result "|" result
1303
 
1304
        return $result
1305
}
1306
 
1307
proc hps_sdram_p0_traverse_to_clkbuf {pin msg_list_name} {
1308
        upvar 1 $msg_list_name msg_list
1309
        set result ""
1310
        if {$pin != ""} {
1311
                set pin_id [get_atom_node_by_name -name $pin]
1312
                set pin_to_clkbuf_path [list {IO_PAD fanin PADIN} {IO_OBUF fanin I} {PSEUDO_DIFF_OUT fanin I -optional} {DELAY_CHAIN fanin DATAIN -optional} {DELAY_CHAIN fanin DATAIN -optional} {DDIO_OUT fanin CLK -optional} {FF fanin CLK -optional} {DDIO_OUT fanin CLKHI -optional} {CLKBUF end OUTCLK}  ]
1313
                set clkbuf_id_list [hps_sdram_p0_traverse_atom_path $pin_id -1 $pin_to_clkbuf_path]
1314
                if {[llength $clkbuf_id_list] == 1} {
1315
                        set atom_oterm_pair [lindex $clkbuf_id_list 0]
1316
                        set result [get_atom_node_info -key name -node [lindex $atom_oterm_pair 0]]
1317
                } else {
1318
                        lappend msg_list "Error: Clock buffer not found for $pin"
1319
                }
1320
        }
1321
 
1322
        regsub {^[^\:]+\:} $result "" result
1323
        regsub -all {\|[^\:]+\:} $result "|" result
1324
 
1325
        return $result
1326
}
1327
 
1328
proc hps_sdram_p0_traverse_to_dll {dqs_pin msg_list_name} {
1329
        upvar 1 $msg_list_name msg_list
1330
        set dqs_pin_id [get_atom_node_by_name -name $dqs_pin]
1331
        set dqs_to_dll_path [list {IO_PAD fanout PADOUT} {IO_IBUF fanout O} {DQS_DELAY_CHAIN fanin DELAYCTRLIN} {DLL end DELAYCTRLOUT}]
1332
        set dll_id_list [hps_sdram_p0_traverse_atom_path $dqs_pin_id -1 $dqs_to_dll_path]
1333
        set result ""
1334
        if {[llength $dll_id_list] == 1} {
1335
                set dll_atom_oterm_pair [lindex $dll_id_list 0]
1336
                set result [get_atom_node_info -key name -node [lindex $dll_atom_oterm_pair 0]]
1337
        } elseif {[llength $dll_id_list] > 1} {
1338
                lappend msg_list "Error: Found more than 1 DLL"
1339
        } else {
1340
                lappend msg_list "Error: DLL not found"
1341
        }
1342
        return $result
1343
}
1344
 
1345
proc hps_sdram_p0_check_hybrid_interface { inst pins_array_name mem_if_memtype } {
1346
        upvar $pins_array_name pins
1347
 
1348
        foreach q_group $pins(q_groups) {
1349
                set q_group $q_group
1350
                lappend q_groups $q_group
1351
        }
1352
        set all_dq_pins [ join [ join $q_groups ] ]
1353
        set dm_pins $pins(dm_pins)
1354
 
1355
        set all_dq_dm_pins [ concat $all_dq_pins $dm_pins ]
1356
        foreach dq_dm_pin $all_dq_dm_pins {
1357
                set io_type [hps_sdram_p0_get_fitter_report_pin_io_type_info $dq_dm_pin]
1358
                if {[string compare -nocase "Column I/O" $io_type] == 0} {
1359
                        set io_types("column") 1
1360
                } elseif {[string compare -nocase "Row I/O" $io_type] == 0} {
1361
                        set io_types("row") 1
1362
                } else {
1363
                        post_message -type warning "Could not determine IO type for pin $dq_dm_pin"
1364
                }
1365
        }
1366
 
1367
        if {[llength [array names io_types]] == 0} {
1368
                post_message -type warning "Could not determine if memory interface $inst is implemented in hybrid mode. Assuming memory interface is implemented in non-hybrid mode"
1369
                return 0
1370
        } elseif {[llength [array names io_types]] == 1} {
1371
                return 0
1372
        } elseif {[llength [array names io_types]] == 2} {
1373
                return 1
1374
        } else {
1375
                post_message -type error "Internal Error: Found IO types [array names io_types]"
1376
                qexit -error
1377
        }
1378
 
1379
}
1380
 
1381
proc hps_sdram_p0_verify_flexible_timing_assumptions { inst pins_array_name mem_if_memtype } {
1382
        return 1
1383
}
1384
 
1385
proc hps_sdram_p0_verify_high_performance_timing_assumptions { inst pins_array_name mem_if_memtype } {
1386
        upvar $pins_array_name pins
1387
 
1388
        set num_errors 0
1389
        load_package verify_ddr
1390
        set ck_ckn_pairs [list]
1391
        set failed_assumptions [list]
1392
        if {[llength $pins(ck_pins)] > 0 && [llength $pins(ck_pins)] == [llength $pins(ckn_pins)]} {
1393
                for {set ck_index 0} {$ck_index != [llength $pins(ck_pins)]} {incr ck_index} {
1394
                        lappend ck_ckn_pairs [list [lindex $pins(ck_pins) $ck_index] [lindex $pins(ckn_pins) $ck_index]]
1395
                }
1396
        } else {
1397
                incr num_errors
1398
                lappend failed_assumptions "Error: Could not locate same number of CK pins as CK# pins"
1399
        }
1400
 
1401
        set read_pins_list [list]
1402
        set write_pins_list [list]
1403
        set read_clock_pairs [list]
1404
        set write_clock_pairs [list]
1405
        foreach { dqs } $pins(dqs_pins) { dqsn } $pins(dqsn_pins) { dq_list } $pins(q_groups) {
1406
                lappend read_pins_list [list $dqs $dq_list]
1407
                lappend read_clock_pairs [list $dqs $dqsn]
1408
        }
1409
 
1410
        foreach { dqs } $pins(dqs_pins) { dqsn } $pins(dqsn_pins) { dm_list } $pins(dm_pins) { dq_list } $pins(q_groups) {
1411
                lappend write_pins_list [list $dqs [concat $dq_list $dm_list]]
1412
                lappend write_clock_pairs [list $dqs $dqsn]
1413
        }
1414
 
1415
        set all_write_dqs_list $pins(dqs_pins)
1416
        set all_d_list $pins(all_dq_pins)
1417
        if {[llength $pins(q_groups)] == 0} {
1418
                incr num_errors
1419
                lappend failed_assumptions "Error: Could not locate DQS pins"
1420
        }
1421
 
1422
        if {$num_errors == 0} {
1423
                set msg_list [list]
1424
                set dll_name [hps_sdram_p0_traverse_to_dll $dqs msg_list]
1425
                set clk_to_write_d [hps_sdram_p0_traverse_to_ddio_out_pll_clock [lindex $all_d_list 0] msg_list]
1426
                set clk_to_write_clock [hps_sdram_p0_traverse_to_ddio_out_pll_clock [lindex $all_write_dqs_list 0] msg_list]
1427
                set clk_to_ck_ckn [hps_sdram_p0_traverse_to_ddio_out_pll_clock [lindex $pins(ck_pins) 0] msg_list]
1428
                foreach msg $msg_list {
1429
                        set verify_assumptions_exception 1
1430
                        incr num_errors
1431
                        lappend failed_assumptions $msg
1432
                }
1433
                if {$num_errors == 0} {
1434
                        set verify_assumptions_exception 0
1435
                        set verify_assumptions_result {0}
1436
                        set verify_assumptions_exception [catch {verify_assumptions -uniphy -memory_type $mem_if_memtype \
1437
                                -read_pins_list $read_pins_list -write_pins_list $write_pins_list -ck_ckn_pairs $ck_ckn_pairs \
1438
                                -clk_to_write_d $clk_to_write_d -clk_to_write_clock $clk_to_write_clock -clk_to_ck_ckn $clk_to_ck_ckn \
1439
                                -dll $dll_name -read_clock_pairs $read_clock_pairs -write_clock_pairs $write_clock_pairs} verify_assumptions_result]
1440
                        if {$verify_assumptions_exception == 0} {
1441
                                incr num_errors [lindex $verify_assumptions_result 0]
1442
                                set failed_assumptions [concat $failed_assumptions [lrange $verify_assumptions_result 1 end]]
1443
                        }
1444
                }
1445
                if {$verify_assumptions_exception != 0} {
1446
                        lappend failed_assumptions "Error: MACRO timing assumptions could not be verified"
1447
                        incr num_errors
1448
                }
1449
        }
1450
 
1451
        if {$num_errors != 0} {
1452
                for {set i 0} {$i != [llength $failed_assumptions]} {incr i} {
1453
                        set raw_msg [lindex $failed_assumptions $i]
1454
                        if {[regexp {^\W*(Info|Extra Info|Warning|Critical Warning|Error): (.*)$} $raw_msg -- msg_type msg]} {
1455
                                regsub " " $msg_type _ msg_type
1456
                                if {$msg_type == "Error"} {
1457
                                        set msg_type "critical_warning"
1458
                                }
1459
                                post_message -type $msg_type $msg
1460
                        } else {
1461
                                post_message -type info $raw_msg
1462
                        }
1463
                }
1464
                post_message -type critical_warning "Read Capture and Write timing analyses may not be valid due to violated timing model assumptions"
1465
        }
1466
 
1467
        return [expr $num_errors == 0]
1468
}
1469
 
1470
# Return a tuple of the tCCS value for a given device
1471
proc hps_sdram_p0_get_tccs { mem_if_memtype dqs_list period args} {
1472
        global TimeQuestInfo
1473
        array set options [list "-write_deskew" "none" "-dll_length" 0 "-config_period" 0 "-ddr3_discrete" 0]
1474
        foreach {option value} $args {
1475
                if {[array names options -exact "$option"] != ""} {
1476
                        set options($option) $value
1477
                } else {
1478
                        error "ERROR: Unknown get_tccs option $option (with value $value; args are $args)"
1479
                }
1480
        }
1481
 
1482
        if {$mem_if_memtype == "ddr2"} {
1483
                set options(-write_deskew) "none"
1484
        }
1485
 
1486
        set speedgrade [ get_speedgrade_string ]
1487
        if { ($mem_if_memtype == "ddr3") && ($speedgrade != "2") && ($options(-write_deskew) == "dynamic") } {
1488
                set options(-write_deskew) "static"
1489
        }
1490
 
1491
        if { ($mem_if_memtype == "ddr3") && ($options(-write_deskew) == "none") } {
1492
                set options(-write_deskew) "static"
1493
        }
1494
 
1495
        if { ($mem_if_memtype == "ddr3") && ($speedgrade == "4") && ($options(-ddr3_discrete) == 0)} {
1496
                set options(-ddr3_discrete) 1
1497
        }
1498
 
1499
        set interface_type [hps_sdram_p0_get_io_interface_type $dqs_list]
1500
        # The tCCS for a VHPAD interface is the same as a HPAD interface
1501
        if {$interface_type == "VHPAD"} {
1502
                set interface_type "HPAD"
1503
        }
1504
        set io_std [hps_sdram_p0_get_io_standard [lindex $dqs_list 0]]
1505
        set result [list 0 0]
1506
        if {$interface_type != "" && $interface_type != "UNKNOWN" && $io_std != "" && $io_std != "UNKNOWN"} {
1507
                package require ::quartus::ddr_timing_model
1508
 
1509
                set tccs_params [list IO $interface_type]
1510
                if {($mem_if_memtype == "ddr3") && ($options(-ddr3_discrete) == 1)} {
1511
                        lappend tccs_params NONLEVELED
1512
                } elseif {($mem_if_memtype == "ddr3") && ($options(-write_deskew) == "static")} {
1513
                        if {$options(-dll_length) == 12} {
1514
                                set options(-dll_length) 10
1515
                        }
1516
                        if {$options(-dll_length) != 0} {
1517
                                lappend tccs_params STATIC_DESKEW_$options(-dll_length)
1518
                        } else {
1519
                                # No DLL length dependency
1520
                                lappend tccs_params STATIC_DESKEW
1521
                        }
1522
                } elseif {($mem_if_memtype == "ddr3") && ($options(-write_deskew) == "dynamic")} {
1523
                        lappend tccs_params DYNAMIC_DESKEW
1524
                }
1525
                if {$options(-ddr3_discrete) == 0 && $options(-write_deskew) != "none"} {
1526
                        set mode [hps_sdram_p0_get_deskew_freq_range $tccs_params $period]
1527
                        if {$mode == [list]} {
1528
                                post_message -type critical_warning "Memory interface with period $period and write $options(-write_deskew) deskew does not fall in a supported frequency range"
1529
                        } elseif {[lindex $mode 0] != [list]} {
1530
                                lappend tccs_params [lindex $mode 0]
1531
                                puts $tccs_params
1532
                        }
1533
                }
1534
                if {[catch {get_io_standard_node_delay -dst TCCS_LEAD -io_standard $io_std -parameters $tccs_params} tccs_lead] != 0 || $tccs_lead == "" || $tccs_lead == 0 || \
1535
                                [catch {get_io_standard_node_delay -dst TCCS_LAG -io_standard $io_std -parameters $tccs_params} tccs_lag] != 0 || $tccs_lag == "" || $tccs_lag == 0 } {
1536
                        set family $TimeQuestInfo(family)
1537
                        error "Missing $family timing model for tCCS of $io_std $tccs_params"
1538
                } else {
1539
                        return [list $tccs_lead $tccs_lag]
1540
                }
1541
        }
1542
}
1543
 
1544
# For static deskew, get the frequency range of the given configuration
1545
# Return triplet {mode min_freq max_freq}
1546
proc hps_sdram_p0_get_deskew_freq_range {timing_params period} {
1547
        set mode [list]
1548
        # freq_range list should be sorted from low to high
1549
        if {[lindex $timing_params 2] == "STATIC_DESKEW_8" || [lindex $timing_params 2] == "STATIC_DESKEW_10"}  {
1550
                # These modes have more than 2 freq ranges
1551
                set range_list [list LOW HIGH]
1552
        } else {
1553
                # Just 1 freq range
1554
                set range_list [list [list]]
1555
        }
1556
        set freq_mode [list]
1557
        foreach freq_range $range_list {
1558
                if {[catch {get_micro_node_delay -micro MIN -parameters [concat $timing_params $freq_range]} min_freq] != 0 || $min_freq == "" ||
1559
                        [catch {get_micro_node_delay -micro MAX -parameters [concat $timing_params $freq_range]} max_freq] != 0 || $max_freq == ""} {
1560
                        # Invalid mode
1561
                } else {
1562
                        set max_freq_period [expr 1000.0 / $min_freq]
1563
                        set min_freq_period [expr 1000.0 / $max_freq]
1564
                        lappend freq_mode [list $freq_range $min_freq $max_freq]
1565
                        if {$period >= $min_freq_period && $period <= $max_freq_period} {
1566
                                set mode [lindex $freq_mode end]
1567
                                break
1568
                        }
1569
                }
1570
        }
1571
        if {$mode == [list] && $freq_mode != [list]} {
1572
                if {$period < $min_freq_period} {
1573
                        # Fastest mode
1574
                        set mode [lindex $freq_mode end]
1575
                } else {
1576
                        # Slowest mode
1577
                        set mode [lindex $freq_mode 0]
1578
                }
1579
        }
1580
        return $mode
1581
}
1582
 
1583
 
1584
 
1585
 
1586
# Return a tuple of setup,hold time for read capture
1587
proc hps_sdram_p0_get_tsw { mem_if_memtype dqs_list period args} {
1588
        global TimeQuestInfo
1589
        array set options [list "-read_deskew" "none" "-dll_length" 0 "-config_period" 0 "-ddr3_discrete" 0]
1590
        foreach {option value} $args {
1591
                if {[array names options -exact "$option"] != ""} {
1592
                        set options($option) $value
1593
                } else {
1594
                        error "ERROR: Unknown get_tsw option $option (with value $value; args are $args)"
1595
                }
1596
        }
1597
 
1598
        set interface_type [hps_sdram_p0_get_io_interface_type $dqs_list]
1599
        if {$interface_type == "VHPAD"} {
1600
                set interface_type "HPAD"
1601
        }
1602
        set io_std [hps_sdram_p0_get_io_standard [lindex $dqs_list 0]]
1603
 
1604
        if {$interface_type != "" && $interface_type != "UNKNOWN" && $io_std != "" && $io_std != "UNKNOWN"} {
1605
                package require ::quartus::ddr_timing_model
1606
                set family $TimeQuestInfo(family)
1607
                set tsw_params [list IO $interface_type]
1608
                if {$options(-ddr3_discrete) == 1} {
1609
                        lappend tsw_params NONLEVELED
1610
                } elseif {$options(-read_deskew) == "static"} {
1611
                        if {$options(-dll_length) != 0} {
1612
                                lappend tsw_params STATIC_DESKEW_$options(-dll_length)
1613
                        } else {
1614
                                # No DLL length dependency
1615
                                lappend tsw_params STATIC_DESKEW
1616
                        }
1617
                } elseif {$options(-read_deskew) == "dynamic"} {
1618
                        lappend tsw_params DYNAMIC_DESKEW
1619
                }
1620
 
1621
                if {[catch {get_io_standard_node_delay -dst TSU -io_standard $io_std -parameters $tsw_params} tsw_setup] != 0 || $tsw_setup == "" || $tsw_setup == 0 || \
1622
                                [catch {get_io_standard_node_delay -dst TH -io_standard $io_std -parameters $tsw_params} tsw_hold] != 0 || $tsw_hold == "" || $tsw_hold == 0 } {
1623
                        error "Missing $family timing model for tSW of $io_std $tsw_params"
1624
                } else {
1625
                        # Derate tSW for DDR2 on VPAD in CIII Q240 parts
1626
                        # The tSW for HPADs and for other interface types on C8 devices
1627
                        # have a large guardband, so derating for them is not required
1628
                        if {[get_part_info -package -pin_count $TimeQuestInfo(part)] == "PQFP 240"} {
1629
                                if {[catch {get_io_standard_node_delay -dst TSU -io_standard $io_std -parameters [list IO $interface_type Q240_DERATING]} tsw_setup_derating] != 0 || $tsw_setup_derating == 0 || \
1630
                                                [catch {get_io_standard_node_delay -dst TH -io_standard $io_std -parameters [list IO $interface_type Q240_DERATING]} tsw_hold_derating] != 0 || $tsw_hold_derating == 0} {
1631
                                        set f "$io_std/$interface_type/$family"
1632
                                        switch -glob $f {
1633
                                                "SSTL_18*/VPAD/Cyclone III"  {
1634
                                                        set tsw_setup_derating 50
1635
                                                        set tsw_hold_derating 135
1636
                                                }
1637
                                                "SSTL_18*/VPAD/Cyclone IV E"  {
1638
                                                        set tsw_setup_derating 50
1639
                                                        set tsw_hold_derating 135
1640
                                                }
1641
                                                default {
1642
                                                        set tsw_setup_derating 0
1643
                                                        set tsw_hold_derating 0
1644
                                                }
1645
                                        }
1646
                                }
1647
                                incr tsw_setup $tsw_setup_derating
1648
                                incr tsw_hold $tsw_hold_derating
1649
                        }
1650
                        return [list $tsw_setup $tsw_hold]
1651
                }
1652
        }
1653
}
1654
 
1655
# ----------------------------------------------------------------
1656
#
1657
proc hps_sdram_p0_get_fitter_report_pin_info_from_report {target_pin info_type pin_report_id} {
1658
#
1659
# Description: Gets the report field for the given pin in the given report
1660
#
1661
# ----------------------------------------------------------------
1662
        set pin_name_column [hps_sdram_p0_get_report_column $pin_report_id "Name"]
1663
        set info_column [hps_sdram_p0_get_report_column $pin_report_id $info_type]
1664
        set result ""
1665
 
1666
        if {$pin_name_column == 0 && 0} {
1667
                set row_index [get_report_panel_row_index -id $pin_report_id $target_pin]
1668
                if {$row_index != -1} {
1669
                        set row [get_report_panel_row -id $pin_report_id -row $row_index]
1670
                        set result [lindex $row $info_column]
1671
                }
1672
        } else {
1673
                set report_rows [get_number_of_rows -id $pin_report_id]
1674
                for {set row_index 1} {$row_index < $report_rows && $result == ""} {incr row_index} {
1675
                        set row [get_report_panel_row -id $pin_report_id -row $row_index]
1676
                        set pin [lindex $row $pin_name_column]
1677
                        if {$pin == $target_pin} {
1678
                                set result [lindex $row $info_column]
1679
                        }
1680
                }
1681
        }
1682
        return $result
1683
}
1684
 
1685
# ----------------------------------------------------------------
1686
#
1687
proc hps_sdram_p0_get_fitter_report_pin_info {target_pin info_type preferred_report_id {found_report_id_name ""}} {
1688
#
1689
# Description: Gets the report field for the given pin by searching through the
1690
#              input, output and bidir pin reports
1691
#
1692
# ----------------------------------------------------------------
1693
        if {$found_report_id_name != ""} {
1694
                upvar 1 $found_report_id_name found_report_id
1695
        }
1696
        set found_report_id -1
1697
        set result ""
1698
        if {$preferred_report_id == -1} {
1699
                set pin_report_list [list "Fitter||Resource Section||Bidir Pins" "Fitter||Resource Section||Input Pins" "Fitter||Resource Section||Output Pins"]
1700
                for {set pin_report_index 0} {$pin_report_index != [llength $pin_report_list] && $result == ""} {incr pin_report_index} {
1701
                        set pin_report_id [get_report_panel_id [lindex $pin_report_list $pin_report_index]]
1702
                        if {$pin_report_id != -1} {
1703
                                set result [hps_sdram_p0_get_fitter_report_pin_info_from_report $target_pin $info_type $pin_report_id]
1704
                                if {$result != ""} {
1705
                                        set found_report_id $pin_report_id
1706
                                }
1707
                        } else {
1708
                                post_message -type error "hps_sdram_p0_pin_map.tcl: Failed to find fitter report. If report timing is run after an ECO, the user must set_global_assignment -name ECO_REGENERATE_REPORT ON in hps_sdram_p0.qsf and in hps_sdram_p0_pin_assignment.tcl files and rerun ECO and STA"
1709
                        }
1710
                }
1711
        } else {
1712
                set result [hps_sdram_p0_get_fitter_report_pin_info_from_report $target_pin $info_type $preferred_report_id]
1713
                if {$result != ""} {
1714
                        set found_report_id $preferred_report_id
1715
                }
1716
        }
1717
        return $result
1718
}
1719
# ----------------------------------------------------------------
1720
#
1721
proc hps_sdram_p0_get_fitter_report_pin_io_type_info {target_pin} {
1722
#
1723
# Description: Gets the type of IO, either column or row for
1724
# a given pin. If none found then "" is returned.
1725
#
1726
# ----------------------------------------------------------------
1727
        set result ""
1728
        set pin_report_id [get_report_panel_id "Fitter||Resource Section||All Package Pins"]
1729
        if {$pin_report_id != -1} {
1730
                set pin_name_column [hps_sdram_p0_get_report_column $pin_report_id "Pin Name/Usage"]
1731
                set info_column [hps_sdram_p0_get_report_column $pin_report_id "I/O Type"]
1732
                if {$pin_name_column == 0 && 0} {
1733
                        set row_index [get_report_panel_row_index -id $pin_report_id $target_pin]
1734
                        if {$row_index != -1} {
1735
                                set row [get_report_panel_row -id $pin_report_id -row $row_index]
1736
                                set result [lindex $row $info_column]
1737
                        }
1738
                } else {
1739
                        set report_rows [get_number_of_rows -id $pin_report_id]
1740
                        for {set row_index 1} {$row_index < $report_rows && $result == ""} {incr row_index} {
1741
                                set row [get_report_panel_row -id $pin_report_id -row $row_index]
1742
                                set pin [lindex $row $pin_name_column]
1743
                                if {$pin == $target_pin} {
1744
                                        set result [lindex $row $info_column]
1745
                                }
1746
                        }
1747
                }
1748
        } else {
1749
                set pin_report_id [get_report_panel_id "Fitter||Resource Section||DQS Summary"]
1750
                if {$pin_report_id != -1} {
1751
 
1752
                        set report_rows [get_number_of_rows -id $pin_report_id]
1753
                        set pin_name_column [hps_sdram_p0_get_report_column $pin_report_id "Name"]
1754
                        set info_column [hps_sdram_p0_get_report_column $pin_report_id "I/O Edge"]
1755
 
1756
                        for {set row_index 1} {$row_index < $report_rows && $result == ""} {incr row_index} {
1757
                                set row [get_report_panel_row -id $pin_report_id -row $row_index]
1758
                                set pin [lindex $row $pin_name_column]
1759
                                regsub -all {[ \r\t\n]+} $pin "" pin_no_whitespace
1760
                                if {$pin_no_whitespace == $target_pin} {
1761
                                        set result [lindex $row $info_column]
1762
                                }
1763
                        }
1764
 
1765
                        if {($result == "Bottom") || ($result == "Top")} {
1766
                                set result "Column I/O"
1767
                        } elseif {($result == "Left") || ($result == "Right")} {
1768
                                set result "Row I/O"
1769
                        }
1770
                }
1771
        }
1772
 
1773
        return $result
1774
}
1775
# ----------------------------------------------------------------
1776
#
1777
proc hps_sdram_p0_get_io_interface_type {pin_list} {
1778
#
1779
# Description: Gets the type of pin that the given pins are placed on
1780
#              either (HPAD, VPAD, HYBRID, "", or UNKNOWN).
1781
#              "" is returned if pin_list is empty
1782
#              UNKNOWN is returned if an error was encountered
1783
#              This function assumes the fitter has already completed and the
1784
#              compiler report has been loaded.
1785
#
1786
# ----------------------------------------------------------------
1787
        set preferred_report_id -1
1788
        set interface_type ""
1789
        foreach target_pin $pin_list {
1790
                set io_bank [hps_sdram_p0_get_fitter_report_pin_info $target_pin "I/O Bank" $preferred_report_id preferred_report_id]
1791
                if {[regexp -- {^([0-9]+)[A-Z]*} $io_bank -> io_bank_number]} {
1792
                        if {$io_bank_number == 1 || $io_bank_number == 2 || $io_bank_number == 5 || $io_bank_number == 6} {
1793
                                # Row I/O
1794
                                if {$interface_type == ""} {
1795
                                        set interface_type "HPAD"
1796
                                } elseif {$interface_type == "VIO"} {
1797
                                        set interface_type "HYBRID"
1798
                                }
1799
                        } elseif {$io_bank_number == 3 || $io_bank_number == 4 || $io_bank_number == 7 || $io_bank_number == 8} {
1800
                                if {$interface_type == ""} {
1801
                                        set interface_type "VPAD"
1802
                                } elseif {$interface_type == "HIO"} {
1803
                                        set interface_type "HYBRID"
1804
                                }
1805
                        } else {
1806
                                post_message -type critical_warning "Unknown I/O bank $io_bank for pin $target_pin"
1807
                                # Assume worst case performance (mixed HIO/VIO interface)
1808
                                set interface_type "HYBRID"
1809
                        }
1810
                }
1811
        }
1812
        return $interface_type
1813
}
1814
 
1815
 
1816
# ----------------------------------------------------------------
1817
#
1818
proc hps_sdram_p0_get_report_column { report_id str} {
1819
#
1820
# Description: Gets the report column index with the given header string
1821
#
1822
# ----------------------------------------------------------------
1823
        set target_col [get_report_panel_column_index -id $report_id $str]
1824
        if {$target_col == -1} {
1825
                error "Cannot find $str column"
1826
        }
1827
        return $target_col
1828
}
1829
 
1830
proc hps_sdram_p0_traverse_to_dll_id {dqs_pin msg_list_name} {
1831
        upvar 1 $msg_list_name msg_list
1832
        set dqs_pin_id [get_atom_node_by_name -name $dqs_pin]
1833
        set dqs_to_dll_path [list {IO_PAD fanout PADOUT} {IO_IBUF fanout O} {DQS_DELAY_CHAIN fanin DELAYCTRLIN} {DLL end DELAYCTRLOUT}]
1834
        set dll_id_list [hps_sdram_p0_traverse_atom_path $dqs_pin_id -1 $dqs_to_dll_path]
1835
        set dll_id -1
1836
        if {[llength $dll_id_list] == 1} {
1837
                set dll_atom_oterm_pair [lindex $dll_id_list 0]
1838
                set dll_id [lindex $dll_atom_oterm_pair 0]
1839
        } elseif {[llength $dll_id_list] > 1} {
1840
                lappend msg_list "Error: Found more than 1 DLL"
1841
        } else {
1842
                lappend msg_list "Error: DLL not found"
1843
        }
1844
        return $dll_id
1845
}
1846
 
1847
proc hps_sdram_p0_traverse_to_dqs_delaychain_id {dqs_pin msg_list_name} {
1848
        upvar 1 $msg_list_name msg_list
1849
        set dqs_pin_id [get_atom_node_by_name -name $dqs_pin]
1850
        set dqs_to_delaychain_path [list {IO_PAD fanout PADOUT} {IO_IBUF fanout O} {DQS_DELAY_CHAIN atom}]
1851
        set delaychain_id_list [hps_sdram_p0_traverse_atom_path $dqs_pin_id -1 $dqs_to_delaychain_path]
1852
        set delaychain_id -1
1853
        if {[llength $delaychain_id_list] == 1} {
1854
                set delaychain_atom_oterm_pair [lindex $delaychain_id_list 0]
1855
                set delaychain_id [lindex $delaychain_atom_oterm_pair 0]
1856
        } elseif {[llength $delaychain_id_list] > 1} {
1857
                lappend msg_list "Error: Found more than 1 DQS delaychain"
1858
        } else {
1859
                lappend msg_list "Error: DQS delaychain not found"
1860
        }
1861
        return $delaychain_id
1862
}
1863
 
1864
proc hps_sdram_p0_get_dqs_phase { dqs_pins } {
1865
        set dqs_phase -100
1866
        set dqs0 [lindex $dqs_pins 0]
1867
        if {$dqs0 != ""} {
1868
                set dqs_delay_chain_id [hps_sdram_p0_traverse_to_dqs_delaychain_id $dqs0 msg_list]
1869
                if {$dqs_delay_chain_id != -1} {
1870
                        set dqs_phase [get_atom_node_info -key INT_DQS_PHASE_SHIFT -node $dqs_delay_chain_id]
1871
                }
1872
        }
1873
 
1874
        set dqs_phase [expr {$dqs_phase / 100}]
1875
 
1876
        if {$dqs_phase < 0} {
1877
                set dqs_phase 90
1878
                post_message -type critical_warning "Unable to determine DQS delay chain phase shift.  Assuming default setting of $dqs_phase"
1879
        }
1880
 
1881
        return $dqs_phase
1882
}
1883
 
1884
proc hps_sdram_p0_get_dqs_period { dqs_pins } {
1885
        set dqs_period -100
1886
        set dqs0 [lindex $dqs_pins 0]
1887
        if {$dqs0 != ""} {
1888
                set dll_id [hps_sdram_p0_traverse_to_dll_id $dqs0 msg_list]
1889
                if {$dll_id != -1} {
1890
                        set dqs_period_str [get_atom_node_info -key TIME_INPUT_FREQUENCY -node $dll_id]
1891
                        if {[regexp {(.*) ps} $dqs_period_str matched dqs_period_ps] == 1} {
1892
                                set dqs_period [expr $dqs_period_ps/1000.0]
1893
                        } elseif {[regexp {(.*) ps} $dqs_period_str matched dqs_period_ns] == 1} {
1894
                                set dqs_period $dqs_period_ns
1895
                        }
1896
 
1897
                }
1898
        }
1899
 
1900
        if {$dqs_period < 0} {
1901
                set dqs_period 0
1902
                post_message -type critical_warning "Unable to determine DQS delay chain period.  Assuming default setting of $dqs_period"
1903
        }
1904
 
1905
        return $dqs_period
1906
}
1907
 
1908
proc hps_sdram_p0_get_operating_conditions_number {} {
1909
        set cur_operating_condition [get_operating_conditions]
1910
        set counter 0
1911
        foreach_in_collection op [get_available_operating_conditions] {
1912
                if {[string compare $cur_operating_condition $op] == 0} {
1913
                        return $counter
1914
                }
1915
                incr counter
1916
        }
1917
        return $counter
1918
}
1919
 
1920
proc hps_sdram_p0_get_rzq_pins { instname all_rzq_pins } {
1921
        upvar $all_rzq_pins rzqpins
1922
        load_package atoms
1923
        read_atom_netlist
1924
        set rzq_pins [ list ]
1925
        set entity_names_on [ hps_sdram_p0_are_entity_names_on ]
1926
 
1927
        # Get all termination atoms, to which rzqpin should be attached
1928
        set_project_mode -always_show_entity_name off
1929
        set instance ${instname}*
1930
        set atoms [get_atom_nodes -type TERMINATION -matching [escape_brackets $instance] ]
1931
        post_message -type info "Number of Termination Atoms: [get_collection_size $atoms]"
1932
        foreach_in_collection term_atom $atoms {
1933
                set rzq_pin ""
1934
                set atom $term_atom
1935
                set term_atom_name [get_atom_node_info -key name -node $term_atom]
1936
                post_message -type info "Found Termination Atom $term_atom_name"
1937
                set type [get_atom_node_info -key type -node $term_atom]
1938
 
1939
                # Check until you traverse to an IO_PAD for the RZQ Pin
1940
                while { ![regexp IO_PAD $type ] } {
1941
                        set name [get_atom_node_info -key name -node $atom]
1942
                        set iterms [get_atom_iports -node $atom]
1943
                        set iterm_size [llength $iterms]
1944
                        # Check for Multiple Inputs
1945
                        if { $iterm_size > 1 } {
1946
                                post_message -type error " Multiple inputs to a node:$name attached to a  Termination_Atom:$term_atom_name "
1947
                                break
1948
 
1949
                        }
1950
 
1951
                        foreach iterm $iterms {
1952
                                set fanin       [get_atom_port_info -node $atom -type iport -port_id $iterm -key fanin]
1953
                                set atom [lindex $fanin 0]
1954
                                set type [get_atom_node_info -key type -node $atom]
1955
                                set rzq_pin [get_atom_node_info -key name -node $atom]
1956
                        }
1957
                }
1958
 
1959
                lappend rzq_pins [ join $rzq_pin ]
1960
        }
1961
 
1962
        set_project_mode -always_show_entity_name qsf
1963
        set rzqpins $rzq_pins
1964
}
1965
 
1966
proc hps_sdram_p0_get_ddr_pins { instname allpins } {
1967
        # We need to make a local copy of the allpins associative array
1968
        upvar allpins pins
1969
        global ::GLOBAL_hps_sdram_p0_dqs_group_size
1970
        global ::GLOBAL_hps_sdram_p0_number_of_dqs_groups
1971
 
1972
        set synthesis_flow 0
1973
        set sta_flow 0
1974
        if { $::TimeQuestInfo(nameofexecutable) == "quartus_map" } {
1975
                set synthesis_flow 1
1976
        } elseif { $::TimeQuestInfo(nameofexecutable) == "quartus_sta" } {
1977
                set sta_flow 1
1978
        }
1979
 
1980
        set dqs_inst "altdq_dqs2_inst|"
1981
        set dqs_pins [ list ]
1982
        set dqsn_pins [ list ]
1983
        set q_groups [ list ]
1984
        set dqs_in_clocks [ list ]
1985
        set dqs_out_clocks [ list ]
1986
        set dqsn_out_clocks [ list ]
1987
 
1988
        for { set i 0 } { $i < $::GLOBAL_hps_sdram_p0_number_of_dqs_groups } { incr i } {
1989
 
1990
                set dqs_string ${instname}|p0|umemphy|uio_pads|dq_ddio\[$i\].ubidir_dq_dqs|${dqs_inst}obuf_os_0|o
1991
                set dqs_local_pins [ hps_sdram_p0_get_names_in_collection [ get_fanouts $dqs_string ] ]
1992
                set dqsn_string ${instname}|p0|umemphy|uio_pads|dq_ddio\[$i\].ubidir_dq_dqs|${dqs_inst}obuf_os_bar_0|o
1993
                set dqsn_local_pins [ hps_sdram_p0_get_names_in_collection [ get_fanouts $dqsn_string ] ]
1994
 
1995
                set dm_string ${instname}|p0|umemphy|uio_pads|dq_ddio\[$i\].ubidir_dq_dqs|${dqs_inst}extra_output_pad_gen\[0\].obuf_1|o
1996
                set dm_local_pins [ hps_sdram_p0_get_names_in_collection [ get_fanouts $dm_string ] ]
1997
 
1998
                set dqs_in_clock(dqs_pin) [ lindex $dqs_local_pins 0 ]
1999
                set dqs_in_clock(dqs_shifted_pin) "${instname}|p0|umemphy|uio_pads|dq_ddio[$i].ubidir_dq_dqs|${dqs_inst}dqs_delay_chain|dqsbusout"
2000
                set dqs_in_clock(div_name) "${instname}|div_clock_$i"
2001
                set dqs_in_clock(div_pin) "${instname}|p0|umemphy|uread_datapath|read_capture_clk_div2[$i]"
2002
 
2003
                lappend dqs_in_clocks [ array get dqs_in_clock ]
2004
 
2005
                set dqs_out_clock(dst) [ lindex $dqs_local_pins 0 ]
2006
                set dqs_out_clock(src) $dqs_string
2007
                set dqs_out_clock(dm_pin) [ lindex $dm_local_pins 0 ]
2008
                set dqsn_out_clock(dst) [ lindex $dqsn_local_pins 0 ]
2009
                set dqsn_out_clock(src) $dqsn_string
2010
                set dqsn_out_clock(dm_pin) [ lindex $dm_local_pins 0 ]
2011
                lappend dqs_out_clocks [ array get dqs_out_clock ]
2012
                lappend dqsn_out_clocks [ array get dqsn_out_clock ]
2013
 
2014
                set q_group [ list ]
2015
                for { set j 0 } { $j < $::GLOBAL_hps_sdram_p0_dqs_group_size } { incr j } {
2016
                        set index [ expr $i * $::GLOBAL_hps_sdram_p0_dqs_group_size + $j ]
2017
                        set q_string ${instname}|p0|umemphy|uio_pads|dq_ddio\[$i\].ubidir_dq_dqs|${dqs_inst}pad_gen\[${j}\].data_out|o
2018
                        set tmp_q_pins [ hps_sdram_p0_get_names_in_collection [ get_fanouts $q_string ] ]
2019
 
2020
                        lappend q_group $tmp_q_pins
2021
                }
2022
 
2023
                if { [llength $dqs_local_pins] != 1} { post_sdc_message critical_warning "Could not find DQS pin number $i" }
2024
                if { [llength $dqsn_local_pins] != 1} { post_sdc_message critical_warning "Could not find DQSn pin number $i" }
2025
                if { [llength $q_group] != $::GLOBAL_hps_sdram_p0_dqs_group_size} {
2026
                        post_sdc_message critical_warning "Could not find correct number of D pins for K pin $i. \
2027
                                Found [llength $q_group] pins. Expecting ${::GLOBAL_hps_sdram_p0_dqs_group_size}."
2028
                }
2029
 
2030
                lappend dqs_pins [ join $dqs_local_pins ]
2031
                lappend dqsn_pins [ join $dqsn_local_pins ]
2032
                lappend dm_pins [ join $dm_local_pins ]
2033
                lappend q_groups [ join $q_group ]
2034
        }
2035
 
2036
        set pins(dqs_pins) $dqs_pins
2037
        set pins(dqsn_pins) $dqsn_pins
2038
        set pins(dm_pins) $dm_pins
2039
        set pins(q_groups) $q_groups
2040
        set pins(all_dq_pins) [ join [ join $q_groups ] ]
2041
        set pins(dqs_in_clocks) $dqs_in_clocks
2042
        set pins(dqs_out_clocks) $dqs_out_clocks
2043
        set pins(dqsn_out_clocks) $dqsn_out_clocks
2044
 
2045
        set pins(all_dq_dm_pins) [ concat $pins(all_dq_pins) $pins(dm_pins) ]
2046
 
2047
        # Other Outputs
2048
 
2049
        set pins(ck_pins) [ list ]
2050
        set pins(ckn_pins) [ list ]
2051
        set pins(add_pins) [ list ]
2052
        set pins(ba_pins) [ list ]
2053
        set pins(cmd_pins) [ list ]
2054
        set pins(reset_pins) [ list ]
2055
 
2056
        set patterns [ list ]
2057
        lappend patterns ck_pins ${instname}|p0|umemphy|uio_pads|uaddr_cmd_pads|clock_gen[*].uclk_generator|pseudo_diffa_0|o
2058
        lappend patterns ckn_pins ${instname}|p0|umemphy|uio_pads|uaddr_cmd_pads|clock_gen[*].uclk_generator|pseudo_diffa_0|obar
2059
 
2060
        set addr_cmd_postfix "acblock[*].ddio_out|dataout"
2061
        lappend patterns reset_pins ${instname}|p0|umemphy|uio_pads|uaddr_cmd_pads|ureset_n_pad|${addr_cmd_postfix}
2062
 
2063
        lappend patterns add_pins ${instname}|p0|umemphy|uio_pads|uaddr_cmd_pads|uaddress_pad|${addr_cmd_postfix}
2064
        lappend patterns ba_pins ${instname}|p0|umemphy|uio_pads|uaddr_cmd_pads|ubank_pad|${addr_cmd_postfix}
2065
        lappend patterns cmd_pins ${instname}|p0|umemphy|uio_pads|uaddr_cmd_pads|ucmd_pad|${addr_cmd_postfix}
2066
 
2067
        foreach {pin_type pattern} $patterns {
2068
                set local_pins [ hps_sdram_p0_get_names_in_collection [ get_fanouts $pattern ] ]
2069
                if {[llength $local_pins] == 0} {
2070
                        post_message -type critical_warning "Could not find pin of type $pin_type from pattern $pattern"
2071
                } else {
2072
                        foreach pin [lsort -unique $local_pins] {
2073
                                lappend pins($pin_type) $pin
2074
                        }
2075
                }
2076
        }
2077
 
2078
 
2079
        set pins(ac_pins) [ concat $pins(add_pins) $pins(ba_pins) $pins(cmd_pins) $pins(reset_pins)]
2080
        set pins(ac_wo_reset_pins) [ concat $pins(add_pins) $pins(ba_pins) $pins(cmd_pins)]
2081
 
2082
        set pins(afi_ck_pins) ${instname}|p0|umemphy|afi_clk_reg
2083
        set pins(dqs_enable_regs_pins) ${instname}|p0|umemphy|uio_pads|dq_ddio[*].ubidir_dq_dqs|altdq_dqs2_inst|dqs_enable_ctrl~DQSENABLEOUT_DFF
2084
        set inst_driver ""
2085
        set pins(driver_core_ck_pins) ""
2086
        if {[regexp -nocase {if[0-9]$} $instname] == 1} {
2087
                set inst_driver [regsub {if[0-9]$} $instname "d0"]
2088
        }
2089
        if {[string compare -nocase $inst_driver ""] != 0} {
2090
                set pins(driver_core_ck_pins) ${inst_driver}|traffic_generator_0|pnf_per_bit_persist[0]
2091
        }
2092
 
2093
        #############
2094
        # PLL STUFF #
2095
        #############
2096
 
2097
        set pll_ck_clock "_UNDEFINED_PIN_"
2098
        set pll_dq_write_clock "_UNDEFINED_PIN_"
2099
        set pll_write_clock "_UNDEFINED_PIN_"
2100
        set pll_ref_clock "_UNDEFINED_PIN_"
2101
        set pll_ref_clock_input_buffer "_UNDEFINED_PIN_"
2102
        set pll_driver_core_clock "_UNDEFINED_PIN_"
2103
 
2104
        set msg_list [ list ]
2105
 
2106
        # CLOCK OUTPUT PLL
2107
        set pll_ck_clock_id [hps_sdram_p0_get_output_clock_id $pins(ck_pins) "CK Output" msg_list]
2108
        if {$pll_ck_clock_id == -1} {
2109
                foreach {msg_type msg} $msg_list {
2110
                        post_message -type $msg_type "hps_sdram_p0_pin_map.tcl: $msg"
2111
                }
2112
                post_message -type critical_warning "hps_sdram_p0_pin_map.tcl: Failed to find PLL clock for pins [join $pins(ck_pins)]"
2113
        } else {
2114
                set pll_ck_clock [hps_sdram_p0_get_pll_clock_name $pll_ck_clock_id]
2115
        }
2116
        set pins(pll_ck_clock) $pll_ck_clock
2117
 
2118
 
2119
        # DRIVER CORE CLOCK PLL
2120
        if {[string compare -nocase $pins(driver_core_ck_pins) ""] != 0 && [get_collection_size [get_registers -nowarn $pins(driver_core_ck_pins)]] > 0} {
2121
                set pll_driver_core_clock_id [hps_sdram_p0_get_output_clock_id $pins(driver_core_ck_pins) "DRIVER CORE CK" msg_list]
2122
                if {$pll_driver_core_clock_id == -1} {
2123
                        foreach {msg_type msg} $msg_list {
2124
                                post_message -type $msg_type "hps_sdram_p0_pin_map.tcl: $msg"
2125
                        }
2126
                        post_message -type critical_warning "hps_sdram_p0_pin_map.tcl: Failed to find PLL clock for pins [join $pins(driver_core_ck_pins)]"
2127
                } else {
2128
                        set pll_driver_core_clock [hps_sdram_p0_get_pll_clock_name $pll_driver_core_clock_id]
2129
                }
2130
        }
2131
        set pins(pll_driver_core_clock) $pll_driver_core_clock
2132
 
2133
 
2134
 
2135
        # DQ PLL
2136
        set pll_dq_write_clock_id [hps_sdram_p0_get_output_clock_id [ join [ join $pins(q_groups) ]] "Write DQ CK" msg_list 20]
2137
        if {$pll_dq_write_clock_id == -1} {
2138
                foreach {msg_type msg} $msg_list {
2139
                        post_message -type $msg_type "hps_sdram_p0_pin_map.tcl: $msg"
2140
                }
2141
                post_message -type critical_warning "hps_sdram_p0_pin_map.tcl: Failed to find PLL clock for pins [ join [ join $pins(q_groups) ]]"
2142
        } else {
2143
                set pll_dq_write_clock [hps_sdram_p0_get_pll_clock_name $pll_dq_write_clock_id]
2144
        }
2145
        set pins(pll_dq_write_clock) $pll_dq_write_clock
2146
 
2147
        # DQS PLL
2148
        set pll_write_clock_id [hps_sdram_p0_get_output_clock_id $pins(dqs_pins) "Write CK" msg_list 20]
2149
        if {$pll_write_clock_id == -1} {
2150
                foreach {msg_type msg} $msg_list {
2151
                        post_message -type $msg_type "hps_sdram_p0_pin_map.tcl: $msg"
2152
                }
2153
                post_message -type critical_warning "hps_sdram_p0_pin_map.tcl: Failed to find PLL clock for pins $pins(dqs_pins)"
2154
        } else {
2155
                set pll_write_clock [hps_sdram_p0_get_pll_clock_name $pll_write_clock_id]
2156
        }
2157
        set pins(pll_write_clock) $pll_write_clock
2158
 
2159
 
2160
 
2161
 
2162
 
2163
 
2164
 
2165
        set entity_names_on [ hps_sdram_p0_are_entity_names_on ]
2166
 
2167
        # Instance name prefix
2168
 
2169
        set prefix [ string map "| |*:" $instname ]
2170
        set prefix "*:$prefix"
2171
 
2172
        #####################
2173
        # READ CAPTURE DDIO #
2174
        #####################
2175
 
2176
        # Pending ALTDQ_DQS fix
2177
        # Half rate: separate read and write ALTDQ_DQS
2178
        # Full rate: bidirectional ALTDQ_DQS
2179
 
2180
        set read_capture_ddio_prefix [expr { $entity_names_on ? \
2181
                "$prefix|*:p0|*:umemphy|*:uio_pads|*:dq_ddio\[*\].ubidir_dq_dqs|*:" : \
2182
                "$instname|p0|umemphy|uio_pads|dq_ddio\[*\].ubidir_dq_dqs|" }]
2183
 
2184
        set read_capture_ddio [list "${read_capture_ddio_prefix}${dqs_inst}*input_path_gen\[*\].capture_reg~DFFLO" \
2185
                                                                "${read_capture_ddio_prefix}${dqs_inst}*input_path_gen\[*\].aligned_input\[*\]"]
2186
        set pins(read_capture_ddio) $read_capture_ddio
2187
 
2188
        ###################
2189
        # RESET REGISTERS #
2190
        ###################
2191
 
2192
        # the output of this flop feeds the asynchronous clear pin of the reset registers and should be false pathed
2193
    # since the deassertion of the reset is synchronous with the use of a reset pipeline
2194
    # normal timing analysis will take care that
2195
        set afi_reset_reg $prefix|*:p0|*:umemphy|*:ureset|*:ureset_afi_clk|reset_reg[3]
2196
        if { ! $entity_names_on } {
2197
                set afi_reset_reg $instname|p0|umemphy|ureset|ureset_afi_clk|reset_reg[3]
2198
        }
2199
        set pins(afi_reset_reg) $afi_reset_reg
2200
 
2201
 
2202
    # first flop of a synchronzier
2203
    # sequencer issues multiple resets during calibration, reset is synced over from AFI to read capture clock domain
2204
        set sync_reg $prefix|*:p0|*:umemphy|*:uread_datapath|read_buffering[*].seq_read_fifo_reset_sync
2205
        if { ! $entity_names_on } {
2206
                set sync_reg $instname|p0|umemphy|uread_datapath|read_buffering[*].seq_read_fifo_reset_sync
2207
        }
2208
        set pins(sync_reg) $sync_reg
2209
 
2210
 
2211
        ###############################
2212
        # DATA RESYNCHRONIZATION FIFO #
2213
        ###############################
2214
 
2215
        set fifo_wraddress_reg $prefix|*:p0|*:umemphy|*:uread_datapath|read_buffering[*].read_subgroup[*].wraddress[*]
2216
        if { ! $entity_names_on } {
2217
                set fifo_wraddress_reg $instname|p0|umemphy|uread_datapath|read_buffering[*].read_subgroup[*].wraddress[*]
2218
        }
2219
        set pins(fifo_wraddress_reg) $fifo_wraddress_reg
2220
 
2221
        set fifo_rdaddress_reg $prefix|*:p0|*:umemphy|*:uread_datapath|read_buffering[*].read_subgroup[*].rdaddress[*]
2222
        if { ! $entity_names_on } {
2223
                set fifo_rdaddress_reg $instname|p0|umemphy|uread_datapath|read_buffering[*].read_subgroup[*].rdaddress[*]
2224
        }
2225
        set pins(fifo_rdaddress_reg) $fifo_rdaddress_reg
2226
 
2227
        set fifo_wrdata_reg $prefix|*:p0|*:umemphy|*:uio_pads|*:dq_ddio[*].ubidir_dq_dqs|*:altdq_dqs2_inst|input_path_gen[*].read_fifo|*INPUT_DFF*
2228
        if { ! $entity_names_on } {
2229
                set fifo_wrdata_reg $instname|p0|umemphy|uio_pads|dq_ddio[*].ubidir_dq_dqs|altdq_dqs2_inst|input_path_gen[*].read_fifo|*INPUT_DFF*
2230
        }
2231
        set pins(fifo_wrdata_reg) $fifo_wrdata_reg
2232
 
2233
        set fifo_rddata_reg $prefix|*:p0|*:umemphy|*:uio_pads|*:dq_ddio[*].ubidir_dq_dqs|*:altdq_dqs2_inst|input_path_gen[*].read_fifo|dout[*]
2234
        if { ! $entity_names_on } {
2235
                set fifo_rddata_reg $instname|p0|umemphy|uio_pads|dq_ddio[*].ubidir_dq_dqs|altdq_dqs2_inst|input_path_gen[*].read_fifo|dout[*]
2236
        }
2237
        set pins(fifo_rddata_reg) $fifo_rddata_reg
2238
 
2239
}
2240
 
2241
proc hps_sdram_p0_initialize_ddr_db { ddr_db_par } {
2242
        upvar $ddr_db_par local_ddr_db
2243
 
2244
        global ::GLOBAL_hps_sdram_p0_corename
2245
 
2246
        post_sdc_message info "Initializing DDR database for CORE $::GLOBAL_hps_sdram_p0_corename"
2247
        set instance_list [hps_sdram_p0_get_core_instance_list $::GLOBAL_hps_sdram_p0_corename]
2248
        # set local_ddr_db(instance_list) $instance_list
2249
 
2250
        foreach instname $instance_list {
2251
                post_sdc_message info "Finding port-to-pin mapping for CORE: $::GLOBAL_hps_sdram_p0_corename INSTANCE: $instname"
2252
 
2253
                hps_sdram_p0_get_ddr_pins $instname allpins
2254
 
2255
                hps_sdram_p0_verify_ddr_pins allpins
2256
 
2257
                set local_ddr_db($instname) [ array get allpins ]
2258
        }
2259
}
2260
 
2261
proc hps_sdram_p0_verify_ddr_pins { pins_par } {
2262
        upvar $pins_par pins
2263
 
2264
        # Verify Q groups
2265
        set current_q_group_size -1
2266
        foreach q_group $pins(q_groups) {
2267
                set group_size [ llength $q_group ]
2268
                if { $group_size == 0 } {
2269
                        post_message -type critical_warning "Q group of size 0"
2270
                }
2271
                if { $current_q_group_size == -1 } {
2272
                        set current_q_group_size $group_size
2273
                } else {
2274
                        if { $current_q_group_size != $group_size } {
2275
                                post_message -type critical_warning "Inconsistent Q group size across groups"
2276
                        }
2277
                }
2278
        }
2279
 
2280
        # Verify DM pins
2281
        set counted_dm_pins [ llength $pins(dm_pins) ]
2282
        if { $::GLOBAL_hps_sdram_p0_number_of_dm_pins != $counted_dm_pins } {
2283
                post_message -type critical_warning "Unexpected number of detected DM pins: $counted_dm_pins"
2284
                post_message -type critical_warning "   expected: $::GLOBAL_hps_sdram_p0_number_of_dm_pins"
2285
        }
2286
        # Verify Address/Command/BA pins
2287
        if { [ llength $pins(add_pins) ] == 0 } {
2288
                post_message -type critical_warning "Address pins of size 0"
2289
        }
2290
        if { [ llength $pins(cmd_pins) ] == 0 } {
2291
                post_message -type critical_warning "Command pins of size 0"
2292
        }
2293
        if { [ llength $pins(ba_pins) ] == 0 } {
2294
                post_message -type critical_warning "BA pins of size 0"
2295
        }
2296
        if { [ llength $pins(reset_pins) ] == 0 } {
2297
                post_message -type critical_warning "Reset pins of size 0"
2298
        }
2299
}
2300
 
2301
proc hps_sdram_p0_get_all_instances_div_names { ddr_db_par } {
2302
        upvar $ddr_db_par local_ddr_db
2303
 
2304
        set div_names [ list ]
2305
        set instnames [ array names local_ddr_db ]
2306
        foreach instance $instnames {
2307
                array set pins $local_ddr_db($instance)
2308
 
2309
                foreach { dqs_in_clock_struct } $pins(dqs_in_clocks) {
2310
                        array set dqs_in_clock $dqs_in_clock_struct
2311
                        lappend div_names $dqs_in_clock(div_name)
2312
                }
2313
        }
2314
 
2315
        return $div_names
2316
}
2317
 
2318
proc hps_sdram_p0_get_all_instances_dqs_pins { ddr_db_par } {
2319
        upvar $ddr_db_par local_ddr_db
2320
 
2321
        set dqs_pins [ list ]
2322
        set instnames [ array names local_ddr_db ]
2323
        foreach instance $instnames {
2324
                array set pins $local_ddr_db($instance)
2325
 
2326
                foreach { dqs_pin } $pins(dqs_pins) {
2327
                        lappend dqs_pins ${dqs_pin}_IN
2328
                        lappend dqs_pins ${dqs_pin}_OUT
2329
                }
2330
                foreach { dqsn_pin } $pins(dqsn_pins) {
2331
                        lappend dqs_pins ${dqsn_pin}_OUT
2332
                }
2333
                foreach { ck_pin } $pins(ck_pins) {
2334
                        lappend dqs_pins $ck_pin
2335
                }
2336
                foreach { ckn_pin } $pins(ckn_pins) {
2337
                        lappend dqs_pins $ckn_pin
2338
                }
2339
        }
2340
 
2341
        return $dqs_pins
2342
}
2343
 
2344
proc hps_sdram_p0_dump_all_pins { ddr_db_par } {
2345
        upvar $ddr_db_par local_ddr_db
2346
 
2347
        set instnames [ array names local_ddr_db ]
2348
 
2349
        set filename "${::GLOBAL_hps_sdram_p0_corename}_all_pins.txt"
2350
        if [ catch { open $filename w 0777 } FH ] {
2351
                post_message -type error "Can't open file < $filename > for writing"
2352
        }
2353
 
2354
        post_message -type info "Dumping reference pin-map file: $filename"
2355
 
2356
        set script_name [ info script ]
2357
        puts $FH "# PIN MAP for core < $::GLOBAL_hps_sdram_p0_corename >"
2358
        puts $FH "#"
2359
        puts $FH "# Generated by ${::GLOBAL_hps_sdram_p0_corename}_pin_assignments.tcl"
2360
        puts $FH "#"
2361
        puts $FH "# This file is for reference only and is not used by Quartus Prime"
2362
        puts $FH "#"
2363
        puts $FH ""
2364
 
2365
        foreach instance $instnames {
2366
                array set pins $local_ddr_db($instance)
2367
 
2368
                puts $FH "INSTANCE: $instance"
2369
                puts $FH "DQS: $pins(dqs_pins)"
2370
                puts $FH "DQSn: $pins(dqsn_pins)"
2371
                puts $FH "DQ: $pins(q_groups)"
2372
 
2373
                puts $FH "DM $pins(dm_pins)"
2374
 
2375
                puts $FH "CK: $pins(ck_pins)"
2376
                puts $FH "CKn: $pins(ckn_pins)"
2377
 
2378
                puts $FH "ADD: $pins(add_pins)"
2379
                puts $FH "CMD: $pins(cmd_pins)"
2380
                puts $FH "RESET: $pins(reset_pins)"
2381
                puts $FH "BA: $pins(ba_pins)"
2382
 
2383
                puts $FH "PLL CK: $pins(pll_ck_clock)"
2384
                puts $FH "PLL DQ WRITE: $pins(pll_dq_write_clock)"
2385
                puts $FH "PLL WRITE: $pins(pll_write_clock)"
2386
                puts $FH "PLL DRIVER CORE: $pins(pll_driver_core_clock)"
2387
 
2388
                set i 0
2389
                foreach dqs_in_clock_struct $pins(dqs_in_clocks) {
2390
                        array set dqs_in_clock $dqs_in_clock_struct
2391
                        puts $FH "DQS_IN_CLOCK DQS_PIN ($i): $dqs_in_clock(dqs_pin)"
2392
                        puts $FH "DQS_IN_CLOCK DQS_SHIFTED_PIN ($i): $dqs_in_clock(dqs_shifted_pin)"
2393
                        puts $FH "DQS_IN_CLOCK DIV_NAME ($i): $dqs_in_clock(div_name)"
2394
                        puts $FH "DQS_IN_CLOCK DIV_PIN ($i): $dqs_in_clock(div_pin)"
2395
 
2396
                        incr i
2397
                }
2398
 
2399
                set i 0
2400
                foreach dqs_out_clock_struct $pins(dqs_out_clocks) {
2401
                        array set dqs_out_clock $dqs_out_clock_struct
2402
                        puts $FH "DQS_OUT_CLOCK SRC ($i): $dqs_out_clock(src)"
2403
                        puts $FH "DQS_OUT_CLOCK DST ($i): $dqs_out_clock(dst)"
2404
                        puts $FH "DQS_OUT_CLOCK DM ($i): $dqs_out_clock(dm_pin)"
2405
 
2406
                        incr i
2407
                }
2408
 
2409
                set i 0
2410
                foreach dqsn_out_clock_struct $pins(dqsn_out_clocks) {
2411
                        array set dqsn_out_clock $dqsn_out_clock_struct
2412
                        puts $FH "DQSN_OUT_CLOCK SRC ($i): $dqsn_out_clock(src)"
2413
                        puts $FH "DQSN_OUT_CLOCK DST ($i): $dqsn_out_clock(dst)"
2414
                        puts $FH "DQSN_OUT_CLOCK DM ($i): $dqsn_out_clock(dm_pin)"
2415
 
2416
                        incr i
2417
                }
2418
 
2419
                puts $FH "READ CAPTURE DDIO: $pins(read_capture_ddio)"
2420
                puts $FH "AFI RESET REGISTERS: $pins(afi_reset_reg)"
2421
                puts $FH "SYNCHRONIZERS: $pins(sync_reg)"
2422
                puts $FH "SYNCHRONIZATION FIFO WRITE ADDRESS REGISTERS: $pins(fifo_wraddress_reg)"
2423
                puts $FH "SYNCHRONIZATION FIFO WRITE REGISTERS: $pins(fifo_wrdata_reg)"
2424
                puts $FH "SYNCHRONIZATION FIFO READ REGISTERS: $pins(fifo_rddata_reg)"
2425
 
2426
                puts $FH ""
2427
                puts $FH "#"
2428
                puts $FH "# END OF INSTANCE: $instance"
2429
                puts $FH ""
2430
        }
2431
 
2432
        close $FH
2433
}
2434
proc hps_sdram_p0_dump_static_pin_map { ddr_db_par filename } {
2435
        upvar $ddr_db_par local_ddr_db
2436
 
2437
        set instnames [ array names local_ddr_db ]
2438
 
2439
        if [ catch { open $filename w 0777 } FH ] {
2440
                post_message -type error "Can't open file < $filename > for writing"
2441
        }
2442
 
2443
        post_message -type info "Dumping static pin-map file: $filename"
2444
 
2445
        puts $FH "# AUTO-GENERATED static pin map for core < $::GLOBAL_hps_sdram_p0_corename >"
2446
        puts $FH ""
2447
        puts $FH "proc ${::GLOBAL_hps_sdram_p0_corename}_initialize_static_ddr_db { ddr_db_par } {"
2448
        puts $FH "   upvar \$ddr_db_par local_ddr_db"
2449
        puts $FH ""
2450
 
2451
        foreach instname $instnames {
2452
                array set pins $local_ddr_db($instname)
2453
 
2454
                puts $FH "   # Pin Mapping for instance: $instname"
2455
 
2456
                hps_sdram_p0_static_map_expand_list $FH pins dqs_pins
2457
                hps_sdram_p0_static_map_expand_list $FH pins dqsn_pins
2458
 
2459
                hps_sdram_p0_static_map_expand_list_of_list $FH pins q_groups
2460
 
2461
                puts $FH ""
2462
                puts $FH "   set pins(all_dq_pins) \[ join \[ join \$pins(q_groups) \] \]"
2463
 
2464
                hps_sdram_p0_static_map_expand_list $FH pins dm_pins
2465
 
2466
                hps_sdram_p0_static_map_expand_list $FH pins ck_pins
2467
                hps_sdram_p0_static_map_expand_list $FH pins ckn_pins
2468
 
2469
                hps_sdram_p0_static_map_expand_list $FH pins add_pins
2470
                hps_sdram_p0_static_map_expand_list $FH pins cmd_pins
2471
                hps_sdram_p0_static_map_expand_list $FH pins reset_pins
2472
                hps_sdram_p0_static_map_expand_list $FH pins ba_pins
2473
 
2474
                puts $FH ""
2475
                puts $FH "   set pins(ac_pins) \[ concat \$pins(add_pins) \$pins(ba_pins) \$pins(cmd_pins) \$pins(reset_pins)\]"
2476
 
2477
                hps_sdram_p0_static_map_expand_string $FH pins pll_ck_clock
2478
                hps_sdram_p0_static_map_expand_string $FH pins pll_dq_write_clock
2479
                hps_sdram_p0_static_map_expand_string $FH pins pll_write_clock
2480
                hps_sdram_p0_static_map_expand_string $FH pins pll_driver_core_clock
2481
 
2482
                puts $FH ""
2483
                puts $FH "   set dqs_in_clocks \[ list \]"
2484
                set i 0
2485
                foreach dqs_in_clock_struct $pins(dqs_in_clocks) {
2486
                        array set dqs_in_clock $dqs_in_clock_struct
2487
                        puts $FH "   # DIV Clock ($i)"
2488
                        puts $FH "   set dqs_in_clock(dqs_pin) $dqs_in_clock(dqs_pin)"
2489
                        puts $FH "   set dqs_in_clock(dqs_shifted_pin) $dqs_in_clock(dqs_shifted_pin)"
2490
                        puts $FH "   set dqs_in_clock(div_name) $dqs_in_clock(div_name)"
2491
                        puts $FH "   set dqs_in_clock(div_pin) $dqs_in_clock(div_pin)"
2492
 
2493
                        puts $FH "   lappend dqs_in_clocks \[ array get dqs_in_clock \]"
2494
 
2495
                        incr i
2496
                }
2497
                puts $FH "   set pins(dqs_in_clocks) \$dqs_in_clocks"
2498
 
2499
 
2500
                puts $FH ""
2501
                puts $FH "   set dqs_out_clocks \[ list \]"
2502
                set i 0
2503
                foreach dqs_out_clock_struct $pins(dqs_out_clocks) {
2504
                        array set dqs_out_clock $dqs_out_clock_struct
2505
                        puts $FH "   # DQS OUT Clock ($i)"
2506
                        puts $FH "   set dqs_out_clock(src) $dqs_out_clock(src)"
2507
                        puts $FH "   set dqs_out_clock(dst) $dqs_out_clock(dst)"
2508
                        puts $FH "   set dqs_out_clock(dm_pin) $dqs_out_clock(dm_pin)"
2509
                        puts $FH "   lappend dqs_out_clocks \[ array get dqs_out_clock \]"
2510
 
2511
                        incr i
2512
                }
2513
                puts $FH "   set pins(dqs_out_clocks) \$dqs_out_clocks"
2514
 
2515
                puts $FH ""
2516
                puts $FH "   set dqsn_out_clocks \[ list \]"
2517
                set i 0
2518
                foreach dqsn_out_clock_struct $pins(dqsn_out_clocks) {
2519
                        array set dqsn_out_clock $dqsn_out_clock_struct
2520
                        puts $FH "   # DQSN OUT Clock ($i)"
2521
                        puts $FH "   set dqsn_out_clock(src) $dqsn_out_clock(src)"
2522
                        puts $FH "   set dqsn_out_clock(dst) $dqsn_out_clock(dst)"
2523
                        puts $FH "   set dqsn_out_clock(dm_pin) $dqsn_out_clock(dm_pin)"
2524
                        puts $FH "   lappend dqsn_out_clocks \[ array get dqsn_out_clock \]"
2525
 
2526
                        incr i
2527
                }
2528
                puts $FH "   set pins(dqsn_out_clocks) \$dqsn_out_clocks"
2529
 
2530
                hps_sdram_p0_static_map_expand_string $FH pins read_capture_ddio
2531
                hps_sdram_p0_static_map_expand_string $FH pins afi_reset_reg
2532
                hps_sdram_p0_static_map_expand_string $FH pins sync_reg
2533
                hps_sdram_p0_static_map_expand_string $FH pins fifo_wraddress_reg
2534
                hps_sdram_p0_static_map_expand_string $FH pins fifo_wrdata_reg
2535
                hps_sdram_p0_static_map_expand_string $FH pins fifo_rddata_reg
2536
 
2537
                puts $FH ""
2538
                puts $FH "   set local_ddr_db($instname) \[ array get pins \]"
2539
        }
2540
 
2541
        puts $FH "}"
2542
 
2543
        close $FH
2544
}

powered by: WebSVN 2.1.0

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