-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsiwave_dcir.py
209 lines (161 loc) · 5.93 KB
/
siwave_dcir.py
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
# # EDB: SIwave DC-IR Analysis
#
# This example demonstrates the use of EDB to interact with a PCB
# layout and run DC-IR analysis in SIwave.
# Perform required imports
# +
import os
import tempfile
import time
import pyedb
from pyedb.misc.downloads import download_file
temp_dir = tempfile.TemporaryDirectory(suffix=".ansys")
targetfile = download_file("edb/ANSYS-HSD_V1.aedb", destination=temp_dir.name)
siwave_file = os.path.join(os.path.dirname(targetfile), "ANSYS-HSD_V1.siw")
print(targetfile)
aedt_file = targetfile[:-4] + "aedt"
# -
# ## Launch Ansys Electronics Database (EDB)
#
# Instantiate an instance of the `pyedb.Edb` class using SI units.
# +
if os.path.exists(aedt_file):
os.remove(aedt_file)
# Select EDB version (change it manually if needed, e.g. "2025.1")
edb_version = "2025.1"
print(f"EDB version: {edb_version}")
edb = pyedb.Edb(edbpath=targetfile, edbversion=edb_version)
# -
# ## Identify nets and components
#
# The ``Edb.nets.netlist`` and ``Edb.components.instances`` properties contain information
# about all of the nets and components. The following cell uses this information to print the
# number of nets and components.
print("Nets {}".format(len(edb.nets.netlist)))
start = time.time()
print("Components {}".format(len(edb.components.instances.keys())))
print("elapsed time = ", time.time() - start)
# ## Identify pin positions
#
# This code shows how to obtain all pins for a specific component and
# print the ``[x, y]`` position of each pin.
pins = edb.components["U2"].pins
count = 0
for pin in edb.components["U2"].pins.values():
if count < 10: # Only print the first 10 pin coordinates.
print(pin.position)
elif count == 10:
print("...and many more.")
else:
pass
count += 1
# Get all nets connected to a specific component. Print
# the pin and the name of the net that it is connected to.
connections = edb.components.get_component_net_connection_info("U2")
n_print = 0 # Counter to limit the number of printed lines.
print_max = 15
for m in range(len(connections["pin_name"])):
ref_des = connections["refdes"][m]
pin_name = connections["pin_name"][m]
net_name = connections["net_name"][m]
if net_name != "" and (n_print < print_max):
print('{}, pin {} -> net "{}"'.format(ref_des, pin_name, net_name))
n_print += 1
elif n_print == print_max:
print("...and many more.")
n_print += 1
# Compute rats.
rats = edb.components.get_rats()
# ## Identify connected nets
#
# The ``get_dcconnected_net_list()`` method retrieves a list of
# all DC-connected power nets. Each group of connected nets is returned
# as a [set](https://docs.python.org/3/tutorial/datastructures.html#sets).
# The first argument to the method is the list of ground nets, which are
# not considered in the search for connected nets.
GROUND_NETS = ["GND", "GND_DP"]
dc_connected_net_list = edb.nets.get_dcconnected_net_list(GROUND_NETS)
for pnets in dc_connected_net_list:
print(pnets)
# ## Power Tree
#
# The power tree provides connectivity through all components from the VRM to
# the device.
VRM = "U1"
OUTPUT_NET = "AVCC_1V3"
powertree_df, component_list_columns, net_group = edb.nets.get_powertree(OUTPUT_NET, GROUND_NETS)
# Print some information about the power tree.
print_columns = ["refdes", "pin_name", "component_partname"]
ncol = [component_list_columns.index(c) for c in print_columns]
# This prints the header. Replace "pin_name" with "pin" to
# make the header align with the values.
# +
print("\t".join(print_columns).replace("pin_name", "pin"))
for el in powertree_df:
s = ""
count = 0
for e in el:
if count in ncol:
s += "{}\t".format(e)
count += 1
s.rstrip()
print(s)
# -
# ## Remove unused components
#
# Delete all RLC components that are connected with only one pin.
# The ``Edb.components.delete_single_pin_rlc()`` method
# provides a useful way to
# remove components that are not needed for the simulation.
edb.components.delete_single_pin_rlc()
# You can also remove unused components explicitly by name.
edb.components.delete("C380")
# Nets can also be removed explicitly.
edb.nets.delete("PDEN")
# Print the top and bottom elevation of the stackup obtained using
# the ``Edb.stackup.limits()`` method.
s = 'Top layer name: "{top}", Elevation: {top_el:.2f} '
s += 'mm\nBottom layer name: "{bot}", Elevation: {bot_el:2f} mm'
top, top_el, bot, bot_el = edb.stackup.limits()
print(s.format(top=top, top_el=top_el * 1e3, bot=bot, bot_el=bot_el * 1e3))
# ## Set up for SIwave DCIR analysis
#
# Create a voltage source and then set up a DCIR analysis.
edb.siwave.create_voltage_source_on_net("U1", "AVCC_1V3", "U1", "GND", 1.3, 0, "V1")
edb.siwave.create_current_source_on_net("IC2", "NetD3_2", "IC2", "GND", 1.0, 0, "I1")
setup = edb.siwave.add_siwave_dc_analysis("myDCIR_4")
setup.use_dc_custom_settings = True
setup.set_dc_slider = 0
setup.add_source_terminal_to_ground("V1", 1)
# ## Solve
#
# Save the modifications and run the analysis in SIwave.
edb.save_edb()
edb.nets.plot(None, "1_Top", plot_components_on_top=True)
# ## Export results
#
# Export all quantities calculated from the DC-IR analysis.
# The following method runs SIwave in batch mode from the command line.
# Results are written to the edb folder.
# Un-commment following lines to analyze with SIwave and export results.
#siw_file = edb.solve_siwave()
# outputs = edb.export_siwave_dc_results(
# siw_file,
# setup.name,
# )
# Close EDB. After EDB is closed, it can be opened by AEDT.
edb.close_edb()
# ## View Layout in SIwave
#
# The SIwave user interface can be visualized and manipulated
# using the SIwave user interface. This command works on Window OS only.
# +
# siwave = pyedb.Siwave("2025.1")
# siwave.open_project(siwave_file)
# report_file = os.path.join(temp_folder,'Ansys.htm')
# siwave.export_siwave_report("myDCIR_4", report_file)
# siwave.close_project()
# siwave.quit_application()
# -
# Clean up the temporary files and directory.
temp_dir.cleanup()