Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / share / tcl / Greybox_API.tcl
1
2
3 #---------------------------------------------------------------------
4 #
5 proc Debug_Table {margin_list} {
6 puts "TABLE"
7 set li [llength $margin_list]
8 set i 0
9 while {$i < $li} {
10 set margin_by_data [lindex $margin_list $i]
11 set lj [llength $margin_by_data]
12 set j 0
13 while {$j < $lj - 1} {
14 puts -nonewline "[lindex $margin_by_data $j] "
15 incr j
16 }
17 puts "[lindex $margin_by_data $j]"
18 incr i
19 }
20 puts " "
21 puts " "
22 }
23
24 #---------------------------------------------------------------------
25 #
26 proc Print_Table {margin_list} {
27 set li [llength $margin_list]
28 set i 0
29 while {$i < $li} {
30 if {$i == 0} {puts -nonewline " values (\""}
31 if {$i > 0} {puts -nonewline " \""}
32 set margin_by_data [lindex $margin_list $i]
33 set lj [llength $margin_by_data]
34 set j 0
35 while {$j < $lj - 1} {
36 puts -nonewline "[lindex $margin_by_data $j], "
37 incr j
38 }
39 if {$i < $li - 1} {
40 puts "[lindex $margin_by_data $j]\", \\"
41 } else {
42 puts "[lindex $margin_by_data $j]\");"
43 }
44 incr i
45 }
46 }
47
48 #---------------------------------------------------------------------
49 #
50 proc Get_Sum {margin_list} {
51 set sum 0
52 set margin_list [lindex $margin_list 0]
53 set li [llength $margin_list]
54 set i 0
55 while {$i < $li} {
56 set margin_by_data [lindex $margin_list $i]
57 set lj [llength $margin_by_data]
58 set j 0
59 while {$j < $lj} {
60 set sum [expr "$sum + [lindex $margin_by_data $j]"]
61 incr j
62 }
63 incr i
64 }
65 return $sum
66 }
67
68 #---------------------------------------------------------------------
69 #
70 proc DebugTimingGroup {pin clocks rise_constraint rise_debug fall_constraint fall_debug type mode} {
71 set canonic_pin [lib_CanonicPinName $pin]
72 set canonic_ck [lib_CanonicPinName $clocks]
73 if {$type == "setup_rising"} {
74 if {$rise_constraint != ""} {
75 puts "--- SETUP $canonic_pin (R) $canonic_ck (R)"
76 PrintPath "DATA PATH" [lindex $rise_debug 0]
77 PrintPath "CLOCK PATH" [lindex $rise_debug 1]
78 Debug_Table $rise_constraint
79 }
80 if {$fall_constraint != ""} {
81 puts "--- SETUP $canonic_pin (F) $canonic_ck (R)"
82 PrintPath "DATA PATH" [lindex $fall_debug 0]
83 PrintPath "CLOCK PATH" [lindex $fall_debug 1]
84 Debug_Table $fall_constraint
85 }
86 } elseif {$type == "setup_falling"} {
87 if {$rise_constraint != ""} {
88 puts "--- SETUP $canonic_pin (R) $canonic_ck (F)"
89 PrintPath "DATA PATH" [lindex $rise_debug 0]
90 PrintPath "CLOCK PATH" [lindex $rise_debug 1]
91 Debug_Table $rise_constraint
92 }
93 if {$fall_constraint != ""} {
94 puts "--- SETUP $canonic_pin (F) $canonic_ck (F)"
95 PrintPath "DATA PATH" [lindex $fall_debug 0]
96 PrintPath "CLOCK PATH" [lindex $fall_debug 1]
97 Debug_Table $fall_constraint
98 }
99 } elseif {$type == "hold_rising"} {
100 if {$rise_constraint != ""} {
101 puts "--- HOLD $canonic_pin (R) $canonic_ck (R)"
102 PrintPath "DATA PATH" [lindex $rise_debug 0]
103 PrintPath "CLOCK PATH" [lindex $rise_debug 1]
104 Debug_Table $rise_constraint
105 }
106 if {$fall_constraint != ""} {
107 puts "--- HOLD $canonic_pin (F) $canonic_ck (R)"
108 PrintPath "DATA PATH" [lindex $fall_debug 0]
109 PrintPath "CLOCK PATH" [lindex $fall_debug 1]
110 Debug_Table $fall_constraint
111 }
112 } elseif {$type == "hold_falling"} {
113 if {$rise_constraint != ""} {
114 puts "--- HOLD $canonic_pin (R) $canonic_ck (F)"
115 PrintPath "DATA PATH" [lindex $rise_debug 0]
116 PrintPath "CLOCK PATH" [lindex $rise_debug 1]
117 Debug_Table $rise_constraint
118 }
119 if {$fall_constraint != ""} {
120 puts "--- HOLD $canonic_pin (F) $canonic_ck (F)"
121 PrintPath "DATA PATH" [lindex $fall_debug 0]
122 PrintPath "CLOCK PATH" [lindex $fall_debug 1]
123 Debug_Table $fall_constraint
124 }
125 } elseif {$type == "rising_edge"} {
126 if {$rise_constraint != ""} {
127 puts "--- ACCESS $canonic_ck (R) $canonic_pin (R)"
128 PrintPath "DATA PATH" [lindex $rise_debug 0]
129 PrintPath "CLOCK PATH" [lindex $rise_debug 1]
130 Debug_Table $rise_constraint
131 }
132 if {$fall_constraint != ""} {
133 puts "--- ACCESS $canonic_ck (R) $canonic_pin (F)"
134 PrintPath "DATA PATH" [lindex $fall_debug 0]
135 PrintPath "CLOCK PATH" [lindex $fall_debug 1]
136 Debug_Table $fall_constraint
137 }
138 } elseif {$type == "falling_edge"} {
139 if {$rise_constraint != ""} {
140 puts "--- ACCESS $canonic_ck (F) $canonic_pin (R)"
141 PrintPath "DATA PATH" [lindex $rise_debug 0]
142 PrintPath "CLOCK PATH" [lindex $rise_debug 1]
143 Debug_Table $rise_constraint
144 }
145 if {$fall_constraint != ""} {
146 puts "--- ACCESS $canonic_ck (F) $canonic_pin (F)"
147 PrintPath "DATA PATH" [lindex $fall_debug 0]
148 PrintPath "CLOCK PATH" [lindex $fall_debug 1]
149 Debug_Table $fall_constraint
150 }
151 }
152 }
153
154 #---------------------------------------------------------------------
155 #
156 proc PrintTimingGroup {pin clocks rise_constraint rise_debug fall_constraint fall_debug type mode} {
157 set canonic_pin [lib_CanonicPinName $pin]
158 set canonic_ck [lib_CanonicPinName $clocks]
159 if {$rise_constraint != "" || $fall_constraint != "" } {
160 puts " "
161 if {$type == "setup_rising"} {
162 puts " timing ($canonic_pin\_$canonic_ck\_setup_rising) \{"
163 puts " timing_type : setup_rising;"
164 } elseif {$type == "setup_falling"} {
165 puts " timing ($canonic_pin\_$canonic_ck\_setup_falling) \{"
166 puts " timing_type : setup_falling;"
167 } elseif {$type == "hold_rising"} {
168 puts " timing ($canonic_pin\_$canonic_ck\_hold_rising) \{"
169 puts " timing_type : hold_rising;"
170 } elseif {$type == "hold_falling"} {
171 puts " timing ($canonic_pin\_$canonic_ck\_hold_falling) \{"
172 puts " timing_type : hold_falling;"
173 } elseif {$type == "rising_edge"} {
174 puts " timing ($canonic_ck\_$canonic_pin\_rising_edge) \{"
175 puts " timing_type : rising_edge;"
176 } elseif {$type == "falling_edge"} {
177 puts " timing ($canonic_ck\_$canonic_pin\_falling_edge) \{"
178 puts " timing_type : falling_edge;"
179 }
180 puts " related_pin : $clocks;"
181 if { $type == "rising_edge" || $type == "falling_edge" } {
182 puts " cell_rise (access_template) \{"
183 } else {
184 puts " rise_constraint (setup_hold_template) \{"
185 }
186 Print_Table $rise_constraint
187 puts " \}"
188 if { $type == "rising_edge" || $type == "falling_edge" } {
189 puts " cell_fall (access_template) \{"
190 } else {
191 puts " fall_constraint (setup_hold_template) \{"
192 }
193 Print_Table $fall_constraint
194 puts " \}"
195 puts " \}"
196 }
197 }
198
199 #---------------------------------------------------------------------
200 proc PrintPath { tag path } {
201 set detail_list [ttv_GetPathDetail $path]
202 puts -nonewline "$tag"
203 foreach detail $detail_list {
204 set net_name [ttv_GetTimingDetailProperty $detail NODE_NAME]
205 set trans [ttv_GetTimingDetailProperty $detail TRANS]
206 puts -nonewline " - $net_name ($trans) "
207 }
208 puts ""
209 }
210 #---------------------------------------------------------------------
211 #It gets all the interface latches
212 proc Interface_Latches { fig } {
213 set latch_list ""
214 foreach latch [ttv_GetTimingSignalList $fig latch interface] {
215 lappend latch_list [ttv_GetSignalName $latch]
216 }
217 return $latch_list
218 }
219
220 #---------------------------------------------------------------------
221 #It gets all the interface clocks
222 proc Interface_Commands { fig ck } {
223 set com_list ""
224 foreach com [ttv_GetTimingSignalList $fig command interface] {
225 lappend com_list [ttv_GetSignalName $com]
226 }
227 set red_com_list ""
228 foreach com $com_list {
229 set ckpath_list [ttv_GetPaths $fig $ck $com ?? 1000 critic path max]
230 if {$ckpath_list != ""} { lappend red_com_list $com }
231 }
232 # add commands on interface
233 lappend red_com_list $ck
234 return $red_com_list
235 }
236
237 #---------------------------------------------------------------------
238 # Constructs all data_paths to interface latches clocked on clocks
239 proc DPLatch { fig source sink clock delay_type } {
240 set all_max_data_paths [ttv_GetPaths $fig $source $sink ?? 1000 critic path $delay_type]
241
242 # Refines data_paths to those ending on latches
243 set max_data_paths ""
244 foreach data_path $all_max_data_paths {
245 set com [ttv_GetTimingPathProperty $data_path COMMAND]
246 set com_sig [ttv_GetTimingEventProperty $com SIGNAL]
247 set com_name [ttv_GetTimingSignalProperty $com_sig NAME]
248 set clock_path [ttv_GetPaths $fig $clock $com_name ?? 1000 critic path $delay_type]
249 if {$clock_path != ""} { lappend max_data_paths $data_path }
250 }
251 return $max_data_paths
252 }
253
254 #---------------------------------------------------------------------
255 #
256 proc Compute_Delay { fig slope load path delay_type slope_unit cap_unit } {
257 set start_tran [ttv_GetTimingPathProperty $path START_TRAN]
258 set end_tran [ttv_GetTimingPathProperty $path END_TRAN]
259 set start_sig [ttv_GetTimingPathProperty $path START_SIG]
260 set start_name [ttv_GetTimingSignalProperty $start_sig NAME]
261 set end_sig [ttv_GetTimingPathProperty $path END_SIG]
262 set end_name [ttv_GetTimingSignalProperty $end_sig NAME]
263 set sl [expr $slope * $slope_unit]
264 set ld [expr $load * $cap_unit]
265 set tran $start_tran$end_tran
266 # no slope propagation prop = 0
267 # full slope propagation prop = 1
268 # 1-stage slope propagation prop = 2
269 set prop 1
270 set res_path [ttv_CharacPaths $fig $sl $start_name $end_name $tran 1 critic path $delay_type $ld $prop]
271 set delay [ttv_GetTimingPathProperty $res_path REF_DELAY]
272 return [expr $delay / $slope_unit]
273 }
274
275 #---------------------------------------------------------------------
276 #
277 proc Intrinsic_Margin { fig path com_sig type slope_unit } {
278
279 set end_sig [ttv_GetTimingPathProperty $path END_SIG]
280 set end_tran [ttv_GetTimingPathProperty $path END_TRAN]
281 set start_sig [ttv_GetTimingPathProperty $path START_SIG]
282 set start_tran [ttv_GetTimingPathProperty $path START_TRAN]
283
284 if {$type == "setup"} {
285 set intrinsic [ttv_GetLatchSetup $fig $end_sig $end_tran $com_sig]
286 } elseif {$type == "hold"} {
287 set intrinsic [ttv_GetLatchHold $fig $end_sig $end_tran $com_sig]
288 } elseif {$type == "access_min"} {
289 set intrinsic [ttv_GetLatchAccess $fig $start_sig $start_tran $com_sig min]
290 } elseif {$type == "access_max"} {
291 set intrinsic [ttv_GetLatchAccess $fig $start_sig $start_tran $com_sig max]
292 }
293 return [expr $intrinsic / $slope_unit]
294 }
295
296 #---------------------------------------------------------------------
297 #
298 proc Global_Margin { fig slope_list data_path ck_path com_sig type slope_unit cap_unit } {
299 # Tables construction
300 set data_delay_list ""
301 set ck_delay_list ""
302
303 foreach slope $slope_list {
304 if {$type == "setup"} {
305 # max data path
306 # min clock path
307 set data_delay [Compute_Delay $fig $slope 0 $data_path max $slope_unit $cap_unit]
308 set ck_delay [Compute_Delay $fig $slope 0 $ck_path min $slope_unit $cap_unit]
309 } elseif {$type == "hold"} {
310 # min data path
311 # max clock path
312 set data_delay [Compute_Delay $fig $slope 0 $data_path min $slope_unit $cap_unit]
313 set ck_delay [Compute_Delay $fig $slope 0 $ck_path max $slope_unit $cap_unit]
314 }
315 lappend data_delay_list [format "%.4f" $data_delay]
316 lappend ck_delay_list [format "%.4f" $ck_delay]
317 }
318
319 # Setup/Hold calculation
320 set margin_list ""
321 foreach data_delay $data_delay_list {
322 set margin_by_data ""
323 foreach ck_delay $ck_delay_list {
324 set intrinsic_margin [Intrinsic_Margin $fig $data_path $com_sig $type $slope_unit]
325 if {$type == "setup"} {
326 set margin [expr $data_delay - $ck_delay + $intrinsic_margin]
327 } elseif {$type == "hold"} {
328 set margin [expr $ck_delay - $data_delay + $intrinsic_margin]
329 }
330 lappend margin_by_data [format "%.4f" $margin]
331 }
332 lappend margin_list $margin_by_data
333 }
334 return $margin_list
335 }
336
337 #---------------------------------------------------------------------
338 #
339 proc Global_Prop { fig slope_list load_list path type slope_unit cap_unit } {
340 # Tables construction
341 set delay_list_list ""
342
343 foreach slope $slope_list {
344 set delay_list ""
345 foreach load $load_list {
346 if {$type == "max"} {
347 set delay [Compute_Delay $fig $slope $load $path max $slope_unit $cap_unit]
348 } elseif {$type == "min"} {
349 set delay [Compute_Delay $fig $slope $load $path max $slope_unit $cap_unit]
350 }
351 lappend delay_list [format "%.4f" $delay]
352 }
353 lappend delay_list_list $delay_list
354 }
355
356 return $delay_list_list
357 }
358
359 #---------------------------------------------------------------------
360 #
361 proc Global_Access { fig slope_list load_list data_path ck_path com_sig type slope_unit cap_unit } {
362 # Tables construction
363 set data_delay_list ""
364 set ck_delay_list ""
365
366 foreach slope $slope_list {
367 if {$type == "max"} {
368 # max clock path
369 set ck_delay [Compute_Delay $fig $slope 0 $ck_path max $slope_unit $cap_unit]
370 } elseif {$type == "min"} {
371 # min clock path
372 set ck_delay [Compute_Delay $fig $slope 0 $ck_path min $slope_unit $cap_unit]
373 }
374 lappend ck_delay_list [format "%.4f" $ck_delay]
375 }
376
377 foreach load $load_list {
378 if {$type == "max"} {
379 # max data path
380 set data_delay [Compute_Delay $fig 0 $load $data_path max $slope_unit $cap_unit]
381 } elseif {$type == "min"} {
382 # min data path
383 set data_delay [Compute_Delay $fig 0 $load $data_path min $slope_unit $cap_unit]
384 }
385 lappend data_delay_list [format "%.4f" $data_delay]
386 }
387
388 # Setup/Hold/Access calculation
389 set margin_list ""
390 foreach ck_delay $ck_delay_list {
391 set margin_by_data ""
392 foreach data_delay $data_delay_list {
393 set intrinsic_margin [Intrinsic_Margin $fig $data_path $com_sig $type $slope_unit]
394 set margin [expr $ck_delay + $data_delay + $intrinsic_margin]
395 lappend margin_by_data [format "%.4f" $margin]
396 }
397 lappend margin_list $margin_by_data
398 }
399 return $margin_list
400 }
401
402 #---------------------------------------------------------------------
403 #
404 proc extractSetupHold {slope slope_unit cap_unit fig clocks pin delay mode} {
405
406 # Constructs the list of interface latches
407 set all_latches [Interface_Latches $fig]
408
409 # Constructs all data_paths to interface latches clocked on clocks
410 set max_data_paths [DPLatch $fig $pin $all_latches $clocks max]
411
412 # Build setup & hold
413 set su_rr ""
414 set su_rf ""
415 set su_fr ""
416 set su_ff ""
417 set su_rr_debug ""
418 set su_rf_debug ""
419 set su_fr_debug ""
420 set su_ff_debug ""
421 set su_rr_sum -1000000
422 set su_rf_sum -1000000
423 set su_fr_sum -1000000
424 set su_ff_sum -1000000
425
426 set ho_rr ""
427 set ho_rf ""
428 set ho_fr ""
429 set ho_ff ""
430 set ho_rr_debug ""
431 set ho_rf_debug ""
432 set ho_fr_debug ""
433 set ho_ff_debug ""
434 set ho_rr_sum 1000000
435 set ho_rf_sum 1000000
436 set ho_fr_sum 1000000
437 set ho_ff_sum 1000000
438
439 foreach data_path $max_data_paths {
440
441 # Clock path
442 set com [ttv_GetTimingPathProperty $data_path COMMAND]
443 set com_sig [ttv_GetTimingEventProperty $com SIGNAL]
444 set com_name [ttv_GetTimingSignalProperty $com_sig NAME]
445 set com_tran [ttv_GetTimingEventProperty $com TRANS]
446 if {$com_tran == "u"} {
447 set com_tran d
448 } else {
449 set com_tran u
450 }
451 set ck_path [ttv_GetPaths $fig $clocks $com_name ?$com_tran 1 critic path max]
452 set ck_tran [ttv_GetTimingPathProperty $ck_path START_TRAN]
453
454 # Transitions
455 set start_tran [ttv_GetTimingPathProperty $data_path START_TRAN]
456 set end_tran [ttv_GetTimingPathProperty $data_path END_TRAN]
457 set end_sig [ttv_GetTimingPathProperty $data_path END_SIG]
458 set end_sig_name [ttv_GetTimingSignalProperty $end_sig NAME]
459
460 # Setup
461 set setup_list [Global_Margin $fig $slope $data_path $ck_path $com_sig setup $slope_unit $cap_unit]
462 set sum [Get_Sum $setup_list]
463 if {$ck_tran == "u"} {
464 if {$start_tran == "u"} {
465 if {$sum > $su_rr_sum} {
466 set su_rr_sum $sum
467 set su_rr $setup_list
468 if {$mode == "debug"} {
469 set su_rr_debug $data_path
470 lappend su_rr_debug $ck_path
471 }
472 }
473 }
474 if {$start_tran == "d"} {
475 if {$sum > $su_rf_sum} {
476 set su_rf_sum $sum
477 set su_rf $setup_list
478 if {$mode == "debug"} {
479 set su_rf_debug $data_path
480 lappend su_rf_debug $ck_path
481 }
482 }
483 }
484 } elseif {$ck_tran == "d"} {
485 if {$start_tran == "u"} {
486 if {$sum > $su_fr_sum} {
487 set su_fr_sum $sum
488 set su_fr $setup_list
489 if {$mode == "debug"} {
490 set su_fr_debug $data_path
491 lappend su_fr_debug $ck_path
492 }
493 }
494 }
495 if {$start_tran == "d"} {
496 if {$sum > $su_ff_sum} {
497 set su_ff_sum $sum
498 set su_ff $setup_list
499 if {$mode == "debug"} {
500 set su_ff_debug $data_path
501 lappend su_ff_debug $ck_path
502 }
503 }
504 }
505 }
506
507 # Hold
508 set hold_list [Global_Margin $fig $slope $data_path $ck_path $com_sig hold $slope_unit $cap_unit]
509 set sum [Get_Sum $hold_list]
510 if {$ck_tran == "u"} {
511 if {$start_tran == "u"} {
512 if {$sum < $ho_rr_sum} {
513 set ho_rr_sum $sum
514 set ho_rr $hold_list
515 if {$mode == "debug"} {
516 set ho_rr_debug $data_path
517 lappend ho_rr_debug $ck_path
518 }
519 }
520 }
521 if {$start_tran == "d"} {
522 if {$sum < $ho_rf_sum} {
523 set ho_rf_sum $sum
524 set ho_rf $hold_list
525 if {$mode == "debug"} {
526 set ho_rf_debug $data_path
527 lappend ho_rf_debug $ck_path
528 }
529 }
530 }
531 } elseif {$ck_tran == "d"} {
532 if {$start_tran == "u"} {
533 if {$sum < $ho_fr_sum} {
534 set ho_fr_sum $sum
535 set ho_fr $hold_list
536 if {$mode == "debug"} {
537 set ho_fr_debug $data_path
538 lappend ho_fr_debug $ck_path
539 }
540 }
541 }
542 if {$start_tran == "d"} {
543 if {$sum < $ho_ff_sum} {
544 set ho_ff_sum $sum
545 set ho_ff $hold_list
546 if {$mode == "debug"} {
547 set ho_ff_debug $data_path
548 lappend ho_ff_debug $ck_path
549 }
550 }
551 }
552 }
553 }
554 # PrintTimingGroup $pin $clocks $su_rr $su_rr_debug $su_rf $su_rr_debug "setup_rising" $mode
555 # PrintTimingGroup $pin $clocks $ho_rr $ho_rr_debug $ho_rf $ho_rf_debug "hold_rising" $mode
556 # PrintTimingGroup $pin $clocks $su_fr $su_fr_debug $su_ff $su_ff_debug "setup_falling" $mode
557 # PrintTimingGroup $pin $clocks $ho_fr $ho_fr_debug $ho_ff $ho_ff_debug "hold_falling" $mode
558
559 if {$mode == "debug"} {
560 DebugTimingGroup $pin $clocks $su_rr $su_rr_debug $su_rf $su_rr_debug "setup_rising" $mode
561 DebugTimingGroup $pin $clocks $ho_rr $ho_rr_debug $ho_rf $ho_rf_debug "hold_rising" $mode
562 DebugTimingGroup $pin $clocks $su_fr $su_fr_debug $su_ff $su_ff_debug "setup_falling" $mode
563 DebugTimingGroup $pin $clocks $ho_fr $ho_fr_debug $ho_ff $ho_ff_debug "hold_falling" $mode
564 }
565
566 return [list $su_rr $su_rf $ho_rr $ho_rf $su_fr $su_ff $ho_fr $ho_ff]
567 }
568
569 #---------------------------------------------------------------------
570 #
571 proc extractPropDelay { slope load slope_unit cap_unit fig pin_in pin_out mode minmax} {
572
573 set prop_rr ""
574 set prop_rf ""
575 set prop_fr ""
576 set prop_ff ""
577
578 if {$minmax == "max"} {
579 set path_list [ttv_GetPaths $fig $pin_in $pin_out ?? 1000 critic path max]
580 } elseif {$minmax == "min"} {
581 set path_list [ttv_GetPaths $fig $pin_in $pin_out ?? 1000 critic path min]
582 }
583
584
585 foreach path $path_list {
586 set start_sig [ttv_GetTimingPathProperty $path START_SIG]
587 set end_sig [ttv_GetTimingPathProperty $path END_SIG]
588 set start_tran [ttv_GetTimingPathProperty $path START_TRAN]
589 set end_tran [ttv_GetTimingPathProperty $path END_TRAN]
590
591 set prop_list [Global_Prop $fig $slope $load $path $minmax $slope_unit $cap_unit]
592
593 if {$start_tran == "u"} {
594 if {$end_tran == "u"} { set prop_rr $prop_list }
595 if {$end_tran == "d"} { set prop_rf $prop_list }
596 } elseif {$start_tran == "d"} {
597 if {$end_tran == "u"} { set prop_fr $prop_list }
598 if {$end_tran == "d"} { set prop_ff $prop_list }
599 }
600 }
601
602 return [list $prop_rr $prop_rf $prop_fr $prop_ff]
603 }
604 #---------------------------------------------------------------------
605 #
606 proc extractAccess { slope load slope_unit cap_unit fig clocks pin fig mode minmax} {
607
608 set acs_rr ""
609 set acs_rf ""
610 set acs_fr ""
611 set acs_ff ""
612 set acs_rr_debug ""
613 set acs_rf_debug ""
614 set acs_fr_debug ""
615 set acs_ff_debug ""
616 if {$minmax == "max"} {
617 set acs_rr_sum 0
618 set acs_rf_sum 0
619 set acs_fr_sum 0
620 set acs_ff_sum 0
621 } elseif {$minmax == "min"} {
622 set acs_rr_sum 100000
623 set acs_rf_sum 100000
624 set acs_fr_sum 100000
625 set acs_ff_sum 100000
626 }
627
628 # Constructs the list of interface latches
629 set all_latches [Interface_Latches $fig]
630
631 # Constructs all data_paths from interface latches to output clocked on clocks
632 if {$minmax == "max"} {
633 set max_data_paths [ttv_GetPaths $fig $all_latches $pin ?? 1000 critic path max]
634 } elseif {$minmax == "min"} {
635 set max_data_paths [ttv_GetPaths $fig $all_latches $pin ?? 1000 critic path min]
636 }
637
638 # Build access
639 foreach data_path $max_data_paths {
640
641 # Clock path
642 set start_sig [ttv_GetTimingPathProperty $data_path START_SIG]
643 set start_tran [ttv_GetTimingPathProperty $data_path START_TRAN]
644 set end_tran [ttv_GetTimingPathProperty $data_path END_TRAN]
645 set com_list [ttv_GetLatchEventCommands $start_sig $start_tran]
646
647 foreach com $com_list {
648 set com_sig [ttv_GetTimingEventProperty $com SIGNAL]
649 set com_name [ttv_GetTimingSignalProperty $com_sig NAME]
650 set com_tran [ttv_GetTimingEventProperty $com TRANS]
651
652 set ck_path [ttv_GetPaths $fig $clocks $com_name ?$com_tran 1 critic path max]
653 if {[llength $ck_path] == 0} { continue }
654 set ck_tran [ttv_GetTimingPathProperty $ck_path START_TRAN]
655
656 set access_list [Global_Access $fig $slope $load $data_path $ck_path $com_sig $minmax $slope_unit $cap_unit]
657 set sum [Get_Sum $access_list]
658
659 if {$ck_tran == "u"} {
660 if {$end_tran == "u"} {
661 if {$minmax == "max"} { set diff [expr $sum - $acs_rr_sum] }
662 if {$minmax == "min"} { set diff [expr $acs_rr_sum - $sum] }
663 if {$diff > 0} {
664 set acs_rr_sum $sum
665 set acs_rr $access_list
666 if {$mode == "debug"} {
667 set acs_rr_debug $data_path
668 lappend acs_rr_debug $ck_path
669 }
670 }
671 }
672 if {$end_tran == "d"} {
673 if {$minmax == "max"} { set diff [expr $sum - $acs_rf_sum] }
674 if {$minmax == "min"} { set diff [expr $acs_rf_sum - $sum] }
675 if {$diff > 0} {
676 set acs_rf_sum $sum
677 set acs_rf $access_list
678 if {$mode == "debug"} {
679 set acs_rf_debug $data_path
680 lappend acs_rf_debug $ck_path
681 }
682 }
683 }
684 } elseif {$ck_tran == "d"} {
685 if {$end_tran == "u"} {
686 if {$minmax == "max"} { set diff [expr $sum - $acs_fr_sum] }
687 if {$minmax == "min"} { set diff [expr $acs_fr_sum - $sum] }
688 if {$diff > 0} {
689 set acs_fr_sum $sum
690 set acs_fr $access_list
691 if {$mode == "debug"} {
692 set acs_fr_debug $data_path
693 lappend acs_fr_debug $ck_path
694 }
695 }
696 }
697 if {$end_tran == "d"} {
698 if {$minmax == "max"} { set diff [expr $sum - $acs_ff_sum] }
699 if {$minmax == "min"} { set diff [expr $acs_ff_sum - $sum] }
700 if {$diff > 0} {
701 set acs_ff_sum $sum
702 set acs_ff $access_list
703 if {$mode == "debug"} {
704 set acs_ff_debug $data_path
705 lappend acs_ff_debug $ck_path
706 }
707 }
708 }
709 }
710 }
711 }
712
713 if {$mode == "debug"} {
714 DebugTimingGroup $pin $clocks $acs_rr $acs_rr_debug $acs_rf $acs_rf_debug "rising_edge" $mode
715 DebugTimingGroup $pin $clocks $acs_fr $acs_fr_debug $acs_ff $acs_ff_debug "falling_edge" $mode
716 }
717 # PrintTimingGroup $pin $clocks $acs_rr $acs_rr_debug $acs_rf $acs_rf_debug "rising_edge" $mode
718 # PrintTimingGroup $pin $clocks $acs_fr $acs_fr_debug $acs_ff $acs_ff_debug "falling_edge" $mode
719
720 return [list $acs_rr $acs_rf $acs_fr $acs_ff]
721 }