pyedb 0.19.0__py3-none-any.whl → 0.20.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.

Files changed (40) hide show
  1. pyedb/__init__.py +1 -1
  2. pyedb/dotnet/edb.py +154 -235
  3. pyedb/dotnet/edb_core/cell/connectable.py +64 -0
  4. pyedb/dotnet/edb_core/cell/hierarchy/component.py +12 -10
  5. pyedb/dotnet/edb_core/cell/hierarchy/hierarchy_obj.py +1 -1
  6. pyedb/dotnet/edb_core/cell/layout.py +253 -105
  7. pyedb/dotnet/edb_core/cell/layout_obj.py +4 -49
  8. pyedb/dotnet/edb_core/cell/primitive.py +14 -2
  9. pyedb/dotnet/edb_core/cell/terminal/padstack_instance_terminal.py +1 -1
  10. pyedb/dotnet/edb_core/cell/terminal/point_terminal.py +1 -1
  11. pyedb/dotnet/edb_core/cell/terminal/terminal.py +1 -19
  12. pyedb/dotnet/edb_core/cell/voltage_regulator.py +2 -16
  13. pyedb/dotnet/edb_core/components.py +14 -13
  14. pyedb/dotnet/edb_core/dotnet/database.py +5 -10
  15. pyedb/dotnet/edb_core/dotnet/primitive.py +11 -1
  16. pyedb/dotnet/edb_core/edb_data/control_file.py +2 -12
  17. pyedb/dotnet/edb_core/edb_data/padstacks_data.py +20 -33
  18. pyedb/dotnet/edb_core/general.py +6 -9
  19. pyedb/dotnet/edb_core/hfss.py +4 -8
  20. pyedb/dotnet/edb_core/layout_obj_instance.py +30 -0
  21. pyedb/dotnet/edb_core/materials.py +4 -11
  22. pyedb/dotnet/edb_core/{layout.py → modeler.py} +153 -7
  23. pyedb/dotnet/edb_core/net_class.py +7 -8
  24. pyedb/dotnet/edb_core/nets.py +3 -9
  25. pyedb/dotnet/edb_core/padstack.py +13 -9
  26. pyedb/dotnet/edb_core/sim_setup_data/data/sweep_data.py +5 -2
  27. pyedb/dotnet/edb_core/siwave.py +5 -6
  28. pyedb/dotnet/edb_core/stackup.py +18 -23
  29. pyedb/dotnet/edb_core/utilities/simulation_setup.py +1 -4
  30. pyedb/generic/filesystem.py +2 -8
  31. pyedb/generic/general_methods.py +4 -10
  32. pyedb/generic/plot.py +26 -29
  33. pyedb/generic/process.py +2 -6
  34. pyedb/misc/downloads.py +3 -40
  35. pyedb/siwave.py +2 -5
  36. {pyedb-0.19.0.dist-info → pyedb-0.20.0.dist-info}/METADATA +2 -2
  37. {pyedb-0.19.0.dist-info → pyedb-0.20.0.dist-info}/RECORD +39 -38
  38. pyedb/dotnet/edb_core/dotnet/layout.py +0 -260
  39. {pyedb-0.19.0.dist-info → pyedb-0.20.0.dist-info}/LICENSE +0 -0
  40. {pyedb-0.19.0.dist-info → pyedb-0.20.0.dist-info}/WHEEL +0 -0
pyedb/__init__.py CHANGED
@@ -44,7 +44,7 @@ deprecation_warning()
44
44
  #
45
45
 
46
46
  pyedb_path = os.path.dirname(__file__)
47
- __version__ = "0.19.0"
47
+ __version__ = "0.20.0"
48
48
  version = __version__
49
49
 
50
50
  #
pyedb/dotnet/edb.py CHANGED
@@ -30,6 +30,7 @@ import os
30
30
  from pathlib import Path
31
31
  import re
32
32
  import shutil
33
+ import subprocess
33
34
  import sys
34
35
  import tempfile
35
36
  import time
@@ -37,21 +38,14 @@ import traceback
37
38
  from typing import Union
38
39
  import warnings
39
40
 
41
+ import rtree
42
+
40
43
  from pyedb.configuration.configuration import Configuration
41
44
  from pyedb.dotnet.application.Variables import decompose_variable_value
42
45
  from pyedb.dotnet.edb_core.cell.layout import Layout
