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 | ###############################################################################
# Copyright (c) 2014-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.
# =============================================================================
# @plugin
# Analyze RC Networks
# @namespace
# AnalyzeRC
# @section
# Create Reports
# @description
# Report the top 5 resistance values in the selected RC network.
# Usage:
#
# 1. Add the signals (turn on "Signal Mode") to investigate into
# the Mem window (e.g. by Drag&Drop).
#
# 2. Invoke the "Top 5 Resistors" menu entry to run the analysis.
# @test
# ModuleTest
# @files
# parasitic/analyzeRC.tcl
# @example
# demo/spef/usb_phy.spef
# @cmdline
# -readSPEF @example[0]
# -userware @files[0]
# @tag
# gui parasitic spf dspf
###############################################################################
# =============================================================================
# Init - Initialize the plugin.
# =============================================================================
#
proc AnalyzeRC:Init {} {
gui menu command {"Userware" "Top 5 Resistors"} {AnalyzeRC:Run}
}
# =============================================================================
# Finit - Finalize the plugin.
# =============================================================================
#
proc AnalyzeRC:Finit {} {
gui menu removeEntry {"Userware" "Top 5 Resistors"}
}
# =============================================================================
# Run - Run the analysis.
# =============================================================================
#
proc AnalyzeRC:Run {} {
set db [gui database get]
##
# Add a list of signal OIDs you would like to investigate.
# Select the signals in the GUI and use the popup menu entry
# "Copy <N> OIDs".
#
set signalOidList {}
##
# Get all OIDs from the MEM and use all signals for investigation.
#
set memOids [gui mem contents]
foreach oid $memOids {
set type [$db oid type $oid]
if {$type == "signal"} {
lappend signalOidList $oid
}
}
##
# Load the RC network for the selected signals.
#
gui parasitic showWindow
gui parasitic show $signalOidList
##
# Initialize hash table to calculate the result.
#
array unset _resVal
array set _resVal {}
##
# Loop over all loaded signals.
#
foreach signal $signalOidList {
##
# Search for the corresponding parasitic module.
#
set name [$db oid oname $signal]
set parasitic [$db search parasitic $name]
if {[$db oid isnull $parasitic]} {
zmessage print ERR "Could not find signal '$name'"
continue
}
##
# Lop over all instances inside the parasitic module.
#
$db foreach inst $parasitic inst {
##
# Only investigate resistor instances.
#
if {[$db primFuncOf $inst] != "RES"} {
continue
}
##
# Get the resistance value and add it to the result hash table.
#
set value [$db attr $inst getValue "R"]
if {$value eq ""} {
continue
}
set value [zdb formatvalue fromspice $value]
if {![info exist _resVal($value)]} {
set _resVal($value) {}
}
lappend _resVal($value) $inst
}
}
##
# Initialize the result list (top 5 resistances).
#
set limit 5
set resList {}
##
# Loop over the sorted values (largest items first).
#
foreach value [lsort -real -decreasing [array names _resVal]] {
foreach inst $_resVal($value) {
lappend resList $inst
if {[llength $resList] >= $limit} {
break
}
}
if {[llength $resList] >= $limit} {
break
}
}
##
# Show the result.
#
gui window show Mem
gui mem clear
gui mem append $resList
}
# =============================================================================
# Call the initialization procedure.
# =============================================================================
#
AnalyzeRC:Init
|