Exemple #1
0
    def get_parts(self, use_backup_lib=True, **criteria):
        """
        Return parts from a library that match *all* the given criteria.

        Keyword Args:
            criteria: One or more keyword-argument pairs. The keyword specifies
                the attribute name while the argument contains the desired value
                of the attribute.

        Returns:
            A single Part or a list of Parts that match all the criteria.
        """

        import skidl

        parts = list_or_scalar(filter_list(self.parts, **criteria))
        if not parts and use_backup_lib and skidl.QUERY_BACKUP_LIB:
            try:
                backup_lib_ = skidl.load_backup_lib()
                parts = backup_lib_.get_parts(use_backup_lib=False, **criteria)
            except AttributeError:
                pass
        return parts
Exemple #2
0
    def get_parts(self, use_backup_lib=True, **criteria):
        """
        Return parts from a library that match *all* the given criteria.

        Keyword Args:
            criteria: One or more keyword-argument pairs. The keyword specifies
                the attribute name while the argument contains the desired value
                of the attribute.

        Returns:
            A single Part or a list of Parts that match all the criteria.
        """

        import skidl

        parts = list_or_scalar(filter_list(self.parts, **criteria))
        if not parts and use_backup_lib and skidl.QUERY_BACKUP_LIB:
            try:
                backup_lib_ = skidl.load_backup_lib()
                parts = backup_lib_.get_parts(use_backup_lib=False, **criteria)
            except AttributeError:
                pass
        return parts
Exemple #3
0
    def __init__(self,
                 lib=None,
                 name=None,
                 dest=NETLIST,
                 tool=None,
                 connections=None,
                 part_defn=None,
                 circuit=None,
                 **attribs):

        import skidl
        from .SchLib import SchLib
        from .defines import TEMPLATE, NETLIST, LIBRARY, SKIDL

        super(Part, self).__init__()

        if tool is None:
            tool = skidl.get_default_tool()

        # Setup some part attributes that might be overwritten later on.
        self.do_erc = True  # Allow part to be included in ERC.
        self.unit = {
        }  # Dictionary for storing subunits of the part, if desired.
        self.pins = []  # Start with no pins, but a place to store them.
        self.name = name  # Assign initial part name. (Must come after circuit is assigned.)
        self.description = ''  # Make sure there is a description, even if empty.
        self._ref = ''  # Provide a member for holding a reference.
        self.ref_prefix = ''  # Provide a member for holding the part reference prefix.
        self.tool = tool  # Initial type of part (SKIDL, KICAD, etc.)
        self.circuit = None  # Part starts off unassociated with any circuit.

        # Create a Part from a library entry.
        if lib:
            # If the lib argument is a string, then create a library using the
            # string as the library file name.
            if isinstance(lib, basestring):
                try:
                    libname = lib
                    lib = SchLib(filename=libname, tool=tool)
                except Exception as e:
                    if skidl.QUERY_BACKUP_LIB:
                        logger.warning(
                            'Could not load KiCad schematic library "{}", falling back to backup library.'
                            .format(libname))
                        lib = skidl.load_backup_lib()
                        if not lib:
                            raise e
                    else:
                        raise e

            # Make a copy of the part from the library but don't add it to the netlist.
            part = lib[name].copy(dest=TEMPLATE)

            # Overwrite self with the new part.
            self.__dict__.update(part.__dict__)

            # Make sure all the pins have a valid reference to this part.
            self.associate_pins()

            # Store the library name of this part.
            self.lib = getattr(lib, 'filename', None)

        # Otherwise, create a Part from a part definition. If the part is
        # destined for a library, then just get its name. If it's going into
        # a netlist, then parse the entire part definition.
        elif part_defn:
            self.part_defn = part_defn
            self.parse(just_get_name=(dest != NETLIST))

        # If the part is destined for a SKiDL library, then it will be defined
        # by the additional attribute values that are passed.
        elif tool == SKIDL and name:
            pass

        else:
            logger.error(
                "Can't make a part without a library & part name or a part definition."
            )
            raise Exception

        # If the part is going to be an element in a circuit, then add it to the
        # the circuit and make any indicated pin/net connections.
        if dest != LIBRARY:
            if dest == NETLIST:
                # If no Circuit object is given, then use the default Circuit that always exists.
                # Always set circuit first because naming the part requires a lookup
                # of existing names in the circuit.
                if not circuit:
                    circuit = default_circuit  # pylint: disable=undefined-variable
                circuit += self
            elif dest == TEMPLATE:
                # If this is just a part template, don't add the part to the circuit.
                # Just place the reference to the Circuit object in the template.
                if not circuit:
                    self.circuit = default_circuit  # pylint: disable=undefined-variable
                self.circuit = circuit

            # Add any net/pin connections to this part that were passed as arguments.
            if isinstance(connections, dict):
                for pin, net in connections.items():
                    net += self[pin]

            # Add any other passed-in attributes to the part.
            for k, v in attribs.items():
                setattr(self, k, v)
