From 97506e9a15e7fbfb9c9b7c4392e84e85d6f6f0b2 Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Fri, 19 Jul 2024 09:37:31 +0200 Subject: [PATCH 01/20] Added new method for creating ibis circuit schematic starting from a touchstone file --- _unittest/test_21_Circuit.py | 27 ++ pyaedt/circuit.py | 366 +++++++++++++++++--- pyaedt/generic/ibis_reader.py | 6 +- pyaedt/modeler/circuits/PrimitivesNexxim.py | 12 +- pyaedt/modeler/circuits/object3dcircuit.py | 22 +- pyaedt/modeler/schematic.py | 61 ++-- 6 files changed, 396 insertions(+), 98 deletions(-) diff --git a/_unittest/test_21_Circuit.py b/_unittest/test_21_Circuit.py index 48127cd7b72..90aa2dbc9bb 100644 --- a/_unittest/test_21_Circuit.py +++ b/_unittest/test_21_Circuit.py @@ -169,6 +169,8 @@ def test_11_export_fullwave(self): def test_12_connect_components(self): myind = self.aedtapp.modeler.schematic.create_inductor("L100", 1e-9) + myind2 = self.aedtapp.modeler.schematic.create_inductor("L1001", 1e-9) + myind3 = self.aedtapp.modeler.schematic.create_inductor("L1002", 1e-9) myres = self.aedtapp.modeler.schematic.create_resistor("R100", 50) mycap = self.aedtapp.modeler.schematic.create_capacitor("C100", 1e-12) portname = self.aedtapp.modeler.schematic.create_interface_port("Port1") @@ -177,6 +179,9 @@ def test_12_connect_components(self): assert myind.pins[0].connect_to_component(portname.pins[0]) assert myind.pins[1].connect_to_component(myres.pins[1], use_wire=True) assert self.aedtapp.modeler.connect_schematic_components(myres.id, mycap.id, pin_starting=1) + assert self.aedtapp.modeler.connect_schematic_components( + myind2, myind3, pin_starting=["n1", "n2"], pin_ending=["n2", "n1"], use_wire=False + ) gnd = self.aedtapp.modeler.schematic.create_gnd() assert mycap.pins[1].connect_to_component(gnd.pins[0]) # create_interface_port @@ -923,6 +928,28 @@ def test_49_automatic_ami(self): ) assert result + @pytest.mark.skipif(config["NonGraphical"] and is_linux, reason="Method not working in Linux and Non graphical.") + def test_49_automatic_ibis(self): + touchstone_file = os.path.join(local_path, "example_models", test_subfolder, touchstone_custom) + ibis_file = os.path.join(local_path, "example_models", "T15", "u26a_800_modified.ibs") + result, eye_curve_tx, eye_curve_rx = self.aedtapp.create_ibis_schematic_from_snp( + input_file=touchstone_file, + ibis_file=ibis_file, + component_name=None, + tx_buffer_name="DQ_FULL_800", + rx_buffer_name="DQ_FULL_800", + tx_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], + rx_pins=["A-MII-RXD2_32.SQFP28X28_208.P"], + use_ibis_buffer=True, + differential=False, + bit_pattern="random_bit_count=2.5e3 random_seed=1", + unit_interval="31.25ps", + use_convolution=True, + analyze=False, + design_name="AMI", + ) + assert result + def test_50_enforce_touchstone_passive(self): self.aedtapp.insert_design("Touchstone_passive") self.aedtapp.modeler.schematic_units = "mil" diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 3b81392a75c..c309834f5a0 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -1911,8 +1911,8 @@ def create_ami_schematic_from_snp( tx_buffer_name, rx_buffer_name, tx_pins, - tx_refs, rx_pins, + tx_refs, rx_refs, use_ibis_buffer=True, differential=True, @@ -1921,6 +1921,8 @@ def create_ami_schematic_from_snp( use_convolution=True, analyze=False, design_name="AMI", + ibis_rx_file=None, + create_setup=True, ): """Create a schematic from a Touchstone file and automatically set up an IBIS-AMI analysis. @@ -1962,7 +1964,111 @@ def create_ami_schematic_from_snp( Whether to automatically assign differential pairs. The default is ``False``. design_name : str, optional New schematic name. The default is ``"LNA"``. + ibis_rx_file : str, optional + Ibis receiver file. + create_setup : bool, optional + Whether if create transient or ami setup or not. The default is ``True``. + + Returns + ------- + (bool, list, list) + First argument is ``True`` if successful. + Second and third arguments are respectively the names of the tx and rx mode probes. + """ + return self.create_ibis_schematic_from_snp( + input_file=input_file, + ibis_tx_file=ibis_ami, + component_name=component_name, + tx_buffer_name=tx_buffer_name, + rx_buffer_name=rx_buffer_name, + tx_pins=tx_pins, + tx_refs=tx_refs, + rx_pins=rx_pins, + rx_refs=rx_refs, + use_ibis_buffer=use_ibis_buffer, + differential=differential, + bit_pattern=bit_pattern, + unit_interval=unit_interval, + use_convolution=use_convolution, + analyze=analyze, + design_name=design_name, + is_ami=True, + ibis_rx_file=ibis_rx_file, + create_setup=create_setup, + ) + + @pyaedt_function_handler() + def create_ibis_schematic_from_snp( + self, + input_file, + ibis_tx_file, + tx_buffer_name, + rx_buffer_name, + tx_pins, + rx_pins, + ibis_rx_file=None, + tx_refs=None, + rx_refs=None, + component_name=None, + use_ibis_buffer=True, + differential=True, + bit_pattern=None, + unit_interval=None, + use_convolution=True, + analyze=False, + design_name="IBIS", + is_ami=False, + create_setup=True, + ): + """Create a schematic from a Touchstone file and automatically set up an IBIS-AMI analysis. + + Parameters + ---------- + input_file : str + Full path to the sNp file. + ibis_tx_file : str + Full path to the IBIS file. + tx_buffer_name : str + Transmission buffer name. It can be a buffer or a ibis pin name. + In this last case the user has to provide also the component_name. + rx_buffer_name : str + Receiver buffer name. + tx_pins : list + Pins to assign the transmitter IBIS. + rx_pins : list, optional + Pins to assign the receiver IBIS. + tx_refs : list, optional + Reference pins to assign the transmitter IBIS. This parameter is only used in + a differential configuration. + rx_refs : list + Reference pins to assign the receiver IBIS. This parameter is only used + in a differential configuration. + component_name : str, optional + Component name in the IBIS file to assign to components. + Needed only when ibis component pins are used. + use_ibis_buffer : bool, optional + Whether to use the IBIS buffer. The default is ``True``. If ``False``, pins are used. + differential : bool, optional + Whether the buffers are differential. The default is ``True``. If ``False``, + the buffers are single-ended. + bit_pattern : str, optional + IBIS bit pattern. + unit_interval : str, optional + Unit interval of the bit pattern. + use_convolution : bool, optional + Whether to use convolution for the Touchstone file. The default is + ``True``. If ``False``, state-space is used. + analyze : bool + Whether to automatically assign differential pairs. The default is ``False``. + design_name : str, optional + New schematic name. The default is ``"IBIS"``. + is_ami : bool, optional + Whether if the ibis is AMI or not. The default is ``False``. + ibis_rx_file : str, optional + Ibis receiver file. + create_setup : bool, optional + Whether if create transient or ami setup or not. The default is ``True``. Returns ------- @@ -1980,67 +2086,214 @@ def create_ami_schematic_from_snp( touchstone_path = input_file sub = self.modeler.components.create_touchstone_component(touchstone_path) + return self.create_ibis_schematic_from_pins( + ibis_tx_file=ibis_tx_file, + tx_buffer_name=tx_buffer_name, + rx_buffer_name=rx_buffer_name, + tx_pins=tx_pins, + rx_pins=rx_pins, + tx_refs=tx_refs, + rx_refs=rx_refs, + tx_component_name=sub.name, + ibis_component_name=component_name, + use_ibis_buffer=use_ibis_buffer, + differential=differential, + bit_pattern=bit_pattern, + unit_interval=unit_interval, + use_convolution=use_convolution, + analyze=analyze, + is_ami=is_ami, + ibis_rx_file=ibis_rx_file, + create_setup=create_setup, + ) + + @pyaedt_function_handler() + def create_ibis_schematic_from_pins( + self, + ibis_tx_file, + ibis_rx_file=None, + tx_buffer_name="", + rx_buffer_name="", + tx_pins=None, + rx_pins=None, + tx_refs=None, + rx_refs=None, + tx_component_name=None, + rx_component_name=None, + ibis_component_name=None, + use_ibis_buffer=True, + differential=True, + bit_pattern=None, + unit_interval=None, + use_convolution=True, + analyze=False, + is_ami=False, + create_setup=True, + ): + """Create a schematic from a list of pins and automatically set up an IBIS-AMI analysis. + + Parameters + ---------- + + ibis_tx_file : str + Full path to the IBIS file for transmitters. + ibis_rx_file : str + Full path to the IBIS file for receiver. + tx_buffer_name : str + Transmission buffer name. It can be a buffer or a ibis pin name. + In this last case the user has to provide also the component_name. + rx_buffer_name : str + Receiver buffer name. + tx_pins : list + Pins to assign the transmitter IBIS. + rx_pins : list, optional + Pins to assign the receiver IBIS. + tx_refs : list, optional + Reference pins to assign the transmitter IBIS. This parameter is only used in + a differential configuration. + rx_refs : list + Reference pins to assign the receiver IBIS. This parameter is only used + in a differential configuration. + tx_component_name : str, optional + Name of component to which tx_pins belongs. + rx_component_name : str, optional + Name of component to which rx_pins belongs. + ibis_component_name : str, optional + Component name in the IBIS file to assign to components. + Needed only when ibis component pins are used. + use_ibis_buffer : bool, optional + Whether to use the IBIS buffer. The default is ``True``. If ``False``, pins are used. + differential : bool, optional + Whether the buffers are differential. The default is ``True``. If ``False``, + the buffers are single-ended. + bit_pattern : str, optional + IBIS bit pattern. + unit_interval : str, optional + Unit interval of the bit pattern. + use_convolution : bool, optional + Whether to use convolution for the Touchstone file. The default is + ``True``. If ``False``, state-space is used. + analyze : bool + Whether to automatically assign differential pairs. The default is ``False``. + is_ami : bool, optional + Whether if the ibis is AMI or not. The default is ``False``. + create_setup : bool, optional + Whether if create transient or ami setup or not. The default is ``True``. + + + Returns + ------- + (bool, list, list) + First argument is ``True`` if successful. + Second and third arguments are respectively the names of the tx and rx mode probes. + """ + + if tx_component_name is None: + try: + tx_component_name = [ + i + for i, v in self.modeler.components.components.items() + if "FileName" in v.parameters + or "ModelName" in v.parameters + and v.parameters["ModelName"] == "FieldSolver" + ][0] + except: + self.logger.error("A component has to be passed or an Sparameter present.") + return False + if rx_component_name is None: + rx_component_name = tx_component_name + sub = self.modeler.components[tx_component_name] center_x = sub.location[0] center_y = sub.location[1] + subx = self.modeler.components[rx_component_name] + center_x_rx = subx.location[0] + center_y_rx = subx.location[1] left = 0 - delta_y = -1 * sub.location[1] - 2000 - 50 * len(tx_pins) - ibis = self.get_ibis_model_from_file(ibis_ami, is_ami=True) + delta_y = center_y - 0.0508 - 0.00127 * len(tx_pins) + delta_y_rx = center_y_rx - 0.0508 - 0.00127 * len(tx_pins) + for el in self.modeler.components.components.values(): + if delta_y >= el.bounding_box[1]: + delta_y = el.bounding_box[1] - 0.02032 + if delta_y_rx <= el.bounding_box[3]: + delta_y_rx = el.bounding_box[3] + 0.02032 + + ibis = self.get_ibis_model_from_file(ibis_tx_file, is_ami=is_ami) + if ibis_rx_file: + ibis_rx = self.get_ibis_model_from_file(ibis_rx_file, is_ami=is_ami) + else: + ibis_rx = ibis tx_eye_names = [] rx_eye_names = [] + for j in range(len(tx_pins)): - pos_x = unit_converter(2000, input_units="mil", output_units=self.modeler.schematic_units) - pos_y = unit_converter(delta_y - left * 800, input_units="mil", output_units=self.modeler.schematic_units) - left += 1 + pos_x = center_x - unit_converter(1200, input_units="mil", output_units=self.modeler.schematic_units) + pos_y = delta_y + unit_converter( + left * 0.02032, input_units="meter", output_units=self.modeler.schematic_units + ) + pos_x_rx = center_x_rx + unit_converter(1200, input_units="mil", output_units=self.modeler.schematic_units) + pos_y_rx = delta_y_rx + unit_converter( + left * 0.02032, input_units="mil", output_units=self.modeler.schematic_units + ) - p_pin1 = [i for i in sub.pins if i.name == tx_pins[j]][0] - p_pin2 = [i for i in sub.pins if i.name == rx_pins[j]][0] + left += 1 + p_pin1 = sub[tx_pins[j]] + p_pin2 = subx[rx_pins[j]] if differential: - n_pin1 = [i for i in sub.pins if i.name == tx_refs[j]][0] - n_pin2 = [i for i in sub.pins if i.name == rx_refs[j]][0] + n_pin1 = sub.pin[tx_refs[j]] + n_pin2 = subx.pins[rx_refs[j]] if use_ibis_buffer: - buf = [k for k in ibis.components[component_name].buffer.keys() if k.startswith(tx_buffer_name + "_")] + buf = [k for k in ibis.buffers.keys() if k.startswith(tx_buffer_name + "_")] if differential: buf = [k for k in buf if k.endswith("diff")] - tx = ibis.components[component_name].buffer[buf[0]].insert(center_x - pos_x, center_y + pos_y) - buf = [k for k in ibis.components[component_name].buffer.keys() if k.startswith(rx_buffer_name + "_")] + tx = ibis.buffers[buf[0]].insert(pos_x, pos_y) + if tx.location[0] > tx.pins[0].location[0]: + tx.angle = 180 + buf = [k for k in ibis_rx.buffers.keys() if k.startswith(rx_buffer_name + "_")] if differential: buf = [k for k in buf if k.endswith("diff")] - rx = ibis.components[component_name].buffer[buf[0]].insert(center_x + pos_x, center_y + pos_y, 180) + rx = ibis_rx.buffers[buf[0]].insert(pos_x_rx, pos_y_rx, 180) + if rx.location[0] < rx.pins[0].location[0]: + rx.angle = 0 else: - buf = [k for k in ibis.components[component_name].pins.keys() if k.startswith(tx_buffer_name + "_")] + buf = [ + k for k in ibis.components[ibis_component_name].pins.keys() if k.startswith(tx_buffer_name + "_") + ] if differential: buf = [k for k in buf if k.endswith("diff")] - tx = ibis.components[component_name].pins[buf[0]].insert(center_x - pos_x, center_y + pos_y) - buf = [k for k in ibis.components[component_name].pins.keys() if k.startswith(rx_buffer_name + "_")] + tx = ibis.components[ibis_component_name].pins[buf[0]].insert(pos_x, pos_y) + if tx.location[0] > tx.pins[0].location[0]: + tx.angle = 180 + buf = [ + k for k in ibis_rx.components[ibis_component_name].pins.keys() if k.startswith(rx_buffer_name + "_") + ] if differential: buf = [k for k in buf if k.endswith("diff")] - rx = ibis.components[component_name].pins[buf[0]].insert(center_x + pos_x, center_y + pos_y, 180) - - tx_eye_names.append(tx.parameters["probe_name"]) - rx_eye_names.append(rx.parameters["source_name"]) - _, first, second = tx.pins[0].connect_to_component(p_pin1, page_port_angle=180) - self.modeler.move(first, [0, 100], "mil") - if second.pins[0].location[0] > center_x: - self.modeler.move(second, [1000, 0], "mil") + rx = ibis_rx.components[ibis_component_name].pins[buf[0]].insert(pos_x_rx, pos_y_rx, 180) + if rx.location[0] < rx.pins[0].location[0]: + rx.angle = 0 + _, first_tx, second_tx = tx.pins[0].connect_to_component(p_pin1, page_port_angle=180) + self.modeler.move(first_tx, [0, 100], "mil") + if second_tx.pins[0].location[0] > center_x: + self.modeler.move(second_tx, [1000, 0], "mil") else: - self.modeler.move(second, [-1000, 0], "mil") - _, first, second = rx.pins[0].connect_to_component(p_pin2, page_port_angle=0) - self.modeler.move(first, [0, -100], "mil") - if second.pins[0].location[0] > center_x: - self.modeler.move(second, [1000, 0], "mil") + self.modeler.move(second_tx, [-1000, 0], "mil") + _, first_rx, second_rx = rx.pins[0].connect_to_component(p_pin2, page_port_angle=0) + self.modeler.move(first_rx, [0, -100], "mil") + if second_rx.pins[0].location[0] > center_x_rx: + self.modeler.move(second_rx, [1000, 0], "mil") else: - self.modeler.move(second, [-1000, 0], "mil") + self.modeler.move(second_rx, [-1000, 0], "mil") if differential: _, first, second = tx.pins[1].connect_to_component(n_pin1, page_port_angle=180) self.modeler.move(first, [0, -100], "mil") - if second.pins[0].location[0] > center_x: + if second.pins[0].location[0] > center_x_rx: self.modeler.move(second, [1000, 0], "mil") else: self.modeler.move(second, [-1000, 0], "mil") _, first, second = rx.pins[1].connect_to_component(n_pin2, page_port_angle=0) self.modeler.move(first, [0, 100], "mil") - if second.pins[0].location[0] > center_x: + if second.pins[0].location[0] > center_x_rx: self.modeler.move(second, [1000, 0], "mil") else: self.modeler.move(second, [-1000, 0], "mil") @@ -2048,24 +2301,33 @@ def create_ami_schematic_from_snp( tx.parameters["UIorBPSValue"] = unit_interval if bit_pattern: tx.parameters["BitPattern"] = "random_bit_count=2.5e3 random_seed=1" - - setup_ami = self.create_setup("AMI", "NexximAMI") - if use_convolution: - self.oanalysis.AddAnalysisOptions( - [ - "NAME:DataBlock", - "DataBlockID:=", - 8, - "Name:=", - "Nexxim Options", + if is_ami: + tx_eye_names.append(tx.parameters["probe_name"]) + rx_eye_names.append(rx.parameters["source_name"]) + else: + tx_eye_names.append(first_tx.name.split("@")[1]) + rx_eye_names.append(first_rx.name.split("@")[1]) + if create_setup: + setup_type = "NexximTransient" + if is_ami: + setup_type = "NexximAMI" + setup_ibis = self.create_setup("Transient", setup_type) + if use_convolution: + self.oanalysis.AddAnalysisOptions( [ - "NAME:ModifiedOptions", - "ts_convolution:=", - True, - ], - ] - ) - setup_ami.props["OptionName"] = "Nexxim Options" - if analyze: - setup_ami.analyze() + "NAME:DataBlock", + "DataBlockID:=", + 8, + "Name:=", + "Nexxim Options", + [ + "NAME:ModifiedOptions", + "ts_convolution:=", + True, + ], + ] + ) + setup_ibis.props["OptionName"] = "Nexxim Options" + if analyze: + setup_ibis.analyze() return True, tx_eye_names, rx_eye_names diff --git a/pyaedt/generic/ibis_reader.py b/pyaedt/generic/ibis_reader.py index 25bd8078a4d..cb86695cd5e 100644 --- a/pyaedt/generic/ibis_reader.py +++ b/pyaedt/generic/ibis_reader.py @@ -841,7 +841,12 @@ def parse_ibis_file(self): buffers[buffer.name] = buffer ibis.buffers = buffers + self._ibis_model = ibis + available_names = self._circuit.modeler.schematic.o_component_manager.GetNames() + already_present = [i for i in buffers.keys() if i in available_names] + if len(already_present) == len(buffers): + return ibis_info if self._circuit: args = [ "NAME:Options", @@ -875,7 +880,6 @@ def parse_ibis_file(self): self._circuit.modeler.schematic.o_component_manager.ImportModelsFromFile(self._filename, args) - self._ibis_model = ibis return ibis_info # Model diff --git a/pyaedt/modeler/circuits/PrimitivesNexxim.py b/pyaedt/modeler/circuits/PrimitivesNexxim.py index 050cff65412..f765a5df8ce 100644 --- a/pyaedt/modeler/circuits/PrimitivesNexxim.py +++ b/pyaedt/modeler/circuits/PrimitivesNexxim.py @@ -83,9 +83,17 @@ def __getitem__(self, partname): if isinstance(partname, int): return self.components[partname] for el in self.components: - if self.components[el].name == partname or self.components[el].composed_name == partname or el == partname: + cmp = self.components[el] + if ( + cmp.name == partname + or cmp.composed_name == partname + or el == partname + or cmp.refdes == partname + or cmp.parameters.get("InstanceName", "") == partname + ): return self.components[el] - + if isinstance(partname, CircuitComponent): + return partname return None @property diff --git a/pyaedt/modeler/circuits/object3dcircuit.py b/pyaedt/modeler/circuits/object3dcircuit.py index 93fe04f51df..911c78c8ab8 100644 --- a/pyaedt/modeler/circuits/object3dcircuit.py +++ b/pyaedt/modeler/circuits/object3dcircuit.py @@ -41,9 +41,10 @@ class CircuitPins(object): """Manages circuit component pins.""" - def __init__(self, circuit_comp, pinname): + def __init__(self, circuit_comp, pinname, pin_number): self._circuit_comp = circuit_comp self.name = pinname + self.pin_number = pin_number self._oeditor = circuit_comp._oeditor @property @@ -414,6 +415,14 @@ def __init__(self, component, name, props): class CircuitComponent(object): """Manages circuit components.""" + def __getitem__(self, item): + if isinstance(item, int): + return self.pins[item - 1] + for i in self.pins: + if i.name == item: + return i + raise KeyError("Pin {} not found.".format(item)) + @property def composed_name(self): """Composed names.""" @@ -607,21 +616,22 @@ def pins(self): if self._pins: return self._pins self._pins = [] - + idx = 1 try: pins = list(self._oeditor.GetComponentPins(self.composed_name)) if "Port@" in self.composed_name and pins == []: - self._pins.append(CircuitPins(self, self.composed_name)) + self._pins.append(CircuitPins(self, self.composed_name, idx)) return self._pins elif not pins: return [] for pin in pins: if self._circuit_components._app.design_type != "Twin Builder": - self._pins.append(CircuitPins(self, pin)) + self._pins.append(CircuitPins(self, pin, idx)) elif pin not in list(self.parameters.keys()): - self._pins.append(CircuitPins(self, pin)) + self._pins.append(CircuitPins(self, pin, idx)) + idx += 1 except AttributeError: - self._pins.append(CircuitPins(self, self.composed_name)) + self._pins.append(CircuitPins(self, self.composed_name, idx)) return self._pins @property diff --git a/pyaedt/modeler/schematic.py b/pyaedt/modeler/schematic.py index cc9100ad4b8..419a1f5c215 100644 --- a/pyaedt/modeler/schematic.py +++ b/pyaedt/modeler/schematic.py @@ -23,7 +23,6 @@ # SOFTWARE. import random -import re import sys import time import warnings @@ -128,7 +127,9 @@ def zoom_to_fit(self): pinnum_first="pin_starting", pinnum_second="pin_ending", ) - def connect_schematic_components(self, starting_component, ending_component, pin_starting=2, pin_ending=1): + def connect_schematic_components( + self, starting_component, ending_component, pin_starting=2, pin_ending=1, use_wire=True + ): """Connect schematic components. Parameters @@ -137,12 +138,16 @@ def connect_schematic_components(self, starting_component, ending_component, pin Starting (right) component. ending_component : str Ending (left) component for the connection line. - pin_starting : str, optional - Number of the pin at which to terminate the connection from the right end of the + pin_starting : int, str, list optional + Number or name of the pins at which to terminate the connection from the right end of the starting component. The default is ``2``. - pin_ending : str, optional - Number of the pin at which to terminate the connection from the left end of the + pin_ending : int, str, list optional + Number or name of the pins at which to terminate the connection from the left end of the ending component. The default is ``1``. + use_wire : bool, optional + Whether to use wires or a page port to connect the pins. + The default is ``True``, in which case wires are used. Note + that if wires are not well placed, shorts can result. Returns ------- @@ -156,39 +161,21 @@ def connect_schematic_components(self, starting_component, ending_component, pin """ if self._app.design_type == "Maxwell Circuit": components = self.schematic.components - obj1 = components[starting_component] else: components = self.components - obj1 = components[starting_component] - if "Port" in obj1.composed_name: - pos1 = self.oeditor.GetPropertyValue("BaseElementTab", obj1.composed_name, "Component Location").split(", ") - pos1 = [float(i.strip()[:-3]) * 0.0000254 for i in pos1] - if "GPort" in obj1.composed_name: - pos1[1] += 0.00254 - else: - if self._app.design_type == "Maxwell Circuit": - pos1 = [float(re.sub(r"[^0-9.\-]", "", x)) * 0.0000254 for x in obj1.location] - else: - pins1 = components.get_pins(starting_component) - pos1 = components.get_pin_location(starting_component, pins1[pin_starting - 1]) - obj2 = components[ending_component] - if "Port" in obj2.composed_name: - pos2 = self.oeditor.GetPropertyValue("BaseElementTab", obj2.composed_name, "Component Location").split(", ") - pos2 = [float(i.strip()[:-3]) * 0.0000254 for i in pos2] - if "GPort" in obj2.composed_name: - pos2[1] += 0.00254 - - else: - if self._app.design_type == "Maxwell Circuit": - pos2 = [float(re.sub(r"[^0-9.\-]", "", x)) * 0.0000254 for x in obj2.location] - else: - pins2 = components.get_pins(ending_component) - pos2 = components.get_pin_location(ending_component, pins2[pin_ending - 1]) - try: - self.schematic.create_wire([pos1, pos2]) - return True - except Exception: - return False + start = components[starting_component] + end = components[ending_component] + if isinstance(pin_starting, (int, str)): + pin_starting = [pin_starting] + if isinstance(pin_ending, (int, str)): + pin_ending = [pin_ending] + for pstart, pend in zip(pin_starting, pin_ending): + try: + start[pstart].connect_to_component(end[pend], use_wire=use_wire) + except: + self.logger.error("Failed to connect pin {} with {}".format(pstart, pend)) + return False + return True @pyaedt_function_handler() def create_text( From da56a8fa99f80f629f89e876b9016963f7c92f52 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:50:17 +0200 Subject: [PATCH 02/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index c309834f5a0..232b761d091 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -1967,7 +1967,7 @@ def create_ami_schematic_from_snp( ibis_rx_file : str, optional Ibis receiver file. create_setup : bool, optional - Whether if create transient or ami setup or not. The default is ``True``. + Whether to create a transient or an ami setup. The default is ``True``. Returns ------- From 23475b78cf76ea63c05810a5be9276ab072bd4f3 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:50:25 +0200 Subject: [PATCH 03/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 232b761d091..143ad44c44f 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2030,7 +2030,7 @@ def create_ibis_schematic_from_snp( ibis_tx_file : str Full path to the IBIS file. tx_buffer_name : str - Transmission buffer name. It can be a buffer or a ibis pin name. + Transmission buffer name. It can be a buffer or an ibis pin name. In this last case the user has to provide also the component_name. rx_buffer_name : str Receiver buffer name. From 4fe471a98af079ef2ae171f5fbb9e37a3f8b524c Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:50:34 +0200 Subject: [PATCH 04/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 143ad44c44f..47f0e2d8c10 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2031,7 +2031,7 @@ def create_ibis_schematic_from_snp( Full path to the IBIS file. tx_buffer_name : str Transmission buffer name. It can be a buffer or an ibis pin name. - In this last case the user has to provide also the component_name. + In the latter case the user has to provide also the component_name. rx_buffer_name : str Receiver buffer name. tx_pins : list From e13385726f2486fa6df9a1382dd9b6c57013530a Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:50:41 +0200 Subject: [PATCH 05/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 47f0e2d8c10..b4ff0d4093a 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2035,7 +2035,7 @@ def create_ibis_schematic_from_snp( rx_buffer_name : str Receiver buffer name. tx_pins : list - Pins to assign the transmitter IBIS. + Pins to assign to the transmitter IBIS. rx_pins : list, optional Pins to assign the receiver IBIS. tx_refs : list, optional From f5d9e340ae09d4e7c7485dbb841a5b0b6ecd281c Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:50:54 +0200 Subject: [PATCH 06/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index b4ff0d4093a..2f827f3a0ce 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2037,7 +2037,7 @@ def create_ibis_schematic_from_snp( tx_pins : list Pins to assign to the transmitter IBIS. rx_pins : list, optional - Pins to assign the receiver IBIS. + Pins to assign to the receiver IBIS. tx_refs : list, optional Reference pins to assign the transmitter IBIS. This parameter is only used in a differential configuration. From 67b0148781f4a55fd4d17132be3db8db3eb7dec4 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:51:01 +0200 Subject: [PATCH 07/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 2f827f3a0ce..75b7e0d0c18 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2064,7 +2064,7 @@ def create_ibis_schematic_from_snp( design_name : str, optional New schematic name. The default is ``"IBIS"``. is_ami : bool, optional - Whether if the ibis is AMI or not. The default is ``False``. + Whether the ibis is AMI. The default is ``False``. ibis_rx_file : str, optional Ibis receiver file. create_setup : bool, optional From 00ec96c0b65273bfc4bb9ac99b912598ccf2b788 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:51:09 +0200 Subject: [PATCH 08/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 75b7e0d0c18..d50fd591031 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2039,7 +2039,7 @@ def create_ibis_schematic_from_snp( rx_pins : list, optional Pins to assign to the receiver IBIS. tx_refs : list, optional - Reference pins to assign the transmitter IBIS. This parameter is only used in + Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. rx_refs : list Reference pins to assign the receiver IBIS. This parameter is only used From 6986ddf1a46fd382909ef3941b9cdd95e215c213 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:51:15 +0200 Subject: [PATCH 09/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index d50fd591031..28ac969949f 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2042,7 +2042,7 @@ def create_ibis_schematic_from_snp( Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. rx_refs : list - Reference pins to assign the receiver IBIS. This parameter is only used + Reference pins to assign to the receiver IBIS. This parameter is only used in a differential configuration. component_name : str, optional Component name in the IBIS file to assign to components. From f523d236dbca7bce04071c68e307fae8f8bdaf26 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:51:23 +0200 Subject: [PATCH 10/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 28ac969949f..690f9db41cd 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2068,7 +2068,7 @@ def create_ibis_schematic_from_snp( ibis_rx_file : str, optional Ibis receiver file. create_setup : bool, optional - Whether if create transient or ami setup or not. The default is ``True``. + Whether to create transient or ami setup. The default is ``True``. Returns ------- From 8d44e6d0c6d7f2333dbe5a3a1064a5e420991aff Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:51:32 +0200 Subject: [PATCH 11/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 690f9db41cd..d675dd52715 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2145,7 +2145,7 @@ def create_ibis_schematic_from_pins( rx_buffer_name : str Receiver buffer name. tx_pins : list - Pins to assign the transmitter IBIS. + Pins to assign to the transmitter IBIS. rx_pins : list, optional Pins to assign the receiver IBIS. tx_refs : list, optional From f70b49c7cc51a9f4413ed5886e7d16e5180c19a6 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:51:39 +0200 Subject: [PATCH 12/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index d675dd52715..700826fccf6 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2147,7 +2147,7 @@ def create_ibis_schematic_from_pins( tx_pins : list Pins to assign to the transmitter IBIS. rx_pins : list, optional - Pins to assign the receiver IBIS. + Pins to assign to the receiver IBIS. tx_refs : list, optional Reference pins to assign the transmitter IBIS. This parameter is only used in a differential configuration. From 7aec56ef0876f5d46424ddf9b7a4967d77967447 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:52:10 +0200 Subject: [PATCH 13/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 700826fccf6..084c656aaba 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2149,7 +2149,7 @@ def create_ibis_schematic_from_pins( rx_pins : list, optional Pins to assign to the receiver IBIS. tx_refs : list, optional - Reference pins to assign the transmitter IBIS. This parameter is only used in + Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. rx_refs : list Reference pins to assign the receiver IBIS. This parameter is only used From 9be045672eed49e68a3b594d67f0be9b52775f34 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:52:18 +0200 Subject: [PATCH 14/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 084c656aaba..083690b72f3 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2155,7 +2155,7 @@ def create_ibis_schematic_from_pins( Reference pins to assign the receiver IBIS. This parameter is only used in a differential configuration. tx_component_name : str, optional - Name of component to which tx_pins belongs. + Component name to which tx_pins belongs. rx_component_name : str, optional Name of component to which rx_pins belongs. ibis_component_name : str, optional From ee367a6190a62d9487a1050729c153b3695017a8 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:52:24 +0200 Subject: [PATCH 15/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 083690b72f3..4c08fc32cef 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2152,7 +2152,7 @@ def create_ibis_schematic_from_pins( Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. rx_refs : list - Reference pins to assign the receiver IBIS. This parameter is only used + Reference pins to assign to the receiver IBIS. This parameter is only used in a differential configuration. tx_component_name : str, optional Component name to which tx_pins belongs. From f3b14e58f079c7ea8b48b3920cf3dd00b0788d8d Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:52:32 +0200 Subject: [PATCH 16/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 4c08fc32cef..5854efc376b 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2157,7 +2157,7 @@ def create_ibis_schematic_from_pins( tx_component_name : str, optional Component name to which tx_pins belongs. rx_component_name : str, optional - Name of component to which rx_pins belongs. + Component name to which rx_pins belongs. ibis_component_name : str, optional Component name in the IBIS file to assign to components. Needed only when ibis component pins are used. From 4f5925e2801091e01833b7b2cae741062de4283f Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:52:41 +0200 Subject: [PATCH 17/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 5854efc376b..a60f07bede0 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2178,7 +2178,7 @@ def create_ibis_schematic_from_pins( is_ami : bool, optional Whether if the ibis is AMI or not. The default is ``False``. create_setup : bool, optional - Whether if create transient or ami setup or not. The default is ``True``. + Whether to create transient or ami setup. The default is ``True``. Returns From f01299bfa9e1bcb4c3e7ef5952f2edb823963334 Mon Sep 17 00:00:00 2001 From: Massimo Capodiferro <77293250+maxcapodi78@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:52:53 +0200 Subject: [PATCH 18/20] Update pyaedt/circuit.py Co-authored-by: gmalinve <103059376+gmalinve@users.noreply.github.com> --- pyaedt/circuit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index a60f07bede0..9d85034e08f 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2176,7 +2176,7 @@ def create_ibis_schematic_from_pins( analyze : bool Whether to automatically assign differential pairs. The default is ``False``. is_ami : bool, optional - Whether if the ibis is AMI or not. The default is ``False``. + Whether the ibis is AMI. The default is ``False``. create_setup : bool, optional Whether to create transient or ami setup. The default is ``True``. From 764dfab9b810b91eeabfc8d64ffe7daf7deb66e1 Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Fri, 19 Jul 2024 14:22:58 +0200 Subject: [PATCH 19/20] fixing naming and examples --- _unittest/test_21_Circuit.py | 23 ++- examples/07-Circuit/Virtual_Compliance.py | 24 +-- pyaedt/circuit.py | 188 +++++++++++++--------- 3 files changed, 134 insertions(+), 101 deletions(-) diff --git a/_unittest/test_21_Circuit.py b/_unittest/test_21_Circuit.py index 90aa2dbc9bb..b7a7adf1f31 100644 --- a/_unittest/test_21_Circuit.py +++ b/_unittest/test_21_Circuit.py @@ -893,8 +893,8 @@ def test_48_automatic_tdr(self): result, tdr_probe_name = self.aedtapp.create_tdr_schematic_from_snp( input_file=touchstone_file, - probe_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], - probe_ref_pins=["A-MII-RXD1_65.SQFP20X20_144.N"], + tx_schematic_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], + tx_schematic_differential_pins=["A-MII-RXD1_65.SQFP20X20_144.N"], termination_pins=["A-MII-RXD2_32.SQFP28X28_208.P", "A-MII-RXD2_66.SQFP20X20_144.N"], differential=True, rise_time=35, @@ -910,14 +910,13 @@ def test_49_automatic_ami(self): ami_file = os.path.join(local_path, "example_models", test_subfolder, "pcieg5_32gt.ibs") result, eye_curve_tx, eye_curve_rx = self.aedtapp.create_ami_schematic_from_snp( input_file=touchstone_file, - ibis_ami=ami_file, - component_name="Spec_Model", + ibis_tx_file=ami_file, tx_buffer_name="1p", rx_buffer_name="2p", - tx_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], - tx_refs=["A-MII-RXD1_65.SQFP20X20_144.N"], - rx_pins=["A-MII-RXD2_32.SQFP28X28_208.P"], - rx_refs=["A-MII-RXD2_66.SQFP20X20_144.N"], + tx_schematic_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], + rx_schematic_pins=["A-MII-RXD2_32.SQFP28X28_208.P"], + tx_schematic_differential_pins=["A-MII-RXD1_65.SQFP20X20_144.N"], + rx_schematic_differentialial_pins=["A-MII-RXD2_66.SQFP20X20_144.N"], use_ibis_buffer=False, differential=True, bit_pattern="random_bit_count=2.5e3 random_seed=1", @@ -934,12 +933,12 @@ def test_49_automatic_ibis(self): ibis_file = os.path.join(local_path, "example_models", "T15", "u26a_800_modified.ibs") result, eye_curve_tx, eye_curve_rx = self.aedtapp.create_ibis_schematic_from_snp( input_file=touchstone_file, - ibis_file=ibis_file, - component_name=None, + ibis_tx_file=ibis_file, tx_buffer_name="DQ_FULL_800", rx_buffer_name="DQ_FULL_800", - tx_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], - rx_pins=["A-MII-RXD2_32.SQFP28X28_208.P"], + tx_schematic_pins=["A-MII-RXD1_30.SQFP28X28_208.P"], + rx_schematic_pins=["A-MII-RXD2_32.SQFP28X28_208.P"], + ibis_rx_file=ibis_file, use_ibis_buffer=True, differential=False, bit_pattern="random_bit_count=2.5e3 random_seed=1", diff --git a/examples/07-Circuit/Virtual_Compliance.py b/examples/07-Circuit/Virtual_Compliance.py index 05fbe880dd8..3c9f444ddb7 100644 --- a/examples/07-Circuit/Virtual_Compliance.py +++ b/examples/07-Circuit/Virtual_Compliance.py @@ -92,8 +92,8 @@ # The original circuit schematic is duplicated and modified to achieve this target. result, tdr_probe_name = cir.create_tdr_schematic_from_snp(input_file=touchstone_path, - probe_pins=["X1.A2.PCIe_Gen4_RX0_P"], - probe_ref_pins=["X1.A3.PCIe_Gen4_RX0_N"], + tx_schematic_pins=["X1.A2.PCIe_Gen4_RX0_P"], + tx_schematic_differential_pins=["X1.A3.PCIe_Gen4_RX0_N"], termination_pins=["U1.AP26.PCIe_Gen4_RX0_P", "U1.AN26.PCIe_Gen4_RX0_N"], differential=True, rise_time=35, use_convolution=True, @@ -105,14 +105,18 @@ # Create an Ibis AMI project to compute an eye diagram simulation and retrieve # eye mask violations. result, eye_curve_tx, eye_curve_rx = cir.create_ami_schematic_from_snp(input_file=touchstone_path, - ibis_ami=os.path.join(projectdir, "models", - "pcieg5_32gt.ibs"), - component_name="Spec_Model", tx_buffer_name="1p", - rx_buffer_name="2p", - tx_pins=["U1.AM25.PCIe_Gen4_TX0_CAP_P"], - tx_refs=["U1.AL25.PCIe_Gen4_TX0_CAP_N"], - rx_pins=["X1.B2.PCIe_Gen4_TX0_P"], - rx_refs=["X1.B3.PCIe_Gen4_TX0_N"], + ibis_tx_file=os.path.join(projectdir, "models", + "pcieg5_32gt.ibs"), + tx_buffer_name="1p", rx_buffer_name="2p", + tx_schematic_pins=[ + "U1.AM25.PCIe_Gen4_TX0_CAP_P"], + rx_schematic_pins=[ + "X1.B2.PCIe_Gen4_TX0_P"], + tx_schematic_differential_pins=[ + "U1.AL25.PCIe_Gen4_TX0_CAP_N"], + rx_schematic_differentialial_pins=[ + "X1.B3.PCIe_Gen4_TX0_N"], + ibis_tx_component_name="Spec_Model", use_ibis_buffer=False, differential=True, bit_pattern="random_bit_count=2.5e3 random_seed=1", unit_interval="31.25ps", use_convolution=True, diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index 9d85034e08f..a75e8c6b560 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -1659,12 +1659,14 @@ def import_edb_in_circuit(self, input_dir): hfss.close_project(save=False) return hfss_3d_layout_model - @pyaedt_function_handler(touchstone="input_file") + @pyaedt_function_handler( + touchstone="input_file", probe_pins="tx_schematic_pins", probe_ref_pins="tx_schematic_differential_pins" + ) def create_tdr_schematic_from_snp( self, input_file, - probe_pins, - probe_ref_pins=None, + tx_schematic_pins, + tx_schematic_differential_pins=None, termination_pins=None, differential=True, rise_time=30, @@ -1678,9 +1680,9 @@ def create_tdr_schematic_from_snp( ---------- input_file : str Full path to the sNp file. - probe_pins : list + tx_schematic_pins : list List of pins to attach to the probe components. - probe_ref_pins : list, optional + tx_schematic_differential_pins : list, optional Reference pins to attach to probe components. The default is ``None``. This parameter is valid only in differential TDR probes. termination_pins : list, optional @@ -1715,13 +1717,13 @@ def create_tdr_schematic_from_snp( center_x = sub.location[0] center_y = sub.location[1] left = 0 - delta_y = -1 * sub.location[1] - 2000 - 50 * len(probe_pins) + delta_y = -1 * sub.location[1] - 2000 - 50 * len(tx_schematic_pins) if differential: tdr_probe = self.modeler.components.components_catalog["TDR_Differential_Ended"] else: tdr_probe = self.modeler.components.components_catalog["TDR_Single_Ended"] tdr_probe_names = [] - for i, probe_pin in enumerate(probe_pins): + for i, probe_pin in enumerate(tx_schematic_pins): pos_y = unit_converter(delta_y - left * 1000, input_units="mil", output_units=self.modeler.schematic_units) left += 1 new_tdr_comp = tdr_probe.place("Tdr_probe", [center_x, center_y + pos_y], angle=-90) @@ -1729,11 +1731,11 @@ def create_tdr_schematic_from_snp( if isinstance(probe_pin, int): p_pin = probe_pin if differential: - n_pin = probe_ref_pins[i] + n_pin = tx_schematic_differential_pins[i] else: p_pin = [k for k in sub.pins if k.name == probe_pin][0] if differential: - n_pin = [k for k in sub.pins if k.name == probe_ref_pins[i]][0] + n_pin = [k for k in sub.pins if k.name == tx_schematic_differential_pins[i]][0] except IndexError: self.logger.error("Failed to retrieve the pins.") return False @@ -1902,18 +1904,26 @@ def create_lna_schematic_from_snp( self.analyze() return True, diff_pairs, comm_pairs - @pyaedt_function_handler(touchstone="input_file") + @pyaedt_function_handler( + touchstone="input_file", + ibis_ami="ibis_tx_file", + tx_pins="tx_schematic_pins", + rx_pins="rx_schematic_pins", + tx_refs="tx_schematic_differential_pins", + rx_refs="rx_schematic_differentialial_pins", + ) def create_ami_schematic_from_snp( self, input_file, - ibis_ami, - component_name, + ibis_tx_file, tx_buffer_name, rx_buffer_name, - tx_pins, - rx_pins, - tx_refs, - rx_refs, + tx_schematic_pins, + rx_schematic_pins, + tx_schematic_differential_pins=None, + rx_schematic_differentialial_pins=None, + ibis_tx_component_name=None, + ibis_rx_component_name=None, use_ibis_buffer=True, differential=True, bit_pattern=None, @@ -1930,22 +1940,26 @@ def create_ami_schematic_from_snp( ---------- input_file : str Full path to the sNp file. - ibis_ami : str + ibis_tx_file : str Full path to the IBIS file. - component_name : str - Component name in the IBIS file to assign to components. + ibis_tx_component_name : str, optional + IBIS component name to use for the simulation of the transmitter. + This parameter is needed only if IBIS component pins are used. + ibis_rx_component_name : str, optional + IBIS component name to use for the simulation of the receiver. + This parameter is needed only if IBIS component pins are used. tx_buffer_name : str Transmission buffer name. rx_buffer_name : str Receiver buffer name - tx_pins : list + tx_schematic_pins : list Pins to assign the transmitter IBIS. - tx_refs : list + tx_schematic_differential_pins : list Reference pins to assign the transmitter IBIS. This parameter is only used in a differential configuration. - rx_pins : list + rx_schematic_pins : list Pins to assign the receiver IBIS. - rx_refs : list + rx_schematic_differentialial_pins : list Reference pins to assign the receiver IBIS. This parameter is only used in a differential configuration. use_ibis_buffer : bool, optional @@ -1978,14 +1992,16 @@ def create_ami_schematic_from_snp( return self.create_ibis_schematic_from_snp( input_file=input_file, - ibis_tx_file=ibis_ami, - component_name=component_name, + ibis_tx_file=ibis_tx_file, tx_buffer_name=tx_buffer_name, rx_buffer_name=rx_buffer_name, - tx_pins=tx_pins, - tx_refs=tx_refs, - rx_pins=rx_pins, - rx_refs=rx_refs, + tx_schematic_pins=tx_schematic_pins, + rx_schematic_pins=rx_schematic_pins, + ibis_rx_file=ibis_rx_file, + tx_schematic_differential_pins=tx_schematic_differential_pins, + rx_schematic_differential_pins=rx_schematic_differentialial_pins, + ibis_tx_component_name=ibis_tx_component_name, + ibis_rx_component_name=ibis_rx_component_name, use_ibis_buffer=use_ibis_buffer, differential=differential, bit_pattern=bit_pattern, @@ -1994,7 +2010,6 @@ def create_ami_schematic_from_snp( analyze=analyze, design_name=design_name, is_ami=True, - ibis_rx_file=ibis_rx_file, create_setup=create_setup, ) @@ -2005,12 +2020,13 @@ def create_ibis_schematic_from_snp( ibis_tx_file, tx_buffer_name, rx_buffer_name, - tx_pins, - rx_pins, + tx_schematic_pins, + rx_schematic_pins, ibis_rx_file=None, - tx_refs=None, - rx_refs=None, - component_name=None, + tx_schematic_differential_pins=None, + rx_schematic_differential_pins=None, + ibis_tx_component_name=None, + ibis_rx_component_name=None, use_ibis_buffer=True, differential=True, bit_pattern=None, @@ -2034,19 +2050,22 @@ def create_ibis_schematic_from_snp( In the latter case the user has to provide also the component_name. rx_buffer_name : str Receiver buffer name. - tx_pins : list + tx_schematic_pins : list Pins to assign to the transmitter IBIS. - rx_pins : list, optional + rx_schematic_pins : list, optional Pins to assign to the receiver IBIS. - tx_refs : list, optional + tx_schematic_differential_pins : list, optional Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. - rx_refs : list + rx_schematic_differential_pins : list Reference pins to assign to the receiver IBIS. This parameter is only used in a differential configuration. - component_name : str, optional - Component name in the IBIS file to assign to components. - Needed only when ibis component pins are used. + ibis_tx_component_name : str, optional + IBIS component name to use for the simulation of the transmitter. + This parameter is needed only if IBIS component pins are used. + ibis_rx_component_name : str, optional + IBIS component name to use for the simulation of the receiver. + This parameter is needed only if IBIS component pins are used. use_ibis_buffer : bool, optional Whether to use the IBIS buffer. The default is ``True``. If ``False``, pins are used. differential : bool, optional @@ -2088,14 +2107,16 @@ def create_ibis_schematic_from_snp( sub = self.modeler.components.create_touchstone_component(touchstone_path) return self.create_ibis_schematic_from_pins( ibis_tx_file=ibis_tx_file, + ibis_rx_file=ibis_rx_file, tx_buffer_name=tx_buffer_name, rx_buffer_name=rx_buffer_name, - tx_pins=tx_pins, - rx_pins=rx_pins, - tx_refs=tx_refs, - rx_refs=rx_refs, + tx_schematic_pins=tx_schematic_pins, + rx_schematic_pins=rx_schematic_pins, + tx_schematic_differential_pins=tx_schematic_differential_pins, + rx_schematic_differential_pins=rx_schematic_differential_pins, tx_component_name=sub.name, - ibis_component_name=component_name, + ibis_tx_component_name=ibis_tx_component_name, + ibis_rx_component_name=ibis_rx_component_name, use_ibis_buffer=use_ibis_buffer, differential=differential, bit_pattern=bit_pattern, @@ -2103,7 +2124,6 @@ def create_ibis_schematic_from_snp( use_convolution=use_convolution, analyze=analyze, is_ami=is_ami, - ibis_rx_file=ibis_rx_file, create_setup=create_setup, ) @@ -2114,13 +2134,14 @@ def create_ibis_schematic_from_pins( ibis_rx_file=None, tx_buffer_name="", rx_buffer_name="", - tx_pins=None, - rx_pins=None, - tx_refs=None, - rx_refs=None, + tx_schematic_pins=None, + rx_schematic_pins=None, + tx_schematic_differential_pins=None, + rx_schematic_differential_pins=None, tx_component_name=None, rx_component_name=None, - ibis_component_name=None, + ibis_tx_component_name=None, + ibis_rx_component_name=None, use_ibis_buffer=True, differential=True, bit_pattern=None, @@ -2144,23 +2165,26 @@ def create_ibis_schematic_from_pins( In this last case the user has to provide also the component_name. rx_buffer_name : str Receiver buffer name. - tx_pins : list + tx_schematic_pins : list Pins to assign to the transmitter IBIS. - rx_pins : list, optional + rx_schematic_pins : list, optional Pins to assign to the receiver IBIS. - tx_refs : list, optional + tx_schematic_differential_pins : list, optional Reference pins to assign to the transmitter IBIS. This parameter is only used in a differential configuration. - rx_refs : list + rx_schematic_differential_pins : list Reference pins to assign to the receiver IBIS. This parameter is only used in a differential configuration. tx_component_name : str, optional - Component name to which tx_pins belongs. + Component name in AEDT circuit schematic to which tx_pins belongs. rx_component_name : str, optional - Component name to which rx_pins belongs. - ibis_component_name : str, optional - Component name in the IBIS file to assign to components. - Needed only when ibis component pins are used. + Component name in AEDT circuit schematic to which rx_pins belongs. + ibis_tx_component_name : str, optional + IBIS component name to use for the simulation of the transmitter. + This parameter is needed only if IBIS component pins are used. + ibis_rx_component_name : str, optional + IBIS component name to use for the simulation of the receiver. + This parameter is needed only if IBIS component pins are used. use_ibis_buffer : bool, optional Whether to use the IBIS buffer. The default is ``True``. If ``False``, pins are used. differential : bool, optional @@ -2209,8 +2233,8 @@ def create_ibis_schematic_from_pins( center_x_rx = subx.location[0] center_y_rx = subx.location[1] left = 0 - delta_y = center_y - 0.0508 - 0.00127 * len(tx_pins) - delta_y_rx = center_y_rx - 0.0508 - 0.00127 * len(tx_pins) + delta_y = center_y - 0.0508 - 0.00127 * len(tx_schematic_pins) + delta_y_rx = center_y_rx - 0.0508 - 0.00127 * len(tx_schematic_pins) for el in self.modeler.components.components.values(): if delta_y >= el.bounding_box[1]: delta_y = el.bounding_box[1] - 0.02032 @@ -2225,22 +2249,22 @@ def create_ibis_schematic_from_pins( tx_eye_names = [] rx_eye_names = [] - for j in range(len(tx_pins)): - pos_x = center_x - unit_converter(1200, input_units="mil", output_units=self.modeler.schematic_units) + for j in range(len(tx_schematic_pins)): + pos_x = center_x - unit_converter(2000, input_units="mil", output_units=self.modeler.schematic_units) pos_y = delta_y + unit_converter( left * 0.02032, input_units="meter", output_units=self.modeler.schematic_units ) - pos_x_rx = center_x_rx + unit_converter(1200, input_units="mil", output_units=self.modeler.schematic_units) + pos_x_rx = center_x_rx + unit_converter(2000, input_units="mil", output_units=self.modeler.schematic_units) pos_y_rx = delta_y_rx + unit_converter( left * 0.02032, input_units="mil", output_units=self.modeler.schematic_units ) left += 1 - p_pin1 = sub[tx_pins[j]] - p_pin2 = subx[rx_pins[j]] + p_pin1 = sub[tx_schematic_pins[j]] + p_pin2 = subx[rx_schematic_pins[j]] if differential: - n_pin1 = sub.pin[tx_refs[j]] - n_pin2 = subx.pins[rx_refs[j]] + n_pin1 = sub[tx_schematic_differential_pins[j]] + n_pin2 = subx[rx_schematic_differential_pins[j]] if use_ibis_buffer: buf = [k for k in ibis.buffers.keys() if k.startswith(tx_buffer_name + "_")] @@ -2256,20 +2280,26 @@ def create_ibis_schematic_from_pins( if rx.location[0] < rx.pins[0].location[0]: rx.angle = 0 else: - buf = [ - k for k in ibis.components[ibis_component_name].pins.keys() if k.startswith(tx_buffer_name + "_") - ] + if ibis_tx_component_name: + cmp_tx = ibis.components[ibis_tx_component_name] + else: + cmp_tx = list(ibis.components.values())[0] + if ibis_rx_component_name: + cmp_rx = ibis.components[ibis_tx_component_name] + elif not ibis_rx_file: + cmp_rx = cmp_tx + else: + cmp_rx = list(ibis_rx.components.values())[0] + buf = [k for k in cmp_tx.pins.keys() if k.startswith(tx_buffer_name + "_")] if differential: buf = [k for k in buf if k.endswith("diff")] - tx = ibis.components[ibis_component_name].pins[buf[0]].insert(pos_x, pos_y) + tx = cmp_tx.pins[buf[0]].insert(pos_x, pos_y) if tx.location[0] > tx.pins[0].location[0]: tx.angle = 180 - buf = [ - k for k in ibis_rx.components[ibis_component_name].pins.keys() if k.startswith(rx_buffer_name + "_") - ] + buf = [k for k in cmp_rx.pins.keys() if k.startswith(rx_buffer_name + "_")] if differential: buf = [k for k in buf if k.endswith("diff")] - rx = ibis_rx.components[ibis_component_name].pins[buf[0]].insert(pos_x_rx, pos_y_rx, 180) + rx = cmp_rx.pins[buf[0]].insert(pos_x_rx, pos_y_rx, 180) if rx.location[0] < rx.pins[0].location[0]: rx.angle = 0 _, first_tx, second_tx = tx.pins[0].connect_to_component(p_pin1, page_port_angle=180) From 2d3c8873a0d0674e75af6a70407a3f472e36b474 Mon Sep 17 00:00:00 2001 From: maxcapodi78 Date: Fri, 19 Jul 2024 14:56:07 +0200 Subject: [PATCH 20/20] codacy --- pyaedt/circuit.py | 6 +++--- pyaedt/modeler/schematic.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyaedt/circuit.py b/pyaedt/circuit.py index a75e8c6b560..5b257d538af 100644 --- a/pyaedt/circuit.py +++ b/pyaedt/circuit.py @@ -2221,7 +2221,7 @@ def create_ibis_schematic_from_pins( or "ModelName" in v.parameters and v.parameters["ModelName"] == "FieldSolver" ][0] - except: + except Exception: self.logger.error("A component has to be passed or an Sparameter present.") return False if rx_component_name is None: @@ -2267,13 +2267,13 @@ def create_ibis_schematic_from_pins( n_pin2 = subx[rx_schematic_differential_pins[j]] if use_ibis_buffer: - buf = [k for k in ibis.buffers.keys() if k.startswith(tx_buffer_name + "_")] + buf = [k for k, _ in ibis.buffers.items() if k.startswith(tx_buffer_name + "_")] if differential: buf = [k for k in buf if k.endswith("diff")] tx = ibis.buffers[buf[0]].insert(pos_x, pos_y) if tx.location[0] > tx.pins[0].location[0]: tx.angle = 180 - buf = [k for k in ibis_rx.buffers.keys() if k.startswith(rx_buffer_name + "_")] + buf = [k for k, _ in ibis_rx.buffers.items() if k.startswith(rx_buffer_name + "_")] if differential: buf = [k for k in buf if k.endswith("diff")] rx = ibis_rx.buffers[buf[0]].insert(pos_x_rx, pos_y_rx, 180) diff --git a/pyaedt/modeler/schematic.py b/pyaedt/modeler/schematic.py index 419a1f5c215..42df7fb6f52 100644 --- a/pyaedt/modeler/schematic.py +++ b/pyaedt/modeler/schematic.py @@ -172,7 +172,7 @@ def connect_schematic_components( for pstart, pend in zip(pin_starting, pin_ending): try: start[pstart].connect_to_component(end[pend], use_wire=use_wire) - except: + except Exception: self.logger.error("Failed to connect pin {} with {}".format(pstart, pend)) return False return True