43
- from pyedb.dotnet.edb_core.cell.terminal.bundle_terminal import BundleTerminal
44
- from pyedb.dotnet.edb_core.cell.terminal.edge_terminal import EdgeTerminal
45
- from pyedb.dotnet.edb_core.cell.terminal.padstack_instance_terminal import (
46
- PadstackInstanceTerminal,
47
- )
48
- from pyedb.dotnet.edb_core.cell.terminal.pingroup_terminal import PinGroupTerminal
49
- from pyedb.dotnet.edb_core.cell.terminal.point_terminal import PointTerminal
50
46
  from pyedb.dotnet.edb_core.cell.terminal.terminal import Terminal
51
- from pyedb.dotnet.edb_core.cell.voltage_regulator import VoltageRegulator
52
47
  from pyedb.dotnet.edb_core.components import Components
53
48
  from pyedb.dotnet.edb_core.dotnet.database import Database
54
- from pyedb.dotnet.edb_core.dotnet.layout import LayoutDotNet
55
49
  from pyedb.dotnet.edb_core.edb_data.control_file import (
56
50
  ControlFile,
57
51
  convert_technology_file,
@@ -82,6 +76,7 @@ from pyedb.dotnet.edb_core.general import (
82
76
  from pyedb.dotnet.edb_core.hfss import EdbHfss
83
77
  from pyedb.dotnet.edb_core.layout_validation import LayoutValidation
84
78
  from pyedb.dotnet.edb_core.materials import Materials
79
+ from pyedb.dotnet.edb_core.modeler import Modeler
85
80
  from pyedb.dotnet.edb_core.net_class import (
86
81
  EdbDifferentialPairs,
87
82
  EdbExtendedNets,
@@ -103,8 +98,6 @@ from pyedb.generic.constants import AEDT_UNITS, SolverType
103
98
  from pyedb.generic.general_methods import (
104
99
  generate_unique_name,
105
100
  get_string_version,
106
- inside_desktop,
107
- is_ironpython,
108
101
  is_linux,
109
102
  is_windows,
110
103
  )
@@ -114,13 +107,6 @@ from pyedb.ipc2581.ipc2581 import Ipc2581
114
107
  from pyedb.modeler.geometry_operators import GeometryOperators
115
108
  from pyedb.workflow import Workflow
116
109
 
117
- if is_linux and is_ironpython:
118
- import subprocessdotnet as subprocess
119
- else:
120
- import subprocess
121
-
122
- import rtree
123
-
124
110
 
125
111
  class Edb(Database):
126
112
  """Provides the EDB application interface.
@@ -235,9 +221,7 @@ class Edb(Database):
235
221
  if not isreadonly:
236
222
  self._check_remove_project_files(edbpath, remove_existing_aedt)
237
223
 
238
- if isaedtowned and (inside_desktop or settings.remote_rpc_session):
239
- self.open_edb_inside_aedt()
240
- elif edbpath[-3:] in ["brd", "mcm", "sip", "gds", "xml", "dxf", "tgz", "anf"]:
224
+ if edbpath[-3:] in ["brd", "mcm", "sip", "gds", "xml", "dxf", "tgz", "anf"]:
241
225
  self.edbpath = edbpath[:-4] + ".aedb"
242
226
  working_dir = os.path.dirname(edbpath)
243
227
  control_file = None
@@ -361,7 +345,7 @@ class Edb(Database):
361
345
  self._siwave = EdbSiwave(self)
362
346
  self._hfss = EdbHfss(self)
363
347
  self._nets = EdbNets(self)
364
- self._core_primitives = Layout(self, self._active_cell.GetLayout())
348
+ self._core_primitives = Modeler(self)
365
349
  self._stackup2 = self._stackup
366
350
  self._materials = Materials(self)
367
351
 
@@ -437,23 +421,10 @@ class Edb(Database):
437
421
 
438
422
  Returns
439
423
  -------
440
- Terminal dictionary : Dict[str, pyedb.dotnet.edb_core.edb_data.terminals.Terminal]
424
+ Dict
441
425
  """
442
426
 
443
- temp = {}
444
- for i in self.layout.terminals:
445
- terminal_type = i.ToString().split(".")[-1]
446
- if terminal_type == "PinGroupTerminal":
447
- temp[i.GetName()] = PinGroupTerminal(self, i)
448
- elif terminal_type == "PadstackInstanceTerminal":
449
- temp[i.GetName()] = PadstackInstanceTerminal(self, i)
450
- elif terminal_type == "EdgeTerminal":
451
- temp[i.GetName()] = EdgeTerminal(self, i)
452
- elif terminal_type == "BundleTerminal":
453
- temp[i.GetName()] = BundleTerminal(self, i)
454
- elif terminal_type == "PointTerminal":
455
- temp[i.GetName()] = PointTerminal(self, i)
456
- return temp
427
+ return {i.name: i for i in self.layout.terminals}
457
428
 
458
429
  @property
459
430
  def excitations(self):
@@ -516,7 +487,7 @@ class Edb(Database):
516
487
  @property
517
488
  def voltage_regulator_modules(self):
518
489
  """Get all voltage regulator modules"""
519
- vrms = [VoltageRegulator(self, edb_object) for edb_object in list(self.active_layout.VoltageRegulators)]
490
+ vrms = self.layout.voltage_regulators
520
491
  _vrms = {}
521
492
  for vrm in vrms:
522
493
  _vrms[vrm.name] = vrm
@@ -574,40 +545,6 @@ class Edb(Database):
574
545
 
575
546
  return True
576
547
 
577
- def open_edb_inside_aedt(self):
578
- """Open EDB inside AEDT.
579
-
580
- Returns
581
- -------
582
- ``True`` when succeed ``False`` if failed : bool
583
-
584
- """
585
- self.logger.info("Opening EDB from HDL")
586
- self.run_as_standalone(False)
587
- if self.oproject.GetEDBHandle():
588
- self.attach(self.oproject.GetEDBHandle())
589
- if not self.active_db:
590
- self.logger.warning("Error getting the database.")
591
- self._active_cell = None
592
- return None
593
- self._active_cell = self.edb_api.cell.cell.FindByName(
594
- self.active_db,
595
- self.edb_api.cell._cell.CellType.CircuitCell,
596
- self.cellname,
597
- )
598
- if self._active_cell is None:
599
- self._active_cell = list(self.top_circuit_cells)[0]
600
- if self._active_cell:
601
- if not os.path.exists(self.edbpath):
602
- os.makedirs(self.edbpath)
603
- self._init_objects()
604
- return True
605
- else:
606
- return None
607
- else:
608
- self._active_cell = None
609
- return None
610
-
611
548
  def create_edb(self):
612
549
  """Create EDB.
613
550
 
@@ -1153,7 +1090,7 @@ class Edb(Database):
1153
1090
  >>> top_prims = edbapp.modeler.primitives_by_layer["TOP"]
1154
1091
  """
1155
1092
  if not self._core_primitives and self.active_db:
1156
- self._core_primitives = Layout(self, self._active_cell.GetLayout())
1093
+ self._core_primitives = Modeler(self)
1157
1094
  return self._core_primitives
1158
1095
 
1159
1096
  @property
@@ -1164,7 +1101,7 @@ class Edb(Database):
1164
1101
  -------
1165
1102
  :class:`legacy.edb_core.dotnet.layout.Layout`
1166
1103
  """
1167
- return LayoutDotNet(self)
1104
+ return Layout(self, self._active_cell.GetLayout())
1168
1105
 
1169
1106
  @property
1170
1107
  def active_layout(self):
@@ -1174,12 +1111,12 @@ class Edb(Database):
1174
1111
  -------
1175
1112
  Instance of EDB API Layout Class.
1176
1113
  """
1177
- return self.layout._layout
1114
+ return self.layout._edb_object
1178
1115
 
1179
1116
  @property
1180
1117
  def layout_instance(self):
1181
1118
  """Edb Layout Instance."""
1182
- return self.layout.layout_instance
1119
+ return self.layout._edb_object.GetLayoutInstance()
1183
1120
 
1184
1121
  def get_connected_objects(self, layout_object_instance):
1185
1122
  """Get connected objects.
@@ -2218,9 +2155,6 @@ class Edb(Database):
2218
2155
  keep_lines_as_path=False,
2219
2156
  inlcude_voids_in_extents=False,
2220
2157
  ):
2221
- if is_ironpython: # pragma: no cover
2222
- self.logger.error("Method working only in Cpython")
2223
- return False
2224
2158
  from concurrent.futures import ThreadPoolExecutor
2225
2159
 
2226
2160
  if output_aedb_path:
@@ -2750,20 +2684,12 @@ class Edb(Database):
2750
2684
 
2751
2685
  for void_circle in voids_to_add:
2752
2686
  if void_circle.type == "Circle":
2753
- if is_ironpython: # pragma: no cover
2754
- (
2755
- res,
2756
- center_x,
2757
- center_y,
2758
- radius,
2759
- ) = void_circle.primitive_object.GetParameters()
2760
- else:
2761
- (
2762
- res,
2763
- center_x,
2764
- center_y,
2765
- radius,
2766
- ) = void_circle.primitive_object.GetParameters(0.0, 0.0, 0.0)
2687
+ (
2688
+ res,
2689
+ center_x,
2690
+ center_y,
2691
+ radius,
2692
+ ) = void_circle.primitive_object.GetParameters(0.0, 0.0, 0.0)
2767
2693
  cloned_circle = self.edb_api.cell.primitive.circle.create(
2768
2694
  layout,
2769
2695
  void_circle.layer_name,
@@ -3344,163 +3270,156 @@ class Edb(Database):
3344
3270
  legacy_name = self.edbpath
3345
3271
  if simulation_setup.output_aedb:
3346
3272
  self.save_edb_as(simulation_setup.output_aedb)
3347
- try:
3348
- if simulation_setup.signal_layer_etching_instances:
3349
- for layer in simulation_setup.signal_layer_etching_instances:
3350
- if layer in self.stackup.layers:
3351
- idx = simulation_setup.signal_layer_etching_instances.index(layer)
3352
- if len(simulation_setup.etching_factor_instances) > idx:
3353
- self.stackup[layer].etch_factor = float(simulation_setup.etching_factor_instances[idx])
3354
-
3355
- if not simulation_setup.signal_nets and simulation_setup.components:
3356
- nets_to_include = []
3357
- pnets = list(self.nets.power.keys())[:]
3358
- for el in simulation_setup.components:
3359
- nets_to_include.append([i for i in self.components[el].nets if i not in pnets])
3360
- simulation_setup.signal_nets = [
3361
- i
3362
- for i in list(set.intersection(*map(set, nets_to_include)))
3363
- if i not in simulation_setup.power_nets and i != ""
3364
- ]
3365
- self.nets.classify_nets(simulation_setup.power_nets, simulation_setup.signal_nets)
3366
- if not simulation_setup.power_nets or not simulation_setup.signal_nets:
3367
- self.logger.info("Disabling cutout as no signals or power nets have been defined.")
3368
- simulation_setup.do_cutout_subdesign = False
3369
- if simulation_setup.do_cutout_subdesign:
3370
- self.logger.info("Cutting out using method: {0}".format(simulation_setup.cutout_subdesign_type))
3371
- if simulation_setup.use_default_cutout:
3372
- old_cell_name = self.active_cell.GetName()
3373
- if self.cutout(
3374
- signal_list=simulation_setup.signal_nets,
3375
- reference_list=simulation_setup.power_nets,
3376
- expansion_size=simulation_setup.cutout_subdesign_expansion,
3377
- use_round_corner=simulation_setup.cutout_subdesign_round_corner,
3378
- extent_type=simulation_setup.cutout_subdesign_type,
3379
- use_pyaedt_cutout=False,
3380
- use_pyaedt_extent_computing=False,
3381
- ):
3382
- self.logger.info("Cutout processed.")
3383
- old_cell = self.active_cell.FindByName(
3384
- self.db,
3385
- self.edb_api.cell.CellType.CircuitCell,
3386
- old_cell_name,
3387
- )
3388
- if old_cell:
3389
- old_cell.Delete()
3390
- else: # pragma: no cover
3391
- self.logger.error("Cutout failed.")
3392
- else:
3393
- self.logger.info("Cutting out using method: {0}".format(simulation_setup.cutout_subdesign_type))
3394
- self.cutout(
3395
- signal_list=simulation_setup.signal_nets,
3396
- reference_list=simulation_setup.power_nets,
3397
- expansion_size=simulation_setup.cutout_subdesign_expansion,
3398
- use_round_corner=simulation_setup.cutout_subdesign_round_corner,
3399
- extent_type=simulation_setup.cutout_subdesign_type,
3400
- use_pyaedt_cutout=True,
3401
- use_pyaedt_extent_computing=True,
3402
- remove_single_pin_components=True,
3403
- )
3273
+ if simulation_setup.signal_layer_etching_instances:
3274
+ for layer in simulation_setup.signal_layer_etching_instances:
3275
+ if layer in self.stackup.layers:
3276
+ idx = simulation_setup.signal_layer_etching_instances.index(layer)
3277
+ if len(simulation_setup.etching_factor_instances) > idx:
3278
+ self.stackup[layer].etch_factor = float(simulation_setup.etching_factor_instances[idx])
3279
+
3280
+ if not simulation_setup.signal_nets and simulation_setup.components:
3281
+ nets_to_include = []
3282
+ pnets = list(self.nets.power.keys())[:]
3283
+ for el in simulation_setup.components:
3284
+ nets_to_include.append([i for i in self.components[el].nets if i not in pnets])
3285
+ simulation_setup.signal_nets = [
3286
+ i
3287
+ for i in list(set.intersection(*map(set, nets_to_include)))
3288
+ if i not in simulation_setup.power_nets and i != ""
3289
+ ]
3290
+ self.nets.classify_nets(simulation_setup.power_nets, simulation_setup.signal_nets)
3291
+ if not simulation_setup.power_nets or not simulation_setup.signal_nets:
3292
+ self.logger.info("Disabling cutout as no signals or power nets have been defined.")
3293
+ simulation_setup.do_cutout_subdesign = False
3294
+ if simulation_setup.do_cutout_subdesign:
3295
+ self.logger.info("Cutting out using method: {0}".format(simulation_setup.cutout_subdesign_type))
3296
+ if simulation_setup.use_default_cutout:
3297
+ old_cell_name = self.active_cell.GetName()
3298
+ if self.cutout(
3299
+ signal_list=simulation_setup.signal_nets,
3300
+ reference_list=simulation_setup.power_nets,
3301
+ expansion_size=simulation_setup.cutout_subdesign_expansion,
3302
+ use_round_corner=simulation_setup.cutout_subdesign_round_corner,
3303
+ extent_type=simulation_setup.cutout_subdesign_type,
3304
+ use_pyaedt_cutout=False,
3305
+ use_pyaedt_extent_computing=False,
3306
+ ):
3404
3307
  self.logger.info("Cutout processed.")
3308
+ old_cell = self.active_cell.FindByName(
3309
+ self.db,
3310
+ self.edb_api.cell.CellType.CircuitCell,
3311
+ old_cell_name,
3312
+ )
3313
+ if old_cell:
3314
+ old_cell.Delete()
3315
+ else: # pragma: no cover
3316
+ self.logger.error("Cutout failed.")
3405
3317
  else:
3406
- if simulation_setup.include_only_selected_nets:
3407
- included_nets = simulation_setup.signal_nets + simulation_setup.power_nets
3408
- nets_to_remove = [
3409
- net.name for net in list(self.nets.nets.values()) if not net.name in included_nets
3410
- ]
3411
- self.nets.delete(nets_to_remove)
3412
- self.logger.info("Deleting existing ports.")
3413
- map(lambda port: port.Delete(), self.layout.terminals)
3414
- map(lambda pg: pg.Delete(), self.layout.pin_groups)
3415
- if simulation_setup.solver_type == SolverType.Hfss3dLayout:
3416
- if simulation_setup.generate_excitations:
3417
- self.logger.info("Creating HFSS ports for signal nets.")
3418
- source_type = SourceType.CoaxPort
3419
- if not simulation_setup.generate_solder_balls:
3420
- source_type = SourceType.CircPort
3421
- for cmp in simulation_setup.components:
3422
- if isinstance(cmp, str): # keep legacy component
3318
+ self.logger.info("Cutting out using method: {0}".format(simulation_setup.cutout_subdesign_type))
3319
+ self.cutout(
3320
+ signal_list=simulation_setup.signal_nets,
3321
+ reference_list=simulation_setup.power_nets,
3322
+ expansion_size=simulation_setup.cutout_subdesign_expansion,
3323
+ use_round_corner=simulation_setup.cutout_subdesign_round_corner,
3324
+ extent_type=simulation_setup.cutout_subdesign_type,
3325
+ use_pyaedt_cutout=True,
3326
+ use_pyaedt_extent_computing=True,
3327
+ remove_single_pin_components=True,
3328
+ )
3329
+ self.logger.info("Cutout processed.")
3330
+ else:
3331
+ if simulation_setup.include_only_selected_nets:
3332
+ included_nets = simulation_setup.signal_nets + simulation_setup.power_nets
3333
+ nets_to_remove = [net.name for net in list(self.nets.nets.values()) if not net.name in included_nets]
3334
+ self.nets.delete(nets_to_remove)
3335
+ self.logger.info("Deleting existing ports.")
3336
+ map(lambda port: port.Delete(), self.layout.terminals)
3337
+ map(lambda pg: pg.Delete(), self.layout.pin_groups)
3338
+ if simulation_setup.solver_type == SolverType.Hfss3dLayout:
3339
+ if simulation_setup.generate_excitations:
3340
+ self.logger.info("Creating HFSS ports for signal nets.")
3341
+ source_type = SourceType.CoaxPort
3342
+ if not simulation_setup.generate_solder_balls:
3343
+ source_type = SourceType.CircPort
3344
+ for cmp in simulation_setup.components:
3345
+ if isinstance(cmp, str): # keep legacy component
3346
+ self.components.create_port_on_component(
3347
+ cmp,
3348
+ net_list=simulation_setup.signal_nets,
3349
+ do_pingroup=False,
3350
+ reference_net=simulation_setup.power_nets,
3351
+ port_type=source_type,
3352
+ )
3353
+ elif isinstance(cmp, dict):
3354
+ if "refdes" in cmp:
3355
+ if not "solder_balls_height" in cmp: # pragma no cover
3356
+ cmp["solder_balls_height"] = None
3357
+ if not "solder_balls_size" in cmp: # pragma no cover
3358
+ cmp["solder_balls_size"] = None
3359
+ cmp["solder_balls_mid_size"] = None
3360
+ if not "solder_balls_mid_size" in cmp: # pragma no cover
3361
+ cmp["solder_balls_mid_size"] = None
3423
3362
  self.components.create_port_on_component(
3424
- cmp,
3363
+ cmp["refdes"],
3425
3364
  net_list=simulation_setup.signal_nets,
3426
3365
  do_pingroup=False,
3427
3366
  reference_net=simulation_setup.power_nets,
3428
3367
  port_type=source_type,
3368
+ solder_balls_height=cmp["solder_balls_height"],
3369
+ solder_balls_size=cmp["solder_balls_size"],
3370
+ solder_balls_mid_size=cmp["solder_balls_mid_size"],
3429
3371
  )
3430
- elif isinstance(cmp, dict):
3431
- if "refdes" in cmp:
3432
- if not "solder_balls_height" in cmp: # pragma no cover
3433
- cmp["solder_balls_height"] = None
3434
- if not "solder_balls_size" in cmp: # pragma no cover
3435
- cmp["solder_balls_size"] = None
3436
- cmp["solder_balls_mid_size"] = None
3437
- if not "solder_balls_mid_size" in cmp: # pragma no cover
3438
- cmp["solder_balls_mid_size"] = None
3439
- self.components.create_port_on_component(
3440
- cmp["refdes"],
3441
- net_list=simulation_setup.signal_nets,
3442
- do_pingroup=False,
3443
- reference_net=simulation_setup.power_nets,
3444
- port_type=source_type,
3445
- solder_balls_height=cmp["solder_balls_height"],
3446
- solder_balls_size=cmp["solder_balls_size"],
3447
- solder_balls_mid_size=cmp["solder_balls_mid_size"],
3448
- )
3449
- if simulation_setup.generate_solder_balls and not self.hfss.set_coax_port_attributes(
3450
- simulation_setup
3451
- ): # pragma: no cover
3452
- self.logger.error("Failed to configure coaxial port attributes.")
3453
- self.logger.info("Number of ports: {}".format(self.hfss.get_ports_number()))
3454
- self.logger.info("Configure HFSS extents.")
3455
- if (
3456
- simulation_setup.generate_solder_balls and simulation_setup.trim_reference_size
3457
- ): # pragma: no cover
3458
- self.logger.info(
3459
- "Trimming the reference plane for coaxial ports: {0}".format(
3460
- bool(simulation_setup.trim_reference_size)
3461
- )
3372
+ if simulation_setup.generate_solder_balls and not self.hfss.set_coax_port_attributes(
3373
+ simulation_setup
3374
+ ): # pragma: no cover
3375
+ self.logger.error("Failed to configure coaxial port attributes.")
3376
+ self.logger.info("Number of ports: {}".format(self.hfss.get_ports_number()))
3377
+ self.logger.info("Configure HFSS extents.")
3378
+ if simulation_setup.generate_solder_balls and simulation_setup.trim_reference_size: # pragma: no cover
3379
+ self.logger.info(
3380
+ "Trimming the reference plane for coaxial ports: {0}".format(
3381
+ bool(simulation_setup.trim_reference_size)
3382
+ )
3383
+ )
3384
+ self.hfss.trim_component_reference_size(simulation_setup) # pragma: no cover
3385
+ self.hfss.configure_hfss_extents(simulation_setup)
3386
+ if not self.hfss.configure_hfss_analysis_setup(simulation_setup):
3387
+ self.logger.error("Failed to configure HFSS simulation setup.")
3388
+ if simulation_setup.solver_type == SolverType.SiwaveSYZ:
3389
+ if simulation_setup.generate_excitations:
3390
+ for cmp in simulation_setup.components:
3391
+ if isinstance(cmp, str): # keep legacy
3392
+ self.components.create_port_on_component(
3393
+ cmp,
3394
+ net_list=simulation_setup.signal_nets,
3395
+ do_pingroup=simulation_setup.do_pingroup,
3396
+ reference_net=simulation_setup.power_nets,
3397
+ port_type=SourceType.CircPort,
3462
3398
  )
3463
- self.hfss.trim_component_reference_size(simulation_setup) # pragma: no cover
3464
- self.hfss.configure_hfss_extents(simulation_setup)
3465
- if not self.hfss.configure_hfss_analysis_setup(simulation_setup):
3466
- self.logger.error("Failed to configure HFSS simulation setup.")
3467
- if simulation_setup.solver_type == SolverType.SiwaveSYZ:
3468
- if simulation_setup.generate_excitations:
3469
- for cmp in simulation_setup.components:
3470
- if isinstance(cmp, str): # keep legacy
3399
+ elif isinstance(cmp, dict):
3400
+ if "refdes" in cmp: # pragma no cover
3471
3401
  self.components.create_port_on_component(
3472
- cmp,
3402
+ cmp["refdes"],
3473
3403
  net_list=simulation_setup.signal_nets,
3474
3404
  do_pingroup=simulation_setup.do_pingroup,
3475
3405
  reference_net=simulation_setup.power_nets,
3476
3406
  port_type=SourceType.CircPort,
3477
3407
  )
3478
- elif isinstance(cmp, dict):
3479
- if "refdes" in cmp: # pragma no cover
3480
- self.components.create_port_on_component(
3481
- cmp["refdes"],
3482
- net_list=simulation_setup.signal_nets,
3483
- do_pingroup=simulation_setup.do_pingroup,
3484
- reference_net=simulation_setup.power_nets,
3485
- port_type=SourceType.CircPort,
3486
- )
3487
- self.logger.info("Configuring analysis setup.")
3488
- if not self.siwave.configure_siw_analysis_setup(simulation_setup): # pragma: no cover
3489
- self.logger.error("Failed to configure Siwave simulation setup.")
3490
- if simulation_setup.solver_type == SolverType.SiwaveDC:
3491
- if simulation_setup.generate_excitations:
3492
- self.components.create_source_on_component(simulation_setup.sources)
3493
- if not self.siwave.configure_siw_analysis_setup(simulation_setup): # pragma: no cover
3494
- self.logger.error("Failed to configure Siwave simulation setup.")
3495
- self.padstacks.check_and_fix_via_plating()
3496
- self.save_edb()
3497
- if not simulation_setup.open_edb_after_build and simulation_setup.output_aedb:
3498
- self.close_edb()
3499
- self.edbpath = legacy_name
3500
- self.open_edb()
3501
- return True
3502
- except:
3503
- return False
3408
+ self.logger.info("Configuring analysis setup.")
3409
+ if not self.siwave.configure_siw_analysis_setup(simulation_setup): # pragma: no cover
3410
+ self.logger.error("Failed to configure Siwave simulation setup.")
3411
+ if simulation_setup.solver_type == SolverType.SiwaveDC:
3412
+ if simulation_setup.generate_excitations:
3413
+ self.components.create_source_on_component(simulation_setup.sources)
3414
+ if not self.siwave.configure_siw_analysis_setup(simulation_setup): # pragma: no cover
3415
+ self.logger.error("Failed to configure Siwave simulation setup.")
3416
+ self.padstacks.check_and_fix_via_plating()
3417
+ self.save_edb()
3418
+ if not simulation_setup.open_edb_after_build and simulation_setup.output_aedb:
3419
+ self.close_edb()
3420
+ self.edbpath = legacy_name
3421
+ self.open_edb()
3422
+ return True
3504
3423
 
3505
3424
  def get_statistics(self, compute_area=False):
3506
3425
  """Get the EDBStatistics object.
@@ -0,0 +1,64 @@
1
+ # Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
2
+ # SPDX-License-Identifier: MIT
3
+ #
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ from pyedb.dotnet.edb_core.cell.layout_obj import LayoutObj
24
+
25
+
26
+ class Connectable(LayoutObj):
27
+ """Manages EDB functionalities for a connectable object."""
28
+
29
+ def __init__(self, pedb, edb_object):
30
+ super().__init__(pedb, edb_object)
31
+
32
+ @property
33
+ def net(self):
34
+ """Net Object.
35
+
36
+ Returns
37
+ -------
38
+ :class:`pyedb.dotnet.edb_core.edb_data.nets_data.EDBNetsData`
39
+ """
40
+ from pyedb.dotnet.edb_core.edb_data.nets_data import EDBNetsData
41
+
42
+ return EDBNetsData(self._edb_object.GetNet(), self._pedb)
43
+
44
+ @net.setter
45
+ def net(self, value):
46
+ """Set net."""
47
+ net = self._pedb.nets[value]
48
+ self._edb_object.SetNet(net.net_object)
49
+
50
+ @property
51
+ def component(self):
52
+ """Component connected to this object.
53
+
54
+ Returns
55
+ -------
56
+ :class:`dotnet.edb_core.edb_data.nets_data.EDBComponent`
57
+ """
58
+ from pyedb.dotnet.edb_core.cell.hierarchy.component import EDBComponent
59
+
60
+ edb_comp = self._edb_object.GetComponent()
61
+ if edb_comp.IsNull():
62
+ return None
63
+ else:
64
+ return EDBComponent(self._pedb, edb_comp)
@@ -32,16 +32,14 @@ from pyedb.dotnet.edb_core.cell.hierarchy.s_parameter_model import SparamModel
32
32
  from pyedb.dotnet.edb_core.cell.hierarchy.spice_model import SpiceModel
33
33
  from pyedb.dotnet.edb_core.definition.package_def import PackageDef
34
34
  from pyedb.dotnet.edb_core.edb_data.padstacks_data import EDBPadstackInstance
35
- from pyedb.generic.general_methods import is_ironpython
36
-
37
- if not is_ironpython:
38
- try:
39
- import numpy as np
40
- except ImportError:
41
- warnings.warn(
42
- "The NumPy module is required to run some functionalities of EDB.\n"
43
- "Install with \n\npip install numpy\n\nRequires CPython."
44
- )
35
+
36
+ try:
37
+ import numpy as np
38
+ except ImportError:
39
+ warnings.warn(
40
+ "The NumPy module is required to run some functionalities of EDB.\n"
41
+ "Install with \n\npip install numpy\n\nRequires CPython."
42
+ )
45
43
  from pyedb.generic.general_methods import get_filename_without_extension
46
44
 
47
45
 
@@ -63,6 +61,10 @@ class EDBComponent(Group):
63
61
  self._layout_instance = None
64
62
  self._comp_instance = None
65
63
 
64
+ @property
65
+ def group_type(self):
66
+ return self._edb_object.ToString().split(".")[-1].lower()
67
+
66
68
  @property
67
69
  def layout_instance(self):
68
70
  """EDB layout instance object."""
@@ -22,7 +22,7 @@
22
22
 
23
23
  import logging
24
24
 
25
- from pyedb.dotnet.edb_core.cell.layout_obj import Connectable
25
+ from pyedb.dotnet.edb_core.cell.connectable import Connectable
26
26
 
27
27
 
28
28
  class HierarchyObj(Connectable):