Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT: edb configuration export ports and sources #632

Merged
merged 16 commits into from
Jul 3, 2024
7 changes: 3 additions & 4 deletions src/pyedb/configuration/cfg_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from pyedb.configuration.cfg_package_definition import CfgPackageDefinitions
from pyedb.configuration.cfg_padstacks import CfgPadstacks
from pyedb.configuration.cfg_pin_groups import CfgPinGroup
from pyedb.configuration.cfg_ports_sources import CfgPort, CfgSources
from pyedb.configuration.cfg_ports_sources import CfgPorts, CfgSources
from pyedb.configuration.cfg_s_parameter_models import CfgSParameterModel
from pyedb.configuration.cfg_setup import CfgSetups
from pyedb.configuration.cfg_spice_models import CfgSpiceModel
Expand All @@ -41,7 +41,6 @@ class CfgData(object):

def __init__(self, pedb, **kwargs):
self._pedb = pedb
self.edb_comps = self._pedb.components.components
self.general = CfgGeneral(self, kwargs.get("general", None))

self.boundaries = {}
Expand All @@ -58,9 +57,9 @@ def __init__(self, pedb, **kwargs):

self.pin_groups = [CfgPinGroup(self, pin_group) for pin_group in kwargs.get("pin_groups", [])]

self.ports = [CfgPort(self, **port) for port in kwargs.get("ports", [])]
self.ports = CfgPorts(self._pedb, ports_data=kwargs.get("ports", []))

self.sources = [CfgSources(self, **source) for source in kwargs.get("sources", [])]
self.sources = CfgSources(self._pedb, sources_data=kwargs.get("sources", []))

self.setups = CfgSetups(self._pedb, setups_data=kwargs.get("setups", []))

Expand Down
308 changes: 249 additions & 59 deletions src/pyedb/configuration/cfg_ports_sources.py

Large diffs are not rendered by default.

37 changes: 30 additions & 7 deletions src/pyedb/configuration/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,10 @@ def run(self):
pin_group.apply()

# Configure ports
for port in self.cfg_data.ports:
port.create()
self.cfg_data.ports.apply()

# Configure sources
for source in self.cfg_data.sources:
source.create()
self.cfg_data.sources.apply()

# Configure setup
self.cfg_data.setups.apply()
Expand Down Expand Up @@ -271,13 +269,22 @@ def get_data_from_db(self, **kwargs):
data["package_definitions"] = self.cfg_data.package_definitions.get_data_from_db()
if kwargs.get("setups", False):
data["setups"] = self.cfg_data.setups.get_data_from_db()
if kwargs.get("sources", False):
self.cfg_data.sources.get_data_from_db()
data["sources"] = self.cfg_data.sources.export_properties()
if kwargs.get("ports", False):
self.cfg_data.ports.get_data_from_db()
data["ports"] = self.cfg_data.ports.export_properties()
if kwargs.get("components", False):
data["components"] = self.cfg_data.components.get_data_from_db()
if kwargs.get("nets", False):
data["nets"] = self.cfg_data.nets.get_data_from_db()

return data

def export(self, file_path, stackup=True, package_definitions=True, setups=True, nets=True):
def export(
self, file_path, stackup=True, package_definitions=True, setups=True, sources=True, ports=True, nets=True
):
"""Export the configuration data from layout to a file.

Parameters
Expand All @@ -286,14 +293,30 @@ def export(self, file_path, stackup=True, package_definitions=True, setups=True,
File path to export the configuration data.
stackup : bool
Whether to export stackup or not.

package_definitions : bool
Whether to export package definitions or not.
setups : bool
Whether to export setups or not.
sources : bool
Whether to export sources or not.
ports : bool
Whether to export ports or not.
nets : bool
Whether to export nets.
Returns
-------
bool
"""
file_path = file_path if isinstance(file_path, Path) else Path(file_path)
file_path = file_path if file_path.suffix == ".json" else file_path.with_suffix(".json")
data = self.get_data_from_db(stackup=stackup, package_definitions=package_definitions, setups=setups, nets=nets)
data = self.get_data_from_db(
stackup=stackup,
package_definitions=package_definitions,
setups=setups,
sources=sources,
ports=ports,
nets=nets,
)
with open(file_path, "w") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
return True if os.path.isfile(file_path) else False
1 change: 1 addition & 0 deletions src/pyedb/dotnet/edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ def excitations_nets(self):
def sources(self):
"""Get all layout sources."""
terms = [term for term in self.layout.terminals if int(term.GetBoundaryType()) in [3, 4, 7]]
terms = [term for term in terms if not term.IsReferenceTerminal()]
return {ter.GetName(): ExcitationSources(self, ter) for ter in terms}

