pyedb 0.52.0__py3-none-any.whl → 0.53.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyedb might be problematic. Click here for more details.

@@ -0,0 +1,894 @@
1
+ from __future__ import annotations
2
+
3
+ import pyedb.siwave_core.cpa.simulation_setup_data_model
4
+ from pyedb.siwave_core.cpa.simulation_setup_data_model import SIwaveCpaSetup, Vrm
5
+ from pyedb.siwave_core.product_properties import SIwaveProperties
6
+
7
+
8
+ class ChannelSetup:
9
+ """
10
+ A class to manage the channel setup configuration for SIWave CPA simulations.
11
+
12
+ Attributes:
13
+ die_name (str): The name of the die associated with the channel setup.
14
+ pin_grouping_mode (str): The mode for pin grouping, e.g., "perpin", "ploc", or "usediepingroups".
15
+ channel_component_exposure (dict): A dictionary mapping component names to their exposure status (True/False).
16
+ vrm (list): A list of VRM (Voltage Regulator Module) configurations.
17
+ """
18
+
19
+ def __init__(self, pedb, cfg_channel_setup=None):
20
+ self._pedb = pedb
21
+ self.__init_values()
22
+ if cfg_channel_setup:
23
+ self._apply_cfg_object(cfg_channel_setup)
24
+
25
+ def __init_values(self):
26
+ self.die_name = ""
27
+ self.pin_grouping_mode = "perpin"
28
+ self.channel_component_exposure = {}
29
+
30
+ def _apply_cfg_object(self, channel_setup):
31
+ self.die_name = channel_setup.die_name
32
+ self.channel_component_exposure = channel_setup.channel_component_exposure
33
+ self.pin_grouping_mode = channel_setup.pin_grouping_mode
34
+ self.vrm = channel_setup.vrm_setup if hasattr(channel_setup, "vrm_setup") else [] # type: ignore[union-attr]
35
+
36
+ @property
37
+ def die_name(self):
38
+ return self._pedb.active_cell.GetProductProperty(
39
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_DIE_NAME
40
+ )[1]
41
+
42
+ @die_name.setter
43
+ def die_name(self, value):
44
+ """
45
+ Get the die name from the SIWave properties.
46
+
47
+ Returns:
48
+ str: The die name.
49
+ """
50
+
51
+ self._pedb.active_cell.SetProductProperty(
52
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_DIE_NAME, value
53
+ )
54
+
55
+ @property
56
+ def pin_grouping_mode(self):
57
+ """
58
+ Get the pin grouping mode from the SIWave properties.
59
+
60
+ Returns:
61
+ str: The pin grouping mode ("perpin", "ploc", or "usediepingroups").
62
+ """
63
+
64
+ mode_mapping = {-1: "perpin", 0: "ploc", 1: "usediepingroups"}
65
+ pg_mode = self._pedb.active_cell.GetProductProperty(
66
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_PIN_GROUPING_MODE
67
+ )[-1]
68
+ return mode_mapping[int(pg_mode.split(":")[1])] if pg_mode else "perpin"
69
+
70
+ @pin_grouping_mode.setter
71
+ def pin_grouping_mode(self, value):
72
+ mapping = {"perpin": -1, "ploc": 0, "usediepingroups": 1}
73
+ if isinstance(value, str):
74
+ if not value in mapping:
75
+ raise f"value {value} not supported, must be {list(mapping.keys())}"
76
+ value = mapping[value]
77
+ if not value in [-1, 0, 1]:
78
+ raise f"wrong value {value}"
79
+ self._pedb.active_cell.SetProductProperty(
80
+ self._pedb._edb.ProductId.SIWave,
81
+ SIwaveProperties.CPA_CHANNEL_PIN_GROUPING_MODE,
82
+ self.die_name + ":" + str(value),
83
+ )
84
+
85
+ @property
86
+ def channel_component_exposure(self):
87
+ """
88
+ Get the channel component exposure configuration from the SIWave properties.
89
+
90
+ Returns:
91
+ dict: A dictionary mapping component names to their exposure status (True/False).
92
+ """
93
+
94
+ cmp_exposure = self._pedb.active_cell.GetProductProperty(
95
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_COMPONENT_EXPOSURE_CONFIG
96
+ )[-1]
97
+ cmp_dict = {}
98
+ for comp in cmp_exposure.split("*"):
99
+ _comp = comp.split(":")
100
+ cmp_dict[_comp[0]] = bool(_comp[1])
101
+ return cmp_dict
102
+
103
+ @channel_component_exposure.setter
104
+ def channel_component_exposure(self, value):
105
+ if not isinstance(value, dict):
106
+ raise "Channel component exposure input must be a dictionary."
107
+ channel_comp_exposure = ""
108
+ for comp, enabled in value.items():
109
+ if channel_comp_exposure:
110
+ channel_comp_exposure += "*"
111
+ channel_comp_exposure += f"{comp}:{int(enabled)}"
112
+ self._pedb.active_cell.SetProductProperty(
113
+ self._pedb._edb.ProductId.SIWave,
114
+ SIwaveProperties.CPA_CHANNEL_COMPONENT_EXPOSURE_CONFIG,
115
+ channel_comp_exposure,
116
+ )
117
+
118
+ @property
119
+ def vrm(self):
120
+ """
121
+ Get the VRM (Voltage Regulator Module) setup from the SIWave properties.
122
+
123
+ Returns:
124
+ list: A list of VRM objects.
125
+ """
126
+
127
+ vrm = self._pedb.active_cell.GetProductProperty(
128
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_VRM_SETUP
129
+ )[-1]
130
+ vrm_list = []
131
+ for _vrm in vrm.split("*"):
132
+ vrm_obj = Vrm()
133
+ _vrm_values = _vrm.split(":")
134
+ if len(_vrm_values) != 4:
135
+ raise ValueError(
136
+ f"Invalid VRM format: {_vrm}. Expected format is 'name:voltage:power_net:reference_net'."
137
+ )
138
+ vrm_obj.name = _vrm_values[0]
139
+ vrm_obj.voltage = float(_vrm_values[1])
140
+ vrm_obj.power_net = _vrm_values[2]
141
+ vrm_obj.reference_net = _vrm_values[3]
142
+ vrm_list.append(vrm_obj)
143
+ return vrm_list
144
+
145
+ @vrm.setter
146
+ def vrm(self, value):
147
+ if not isinstance(value, list):
148
+ raise "vrm setter must have list as input."
149
+ vrm_str = ""
150
+ for vrm in value:
151
+ if isinstance(vrm, pyedb.siwave_core.cpa.simulation_setup_data_model.Vrm):
152
+ if vrm_str:
153
+ vrm_str += "*"
154
+ vrm_str += vrm.name
155
+ vrm_str += ":"
156
+ vrm_str += str(vrm.voltage)
157
+ vrm_str += ":"
158
+ vrm_str += vrm.power_net
159
+ vrm_str += ":"
160
+ vrm_str += vrm.reference_net
161
+ self._pedb.active_cell.SetProductProperty(
162
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_VRM_SETUP, vrm_str
163
+ )
164
+
165
+ # vrm_setup: Vrm = None
166
+
167
+
168
+ class SolverOptions:
169
+ """
170
+ A class to manage solver options for SIWave CPA simulations.
171
+
172
+ Attributes:
173
+ mode (str): The extraction mode, either "si" or "pi".
174
+ custom_refinement (bool): Whether custom refinement is enabled.
175
+ extraction_frequency (str): The frequency for extraction, e.g., "10Ghz".
176
+ compute_capacitance (bool): Whether to compute capacitance.
177
+ compute_dc_rl (bool): Whether to compute DC resistance and inductance.
178
+ compute_dc_parameters (bool): Whether to compute DC parameters.
179
+ compute_dc_cg (bool): Whether to compute DC capacitance and conductance.
180
+ compute_ac_rl (bool): Whether to compute AC resistance and inductance.
181
+ ground_power_nets_for_si (bool): Whether to ground power nets for SI analysis.
182
+ small_hole_diameter (float or str): The diameter of small holes, or "auto".
183
+ adaptive_refinement_cg_max_passes (int): Maximum passes for adaptive refinement of CG.
184
+ adaptive_refinement_rl_max_passes (int): Maximum passes for adaptive refinement of RL.
185
+ adaptive_refinement_cg_percent_error (float): Percent error for CG adaptive refinement.
186
+ adaptive_refinement_rl_percent_error (float): Percent error for RL adaptive refinement.
187
+ rl_percent_refinement_per_pass (float): Percent refinement per pass for RL.
188
+ cg_percent_refinement_per_pass (float): Percent refinement per pass for CG.
189
+ return_path_net_for_loop_parameters (bool): Whether to use return path net for loop parameters.
190
+
191
+ Methods:
192
+ __init__(pedb, cfg_solver_options=None): Initializes the SolverOptions object.
193
+ __init_values(): Initializes default values for solver options.
194
+ _apply_cfg_object(solver_options): Applies configuration from a given solver options object.
195
+ """
196
+
197
+ def __init__(self, pedb, cfg_solver_options=None):
198
+ self._pedb = pedb
199
+ self.__init_values()
200
+ if cfg_solver_options:
201
+ self._apply_cfg_object(cfg_solver_options)
202
+
203
+ def __init_values(
204
+ self,
205
+ ):
206
+ self.mode = "si"
207
+ self.custom_refinement = False
208
+ self.extraction_frequency = "10Ghz"
209
+ self.compute_capacitance = True
210
+ self.compute_dc_rl = True
211
+ self.compute_dc_parameters = True
212
+ self.compute_dc_cg = True
213
+ self.compute_ac_rl = True
214
+ self.ground_power_nets_for_si = True
215
+ self.small_hole_diameter = 0.0
216
+ self.adaptive_refinement_cg_max_passes = 10
217
+ self.adaptive_refinement_rl_max_passes = 10
218
+ self.adaptive_refinement_cg_percent_error = 0.02
219
+ self.adaptive_refinement_rl_percent_error = 0.02
220
+ self.rl_percent_refinement_per_pass = 0.33
221
+ self.cg_percent_refinement_per_pass = 0.33
222
+ self.return_path_net_for_loop_parameters = True
223
+
224
+ def _apply_cfg_object(self, solver_options):
225
+ self.extraction_mode = solver_options.extraction_mode
226
+ self.custom_refinement = solver_options.custom_refinement
227
+ self.extraction_frequency = solver_options.extraction_frequency
228
+ self.compute_capacitance = solver_options.compute_capacitance
229
+ self.compute_dc_parameters = solver_options.compute_dc_parameters
230
+ self.compute_dc_rl = solver_options.compute_dc_rl
231
+ self.compute_dc_cg = solver_options.compute_dc_cg
232
+ self.compute_ac_rl = solver_options.compute_ac_rl
233
+ self.ground_power_nets_for_si = solver_options.ground_power_ground_nets_for_si
234
+ self.small_hole_diameter = solver_options.small_hole_diameter
235
+ self.adaptive_refinement_cg_max_passes = solver_options.cg_max_passes
236
+ self.adaptive_refinement_rl_max_passes = solver_options.rl_max_passes
237
+ self.adaptive_refinement_cg_percent_error = solver_options.cg_percent_error
238
+ self.adaptive_refinement_rl_percent_error = solver_options.rl_percent_error
239
+ self.rl_percent_refinement_per_pass = solver_options.rl_percent_refinement_per_pass
240
+ self.return_path_net_for_loop_parameters = solver_options.return_path_net_for_loop_parameters
241
+
242
+ @property
243
+ def extraction_mode(self):
244
+ """
245
+ Get the extraction mode.
246
+
247
+ Returns:
248
+ str: The extraction mode ("si" or "pi").
249
+ """
250
+
251
+ mode = self._pedb.active_cell.GetProductProperty(
252
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_EXTRACTION_MODE
253
+ )
254
+ if mode == "1":
255
+ return "si"
256
+ return "pi"
257
+
258
+ @extraction_mode.setter
259
+ def extraction_mode(self, value):
260
+ if value == "si":
261
+ self._pedb.active_cell.SetProductProperty(
262
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_EXTRACTION_MODE, "1"
263
+ )
264
+ else:
265
+ self._pedb.active_cell.SetProductProperty(
266
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_EXTRACTION_MODE, "0"
267
+ )
268
+
269
+ @property
270
+ def custom_refinement(self):
271
+ """
272
+ Get whether custom refinement is enabled.
273
+
274
+ Returns:
275
+ bool: True if custom refinement is enabled, False otherwise.
276
+ """
277
+
278
+ refine = self._pedb.active_cell.GetProductProperty(
279
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CUSTOM_REFINEMENT
280
+ )[-1]
281
+ if refine == "1":
282
+ return True
283
+ return False
284
+
285
+ @custom_refinement.setter
286
+ def custom_refinement(self, value):
287
+ if value:
288
+ self._pedb.active_cell.SetProductProperty(
289
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CUSTOM_REFINEMENT, "1"
290
+ )
291
+ else:
292
+ self._pedb.active_cell.SetProductProperty(
293
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CUSTOM_REFINEMENT, "0"
294
+ )
295
+
296
+ @property
297
+ def extraction_frequency(self):
298
+ """
299
+ Get the extraction frequency.
300
+
301
+ Returns:
302
+ str: The extraction frequency.
303
+ """
304
+ return self._pedb.active_cell.GetProductProperty(
305
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_EXTRACTION_FREQUENCY
306
+ )[-1]
307
+
308
+ @extraction_frequency.setter
309
+ def extraction_frequency(self, value):
310
+ freq = self._pedb.edb_value(value).ToString()
311
+ self._pedb.active_cell.SetProductProperty(
312
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_EXTRACTION_FREQUENCY, freq
313
+ )
314
+
315
+ @property
316
+ def compute_capacitance(self):
317
+ """
318
+ Get whether capacitance computation is enabled.
319
+
320
+ Returns:
321
+ bool: True if enabled, False otherwise.
322
+ """
323
+
324
+ compute = self._pedb.active_cell.GetProductProperty(
325
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_COMPUTE_CAPACITANCE
326
+ )[-1]
327
+ if compute == "1":
328
+ return True
329
+ return False
330
+
331
+ @compute_capacitance.setter
332
+ def compute_capacitance(self, value):
333
+ if value:
334
+ self._pedb.active_cell.SetProductProperty(
335
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_COMPUTE_CAPACITANCE, "1"
336
+ )
337
+ else:
338
+ self._pedb.active_cell.SetProductProperty(
339
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_COMPUTE_CAPACITANCE, "0"
340
+ )
341
+
342
+ @property
343
+ def compute_dc_parameters(self):
344
+ """
345
+ Property setter for the `compute_dc_parameters` attribute.
346
+
347
+ Sets whether the computation of DC parameters is enabled in the SIWave properties.
348
+
349
+ Args:
350
+ value (bool): True to enable DC parameter computation, False to disable it.
351
+ """
352
+ compute = self._pedb.active_cell.GetProductProperty(
353
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_COMPUTE_DC_PARAMS
354
+ )[-1]
355
+ if compute == "1":
356
+ return True
357
+ return False
358
+
359
+ @compute_dc_parameters.setter
360
+ def compute_dc_parameters(self, value):
361
+ if value:
362
+ self._pedb.active_cell.SetProductProperty(
363
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_COMPUTE_DC_PARAMS, "1"
364
+ )
365
+ else:
366
+ self._pedb.active_cell.GetProductProperty(
367
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_COMPUTE_DC_PARAMS, "0"
368
+ )
369
+
370
+ @property
371
+ def compute_dc_rl(self):
372
+ """
373
+ Get whether DC resistance and inductance computation is enabled.
374
+
375
+ Returns:
376
+ bool: True if DC resistance and inductance computation is enabled, False otherwise.
377
+ """
378
+ _res = self._pedb.active_cell.GetProductProperty(
379
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL
380
+ )[-1]
381
+ if _res == "1":
382
+ return True
383
+ return False
384
+
385
+ @compute_dc_rl.setter
386
+ def compute_dc_rl(self, value):
387
+ if value:
388
+ self._pedb.active_cell.SetProductProperty(
389
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL, "1"
390
+ )
391
+ else:
392
+ self._pedb.active_cell.SetProductProperty(
393
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_RL, "0"
394
+ )
395
+
396
+ @property
397
+ def compute_dc_cg(self):
398
+ """
399
+ Get whether DC capacitance and conductance computation is enabled.
400
+
401
+ Returns:
402
+ bool: True if DC capacitance and conductance computation is enabled, False otherwise.
403
+ """
404
+ _res = self._pedb.active_cell.GetProductProperty(
405
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG
406
+ )[-1]
407
+ if _res == "1":
408
+ return True
409
+ return False
410
+
411
+ @compute_dc_cg.setter
412
+ def compute_dc_cg(self, value):
413
+ if value:
414
+ self._pedb.active_cell.SetProductProperty(
415
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG, "1"
416
+ )
417
+ else:
418
+ self._pedb.active_cell.SetProductProperty(
419
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_DC_PARAMS_COMPUTE_CG, "0"
420
+ )
421
+
422
+ @property
423
+ def compute_ac_rl(self):
424
+ """
425
+ Get whether AC resistance and inductance computation is enabled.
426
+
427
+ Returns:
428
+ bool: True if AC resistance and inductance computation is enabled, False otherwise.
429
+ """
430
+ _res = self._pedb.active_cell.GetProductProperty(
431
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL
432
+ )[-1]
433
+ if _res == "1":
434
+ return True
435
+ return False
436
+
437
+ @compute_ac_rl.setter
438
+ def compute_ac_rl(self, value):
439
+ if value:
440
+ self._pedb.active_cell.SetProductProperty(
441
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL, "1"
442
+ )
443
+ else:
444
+ self._pedb.active_cell.SetProductProperty(
445
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_AC_PARAMS_COMPUTE_RL, "0"
446
+ )
447
+
448
+ @property
449
+ def ground_power_nets_for_si(self):
450
+ """
451
+ Gets the ground power nets for SI analysis setting from the database.
452
+
453
+ Returns:
454
+ bool: True if grounding power nets for SI analysis is enabled, False otherwise.
455
+ """
456
+ _res = self._pedb.active_cell.GetProductProperty(
457
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI
458
+ )[-1]
459
+ if _res == "1":
460
+ return True
461
+ return False
462
+
463
+ @ground_power_nets_for_si.setter
464
+ def ground_power_nets_for_si(self, value):
465
+ if value:
466
+ self._pedb.active_cell.SetProductProperty(
467
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI, "1"
468
+ )
469
+ else:
470
+ self._pedb.active_cell.SetProductProperty(
471
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_GROUND_PG_NETS_FOR_SI, "0"
472
+ )
473
+
474
+ @property
475
+ def small_hole_diameter(self):
476
+ """
477
+ Gets the small hole diameter setting from the database.
478
+
479
+ Returns:
480
+ float|str: The small hole diameter as a float, or 'auto' if the value is set to -1.
481
+ """
482
+ _res = self._pedb.active_cell.GetProductProperty(
483
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER
484
+ )[-1]
485
+ if _res == "-1":
486
+ return "auto"
487
+ else:
488
+ return float(_res)
489
+
490
+ @small_hole_diameter.setter
491
+ def small_hole_diameter(self, value):
492
+ if value == "auto" or value == -1:
493
+ self._pedb.active_cell.SetProductProperty(
494
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_SMALL_HOLE_DIAMETER, "-1"
495
+ )
496
+ else:
497
+ self._pedb.active_cell.SetProductProperty(
498
+ self._pedb._edb.ProductId.SIWave,
499
+ SIwaveProperties.CPA_SMALL_HOLE_DIAMETER,
500
+ self._pedb.edb_value(value).ToString(),
501
+ )
502
+
503
+ @property
504
+ def model_type(self):
505
+ """
506
+ Gets the model type setting from the database.
507
+
508
+ Returns:
509
+ str: The model type. Returns "rlcg" if the model type is set to "0", otherwise "esd_r".
510
+ """
511
+ return self._pedb.active_cell.GetProductProperty(
512
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_MODEL_TYPE
513
+ )[-1]
514
+
515
+ @model_type.setter
516
+ def model_type(self, value):
517
+ self._pedb.active_cell.SetProductProperty(
518
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_MODEL_TYPE, value.lower()
519
+ )
520
+
521
+ @property
522
+ def adaptive_refinement_cg_max_passes(self):
523
+ """
524
+ Gets the maximum number of passes for CG adaptive refinement from the database.
525
+
526
+ Returns:
527
+ int: The maximum number of passes for CG adaptive refinement.
528
+ """
529
+ return int(
530
+ self._pedb.active_cell.GetProductProperty(
531
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_MAX_PASSES
532
+ )[-1]
533
+ )
534
+
535
+ @adaptive_refinement_cg_max_passes.setter
536
+ def adaptive_refinement_cg_max_passes(self, value):
537
+ self._pedb.active_cell.SetProductProperty(
538
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_MAX_PASSES, str(int(value))
539
+ )
540
+
541
+ @property
542
+ def adaptive_refinement_cg_percent_error(self):
543
+ """
544
+ Gets the target error percentage for CG adaptive refinement from the database.
545
+
546
+ Returns:
547
+ float: The target error percentage for CG adaptive refinement.
548
+ """
549
+ return float(
550
+ self._pedb.active_cell.GetProductProperty(
551
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_ERROR
552
+ )[-1]
553
+ )
554
+
555
+ @adaptive_refinement_cg_percent_error.setter
556
+ def adaptive_refinement_cg_percent_error(self, value):
557
+ self._pedb.active_cell.SetProductProperty(
558
+ self._pedb._edb.ProductId.SIWave,
559
+ SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_ERROR,
560
+ str(float(value)),
561
+ )
562
+
563
+ @property
564
+ def cg_percent_refinement_per_pass(self):
565
+ """
566
+ Gets the percentage of CG refinement per pass from the database.
567
+
568
+ Returns:
569
+ float: The percentage of CG refinement per pass.
570
+ """
571
+ return float(
572
+ self._pedb.active_cell.GetProductProperty(
573
+ self._pedb._edb.ProductId.SIWave,
574
+ SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_REFINEMENT_PER_PASS,
575
+ )[-1]
576
+ )
577
+
578
+ @cg_percent_refinement_per_pass.setter
579
+ def cg_percent_refinement_per_pass(self, value):
580
+ self._pedb.active_cell.SetProductProperty(
581
+ self._pedb._edb.ProductId.SIWave,
582
+ SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_CG_PERCENT_REFINEMENT_PER_PASS,
583
+ str(float(value)),
584
+ )
585
+
586
+ @property
587
+ def adaptive_refinement_rl_max_passes(self):
588
+ """
589
+ Gets the maximum number of passes for RL adaptive refinement from the database.
590
+
591
+ Returns:
592
+ int: The maximum number of passes for RL adaptive refinement.
593
+ """
594
+ return int(
595
+ float(
596
+ self._pedb.active_cell.GetProductProperty(
597
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_MAX_PASSES
598
+ )[-1]
599
+ )
600
+ )
601
+
602
+ @adaptive_refinement_rl_max_passes.setter
603
+ def adaptive_refinement_rl_max_passes(self, value):
604
+ self._pedb.active_cell.SetProductProperty(
605
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_MAX_PASSES, str(float(value))
606
+ )
607
+
608
+ @property
609
+ def adaptive_refinement_rl_percent_error(self):
610
+ """
611
+ Gets the target error percentage for RL adaptive refinement from the database.
612
+
613
+ Returns:
614
+ float: The target error percentage for RL adaptive refinement.
615
+ """
616
+ return float(
617
+ self._pedb.active_cell.GetProductProperty(
618
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_ERROR
619
+ )[-1]
620
+ )
621
+
622
+ @adaptive_refinement_rl_percent_error.setter
623
+ def adaptive_refinement_rl_percent_error(self, value):
624
+ self._pedb.active_cell.SetProductProperty(
625
+ self._pedb._edb.ProductId.SIWave,
626
+ SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_ERROR,
627
+ str(float(value)),
628
+ )
629
+
630
+ @property
631
+ def rl_percent_refinement_per_pass(self):
632
+ """
633
+ Gets the percentage of RL refinement per pass from the database.
634
+
635
+ Returns:
636
+ float: The percentage of RL refinement per pass.
637
+ """
638
+ return float(
639
+ self._pedb.active_cell.GetProductProperty(
640
+ self._pedb._edb.ProductId.SIWave,
641
+ SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_REFINEMENT_PER_PASS,
642
+ )[-1]
643
+ )
644
+
645
+ @rl_percent_refinement_per_pass.setter
646
+ def rl_percent_refinement_per_pass(self, value):
647
+ self._pedb.active_cell.SetProductProperty(
648
+ self._pedb._edb.ProductId.SIWave,
649
+ SIwaveProperties.CPA_ADAPTIVE_REFINEMENT_RL_PERCENT_REFINEMENT_PER_PASS,
650
+ str(float(value)),
651
+ )
652
+
653
+ @property
654
+ def return_path_net_for_loop_parameters(self):
655
+ """
656
+ Gets the return path net setting for loop parameters from the database.
657
+
658
+ Returns:
659
+ bool: True if the return path net is enabled for loop parameters, False otherwise.
660
+ """
661
+ _res = self._pedb.active_cell.GetProductProperty(
662
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS
663
+ )[-1]
664
+ if _res == "1":
665
+ return True
666
+ return False
667
+
668
+ @return_path_net_for_loop_parameters.setter
669
+ def return_path_net_for_loop_parameters(self, value):
670
+ if value:
671
+ self._pedb.active_cell.SetProductProperty(
672
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS, "1"
673
+ )
674
+ else:
675
+ self._pedb.active_cell.SetProductProperty(
676
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_RETURN_PATH_NET_FOR_LOOP_PARAMS, "0"
677
+ )
678
+
679
+
680
+ class SIWaveCPASimulationSetup:
681
+ """
682
+ Represents the setup configuration for SIwave CPA simulations.
683
+
684
+ Attributes:
685
+ _pedb: The database object representing the active cell.
686
+ _channel_setup (ChannelSetup): The channel setup configuration.
687
+ _solver_options (SolverOptions): The solver options configuration.
688
+ """
689
+
690
+ def __init__(self, pedb, name=None, siwave_cpa_setup_class=None):
691
+ self._pedb = pedb
692
+ self._channel_setup = ChannelSetup(pedb)
693
+ self._solver_options = SolverOptions(pedb)
694
+ if isinstance(siwave_cpa_setup_class, SIwaveCpaSetup):
695
+ self._apply_cfg_object(siwave_cpa_setup_class)
696
+ else:
697
+ self.__init_values()
698
+
699
+ if (
700
+ not self._pedb.active_cell.GetProductProperty(
701
+ self._pedb._edb.ProductId.SIWave,
702
+ SIwaveProperties.CPA_SIM_NAME,
703
+ )
704
+ == name
705
+ ):
706
+ self._pedb.active_cell.SetProductProperty(
707
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_SIM_NAME, name
708
+ )
709
+
710
+ def __init_values(self):
711
+ self.mode = "channel"
712
+ self.model_type = "rlcg"
713
+ self.use_q3d_solver = False
714
+ self.net_processing_mode = "all"
715
+
716
+ def _apply_cfg_object(self, siwave_cpa_setup_class):
717
+ if isinstance(siwave_cpa_setup_class, SIwaveCpaSetup):
718
+ self.name = siwave_cpa_setup_class.name
719
+ self.mode = siwave_cpa_setup_class.mode
720
+ self.nets_to_process = siwave_cpa_setup_class.nets_to_process
721
+ self.model_type = siwave_cpa_setup_class.model_type
722
+ self.use_q3d_solver = siwave_cpa_setup_class.use_q3d_solver
723
+ self.net_processing_mode = siwave_cpa_setup_class.net_processing_mode
724
+ self.channel_setup = ChannelSetup(self._pedb, siwave_cpa_setup_class.channel_setup)
725
+ self.solver_options = SolverOptions(self._pedb, siwave_cpa_setup_class.solver_options)
726
+
727
+ @property
728
+ def name(self) -> str:
729
+ """
730
+ Gets the name of the simulation setup.
731
+
732
+ Returns:
733
+ str: The name of the simulation setup.
734
+ """
735
+ return self._pedb.active_cell.GetProductProperty(
736
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_SIM_NAME
737
+ )[-1]
738
+
739
+ @name.setter
740
+ def name(self, value):
741
+ self._pedb.active_cell.SetProductProperty(
742
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_SIM_NAME, value
743
+ )
744
+
745
+ @property
746
+ def mode(self):
747
+ """
748
+ Gets the mode of the simulation setup.
749
+
750
+ Returns:
751
+ str: The mode of the simulation setup ("channel" or "no_channel").
752
+ """
753
+ cpa_mode = self._pedb.active_cell.GetProductProperty(
754
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_SETUP
755
+ )[-1]
756
+ if cpa_mode == "1":
757
+ return "channel"
758
+ return "no_channel"
759
+
760
+ @mode.setter
761
+ def mode(self, value):
762
+ if value == "channel":
763
+ self._pedb.active_cell.SetProductProperty(
764
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_SETUP, "1"
765
+ )
766
+ else:
767
+ self._pedb.active_cell.SetProductProperty(
768
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_CHANNEL_SETUP, "0"
769
+ )
770
+
771
+ @property
772
+ def model_type(self):
773
+ """
774
+ Gets the model type of the simulation setup.
775
+
776
+ Returns:
777
+ str: The model type ("rlcg" or "esd_r").
778
+ """
779
+ mod_type = self._pedb.active_cell.GetProductProperty(
780
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ESD_R_MODEL
781
+ )[-1]
782
+ if mod_type == "0":
783
+ return "rlcg"
784
+ else:
785
+ return "esd_r"
786
+
787
+ @model_type.setter
788
+ def model_type(self, value):
789
+ if value == "rlcg":
790
+ self._pedb.active_cell.SetProductProperty(
791
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ESD_R_MODEL, "0"
792
+ )
793
+ elif value == "esd_r":
794
+ self._pedb.active_cell.SetProductProperty(
795
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_ESD_R_MODEL, "1"
796
+ )
797
+
798
+ @property
799
+ def use_q3d_solver(self):
800
+ """
801
+ Gets the Q3D solver usage setting.
802
+
803
+ Returns:
804
+ bool: True if the Q3D solver is used, False otherwise.
805
+ """
806
+ return bool(
807
+ int(
808
+ self._pedb.active_cell.GetProductProperty(
809
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_USE_Q3D_SOLVER
810
+ )[-1]
811
+ )
812
+ )
813
+
814
+ @use_q3d_solver.setter
815
+ def use_q3d_solver(self, value):
816
+ if value:
817
+ self._pedb.active_cell.SetProductProperty(
818
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_USE_Q3D_SOLVER, "1"
819
+ )
820
+ else:
821
+ self._pedb.active_cell.SetProductProperty(
822
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_USE_Q3D_SOLVER, "0"
823
+ )
824
+
825
+ @property
826
+ def net_processing_mode(self):
827
+ """
828
+ Gets the net processing mode.
829
+
830
+ Returns:
831
+ str: The net processing mode.
832
+ """
833
+ return self._pedb.active_cell.GetProductProperty(
834
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_NET_PROCESSING_MODE
835
+ )[-1]
836
+
837
+ @net_processing_mode.setter
838
+ def net_processing_mode(self, value):
839
+ self._pedb.active_cell.SetProductProperty(
840
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_NET_PROCESSING_MODE, str(value)
841
+ )
842
+
843
+ @property
844
+ def channel_setup(self):
845
+ """
846
+ Gets the channel setup configuration.
847
+
848
+ Returns:
849
+ ChannelSetup: The channel setup configuration.
850
+ """
851
+ return self._channel_setup
852
+
853
+ @channel_setup.setter
854
+ def channel_setup(self, value):
855
+ if isinstance(value, ChannelSetup):
856
+ self._channel_setup = value
857
+
858
+ @property
859
+ def solver_options(self):
860
+ """
861
+ Gets the solver options configuration.
862
+
863
+ Returns:
864
+ SolverOptions: The solver options configuration.
865
+ """
866
+ return self._solver_options
867
+
868
+ @solver_options.setter
869
+ def solver_options(self, value):
870
+ if isinstance(value, SolverOptions):
871
+ self._solver_options = value
872
+
873
+ @property
874
+ def nets_to_process(self):
875
+ """
876
+ Gets the list of nets to process.
877
+
878
+ Returns:
879
+ list: A list of nets to process.
880
+ """
881
+ nets = self._pedb.active_cell.GetProductProperty(
882
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_NETS_TO_PROCESS
883
+ )[-1]
884
+ return nets.split("*")
885
+
886
+ @nets_to_process.setter
887
+ def nets_to_process(self, value):
888
+ if isinstance(value, list):
889
+ nets = "*".join(value)
890
+ self._pedb.active_cell.SetProductProperty(
891
+ self._pedb._edb.ProductId.SIWave, SIwaveProperties.CPA_NETS_TO_PROCESS, nets
892
+ )
893
+ else:
894
+ raise TypeError("nets_to_process must be a list of strings.")