1 ########################################################################
3 # Set of procedures to generate a wrapup report of a list of slacks #
5 # Slacks are grouped together if the names of start, end, and thru #
6 # nodes are similar. Node names are similar if the only differences #
7 # are indexes suffixed at the end of name segments. #
9 ########################################################################
11 ########################################################################
13 # For a given slack create a string which is a colon separated list of #
14 # the start, thru and end names #
16 ########################################################################
18 proc get_slack_name
{slack
} {
19 set event [stb_GetSlackProperty
$slack START_EVENT
]
20 set signal
[ttv_GetTimingEventProperty
$event SIGNAL
]
21 set start_name
[ttv_GetTimingSignalProperty
$signal NET_NAME
]
23 set event [stb_GetSlackProperty
$slack END_EVENT
]
24 set signal
[ttv_GetTimingEventProperty
$event SIGNAL
]
25 set end_name
[ttv_GetTimingSignalProperty
$signal NET_NAME
]
27 set event [stb_GetSlackProperty
$slack THRU_EVENT
]
28 if {$event != "NULL"} {
29 set signal
[ttv_GetTimingEventProperty
$event SIGNAL
]
30 set thru_name
[ttv_GetTimingSignalProperty
$signal NET_NAME
]
35 return "$start_name:$thru_name:$end_name"
38 proc get_path_name
{path
} {
39 set event [ttv_GetTimingPathProperty
$path START_EVENT
]
40 set signal
[ttv_GetTimingEventProperty
$event SIGNAL
]
41 set start_name
[ttv_GetTimingSignalProperty
$signal NET_NAME
]
43 set event [ttv_GetTimingPathProperty
$path END_EVENT
]
44 set signal
[ttv_GetTimingEventProperty
$event SIGNAL
]
45 set end_name
[ttv_GetTimingSignalProperty
$signal NET_NAME
]
47 set event [ttv_GetTimingPathProperty
$path ACCESS_LATCH
]
48 if {$event != "NULL"} {
49 set signal
[ttv_GetTimingEventProperty
$event SIGNAL
]
50 set thru_name
[ttv_GetTimingSignalProperty
$signal NET_NAME
]
55 return "$start_name:$thru_name:$end_name"
58 ########################################################################
60 # Create bus notation form from an unsorted set of bus indices #
62 ########################################################################
64 proc get_bus
{bus_indices
} {
65 set bus_indices
[lsort -integer $bus_indices]
66 set bus
[lindex $bus_indices 0]
69 foreach index
$bus_indices {
70 if {$index == $last_index} continue
71 if {$index != [expr $last_index+1]} {
72 if {$last_index == $last_bus} {
75 set bus
"$bus-$last_index,$index"
81 if {$last_index != $last_bus} {
82 set bus
"$bus-$last_index"
87 ########################################################################
89 # Function which does most of the work #
91 # Input: A list of slacks #
92 # Output: An array of typical slacks #
93 # Each element of this array is a 2-element list where the #
94 # first element is a string made up of colon separated start, #
95 # end, and thru names in bus notation and the second element #
96 # is an example of this slack #
98 ########################################################################
100 proc get_typical_slacks
{slacks typical_slacks get_name_func
} {
101 upvar $typical_slacks typical_slack_array
102 set base_name_count
0
105 foreach slack
$slacks {
106 set slack_name
[$get_name_func $slack]
107 set index_list
[regexp -all -inline {[0-9]+[:\/\.
]|
[0-9]+$} $slack_name]
108 if {[llength index_list
] > 0} {
109 regsub -all {[0-9]+([:\/\.
])|
[0-9]+$} $slack_name {\[%s
\]\1} base_name
110 if {$base_name_count == 0} {
111 set base_names
(1) $base_name
112 set indices
(1) [list $index_list]
113 set example_slacks
(1) $slack
115 set base_name_count
1
116 puts "$slackcount : $base_name_count : $slack_name"
119 foreach i
[array names base_names
] {
120 if {$base_names($i) == $base_name} {
121 lappend indices
($i) $index_list
122 incr group_count
($i) 1
128 incr base_name_count
1
129 set base_names
($base_name_count) $base_name
130 set indices
($base_name_count) [list $index_list]
131 set example_slacks
($base_name_count) $slack
132 set group_count
($base_name_count) 1
133 puts "$slackcount : $base_name_count : $slack_name"
140 foreach i
[array names base_names
] {
141 set count
[llength [lindex $indices($i) 0]]
143 for {set j
0} {$j < $count} {incr j
1} {
145 foreach index_list
$indices($i) {
146 lappend bus
[string trimright
[lindex $index_list $j] :.
/]
148 set bus
[get_bus
$bus]
149 set bus_list
"$bus_list $bus"
151 set bussed_name
[eval format $base_names($i) $bus_list]
152 set typical_slack_array
($i) [list $bussed_name $example_slacks($i) $group_count($i)]
156 ########################################################################
158 # Display a given bus grouping where start, end and thru nodes are #
161 ########################################################################
163 proc display_bussed_slack_name
{file slack_name index count total labelc
} {
164 regsub -all : $slack_name " " slack_name_list
165 fputs
"Bus Grouped $labelc ($index) : $count objects (out of $total)\n\n" $file
166 fputs
" From: [lindex $slack_name_list 0]\n" $file
167 if {[llength $slack_name_list] == 3} {
168 fputs
" To: [lindex $slack_name_list 2]\n" $file
169 fputs
" Thru: [lindex $slack_name_list 1]\n\n" $file
171 fputs
" To: [lindex $slack_name_list 1]\n\n" $file
175 ########################################################################
177 # Display the details of a given slack #
179 ########################################################################
181 proc display_slack_detail
{file slack index lagdebug
} {
182 set value
[format "%.1fps" [expr 1e12
*[stb_GetSlackProperty
$slack VALUE
]]]
183 fputs
"Example of Bus Grouped Slack ($index) : Slack of $value\n\n" $file
184 if {$lagdebug == 1} {
185 set path
[stb_GetSlackProperty
$slack DATA_VALID_PATH
]
186 if {[ttv_GetTimingPathProperty
$path DATA_LAG
] > 0} {
187 stb_FindLagPaths
$file $slack -closingpath
189 stb_DisplaySlackReport
$file -slacks $slack
192 stb_DisplaySlackReport
$file -slacks $slack
196 proc display_path_detail
{file path index lagdebug
} {
197 set value
[format "%.1fps" [expr 1e12
*[ttv_GetTimingPathProperty
$path DELAY
]]]
198 fputs
"Example of Bus Grouped Path ($index) : Delay of $value\n\n" $file
199 ttv_DisplayPathDetail
$file $index $path
202 ########################################################################
204 # The top-level function for the wrap-up report #
206 ########################################################################
208 proc write_wrapup_report_any
{file slacks get_name_func display_detail_func labelc lagdebug
} {
209 get_typical_slacks
$slacks typical_slacks
$get_name_func
211 set total_slacks
[llength $slacks]
212 foreach i
[lsort -integer [array names typical_slacks
]] {
213 display_bussed_slack_name
$file [lindex $typical_slacks($i) 0] $i [lindex $typical_slacks($i) 2] $total_slacks $labelc
214 $display_detail_func $file [lindex $typical_slacks($i) 1] $i $lagdebug
218 proc write_wrapup_report
{file slacks args
} {
219 global tcl_interactive
224 while {[lindex $lst $i]!=""} {
225 set opt
[lindex $lst $i]
227 if {$opt=="-lagdebug"} {
231 puts "Unknown option '[lindex $lst $prei]'"
232 puts "Usage: write_wrapup_report <file> <slacklist> \[-lagdebug]"
233 if {!$tcl_interactive} {
240 if {[string first
"TimingPath" [lindex $slacks 0]]!=-1} {
241 write_wrapup_report_any
$file $slacks get_path_name display_path_detail Path
$lagdebug
243 write_wrapup_report_any
$file $slacks get_slack_name display_slack_detail Slack
$lagdebug
249 #----------------------------------------------------------------------