@property
Expand Down
9 changes: 9 additions & 0 deletions src/pyedb/dotnet/edb_core/cell/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,12 @@ def create_bondwire(
end_y=self._pedb.edb_value(end_y),
net=self.nets[net]._edb_object,
)

def find_object_by_id(self, value: int):
"""Find a Connectable object by Database ID.

Parameters
----------
value : int
"""
return self._pedb._edb.Cell.Connectable.FindById(self._edb_object, value)
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,13 @@ 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

def _get_parameters(self):
"""Gets the parameters of the padstack instance terminal."""
_, padstack_inst, layer_obj = self._edb_object.GetParameters()
return padstack_inst, layer_obj

@property
def padstack_instance(self):
p_inst, _ = self._get_parameters()
return self._pedb.padstacks.find_instance_by_id(p_inst.GetId())
5 changes: 5 additions & 0 deletions src/pyedb/dotnet/edb_core/cell/terminal/pingroup_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,8 @@ def create(self, name, net_name, pin_group_name, is_ref=False):
)
term = PinGroupTerminal(self._pedb, term)
return term if not term.is_null else False

def pin_group(self):
"""Gets the pin group the terminal refers to."""
name = self._edb_object.GetPinGroup().GetName()
return self._pedb.siwave.pin_groups[name]
11 changes: 0 additions & 11 deletions src/pyedb/dotnet/edb_core/cell/terminal/point_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,3 @@ def create(self, name, net, location, layer, is_ref=False):
)
terminal = PointTerminal(self._pedb, terminal)
return terminal if not terminal.is_null else False

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

terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
return terminal if not terminal.is_null else False

@ref_terminal.setter
def ref_terminal(self, value):
self._edb_object.SetReferenceTerminal(value._edb_object)
36 changes: 35 additions & 1 deletion src/pyedb/dotnet/edb_core/cell/terminal/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,21 @@ def boundary_type(self):
def boundary_type(self, value):
self._edb_object.SetBoundaryType(self._boundary_type_mapping[value])

@property
def is_port(self):
"""Whether it is a port."""
return True if self.boundary_type == "PortBoundary" else False

@property
def is_current_source(self):
"""Whether it is a current source."""
return True if self.boundary_type == "kCurrentSource" else False

@property
def is_voltage_source(self):
"""Whether it is a voltage source."""
return True if self.boundary_type == "kVoltageSource" else False

@property
def impedance(self):
"""Impedance of the port."""
Expand All @@ -235,7 +250,8 @@ def is_reference_terminal(self):
def ref_terminal(self):
"""Get reference terminal."""

terminal = Terminal(self._pedb, self._edb_object.GetReferenceTerminal())
edb_terminal = self._edb_object.GetReferenceTerminal()
terminal = self._pedb.terminals[edb_terminal.GetName()]
if not terminal.is_null:
return terminal

Expand Down Expand Up @@ -444,3 +460,21 @@ def _get_closest_pin(self, ref_pin, pin_list, gnd_net=None):
pin_obj = pin
if pin_obj:
return EDBPadstackInstance(pin_obj, self._pedb)