Exemple #4
0
    def __init__(self,
                 lib=None,
                 name=None,
                 dest=NETLIST,
                 tool=None,
                 connections=None,
                 part_defn=None,
                 circuit=None,
                 **attribs):

        import skidl
        from .SchLib import SchLib

        super().__init__()

        if tool is None:
            tool = skidl.get_default_tool()

        # Setup some part attributes that might be overwritten later on.
        self.do_erc = True  # Allow part to be included in ERC.
        self.unit = {
        }  # Dictionary for storing subunits of the part, if desired.
        self.pins = []  # Start with no pins, but a place to store them.
        self.p = PinNumberSearch(
            self)  # Does pin search using only pin numbers.
        self.n = PinNameSearch(self)  # Does pin search using only pin names.
        self.name = name  # Assign initial part name.
        self.description = ""  # Make sure there is a description, even if empty.
        self._ref = ""  # Provide a member for holding a reference.
        self.ref_prefix = ""  # Provide a member for holding the part reference prefix.
        self.tool = tool  # Initial type of part (SKIDL, KICAD, etc.)
        self.circuit = None  # Part starts off unassociated with any circuit.
        self.match_pin_substring = False  # Only select pins with exact name matches.

        # Create a Part from a library entry.
        if lib:
            # If the lib argument is a string, then create a library using the
            # string as the library file name.
            if isinstance(lib, basestring):
                libname = lib
                try:
                    lib = SchLib(filename=libname, tool=tool)
                except FileNotFoundError as e:
                    if skidl.QUERY_BACKUP_LIB:
                        logger.warning(
                            'Could not load KiCad schematic library "{}", falling back to backup library.'
                            .format(libname))
                        lib = skidl.load_backup_lib()
                        if not lib:
                            raise e
                    else:
                        raise e

            # Make a copy of the part from the library but don't add it to the netlist.
            part = lib[name].copy(dest=TEMPLATE)

            # Overwrite self with the new part.
            self.__dict__.update(part.__dict__)

            # Replace the fields with a copy that points to self.
            self.fields = part.fields.copy(attr_obj=self)

            # Make sure all the pins have a valid reference to this part.
            self.associate_pins()

            # Store the library name of this part.
            self.lib = getattr(lib, "filename", None)

        # Otherwise, create a Part from a part definition. If the part is
        # destined for a library, then just get its name. If it's going into
        # a netlist, then parse the entire part definition.
        elif part_defn:
            self.part_defn = part_defn
            self.parse(get_name_only=(dest != NETLIST))

        # If the part is destined for a SKiDL library, then it will be defined
        # by the additional attribute values that are passed.
        elif tool == SKIDL and name:
            pass

        else:
            log_and_raise(
                logger,
                ValueError,
                "Can't make a part without a library & part name or a part definition.",
            )

        # If the part is going to be an element in a circuit, then add it to the
        # the circuit and make any indicated pin/net connections.
        if dest != LIBRARY:
            # If no Circuit object is given, then use the default Circuit that always exists.
            circuit = circuit or default_circuit
            if dest == NETLIST:
                circuit += self
            elif dest == TEMPLATE:
                # If this is just a part template, don't add the part to the circuit.
                # Just place the reference to the Circuit object in the template.
                self.circuit = circuit

            # Add any net/pin connections to this part that were passed as arguments.
            if isinstance(connections, dict):
                for pin, net in list(connections.items()):
                    net += self[pin]

        # Add any XSPICE I/O as pins. (This only happens with SPICE simulations.)
        self.add_xspice_io(attribs.pop("io", []))

        # Add any other passed-in attributes to the part.
        for k, v in list(attribs.items()):
            setattr(self, k, v)
