Skip to content

Commit

Permalink
terminal enhancement (#3795)
Browse files Browse the repository at this point in the history
* fix

* fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix

* fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update pyaedt/edb_core/edb_data/terminals.py

Co-authored-by: Samuel Lopez <[email protected]>

* Update pyaedt/edb_core/edb_data/terminals.py

Co-authored-by: Samuel Lopez <[email protected]>

* fix

---------

Co-authored-by: ring630 <@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Samuel Lopez <[email protected]>
  • Loading branch information
3 people authored Oct 26, 2023
1 parent bb3830c commit 7eae896
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 37 deletions.
11 changes: 11 additions & 0 deletions _unittest/test_00_EDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,15 @@ def test_042_create_current_source(self):
self.edbapp.siwave.create_pin_group(reference_designator="U1", pin_numbers=["A14", "A15"], group_name="vp_neg")
assert self.edbapp.siwave.create_voltage_probe_on_pin_group("vprobe", "vp_pos", "vp_neg")
assert self.edbapp.probes["vprobe"]
self.edbapp.siwave.place_voltage_probe(
"vprobe_2", "1V0", ["112mm", "24mm"], "1_Top", "GND", ["112mm", "27mm"], "Inner1(GND1)"
)
vprobe_2 = self.edbapp.probes["vprobe_2"]
ref_term = vprobe_2.ref_terminal
assert isinstance(ref_term.location, list)
ref_term.location = [0, 0]
assert ref_term.layer
ref_term.layer = "1_Top"

def test_043_create_dc_terminal(self):
assert self.edbapp.siwave.create_dc_terminal("U1", "DDR4_DQ40", "dc_terminal1") == "dc_terminal1"
Expand Down Expand Up @@ -1602,6 +1611,8 @@ def test_120_edb_create_port(self):
port_ver = edb.ports["port_ver"]
assert not port_ver.is_null
assert port_ver.hfss_type == "Gap"
port_hori = edb.ports["port_hori"]
assert port_hori.ref_terminal

args = {
"layer_name": "1_Top",
Expand Down
13 changes: 10 additions & 3 deletions pyaedt/edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from pyaedt.edb_core.edb_data.hfss_simulation_setup_data import HfssSimulationSetup
from pyaedt.edb_core.edb_data.ports import BundleWavePort
from pyaedt.edb_core.edb_data.ports import CoaxPort
from pyaedt.edb_core.edb_data.ports import ExcitationProbes
from pyaedt.edb_core.edb_data.ports import ExcitationSources
from pyaedt.edb_core.edb_data.ports import GapPort
from pyaedt.edb_core.edb_data.ports import WavePort
Expand All @@ -35,8 +34,10 @@
from pyaedt.edb_core.edb_data.terminals import BundleTerminal
from pyaedt.edb_core.edb_data.terminals import EdgeTerminal
from pyaedt.edb_core.edb_data.terminals import PadstackInstanceTerminal
from pyaedt.edb_core.edb_data.terminals import PinGroupTerminal
from pyaedt.edb_core.edb_data.terminals import Terminal
from pyaedt.edb_core.edb_data.variables import Variable
from pyaedt.edb_core.general import BoundaryType
from pyaedt.edb_core.general import LayoutObjType
from pyaedt.edb_core.general import Primitives
from pyaedt.edb_core.general import TerminalType
Expand Down Expand Up @@ -364,6 +365,8 @@ def terminals(self):
ter = BundleTerminal(self, i)
elif terminal_type == TerminalType.PadstackInstanceTerminal.name:
ter = PadstackInstanceTerminal(self, i)
elif terminal_type == TerminalType.PinGroupTerminal.name:
ter = PinGroupTerminal(self, i)
else:
ter = Terminal(self, i)
temp[ter.name] = ter
Expand Down Expand Up @@ -424,8 +427,12 @@ def sources(self):
@property
def probes(self):
"""Get all layout sources."""
terms = [term for term in self.layout.terminals if int(term.GetBoundaryType()) in [8]]
return {ter.GetName(): ExcitationProbes(self, ter) for ter in terms}
temp = {}
for name, val in self.terminals.items():
if val.boundary_type == BoundaryType.kVoltageProbe.name:
if not val.is_reference_terminal:
temp[name] = val
return temp

@pyaedt_function_handler()
def open_edb(self):
Expand Down
4 changes: 2 additions & 2 deletions pyaedt/edb_core/edb_data/obj_base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
class ObjBase(object):
"""Manages EDB functionalities for a base object."""

def __init__(self, pedb, model):
def __init__(self, pedb, edb_object):
self._pedb = pedb
self._edb_object = model
self._edb_object = edb_object

@property
def is_null(self):
Expand Down
24 changes: 0 additions & 24 deletions pyaedt/edb_core/edb_data/ports.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,30 +176,6 @@ def phase(self, value):
self._edb_object.SetSourcePhase(self._edb.utility.value(value))


class ExcitationProbes(Terminal):
"""Manage probes properties.
Parameters
----------
pedb : pyaedt.edb.Edb
Edb object from Edblib.
edb_terminal : Ansys.Ansoft.Edb.Cell.Terminal.EdgeTerminal
Edge terminal instance from Edb.
Examples
--------
This example shows how to access this class.
>>> from pyaedt import Edb
>>> edb = Edb("myaedb.aedb")
>>> probes = edb.probes
>>> print(probes["Probe1"].name)
"""

def __init__(self, pedb, edb_terminal):
Terminal.__init__(self, pedb, edb_terminal)


class BundleWavePort(BundleTerminal):
"""Manages bundle wave port properties.
Expand Down
118 changes: 112 additions & 6 deletions pyaedt/edb_core/edb_data/terminals.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pyaedt.edb_core.edb_data.connectable import Connectable
from pyaedt.edb_core.edb_data.padstacks_data import EDBPadstackInstance
from pyaedt.edb_core.edb_data.primitives_data import cast
from pyaedt.edb_core.general import BoundaryType
from pyaedt.edb_core.general import TerminalType
from pyaedt.edb_core.general import convert_py_list_to_net_list
from pyaedt.generic.general_methods import generate_unique_name
Expand Down Expand Up @@ -135,7 +136,17 @@ def boundary_type(self):
-------
int
"""
return self._edb_object.GetBoundaryType()
return self._edb_object.GetBoundaryType().ToString()

@boundary_type.setter
def boundary_type(self, value):
if not value in [i.name for i in BoundaryType]: # pragma : no cover
self._pedb.logger.warning("Invalid Boundary Type={}".format(value))
if value == self._pedb.edb_api.cell.terminal.BoundaryType.kVoltageProbe.ToString():
temp = self._pedb.edb_api.cell.terminal.BoundaryType.kVoltageProbe
else: # pragma : no cover
temp = self._pedb.edb_api.cell.terminal.BoundaryType.InvalidBoundary
self._edb_object.SetBoundaryType(temp)

@property
def impedance(self):
Expand All @@ -146,6 +157,28 @@ def impedance(self):
def impedance(self, value):
self._edb_object.SetImpedance(self._pedb.edb_value(value))

@property
def is_reference_terminal(self):
"""Whether it is a reference terminal."""
return self._edb_object.IsReferenceTerminal()

@property
def ref_terminal(self):
"""Get reference terminal."""

terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
if not terminal.is_null:
if terminal.terminal_type == TerminalType.PointTerminal.name:
return PointTerminal(self._pedb, terminal._edb_object)
elif terminal.terminal_type == TerminalType.EdgeTerminal.name:
return EdgeTerminal(self._pedb, terminal._edb_object)
elif terminal.terminal_type == TerminalType.InvalidTerminal.name: # pragma : no cover
return None

@ref_terminal.setter
def ref_terminal(self, value):
self._edb_object.SetReferenceTerminal(value._edb_object)

@property
def reference_object(self): # pragma : no cover
"""This returns the object assigned as reference. It can be a primitive or a padstack instance.
Expand Down Expand Up @@ -244,7 +277,7 @@ def get_pin_group_terminal_reference_pin(self, gnd_net_name_preference=None): #
return EDBPadstackInstance(refTermPSI, self._pedb)
except AttributeError:
return None
return None # pragma: no cover
return None

@pyaedt_function_handler()
def get_edge_terminal_reference_primitive(self): # pragma : no cover
Expand All @@ -268,7 +301,7 @@ def get_edge_terminal_reference_primitive(self): # pragma : no cover
prim_shape_data = primitive.GetPolygonData()
if prim_shape_data.PointInPolygon(shape_pd):
return cast(primitive, self._pedb)
return None # pragma: no cover
return None

@pyaedt_function_handler()
def get_point_terminal_reference_primitive(self): # pragma : no cover
Expand Down Expand Up @@ -331,11 +364,11 @@ def _get_closest_pin(self, ref_pin, pin_list, gnd_net=None):
else:
power_ground_net_names = [net for net in self._pedb.nets.power_nets.keys()]
comp_ref_pins = [i for i in pin_list if i.GetNet().GetName() in power_ground_net_names]
if len(comp_ref_pins) == 0:
if len(comp_ref_pins) == 0: # pragma: no cover
self._pedb.logger.error(
"Terminal with PadStack Instance Name {} component has no reference pins.".format(ref_pin.GetName())
) # pragma: no cover
return None # pragma: no cover
)
return None
closest_pin_distance = None
pin_obj = None
for pin in comp_ref_pins: # find the distance to all the pins to the terminal pin
Expand Down Expand Up @@ -456,3 +489,76 @@ def create(self, padstack_instance, name=None, layer=None, is_ref=False):
terminal = PadstackInstanceTerminal(self._pedb, terminal)

return terminal if not terminal.is_null else False


class PointTerminal(Terminal):
"""Manages point terminal properties."""

def __init__(self, pedb, edb_object=None):
super().__init__(pedb, edb_object)

@pyaedt_function_handler
def create(self, name, net, location, layer, is_ref=False):
"""Create a point terminal.
Parameters
----------
name : str
Name of the terminal.
net : str
Name of the net.
location : list
Location of the terminal.
layer : str
Name of the layer.
is_ref : bool, optional
Whether it is a reference terminal.
Returns
-------
"""
terminal = self._pedb.edb_api.cell.terminal.PointTerminal.Create(
self._pedb.active_layout,
self._pedb.nets[net].net_object,
name,
self._pedb.point_data(*location),
self._pedb.stackup[layer]._edb_layer,
is_ref,
)
terminal = PointTerminal(self._pedb, terminal)
return terminal if not terminal.is_null else False

@property
def location(self):
"""Get location of the terminal."""
point_data = self._pedb.point_data(0, 0)
layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
if self._edb_object.GetParameters(point_data, layer):
return [point_data.X.ToDouble(), point_data.Y.ToDouble()]

@location.setter
def location(self, value):
layer = self.layer
self._edb_object.SetParameters(self._pedb.point_data(*value), layer)

@property
def layer(self):
"""Get layer of the terminal."""
point_data = self._pedb.point_data(0, 0)
layer = list(self._pedb.stackup.layers.values())[0]._edb_layer
if self._edb_object.GetParameters(point_data, layer):
return layer

@layer.setter
def layer(self, value):
layer = self._pedb.stackup.layers[value]._edb_layer
point_data = self._pedb.point_data(*self.location)
self._edb_object.SetParameters(point_data, layer)


class PinGroupTerminal(Terminal):
"""Manages pin group terminal properties."""

def __init__(self, pedb, edb_object=None):
super().__init__(pedb, edb_object)
44 changes: 42 additions & 2 deletions pyaedt/edb_core/siwave.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@

from pyaedt.edb_core.edb_data.simulation_configuration import SimulationConfiguration
from pyaedt.edb_core.edb_data.simulation_configuration import SourceType

# from pyaedt.edb_core.edb_data.sources import SourceType
from pyaedt.edb_core.edb_data.sources import CircuitPort
from pyaedt.edb_core.edb_data.sources import CurrentSource
from pyaedt.edb_core.edb_data.sources import DCTerminal
from pyaedt.edb_core.edb_data.sources import PinGroup
from pyaedt.edb_core.edb_data.sources import ResistorSource
from pyaedt.edb_core.edb_data.sources import VoltageSource
from pyaedt.edb_core.general import BoundaryType
from pyaedt.edb_core.general import convert_py_list_to_net_list
from pyaedt.generic.constants import SolverType
from pyaedt.generic.constants import SweepType
Expand Down Expand Up @@ -1388,3 +1387,44 @@ def create_circuit_port_on_pin_group(self, pos_pin_group_name, neg_pin_group_nam
neg_terminal.SetName(name + "_ref")
pos_terminal.SetReferenceTerminal(neg_terminal)
return True

@pyaedt_function_handler
def place_voltage_probe(
self,
name,
positive_net_name,
positive_location,
positive_layer,
negative_net_name,
negative_location,
negative_layer,
):
"""Place a voltage probe between two points.
Parameters
----------
name : str,
Name of the probe.
positive_net_name : str
Name of the positive net.
positive_location : list
Location of the positive terminal.
positive_layer : str,
Layer of the positive terminal.
negative_net_name : str,
Name of the negative net.
negative_location : list
Location of the negative terminal.
negative_layer : str
Layer of the negative terminal.
"""
from pyaedt.edb_core.edb_data.terminals import PointTerminal

point_terminal = PointTerminal(self._pedb)
p_terminal = point_terminal.create(name, positive_net_name, positive_location, positive_layer)
p_terminal.boundary_type = BoundaryType.kVoltageProbe.name

n_terminal = point_terminal.create(name + "_ref", negative_net_name, negative_location, negative_layer)
n_terminal.boundary_type = BoundaryType.kVoltageProbe.name
p_terminal.ref_terminal = n_terminal
return self._pedb.probes[name]

0 comments on commit 7eae896

Please sign in to comment.