@property
def magnitude(self):
"""Get the magnitude of the source."""
return self._edb_object.GetSourceAmplitude().ToDouble()

@magnitude.setter
def magnitude(self, value):
self._edb_object.SetSourceAmplitude(self._edb.utility.value(value))

@property
def phase(self):
"""Get the phase of the source."""
return self._edb_object.GetSourcePhase().ToDouble()

@phase.setter
def phase(self, value):
self._edb_object.SetSourcePhase(self._edb.utility.value(value))
18 changes: 0 additions & 18 deletions src/pyedb/dotnet/edb_core/edb_data/ports.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,24 +198,6 @@ class ExcitationSources(Terminal):
def __init__(self, pedb, edb_terminal):
Terminal.__init__(self, pedb, edb_terminal)

@property
def magnitude(self):
"""Get the magnitude of the source."""
return self._edb_object.GetSourceAmplitude().ToDouble()

@magnitude.setter
def magnitude(self, value):
self._edb_object.SetSourceAmplitude(self._edb.utility.value(value))

@property
def phase(self):
"""Get the phase of the source."""
return self._edb_object.GetSourcePhase().ToDouble()

@phase.setter
def phase(self, value):
self._edb_object.SetSourcePhase(self._edb.utility.value(value))


class BundleWavePort(BundleTerminal):
"""Manages bundle wave port properties.
Expand Down
9 changes: 9 additions & 0 deletions src/pyedb/dotnet/edb_core/padstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,15 @@ def instances_by_name(self):
)
return padstack_instances

def find_instance_by_id(self, value: int):
"""Find a padstack instance by database id.

Parameters
----------
value : int
"""
return EDBPadstackInstance(self._pedb.modeler.find_object_by_id(value), self._pedb)

@property
def pins(self):
"""Dictionary of all pins instances (belonging to component).
Expand Down
6 changes: 2 additions & 4 deletions tests/legacy/system/test_edb.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ def test_siwave_create_voltage_source(self):
"""Create a voltage source."""
assert len(self.edbapp.sources) == 0
assert "Vsource_" in self.edbapp.siwave.create_voltage_source_on_net("U1", "USB3_D_P", "U1", "GND", 3.3, 0)
assert len(self.edbapp.sources) == 2
assert len(self.edbapp.sources) == 1
assert list(self.edbapp.sources.values())[0].magnitude == 3.3

pins = self.edbapp.components.get_pin_from_component("U1")
assert "VSource_" in self.edbapp.siwave.create_voltage_source_on_pin(pins[300], pins[10], 3.3, 0)
assert len(self.edbapp.sources) == 3
assert len(self.edbapp.sources) == 2
assert len(self.edbapp.probes) == 0
list(self.edbapp.sources.values())[0].phase = 1
assert list(self.edbapp.sources.values())[0].phase == 1
Expand Down Expand Up @@ -1250,8 +1250,6 @@ def test_siwave_source_setter(self):
assert sources[0].magnitude == 1.45
sources[1].magnitude = 1.45
assert sources[1].magnitude == 1.45
sources[2].magnitude = 1.45
assert sources[2].magnitude == 1.45
edbapp.close()

def test_delete_pingroup(self):
Expand Down
81 changes: 73 additions & 8 deletions tests/legacy/system/test_edb_configuration_2p0.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,55 @@ def test_04_nets(self, edb_examples):
edbapp.close()