Exemple #5
0
    def __init__(
        self,
        lib=None,
        name=None,
        dest=NETLIST,
        tool=None,
        connections=None,
        part_defn=None,
        circuit=None,
        **kwargs
    ):

        import skidl
        from .schlib import SchLib

        super().__init__()

        if tool is None:
            tool = skidl.get_default_tool()

        # Setup some part attributes that might be overwritten later on.
        self.do_erc = True  # Allow part to be included in ERC.
        self.unit = {}  # Dictionary for storing subunits of the part, if desired.
        self.pins = []  # Start with no pins, but a place to store them.
        self.p = PinNumberSearch(self)  # Does pin search using only pin numbers.
        self.n = PinNameSearch(self)  # Does pin search using only pin names.
        self.name = name  # Assign initial part name.
        self.description = ""  # Make sure there is a description, even if empty.
        self._ref = ""  # Provide a member for holding a reference.
        self.ref_prefix = ""  # Provide a member for holding the part reference prefix.
        self.tool = tool  # Initial type of part (SKIDL, KICAD, etc.)
        self.circuit = None  # Part starts off unassociated with any circuit.
        self.match_pin_regex = False  # Don't allow regex matches of pin names.

        # Remove a part reference if it has been explicitly set as None.
        # Otherwise, this causes the assigned part reference to be incremented twice:
        # once by Circuit.add_parts() and again by setattr().
        ref = kwargs.pop("ref", None)
        if ref:
            kwargs["ref"] = ref

        # Create a Part from a library entry.
        if lib:
            # If the lib argument is a string, then create a library using the
            # string as the library file name.
            if isinstance(lib, basestring):
                libname = lib
                try:
                    lib = SchLib(filename=libname, tool=tool)
                except FileNotFoundError as e:
                    if skidl.QUERY_BACKUP_LIB:
                        logger.warning(
                            'Could not load KiCad schematic library "{}", falling back to backup library.'.format(
                                libname
                            )
                        )
                        lib = skidl.load_backup_lib()
                        if not lib:
                            raise e
                    else:
                        raise e

            # Make a copy of the part from the library but don't add it to the netlist.
            part = lib[name].copy(dest=TEMPLATE)

            # Overwrite self with the new part.
            self.__dict__.update(part.__dict__)

            # Make sure all the pins have a valid reference to this part.
            self.associate_pins()

            # Copy part units so all the pin and part references stay valid.
            self.copy_units(part)

        # Otherwise, create a Part from a part definition. If the part is
        # destined for a library, then just get its name. If it's going into
        # a netlist, then parse the entire part definition.
        elif part_defn:
            self.part_defn = part_defn

            # If given, set the tool version before parsing the part definition.
            # At this time, this is done to support differences between KiCad V5 and V6.
            tool_version = kwargs.pop("tool_version", None)
            if tool_version:
                self.tool_version = tool_version

            self.parse(get_name_only=(dest != NETLIST))

        # If the part is destined for a SKiDL library, then it will be defined
        # by the additional attribute values that are passed.
        elif tool == SKIDL and name:
            pass

        else:
            log_and_raise(
                logger,
                ValueError,
                "Can't make a part without a library & part name or a part definition.",
            )

        # Split multi-part pin names into individual pin aliases.
        self.split_pin_names(kwargs.pop("pin_splitters", None))

        # Setup the tag for tieing the part to a footprint in a pcb editor.
        # Use the user specified tag if present.
        tag = kwargs.pop("tag", None)
        if tag is not None:
            self.tag = tag
        else:
            self.tag = str(randint(0, 2 ** 64 - 1))

        if dest != LIBRARY:
            if dest == NETLIST:
                # If the part is going to be an element in a circuit, then add it to the
                # the circuit and make any indicated pin/net connections.
                # If no Circuit object is given, then use the default Circuit that always exists.
                circuit = circuit or default_circuit
                circuit += self
            elif dest == TEMPLATE:
                # If this is just a part template, don't add the part to the circuit.
                self.circuit = None

            # Add any net/pin connections to this part that were passed as arguments.
            if isinstance(connections, dict):
                for pin, net in list(connections.items()):
                    net += self[pin]

        # Add any XSPICE I/O as pins. (This only happens with SPICE simulations.)
        self.add_xspice_io(kwargs.pop("io", []))

        # Add any other passed-in attributes to the part.
        for k, v in list(kwargs.items()):
            setattr(self, k, v)
