1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333 | ###############################################################################
# Copyright (c) 2010-2024 by Altair Engineering, Inc.
# All rights reserved.
#
# Altair Engineering, Inc. makes this software available as part of the Vision
# tool platform. As long as you are a licensee of the Vision tool platform
# you may make copies of the software and modify it to be used within the
# Vision tool platform, but you must include all of this notice on any copy.
# Redistribution without written permission to any third party, with or
# without modification, is not permitted.
# Altair Engineering, Inc. does not warrant that this software is error free
# or fit for any purpose. Altair Engineering, Inc. disclaims any liability for
# all claims, expenses, losses, damages and costs any user may incur as a
# result of using, copying or modifying the software.
# =============================================================================
# @userware
# Trace Path to File
# @section
# Create Reports
# @description
# Userware script that reads in a configuration file containing
# names of start net/nodes and target cells.
# Search paths between the start net and the target cell and dump this
# path into an output file.
# @files
# cust13/trace.tcl
# @tag
# zdb report
###############################################################################
# =============================================================================
# Name of the input and output files.
# =============================================================================
#
set _staticConf(inputFileName) "input.txt"
set _staticConf(outputFileName) "output.txt"
set _staticConf(hiersep) "/"
# -----------------------------------------------------------------------------
# _trace - This is the main procedure.
# -----------------------------------------------------------------------------
#
proc _trace {db} {
global _config _staticConf
##
# Return if the database is empty.
#
if {$db == {}} {
return
}
##
# Enable progress updates.
#
zprogress begin
##
# Clear any old configuration and call a procedure to read in the
# configuration file containing the start net and target cell information.
#
array unset _config
_doConfiguration $db
##
# Calculate the top module (here we expect exactly one top).
#
set top {}
$db foreach top top break
##
# Open the output file to store the results.
#
set dir [file dirname [info script]]
set fname [file join $dir $_staticConf(outputFileName)]
set out [open $fname "w"]
##
# Loop over all _config($i:...) entries.
#
zprogress push "Find paths" 1.0
for {set i 1} {$i <= $_config(count)} {incr i} {
set cellName $_config($i:targetCell)
##
# For each start net run the cone extraction and create the report.
#
zprogress push "" [expr {double($i) / double($_config(count))}]
foreach startNet [_getStartNetList $db $i $top] {
##
# Call the automatic cone extraction command '$db cone'.
# For a detailed documentation about all possible options see:
# doc/api/tcone.html
#
set res [$db cone -out -paths -targetCell $cellName $startNet]
_doReport $db $out $res
}
if {[zprogress pop]} {
break
}
}
zprogress pop
zprogress end
##
# Close the output file.
#
close $out
}
# -----------------------------------------------------------------------------
# _getStartNetList - build a list of start net OIDs that match the
# configuration given by $i.
# -----------------------------------------------------------------------------
#
proc _getStartNetList {db i top} {
global _config
##
# Search for the module specified in the first column of the input file.
#
set module [$db search module $_config($i:cellName)]
##
# Skip this configuration entry if the module could not be found in
# the loaded database (search returned a null OID).
#
if {[$db oid isnull $module]} {
zmessage print ERR "Module $_config($i:cellName) not found"
continue
}
##
# Search for the net specified in the third column inside $module
#
set net [$db search net $module $_config($i:startNet)]
##
# Skip this configuration entry if the net could not be found in
# $module of the loaded database (search returned a null OID).
#
if {[$db oid isnull $net]} {
set mod [$db oid oname $module]
zmessage print ERR "Net $_config($i:startNet) not found in $mod"
continue
}
##
# Set the 'blue' flag at this module.
#
$db flag $module set blue
##
# Initialize the result list as an empty list
#
set startNetList {}
##
# Loop over all instances of the cell flagged with the 'blue' flag.
#
$db flat foreach instOfCell blue $top inst {
##
# Check if this instance matches the specified instance pattern.
#
set iName [$db oid oname $inst]
if {![string match $_config($i:instPattern) $iName]} {
continue
}
##
# Convert the (module based) net into a tree based net in the
# current instantiation path and add it to the result list.
#
lappend startNetList [$db oid searchTreeBased $net [$db down $inst]]
}
##
# Clear the used blue flag.
#
$db flag $module clear blue
##
# Return the result list.
#
return $startNetList
}
# -----------------------------------------------------------------------------
# _doReport - generate the report for $res in the output file.
# -----------------------------------------------------------------------------
#
proc _doReport {db out res} {
global _staticConf
##
# To detect branches in the path the length of the result list 'res'
# can be checked.
#
if {[llength $res] > 1} {
##
# A branch in the path was detected.
# Do some action
#
}
##
# Loop over the result which is a list of lists with the format:
# {depth {list of OIDs}}.
#
foreach p $res {
##
# Loop over each OID in the result list.
#
foreach oid [lrange $p 1 end] {
##
# Process only ports.
#
if {[$db oid type $oid] != "port"} {
continue
}
##
# Create a name of the hierarchical port name.
#
set hierPort [concat [$db oid path $oid] [$db oid oname $oid]]
##
# Write the hierarchical port name to the output file.
#
puts -nonewline $out "[join $hierPort $_staticConf(hiersep)]\t"
}
puts $out ""
}
}
# -----------------------------------------------------------------------------
# _doConfiguration - Read the configuration from a file.
# -----------------------------------------------------------------------------
#
proc _doConfiguration {db} {
global _config _staticConf
##
# Clear all flags used later in this Userware.
#
set usedFlags {blue}
$db foreach module mod {foreach flag $usedFlags {$db flag $mod clear $flag}}
##
# Open the input file containing the list of start nodes and target cells.
#
set dir [file dirname [info script]]
set fname [file join $dir $_staticConf(inputFileName)]
set in [open $fname "r"]
##
# Enable the progress bar.
#
set size [file size $fname]
set bytes 0
zprogress push "Read input file" 0.1
##
# Read the file line by line and store the contents as
# _config($count:startNet)
# _config($count:targetCell)
#
set count 0
while {![eof $in]} {
##
# Get the next line in the file.
#
set line [gets $in]
##
# Count the number of bytes in the file.
#
incr bytes [string length $line]
##
# Calculate the position in the file and update the progress bar.
#
if {[zprogress update "" $bytes $size]} {
break
}
##
# Skip empty lines and lines starting with a '#' sign.
#
set line [string trim $line]
if {($line == "") || [string match "#*" $line]} {
continue
}
##
# Check the number of fields in the line. The input file syntax
# expects exactly 4 entries per line.
#
if {[llength $line] != 4} {
return -code error "Expect 4 columns in file $fname."
}
##
# Store the first three columns in the file as cellName, instPattern
# and the start net name. Column 4 specifies the target cell name.
#
incr count
set _config($count:cellName) [lindex $line 0]
set _config($count:instPattern) [lindex $line 1]
set _config($count:startNet) [lindex $line 2]
set _config($count:targetCell) [lindex $line 3]
}
##
# Save the total number of lines in the file.
#
set _config(count) $count
zprogress pop
}
##
# Use gui database runOrRegisterChangedCallback to immediately run _trace
# if we have a database, or otherwise register the proc to be executed after
# the database is available.
#
gui database runOrRegisterChangedCallback _trace
|