def test_05_ports(self, edb_examples):
data = {
"ports": [
{
"name": "CIRCUIT_C375_1_2",
"reference_designator": "C375",
"type": "circuit",
"positive_terminal": {"pin": "1"},
"negative_terminal": {"pin": "2"},
},
{
"name": "CIRCUIT_X1_B8_GND",
"reference_designator": "X1",
"type": "circuit",
"positive_terminal": {"pin": "B8"},
"negative_terminal": {"net": "GND"},
},
{
"name": "CIRCUIT_X1_B9_GND",
"reference_designator": "X1",
"type": "circuit",
"positive_terminal": {"net": "PCIe_Gen4_TX2_N"},
"negative_terminal": {"net": "GND"},
},
{
"name": "CIRCUIT_U7_VDD_DDR_GND",
"reference_designator": "U7",
"type": "circuit",
"positive_terminal": {"net": "VDD_DDR"},
"negative_terminal": {"net": "GND"},
},
]
}
edbapp = edb_examples.get_si_verse()
assert edbapp.configuration.load(str(self.local_input_folder / "ports_coax.json"), apply_file=True)
assert edbapp.configuration.load(str(self.local_input_folder / "ports_circuit.json"), apply_file=True)
assert "COAX_U1_AM17" in edbapp.ports
assert "COAX_U1_PCIe_Gen4_TX2_CAP_N" in edbapp.ports
assert edbapp.configuration.load(data, apply_file=True)
assert "CIRCUIT_C375_1_2" in edbapp.ports
assert "CIRCUIT_X1_B8_GND" in edbapp.ports
assert "CIRCUIT_U7_VDD_DDR_GND" in edbapp.ports
data_from_json = edbapp.configuration.cfg_data.ports.export_properties()
edbapp.configuration.cfg_data.ports.get_data_from_db()
data_from_db = edbapp.configuration.cfg_data.ports.export_properties()
for p1 in data_from_json:
p2 = data_from_db.pop(0)
for k, v in p1.items():
if k in ["reference_designator"]:
continue
if k in ["positive_terminal", "negative_terminal"]:
if "net" in v:
continue
assert p2[k] == v
edbapp.close()

def test_05b_ports_coax(self, edb_examples):
Expand Down Expand Up @@ -683,7 +724,7 @@ def test_14_setup_siwave_syz(self, edb_examples):
assert value == target[p]
edbapp.close()

def test_15b_sources(self, edb_examples):
def test_15b_sources_net_net(self, edb_examples):
edbapp = edb_examples.get_si_verse()
sources_v = [
{
Expand All @@ -699,20 +740,44 @@ def test_15b_sources(self, edb_examples):
data = {"sources": sources_v}
assert edbapp.configuration.load(data, apply_file=True)
assert edbapp.sources["VSOURCE_U2_1V0_GND"].magnitude == 1

data_from_json = edbapp.configuration.cfg_data.sources.export_properties()
edbapp.configuration.cfg_data.sources.get_data_from_db()
data_from_db = edbapp.configuration.cfg_data.sources.export_properties()
for s1 in data_from_json:
s2 = data_from_db.pop(0)
for k, v in s1.items():
if k in ["reference_designator", "distributed"]:
continue
if k in ["positive_terminal", "negative_terminal"]:
if "net" in v:
continue
assert s2[k] == v
edbapp.close()

def test_15c_sources_net_net_distributed(self, edb_examples):
edbapp = edb_examples.get_si_verse()
sources_i = [
{
"name": "ISOURCE",
"reference_designator": "U1",
"type": "current",
"magnitude": 1,
"magnitude": 117,
"distributed": True,
"positive_terminal": {"net": "1V0"},
"negative_terminal": {"net": "GND"},
},
]
data = {"sources": sources_i}
assert edbapp.configuration.load(data, apply_file=True, append=False)
assert not edbapp.sources["ISOURCE_U1_1V0_M16"].magnitude == 1
assert edbapp.configuration.load(data, apply_file=True)

edbapp.configuration.cfg_data.sources.get_data_from_db()
data_from_db = edbapp.configuration.cfg_data.sources.export_properties()
assert len(data_from_db) == 117
for s1 in data_from_db:
assert s1["magnitude"] == 1
assert s1["reference_designator"] == "U1"
assert s1["type"] == "current"
edbapp.close()

def test_15c_sources_nearest_ref(self, edb_examples):
Expand Down
Loading