Exemple #6
0
    def __init__(self,
                 lib=None,
                 name=None,
                 dest=NETLIST,
                 tool=None,
                 connections=None,
                 part_defn=None,
                 circuit=None,
                 **attribs):

        import skidl
        from .SchLib import SchLib
        from .defines import TEMPLATE, NETLIST, LIBRARY, SKIDL

        if tool is None:
            tool = skidl.get_default_tool()

        # Setup some part attributes that might be overwritten later on.
        self.do_erc = True  # Allow part to be included in ERC.
        self.unit = {
        }  # Dictionary for storing subunits of the part, if desired.
        self.pins = []  # Start with no pins, but a place to store them.
        self.name = name  # Assign initial part name. (Must come after circuit is assigned.)
        self.description = ''  # Make sure there is a description, even if empty.
        self._ref = ''  # Provide a member for holding a reference.
        self.ref_prefix = ''  # Provide a member for holding the part reference prefix.
        self.tool = tool  # Initial type of part (SKIDL, KICAD, etc.)
        self.circuit = None  # Part starts off unassociated with any circuit.

        # Create a Part from a library entry.
        if lib:
            # If the lib argument is a string, then create a library using the
            # string as the library file name.
            if isinstance(lib, basestring):
                try:
                    libname = lib
                    lib = SchLib(filename=libname, tool=tool)
                except Exception as e:
                    if skidl.QUERY_BACKUP_LIB:
                        logger.warning(
                            'Could not load KiCad schematic library "{}", falling back to backup library.'
                            .format(libname))
                        lib = skidl.load_backup_lib()
                        if not lib:
                            raise e
                    else:
                        raise e

            # Make a copy of the part from the library but don't add it to the netlist.
            part = lib[name].copy(dest=TEMPLATE)

            # Overwrite self with the new part.
            self.__dict__.update(part.__dict__)

            # Make sure all the pins have a valid reference to this part.
            self.associate_pins()

            # Store the library name of this part.
            self.lib = getattr(lib, 'filename', None)

        # Otherwise, create a Part from a part definition. If the part is
        # destined for a library, then just get its name. If it's going into
        # a netlist, then parse the entire part definition.
        elif part_defn:
            self.part_defn = part_defn
            self.parse(just_get_name=(dest != NETLIST))

        # If the part is destined for a SKiDL library, then it will be defined
        # by the additional attribute values that are passed.
        elif tool == SKIDL and name:
            pass

        else:
            logger.error(
                "Can't make a part without a library & part name or a part definition."
            )
            raise Exception

        # If the part is going to be an element in a circuit, then add it to the
        # the circuit and make any indicated pin/net connections.
        if dest != LIBRARY:
            if dest == NETLIST:
                # If no Circuit object is given, then use the default Circuit that always exists.
                # Always set circuit first because naming the part requires a lookup
                # of existing names in the circuit.
                if not circuit:
                    circuit = default_circuit  # pylint: disable=undefined-variable
                circuit += self
            elif dest == TEMPLATE:
                # If this is just a part template, don't add the part to the circuit.
                # Just place the reference to the Circuit object in the template.
                if not circuit:
                    self.circuit = default_circuit  # pylint: disable=undefined-variable
                self.circuit = circuit

            # Add any net/pin connections to this part that were passed as arguments.
            if isinstance(connections, dict):
                for pin, net in connections.items():
                    net += self[pin]

            # Add any other passed-in attributes to the part.
            for k, v in attribs.items():
                setattr(self, k, v)