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 | ###############################################################################
# Copyright (c) 2022-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
# Update Diodes Width and Height Parameters
# @namespace
# UpdateDiodes
# @section
# Modify the Loaded Database
# @description
# Update all diode instances and add the width and height parameters
# according to the area and perimeter parameters.
# @non-interactive
# @files
# updateDiodes.tcl
# @tag
# zdb spice
###############################################################################
# =============================================================================
# Init - Initialize the plugin.
# =============================================================================
#
proc UpdateDiodes:Init {} {
gui database runAndRegisterChangedCallback [list UpdateDiodes:Start]
}
# =============================================================================
# Finit - Finalize the plugin.
# =============================================================================
#
proc UpdateDiodes:Finit {} {
gui database removeChangedCallback UpdateDiodes:Start
}
# =============================================================================
# Start - Update all diode instances and add the width and height parameters
# according to the area and perimeter parameters.
# Put cell names which should be skipped in exceptionList.
# =============================================================================
#
proc UpdateDiodes:Start {db} {
if {$db == {}} {
return
}
set exceptionList {"cellname1" "cellname2"}
$db foreach module module {
$db foreach inst $module inst {
if {[$db primFuncOf $inst] ne "DIODE"} {
continue
}
set cname [$db oid cname $inst]
if {$cname in $exceptionList} {
continue
}
set area {}
set perim {}
$db attr $inst foreach attr {
lassign [split $attr "="] name value
set n [string tolower $name]
if {$n eq "area"} {
set area $value
}
if {($n eq "perim") || ($n eq "perimeter")} {
set perim $value
}
}
if {($area eq "") || ($perim eq "")} {
continue
}
set area [zdb formatvalue fromspice $area]
set perim [zdb formatvalue fromspice $perim]
set width ""
set height ""
UpdateDiodes:_calculateWidthAndHeight $inst $area $perim \
width height
if {($width eq "") || ($height eq "")} {
continue
}
set width [zdb formatvalue tospice $width]
set height [zdb formatvalue tospice $height]
$db attr $inst set width=$width height=$height
}
}
gui attribute changed
}
# -----------------------------------------------------------------------------
# _calculateWidthAndHeight - Do the actual calculation based on the following
# formula:
#
# area = width * height
# perimeter = 2 * (width + height)
# 0 = 2 * width * width - perimeter * width + 2 * area
# equation 2nd degrees: a * x*x + b * x + c = 0
# a = 2
# b = -1 * perimeter
# c = 2 * area
# delta = b * b - 4 * a * c
# If delta > 0:
# width = (-1 * b - sqrt(delta)) / (2 * a)
# height = (-1 * b + sqrt(delta)) / (2 * a)
# else if -delta > 1E-28
# width = -b / 4
# height = -b / 4
# -----------------------------------------------------------------------------
#
proc UpdateDiodes:_calculateWidthAndHeight {
inst
area
perimeter
widthName
heightName
} {
upvar 1 $widthName width
upvar 1 $heightName height
set a 2
set b [expr {-1 * $perimeter}]
set c [expr { 2 * $area}]
set delta [expr {($b * $b) - (4 * ($a * $c))}]
if {$delta > 0} {
set width [expr {((-1 * $b) - (sqrt($delta)) / (2 * $a))}]
set height [expr {((-1 * $b) + (sqrt($delta)) / (2 * $a))}]
} elseif {-$delta > 1E-28} {
set width [expr {((-1 * $b) / 4.0)}]
set height [expr {((-1 * $b) / 4.0)}]
} else {
zmessage print ERR "Negative delta for equation second degree ($inst)."
}
}
# =============================================================================
# Call the initialization procedure.
# =============================================================================
#
UpdateDiodes:Init
|