From eb32870eb5111af7b4731b944b15e90c598cb80d Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 6 Aug 2024 11:53:55 +0200 Subject: [PATCH 01/63] WIP: Demo of new holder idea --- new_holders.py | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 new_holders.py diff --git a/new_holders.py b/new_holders.py new file mode 100644 index 00000000..2a1ca5fd --- /dev/null +++ b/new_holders.py @@ -0,0 +1,155 @@ +from dataclasses import dataclass, field +from typing import Any, Callable + +from faebryk.core.core import ModuleInterface, Parameter, Trait +from faebryk.core.util import as_unit +from faebryk.library.can_bridge_defined import can_bridge_defined +from faebryk.library.Electrical import Electrical +from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined +from faebryk.library.has_simple_value_representation_based_on_param import ( + has_simple_value_representation_based_on_param, +) +from faebryk.library.LED import LED +from faebryk.library.TBD import TBD +from faebryk.libs.util import times + + +@dataclass(init=False) +class Holder2[T]: + runtime: list[T] = field(default_factory=list) + + def add(self, obj: T): + self.runtime.append(obj) + + +@dataclass(init=False) +class Node2: + class PARAMS(Holder2[Parameter]): + pass + + class NODES(Holder2["Node2"]): + pass + + class TRAITS(Holder2[Trait]): + pass + + PARAMs: PARAMS + NODEs: NODES + TRAITs: TRAITS + + _init: bool + + def __init_subclass__(cls, *, init: bool = True) -> None: + print("Called Node __subclass__") + cls._init = init + + def __init__(self) -> None: + print("Called Node init") + if self._init: + for base in reversed(type(self).mro()): + if hasattr(base, "__post_init__"): + base.__post_init__(self) + + +class Module2(Node2): + class IFS(Holder2[ModuleInterface]): + pass + + IFs: IFS + + +# TODO can we get rid of the explicit bases in the holders? + +# ----------------------------------------------------------------------------- + + +def if_list[T](if_type: type[T], n: int) -> list[T]: + return field(default_factory=lambda: [if_type() for _ in range(n)]) + + +class rt_field[T](property): + def __init__(self, fget: Callable[[Any, T], Any]) -> None: + super().__init__() + self.func = fget + + def _construct(self, obj: T, holder: type): + self.constructed = self.func(holder, obj) + + def __get__(self, instance: Any, owner: type | None = None) -> Any: + return self.constructed() + + +# ----------------------------------------------------------------------------- + + +class Diode2(Module2): + class PARAMS(Module2.PARAMS): + forward_voltage: TBD[float] + max_current: TBD[float] + current: TBD[float] + reverse_working_voltage: TBD[float] + reverse_leakage_current: TBD[float] + + class IFS(Module2.IFS): + anode: Electrical + cathode: Electrical + + class TRAITS(Module2.TRAITS): + # static trait + designator_prefix = has_designator_prefix_defined("D") + + # dynamic trait + @rt_field + def bridge(cls, obj: "Diode2"): + return can_bridge_defined(obj.IFs.anode, obj.IFs.cathode) + + PARAMs: PARAMS + IFs: IFS + TRAITs: TRAITS + + def __post_init__(self): + print("Called Diode post_init") + + # anonymous dynamic trait + self.TRAITs.add( + has_simple_value_representation_based_on_param( + self.PARAMs.forward_voltage, + lambda p: as_unit(p, "V"), + ) + ) + + +class LED2(Diode2): + class PARAMS(Diode2.PARAMS): + color: TBD[LED.Color] + + PARAMs: PARAMS + + def __post_init__(self): + print("Called LED post_init") + + +class LED2_NOINT(LED2, init=False): + def __post_init__(self): + print("Called LED_NOINT post_init") + + +class LED2_WITHEXTRAIFS(LED2): + class IFS(LED2.IFS): + extra = field(default_factory=lambda: times(2, Electrical)) + extra2 = if_list(Electrical, 2) + + IFs: IFS + + def __post_init__(self): + print("Called LED_WITHEXTRAIFS post_init") + + +print("Diode init ----") +D = Diode2() +print("LED init ----") +L = LED2() +print("LEDNOINIT init ----") +L2 = LED2_NOINT() +print("LEDEXTRA init ----") +L3 = LED2_WITHEXTRAIFS() From 813a488c230584e3de24ef085274aee5c08ae7bc Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 22 Aug 2024 22:34:45 +0200 Subject: [PATCH 02/63] Setup new flat structure; Split core --- new_holders.py | 106 ++- new_holders_flat.py | 158 ++++ src/faebryk/core/core.py | 1367 +-------------------------- src/faebryk/core/graphinterface.py | 137 +++ src/faebryk/core/link.py | 115 +++ src/faebryk/core/module.py | 36 + src/faebryk/core/moduleinterface.py | 318 +++++++ src/faebryk/core/node.py | 235 +++++ src/faebryk/core/parameter.py | 381 ++++++++ src/faebryk/core/trait.py | 96 ++ src/faebryk/core/util.py | 36 +- 11 files changed, 1562 insertions(+), 1423 deletions(-) create mode 100644 new_holders_flat.py create mode 100644 src/faebryk/core/graphinterface.py create mode 100644 src/faebryk/core/link.py create mode 100644 src/faebryk/core/module.py create mode 100644 src/faebryk/core/moduleinterface.py create mode 100644 src/faebryk/core/node.py create mode 100644 src/faebryk/core/parameter.py create mode 100644 src/faebryk/core/trait.py diff --git a/new_holders.py b/new_holders.py index 2a1ca5fd..f4db4651 100644 --- a/new_holders.py +++ b/new_holders.py @@ -1,47 +1,73 @@ -from dataclasses import dataclass, field +from dataclasses import dataclass, field, fields from typing import Any, Callable -from faebryk.core.core import ModuleInterface, Parameter, Trait -from faebryk.core.util import as_unit +from faebryk.core.core import GraphInterface, ModuleInterface, Parameter, Trait from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation_based_on_param import ( - has_simple_value_representation_based_on_param, -) from faebryk.library.LED import LED from faebryk.library.TBD import TBD from faebryk.libs.util import times +class FieldExistsError(Exception): + pass + + @dataclass(init=False) class Holder2[T]: - runtime: list[T] = field(default_factory=list) + runtime_anon: list[T] = field(default_factory=list) + runtime: dict[str, T] = field(default_factory=dict) - def add(self, obj: T): - self.runtime.append(obj) + def add(self, obj: T, name: str | None = None): + if name: + if name in self.runtime: + raise FieldExistsError(name) + self.runtime[name] = obj + self.runtime_anon.append(obj) @dataclass(init=False) -class Node2: - class PARAMS(Holder2[Parameter]): +class Node2[T: type[Node2]]: + class T_PARAMS(Holder2[Parameter]): + pass + + class T_NODES(Holder2["Node2"]): pass - class NODES(Holder2["Node2"]): + class T_TRAITS(Holder2[Trait]): pass - class TRAITS(Holder2[Trait]): + class T_GIFS(Holder2[GraphInterface]): pass - PARAMs: PARAMS - NODEs: NODES - TRAITs: TRAITS + P: T_PARAMS + N: T_NODES + T: T_TRAITS + G: T_GIFS _init: bool def __init_subclass__(cls, *, init: bool = True) -> None: - print("Called Node __subclass__") - cls._init = init + print("Called Node __subclass__", "-" * 20) + holders_types = [ + f + for name, f in vars(cls).items() + if not name.startswith("_") and issubclass(f, Holder2) + ] + + holder_fields = [ + f + for f in fields(cls) + if not f.name.startswith("_") and issubclass(f.type, Holder2) + ] + + for f in holders_types: + # setattr(cls, f, field(default_factory=getattr(cls, f))) + print("", f.__qualname__, f) + + for f in holder_fields: + print("", f"{cls.__qualname__}.{f.name}", f.type) def __init__(self) -> None: print("Called Node init") @@ -52,10 +78,10 @@ def __init__(self) -> None: class Module2(Node2): - class IFS(Holder2[ModuleInterface]): + class T_IFS(Holder2[ModuleInterface]): pass - IFs: IFS + F: T_IFS # TODO can we get rid of the explicit bases in the holders? @@ -83,47 +109,47 @@ def __get__(self, instance: Any, owner: type | None = None) -> Any: class Diode2(Module2): - class PARAMS(Module2.PARAMS): + class T_PARAMS(Module2.T_PARAMS): forward_voltage: TBD[float] max_current: TBD[float] current: TBD[float] reverse_working_voltage: TBD[float] reverse_leakage_current: TBD[float] - class IFS(Module2.IFS): + class T_IFS(Module2.T_IFS): anode: Electrical cathode: Electrical - class TRAITS(Module2.TRAITS): + class T_TRAITS(Module2.T_TRAITS): # static trait designator_prefix = has_designator_prefix_defined("D") # dynamic trait @rt_field def bridge(cls, obj: "Diode2"): - return can_bridge_defined(obj.IFs.anode, obj.IFs.cathode) + return can_bridge_defined(obj.F.anode, obj.F.cathode) - PARAMs: PARAMS - IFs: IFS - TRAITs: TRAITS + P: T_PARAMS + F: T_IFS + T: T_TRAITS def __post_init__(self): print("Called Diode post_init") # anonymous dynamic trait - self.TRAITs.add( - has_simple_value_representation_based_on_param( - self.PARAMs.forward_voltage, - lambda p: as_unit(p, "V"), - ) - ) + # self.T.add( + # has_simple_value_representation_based_on_param( + # self.P.forward_voltage, + # lambda p: as_unit(p, "V"), + # ) + # ) class LED2(Diode2): - class PARAMS(Diode2.PARAMS): + class T_PARAMS(Diode2.T_PARAMS): color: TBD[LED.Color] - PARAMs: PARAMS + P: T_PARAMS def __post_init__(self): print("Called LED post_init") @@ -134,15 +160,15 @@ def __post_init__(self): print("Called LED_NOINT post_init") -class LED2_WITHEXTRAIFS(LED2): - class IFS(LED2.IFS): +class LED2_WITHEXTRAT_IFS(LED2): + class T_IFS(LED2.T_IFS): extra = field(default_factory=lambda: times(2, Electrical)) extra2 = if_list(Electrical, 2) - IFs: IFS + F: T_IFS def __post_init__(self): - print("Called LED_WITHEXTRAIFS post_init") + print("Called LED_WITHEXTRAT_IFS post_init") print("Diode init ----") @@ -152,4 +178,4 @@ def __post_init__(self): print("LEDNOINIT init ----") L2 = LED2_NOINT() print("LEDEXTRA init ----") -L3 = LED2_WITHEXTRAIFS() +L3 = LED2_WITHEXTRAT_IFS() diff --git a/new_holders_flat.py b/new_holders_flat.py new file mode 100644 index 00000000..cfab8174 --- /dev/null +++ b/new_holders_flat.py @@ -0,0 +1,158 @@ +from dataclasses import dataclass, field, fields +from itertools import chain +from typing import Any, Callable + +from faebryk.core.core import Node +from faebryk.core.util import as_unit +from faebryk.library.can_bridge_defined import can_bridge_defined +from faebryk.library.Electrical import Electrical +from faebryk.library.has_designator_prefix import has_designator_prefix +from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined +from faebryk.library.has_simple_value_representation_based_on_param import ( + has_simple_value_representation_based_on_param, +) +from faebryk.library.LED import LED +from faebryk.library.TBD import TBD +from faebryk.libs.units import Quantity +from faebryk.libs.util import times + + +class FieldExistsError(Exception): + pass + + +def if_list[T](if_type: type[T], n: int) -> list[T]: + return field(default_factory=lambda: [if_type() for _ in range(n)]) + + +class rt_field[T](property): + def __init__(self, fget: Callable[[T], Any]) -> None: + super().__init__() + self.func = fget + + def _construct(self, obj: T, holder: type): + self.constructed = self.func(holder, obj) + + def __get__(self, instance: Any, owner: type | None = None) -> Any: + return self.constructed() + + +def dfield(default_factory: Callable[[], Any], **kwargs): + return field(default_factory=default_factory, **kwargs) + + +# ----------------------------------------------------------------------------- + + +@dataclass +class Node2: + runtime_anon: list["Node2"] = field(default_factory=list) + runtime: dict[str, "Node2"] = field(default_factory=dict) + + def add(self, obj: "Node2| Node", name: str | None = None): + if name: + if name in self.runtime: + raise FieldExistsError(name) + self.runtime[name] = obj + self.runtime_anon.append(obj) + + _init: bool = False + + def __init_subclass__(cls, *, init: bool = True) -> None: + print("Called Node __subclass__", "-" * 20) + + cls_d = dataclass(init=False)(cls) + + for name, obj in chain( + # vars(cls).items(), + [(f.name, f.type) for f in fields(cls_d)], + # cls.__annotations__.items(), + [(name, f) for name, f in vars(cls).items() if isinstance(f, rt_field)], + ): + if name.startswith("_"): + continue + print(f"{cls.__qualname__}.{name} = {obj}, {type(obj)}") + + # node_fields = [ + # f + # for f in fields(cls) + # if not f.name.startswith("_") and issubclass(f.type, (Node, Node2)) + # ] + # for f in node_fields: + # print(f"{cls.__qualname__}.{f.name} = {f.type.__qualname__}") + + def __post_init__(self) -> None: + print("Called Node init", "-" * 20) + if self._init: + for base in reversed(type(self).mro()): + if hasattr(base, "_init"): + base._init(self) + + +class Module2(Node2): + pass + + +# ----------------------------------------------------------------------------- + + +class Diode2(Module2): + forward_voltage: TBD[Quantity] + max_current: TBD[Quantity] + current: TBD[Quantity] + reverse_working_voltage: TBD[Quantity] + reverse_leakage_current: TBD[Quantity] + + anode: Electrical + cathode: Electrical + + # static trait + designator_prefix: has_designator_prefix = dfield( + lambda: has_designator_prefix_defined("D") + ) + + # dynamic trait + @rt_field + def bridge(self): + return can_bridge_defined(self.anode, self.cathode) + + def _init(self): + print("Called Diode post_init") + + # anonymous dynamic trait + self.add( + has_simple_value_representation_based_on_param( + self.forward_voltage, + lambda p: as_unit(p, "V"), + ) # type: ignore + ) + + +class LED2(Diode2): + color: TBD[LED.Color] + + def _init(self): + print("Called LED post_init") + + +class LED2_NOINT(LED2, init=False): + def _init(self): + print("Called LED_NOINT post_init") + + +class LED2_WITHEXTRAT_IFS(LED2): + extra: list[Electrical] = field(default_factory=lambda: times(2, Electrical)) + extra2: list[Electrical] = if_list(Electrical, 2) + + def _init(self): + print("Called LED_WITHEXTRAT_IFS post_init") + + +print("Diode init ----") +D = Diode2() +print("LED init ----") +L = LED2() +print("LEDNOINIT init ----") +L2 = LED2_NOINT() +print("LEDEXTRA init ----") +L3 = LED2_WITHEXTRAT_IFS() diff --git a/src/faebryk/core/core.py b/src/faebryk/core/core.py index 4d0e98eb..0afb85fe 100644 --- a/src/faebryk/core/core.py +++ b/src/faebryk/core/core.py @@ -1,39 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from __future__ import annotations - -import inspect import logging -from abc import ABC, abstractmethod -from itertools import pairwise -from typing import ( - Any, - Callable, - Generic, - Iterable, - Mapping, - Optional, - Sequence, - Type, - TypeVar, -) +from typing import Any, Callable -from typing_extensions import Self, deprecated +from typing_extensions import Self -from faebryk.core.graph_backends.default import GraphImpl -from faebryk.libs.util import ( - ConfigFlag, - Holder, - NotNone, - TwistArgs, - cast_assert, - groupby, - is_type_pair, - print_stack, - try_avoid_endless_recursion, - unique_ref, -) +from faebryk.libs.util import ConfigFlag logger = logging.getLogger(__name__) @@ -44,1344 +17,10 @@ ) ID_REPR = ConfigFlag("ID_REPR", False, "Add object id to repr") -# 1st order classes ----------------------------------------------------------- -T = TypeVar("T", bound="FaebrykLibObject") - - -class Trait(Generic[T]): - @classmethod - def impl(cls: Type[Trait]): - T_ = TypeVar("T_", bound="FaebrykLibObject") - - class _Impl(Generic[T_], TraitImpl[T_], cls): ... - - return _Impl[T] - - -U = TypeVar("U", bound="FaebrykLibObject") - - -class TraitImpl(Generic[U], ABC): - trait: Type[Trait[U]] - - def __init__(self) -> None: - super().__init__() - - if not hasattr(self, "_obj"): - self._obj: U | None = None - - found = False - bases = type(self).__bases__ - while not found: - for base in bases: - if not issubclass(base, TraitImpl) and issubclass(base, Trait): - self.trait = base - found = True - break - bases = [ - new_base - for base in bases - if issubclass(base, TraitImpl) - for new_base in base.__bases__ - ] - assert len(bases) > 0 - - assert type(self.trait) is type - assert issubclass(self.trait, Trait) - assert self.trait is not TraitImpl - - def set_obj(self, _obj: U): - self._obj = _obj - self.on_obj_set() - - def on_obj_set(self): ... - - def remove_obj(self): - self._obj = None - - def get_obj(self) -> U: - assert self._obj is not None, "trait is not linked to object" - return self._obj - - def cmp(self, other: TraitImpl) -> tuple[bool, TraitImpl]: - assert type(other), TraitImpl - - # If other same or more specific - if other.implements(self.trait): - return True, other - - # If we are more specific - if self.implements(other.trait): - return True, self - - return False, self - - def implements(self, trait: type): - assert issubclass(trait, Trait) - - return issubclass(self.trait, trait) - - # override this to implement a dynamic trait - def is_implemented(self): - return True - class FaebrykLibObject: - traits: list[TraitImpl] - - def __new__(cls, *args, **kwargs): - self = super().__new__(cls) - # TODO maybe dict[class => [obj] - self.traits = [] - return self - def __init__(self) -> None: ... - _TImpl = TypeVar("_TImpl", bound=TraitImpl) - - # TODO type checking InterfaceTrait -> Interface - def add_trait(self, trait: _TImpl) -> _TImpl: - assert isinstance(trait, TraitImpl), ("not a traitimpl:", trait) - assert isinstance(trait, Trait) - assert not hasattr(trait, "_obj") or trait._obj is None, "trait already in use" - trait.set_obj(self) - - # Override existing trait if more specific or same - # TODO deal with dynamic traits - for i, t in enumerate(self.traits): - hit, replace = t.cmp(trait) - if hit: - if replace == trait: - t.remove_obj() - self.traits[i] = replace - return replace - - # No hit: Add new trait - self.traits.append(trait) - return trait - - def _find(self, trait, only_implemented: bool): - return list( - filter( - lambda tup: tup[1].implements(trait) - and (tup[1].is_implemented() or not only_implemented), - enumerate(self.traits), - ) - ) - - def del_trait(self, trait): - candidates = self._find(trait, only_implemented=False) - assert len(candidates) <= 1 - if len(candidates) == 0: - return - assert len(candidates) == 1, "{} not in {}[{}]".format(trait, type(self), self) - i, impl = candidates[0] - assert self.traits[i] == impl - impl.remove_obj() - del self.traits[i] - - def has_trait(self, trait) -> bool: - return len(self._find(trait, only_implemented=True)) > 0 - - V = TypeVar("V", bound=Trait) - - def get_trait(self, trait: Type[V]) -> V: - assert not issubclass( - trait, TraitImpl - ), "You need to specify the trait, not an impl" - - candidates = self._find(trait, only_implemented=True) - assert len(candidates) <= 1 - assert len(candidates) == 1, "{} not in {}[{}]".format(trait, type(self), self) - - out = candidates[0][1] - assert isinstance(out, trait) - return out - def builder(self, op: Callable[[Self], Any]) -> Self: op(self) return self - - -# ----------------------------------------------------------------------------- - -# Traits ---------------------------------------------------------------------- -TI = TypeVar("TI", bound="GraphInterface") - - -class _InterfaceTrait(Generic[TI], Trait[TI]): ... - - -class InterfaceTrait(_InterfaceTrait["GraphInterface"]): ... - - -TN = TypeVar("TN", bound="Node") - - -class _NodeTrait(Generic[TN], Trait[TN]): ... - - -class NodeTrait(_NodeTrait["Node"]): ... - - -TL = TypeVar("TL", bound="Link") - - -class _LinkTrait(Generic[TL], Trait[TL]): ... - - -class LinkTrait(_LinkTrait["Link"]): ... - - -TP = TypeVar("TP", bound="Parameter") - - -class _ParameterTrait(Generic[TP], Trait[TP]): ... - - -class ParameterTrait(_ParameterTrait["Parameter"]): ... - - -class can_determine_partner_by_single_end(LinkTrait): - @abstractmethod - def get_partner(self, other: GraphInterface) -> GraphInterface: ... - - -# ----------------------------------------------------------------------------- - - -# FaebrykLibObjects ----------------------------------------------------------- -class Link(FaebrykLibObject): - def __init__(self) -> None: - super().__init__() - - if LINK_TB: - self.tb = inspect.stack() - - def get_connections(self) -> list[GraphInterface]: - raise NotImplementedError - - def __eq__(self, __value: Link) -> bool: - return set(self.get_connections()) == set(__value.get_connections()) - - def __hash__(self) -> int: - return super().__hash__() - - def __str__(self) -> str: - return ( - f"{type(self).__name__}" - f"([{', '.join(str(i) for i in self.get_connections())}])" - ) - - def __repr__(self) -> str: - return f"{type(self).__name__}()" - - -class LinkSibling(Link): - def __init__(self, interfaces: list[GraphInterface]) -> None: - super().__init__() - self.interfaces = interfaces - - def get_connections(self) -> list[GraphInterface]: - return self.interfaces - - -class LinkParent(Link): - def __init__(self, interfaces: list[GraphInterface]) -> None: - super().__init__() - - assert all([isinstance(i, GraphInterfaceHierarchical) for i in interfaces]) - # TODO rethink invariant - assert len(interfaces) == 2 - assert len([i for i in interfaces if i.is_parent]) == 1 # type: ignore - - self.interfaces: list[GraphInterfaceHierarchical] = interfaces # type: ignore - - def get_connections(self): - return self.interfaces - - def get_parent(self): - return [i for i in self.interfaces if i.is_parent][0] - - def get_child(self): - return [i for i in self.interfaces if not i.is_parent][0] - - -class LinkNamedParent(LinkParent): - def __init__(self, name: str, interfaces: list[GraphInterface]) -> None: - super().__init__(interfaces) - self.name = name - - @classmethod - def curry(cls, name: str): - def curried(interfaces: list[GraphInterface]): - return cls(name, interfaces) - - return curried - - -class LinkDirect(Link): - class _(can_determine_partner_by_single_end.impl()): - def get_partner(_self, other: GraphInterface): - obj = _self.get_obj() - assert isinstance(obj, LinkDirect) - return [i for i in obj.interfaces if i is not other][0] - - def __init__(self, interfaces: list[GraphInterface]) -> None: - super().__init__() - assert len(set(map(type, interfaces))) == 1 - self.interfaces = interfaces - - # TODO not really used, but quite heavy on the performance - # if len(interfaces) == 2: - # self.add_trait(LinkDirect._()) - - def get_connections(self) -> list[GraphInterface]: - return self.interfaces - - -class LinkFilteredException(Exception): ... - - -class _TLinkDirectShallow(LinkDirect): - def __new__(cls, *args, **kwargs): - if cls is _TLinkDirectShallow: - raise TypeError( - "Can't instantiate abstract class _TLinkDirectShallow directly" - ) - return LinkDirect.__new__(cls, *args, **kwargs) - - -def LinkDirectShallow(if_filter: Callable[[LinkDirect, GraphInterface], bool]): - class _LinkDirectShallow(_TLinkDirectShallow): - i_filter = if_filter - - def __init__(self, interfaces: list[GraphInterface]) -> None: - if not all(map(self.i_filter, interfaces)): - raise LinkFilteredException() - super().__init__(interfaces) - - return _LinkDirectShallow - - -Graph = GraphImpl["GraphInterface"] - - -class GraphInterface(FaebrykLibObject): - GT = Graph - - def __init__(self) -> None: - super().__init__() - self.G = self.GT() - - # can't put it into constructor - # else it needs a reference when defining IFs - self._node: Optional[Node] = None - self.name: str = type(self).__name__ - - @property - def node(self): - return NotNone(self._node) - - @node.setter - def node(self, value: Node): - self._node = value - - # Graph stuff - @property - def edges(self) -> Mapping[GraphInterface, Link]: - return self.G.get_edges(self) - - def get_links(self) -> list[Link]: - return list(self.edges.values()) - - def get_links_by_type[T: Link](self, link_type: type[T]) -> list[T]: - return [link for link in self.get_links() if isinstance(link, link_type)] - - @property - @deprecated("Use get_links") - def connections(self): - return self.get_links() - - def get_direct_connections(self) -> set[GraphInterface]: - return set(self.edges.keys()) - - def is_connected(self, other: GraphInterface): - return self.G.is_connected(self, other) - - # Less graph-specific stuff - - # TODO make link trait to initialize from list - def connect(self, other: Self, linkcls=None) -> Self: - assert other is not self - - if linkcls is None: - linkcls = LinkDirect - link = linkcls([other, self]) - - _, no_path = self.G.merge(other.G) - - if not no_path: - dup = self.is_connected(other) - assert ( - not dup or type(dup) is linkcls - ), f"Already connected with different link type: {dup}" - - self.G.add_edge(self, other, link=link) - - if logger.isEnabledFor(logging.DEBUG): - logger.debug(f"GIF connection: {link}") - - return self - - def get_full_name(self, types: bool = False): - typestr = f"|{type(self).__name__}|" if types else "" - return f"{self.node.get_full_name(types=types)}.{self.name}{typestr}" - - def __str__(self) -> str: - return f"{str(self.node)}.{self.name}" - - @try_avoid_endless_recursion - def __repr__(self) -> str: - id_str = f"(@{hex(id(self))})" if ID_REPR else "" - - return ( - f"{self.get_full_name(types=True)}{id_str}" - if self._node is not None - else "| " - ) - - -class GraphInterfaceHierarchical(GraphInterface): - def __init__(self, is_parent: bool) -> None: - super().__init__() - self.is_parent = is_parent - - # TODO make consistent api with get_parent - def get_children(self) -> list[tuple[str, Node]]: - assert self.is_parent - - hier_conns = self.get_links_by_type(LinkNamedParent) - if len(hier_conns) == 0: - return [] - - return [(c.name, c.get_child().node) for c in hier_conns] - - def get_parent(self) -> tuple[Node, str] | None: - assert not self.is_parent - - conns = self.get_links_by_type(LinkNamedParent) - if not conns: - return None - assert len(conns) == 1 - conn = conns[0] - parent = conn.get_parent() - - return parent.node, conn.name - - -class GraphInterfaceSelf(GraphInterface): ... - - -class GraphInterfaceModuleSibling(GraphInterfaceHierarchical): ... - - -class GraphInterfaceModuleConnection(GraphInterface): ... - - -class Node(FaebrykLibObject): - @classmethod - def GraphInterfacesCls(cls): - class InterfaceHolder(Holder(GraphInterface, cls)): - def handle_add(self, name: str, obj: GraphInterface) -> None: - assert isinstance(obj, GraphInterface) - parent: Node = self.get_parent() - obj.node = parent - obj.name = name - if not isinstance(obj, GraphInterfaceSelf): - if hasattr(self, "self"): - obj.connect(self.self, linkcls=LinkSibling) - if isinstance(obj, GraphInterfaceSelf): - assert obj is self.self - for target in self.get_all(): - if target is self.self: - continue - target.connect(obj, linkcls=LinkSibling) - return super().handle_add(name, obj) - - def __init__(self, parent: Node) -> None: - super().__init__(parent) - - # Default Component Interfaces - self.self = GraphInterfaceSelf() - self.children = GraphInterfaceHierarchical(is_parent=True) - self.parent = GraphInterfaceHierarchical(is_parent=False) - - return InterfaceHolder - - NT = TypeVar("NT", bound="Node") - - @classmethod - def NodesCls(cls, t: Type[NT]): - class NodeHolder(Holder(t, cls)): - def handle_add(self, name: str, obj: Node.NT) -> None: - assert isinstance(obj, t) - parent: Node = self.get_parent() - assert not ( - other_p := obj.get_parent() - ), f"{obj} already has parent: {other_p}" - obj.GIFs.parent.connect( - parent.GIFs.children, LinkNamedParent.curry(name) - ) - return super().handle_add(name, obj) - - def __init__(self, parent: Node) -> None: - super().__init__(parent) - - return NodeHolder - - @classmethod - def GIFS(cls): - return cls.GraphInterfacesCls() - - @classmethod - def NODES(cls): - return cls.NodesCls(Node) - - def __init__(self) -> None: - super().__init__() - - self.GIFs = Node.GIFS()(self) - self.NODEs = Node.NODES()(self) - - def get_graph(self): - return self.GIFs.self.G - - def get_parent(self): - return self.GIFs.parent.get_parent() - - def get_name(self): - p = self.get_parent() - if not p: - raise Exception("Parent required for name") - return p[1] - - def get_hierarchy(self) -> list[tuple[Node, str]]: - parent = self.get_parent() - if not parent: - return [(self, "*")] - parent_obj, name = parent - - return parent_obj.get_hierarchy() + [(self, name)] - - def get_full_name(self, types: bool = False): - hierarchy = self.get_hierarchy() - if types: - return ".".join([f"{name}|{type(obj).__name__}" for obj, name in hierarchy]) - else: - return ".".join([f"{name}" for _, name in hierarchy]) - - def inherit(self): - """ - Has to be called if inhereting from another module after setting the holders - """ - from faebryk.core.util import get_children - - children = get_children(self, direct_only=True, include_root=False) - by_name = groupby(children, lambda n: n.get_name()) - for _, cs in by_name.items(): - for c1, c2 in pairwise(cs): - # TODO check equal top-level types (module, etc) - if isinstance(c1, Parameter): - c1.merge(c2) - elif isinstance(c1, (ModuleInterface, GraphInterface)): - c1.connect(c2) - ... - - @try_avoid_endless_recursion - def __str__(self) -> str: - return f"<{self.get_full_name(types=True)}>" - - @try_avoid_endless_recursion - def __repr__(self) -> str: - id_str = f"(@{hex(id(self))})" if ID_REPR else "" - return f"<{self.get_full_name(types=True)}>{id_str}" - - -def _resolved[PV, O]( - func: Callable[[Parameter[PV], Parameter[PV]], O], -) -> Callable[ - [ - PV | set[PV] | tuple[PV, PV] | Parameter[PV], - PV | set[PV] | tuple[PV, PV] | Parameter[PV], - ], - O, -]: - def wrap(*args): - args = [Parameter.from_literal(arg).get_most_narrow() for arg in args] - return func(*args) - - return wrap - - -class Parameter[PV](Node): - type LIT = PV | set[PV] | tuple[PV, PV] - type LIT_OR_PARAM = LIT | "Parameter[PV]" - - class MergeException(Exception): ... - - class SupportsSetOps: - def __contains__(self, other: Parameter[PV].LIT_OR_PARAM) -> bool: ... - - def try_compress(self) -> Parameter[PV]: - return self - - @classmethod - def GIFS(cls): - class GIFS(Node.GIFS()): - narrowed_by = GraphInterface() - narrows = GraphInterface() - - return GIFS - - @classmethod - def PARAMS(cls): - class PARAMS(Module.NodesCls(Parameter)): - # workaround to help pylance - def get_all(self) -> list[Parameter]: - return [cast_assert(Parameter, i) for i in super().get_all()] - - def __str__(self) -> str: - return str({p.get_hierarchy()[-1][1]: p for p in self.get_all()}) - - return PARAMS - - def __init__(self) -> None: - super().__init__() - - self.GIFs = Parameter.GIFS()(self) - self.PARAMs = Parameter.PARAMS()(self) - - @classmethod - def from_literal(cls, value: LIT_OR_PARAM) -> Parameter[PV]: - from faebryk.library.Constant import Constant - from faebryk.library.Range import Range - from faebryk.library.Set import Set - - if isinstance(value, Parameter): - return value - elif isinstance(value, set): - return Set(value) - elif isinstance(value, tuple): - return Range(*value) - else: - return Constant(value) - - def _merge(self, other: Parameter[PV]) -> Parameter[PV]: - from faebryk.library.ANY import ANY - from faebryk.library.Operation import Operation - from faebryk.library.Set import Set - from faebryk.library.TBD import TBD - - def _is_pair(type1: type[T], type2: type[U]) -> Optional[tuple[T, U]]: - return is_type_pair(self, other, type1, type2) - - if self is other: - return self - - try: - if self == other: - return self - except ValueError: - ... - - if pair := _is_pair(Parameter[PV], TBD): - return pair[0] - - if pair := _is_pair(Parameter[PV], ANY): - return pair[0] - - # TODO remove as soon as possible - if pair := _is_pair(Parameter[PV], Operation): - # TODO make MergeOperation that inherits from Operation - # and return that instead, application can check if result is MergeOperation - # if it was checking mergeability - raise self.MergeException("cant merge range with operation") - - if pair := _is_pair(Parameter[PV], Parameter[PV].SupportsSetOps): - out = self.intersect(*pair) - if isinstance(out, Operation): - raise self.MergeException("not resolvable") - if out == Set([]) and not pair[0] == pair[1] == Set([]): - raise self.MergeException("conflicting sets/ranges") - return out - - raise NotImplementedError - - def _narrowed(self, other: Parameter[PV]): - if self is other: - return - - if self.GIFs.narrowed_by.is_connected(other.GIFs.narrows): - return - self.GIFs.narrowed_by.connect(other.GIFs.narrows) - - @_resolved - def is_mergeable_with(self: Parameter[PV], other: Parameter[PV]) -> bool: - try: - self._merge(other) - return True - except self.MergeException: - return False - except NotImplementedError: - return False - - @_resolved - def is_subset_of(self: Parameter[PV], other: Parameter[PV]) -> bool: - from faebryk.library.ANY import ANY - from faebryk.library.Operation import Operation - from faebryk.library.TBD import TBD - - lhs = self - rhs = other - - def is_either_instance(t: type[Parameter[PV]]): - return isinstance(lhs, t) or isinstance(rhs, t) - - # Not resolveable - if isinstance(rhs, ANY): - return True - if isinstance(lhs, ANY): - return False - if is_either_instance(TBD): - return False - if is_either_instance(Operation): - return False - - # Sets - return lhs & rhs == lhs - - @_resolved - def merge(self: Parameter[PV], other: Parameter[PV]) -> Parameter[PV]: - out = self._merge(other) - - self._narrowed(out) - other._narrowed(out) - - return out - - @_resolved - def override(self: Parameter[PV], other: Parameter[PV]) -> "Parameter[PV]": - if not other.is_subset_of(self): - raise self.MergeException("override not possible") - - self._narrowed(other) - return other - - # TODO: replace with graph-based - @staticmethod - def arithmetic_op( - op1: Parameter[PV], op2: Parameter[PV], op: Callable - ) -> "Parameter[PV]": - from faebryk.library.ANY import ANY - from faebryk.library.Constant import Constant - from faebryk.library.Operation import Operation - from faebryk.library.Range import Range - from faebryk.library.Set import Set - from faebryk.library.TBD import TBD - - def _is_pair(type1: type[T], type2: type[U]) -> Optional[tuple[T, U, Callable]]: - if isinstance(op1, type1) and isinstance(op2, type2): - return op1, op2, op - if isinstance(op1, type2) and isinstance(op2, type1): - return op2, op1, TwistArgs(op) - - return None - - if pair := _is_pair(Constant, Constant): - return Constant(op(pair[0].value, pair[1].value)) - - if pair := _is_pair(Range, Range): - try: - p0_min, p0_max = pair[0].min, pair[0].max - p1_min, p1_max = pair[1].min, pair[1].max - except Range.MinMaxError: - return Operation(pair[:2], op) - return Range( - *( - op(lhs, rhs) - for lhs, rhs in [ - (p0_min, p1_min), - (p0_max, p1_max), - (p0_min, p1_max), - (p0_max, p1_min), - ] - ) - ) - - if pair := _is_pair(Constant, Range): - sop = pair[2] - try: - return Range(*(sop(pair[0], bound) for bound in pair[1].bounds)) - except Range.MinMaxError: - return Operation(pair[:2], op) - - if pair := _is_pair(Parameter, ANY): - sop = pair[2] - return Operation(pair[:2], sop) - - if pair := _is_pair(Parameter, Operation): - sop = pair[2] - return Operation(pair[:2], sop) - - if pair := _is_pair(Parameter, TBD): - sop = pair[2] - return Operation(pair[:2], sop) - - if pair := _is_pair(Parameter, Set): - sop = pair[2] - return Set( - Parameter.arithmetic_op(nested, pair[0], sop) - for nested in pair[1].params - ) - - raise NotImplementedError - - @staticmethod - def intersect(op1: Parameter[PV], op2: Parameter[PV]) -> Parameter[PV]: - from faebryk.library.Constant import Constant - from faebryk.library.Operation import Operation - from faebryk.library.Range import Range - from faebryk.library.Set import Set - - if op1 == op2: - return op1 - - def _is_pair(type1: type[T], type2: type[U]) -> Optional[tuple[T, U, Callable]]: - if isinstance(op1, type1) and isinstance(op2, type2): - return op1, op2, op - if isinstance(op1, type2) and isinstance(op2, type1): - return op2, op1, TwistArgs(op) - - return None - - def op(a, b): - return a & b - - # same types - if pair := _is_pair(Constant, Constant): - return Set([]) - if pair := _is_pair(Set, Set): - return Set(pair[0].params.intersection(pair[1].params)) - if pair := _is_pair(Range, Range): - try: - min_ = max(pair[0].min, pair[1].min) - max_ = min(pair[0].max, pair[1].max) - if min_ > max_: - return Set([]) - if min_ == max_: - return Constant(min_) - return Range(max_, min_) - except Range.MinMaxError: - return Operation(pair[:2], op) - - # diff types - if pair := _is_pair(Constant, Range): - try: - if pair[0] in pair[1]: - return pair[0] - else: - return Set([]) - except Range.MinMaxError: - return Operation(pair[:2], op) - if pair := _is_pair(Constant, Set): - if pair[0] in pair[1]: - return pair[0] - else: - return Set([]) - if pair := _is_pair(Range, Set): - try: - return Set(i for i in pair[1].params if i in pair[0]) - except Range.MinMaxError: - return Operation(pair[:2], op) - - return Operation((op1, op2), op) - - @_resolved - def __add__(self: Parameter[PV], other: Parameter[PV]): - return self.arithmetic_op(self, other, lambda a, b: a + b) - - @_resolved - def __sub__(self: Parameter[PV], other: Parameter[PV]): - return self.arithmetic_op(self, other, lambda a, b: a - b) - - # TODO PV | float - @_resolved - def __mul__(self: Parameter[PV], other: Parameter[PV]): - return self.arithmetic_op(self, other, lambda a, b: a * b) - - # TODO PV | float - @_resolved - def __truediv__(self: Parameter[PV], other: Parameter[PV]): - return self.arithmetic_op(self, other, lambda a, b: a / b) - - @_resolved - def __and__(self: Parameter[PV], other: Parameter[PV]) -> Parameter[PV]: - return self.intersect(self, other) - - def get_most_narrow(self) -> Parameter[PV]: - out = self.get_narrowing_chain()[-1] - - com = out.try_compress() - if com is not out: - com = com.get_most_narrow() - out._narrowed(com) - out = com - - return out - - @staticmethod - def resolve_all(params: "Sequence[Parameter[PV]]") -> Parameter[PV]: - from faebryk.library.TBD import TBD - - params_set = list(params) - if not params_set: - return TBD[PV]() - it = iter(params_set) - most_specific = next(it) - for param in it: - most_specific = most_specific.merge(param) - - return most_specific - - @try_avoid_endless_recursion - def __str__(self) -> str: - narrowest = self.get_most_narrow() - if narrowest is self: - return super().__str__() - return str(narrowest) - - # @try_avoid_endless_recursion - # def __repr__(self) -> str: - # narrowest = self.get_most_narrow() - # if narrowest is self: - # return super().__repr__() - # # return f"{super().__repr__()} -> {repr(narrowest)}" - # return repr(narrowest) - - def get_narrowing_chain(self) -> list[Parameter]: - from faebryk.core.util import get_direct_connected_nodes - - out: list[Parameter] = [self] - narrowers = get_direct_connected_nodes(self.GIFs.narrowed_by, Parameter) - if narrowers: - assert len(narrowers) == 1, "Narrowing tree diverged" - out += next(iter(narrowers)).get_narrowing_chain() - assert id(self) not in map(id, out[1:]), "Narrowing tree cycle" - return out - - def get_narrowed_siblings(self) -> set[Parameter]: - from faebryk.core.util import get_direct_connected_nodes - - return get_direct_connected_nodes(self.GIFs.narrows, Parameter) - - def __copy__(self) -> Self: - return type(self)() - - def __deepcopy__(self, memo) -> Self: - return self.__copy__() - - -# ----------------------------------------------------------------------------- - -# TODO: move file-------------------------------------------------------------- -TMI = TypeVar("TMI", bound="ModuleInterface") - - -# The resolve functions are really weird -# You have to look into where they are called to make sense of what they are doing -# Chain resolve is for deciding what to do in a case like this -# if1 -> link1 -> if2 -> link2 -> if3 -# This will then decide with which link if1 and if3 are connected -def _resolve_link_transitive(links: Iterable[type[Link]]) -> type[Link]: - from faebryk.libs.util import is_type_set_subclasses - - uniq = set(links) - assert uniq - - if len(uniq) == 1: - return next(iter(uniq)) - - if is_type_set_subclasses(uniq, {_TLinkDirectShallow}): - # TODO this only works if the filter is identical - raise NotImplementedError() - - if is_type_set_subclasses(uniq, {LinkDirect, _TLinkDirectShallow}): - return [u for u in uniq if issubclass(u, _TLinkDirectShallow)][0] - - raise NotImplementedError() - - -# This one resolves the case if1 -> link1 -> if2; if1 -> link2 -> if2 -def _resolve_link_duplicate(links: Iterable[type[Link]]) -> type[Link]: - from faebryk.libs.util import is_type_set_subclasses - - uniq = set(links) - assert uniq - - if len(uniq) == 1: - return next(iter(uniq)) - - if is_type_set_subclasses(uniq, {LinkDirect, _TLinkDirectShallow}): - return [u for u in uniq if not issubclass(u, _TLinkDirectShallow)][0] - - raise NotImplementedError() - - -class _ModuleInterfaceTrait(Generic[TMI], Trait[TMI]): ... - - -class ModuleInterfaceTrait(_ModuleInterfaceTrait["ModuleInterface"]): ... - - -class _LEVEL: - """connect depth counter to debug connections in ModuleInterface""" - - def __init__(self) -> None: - self.value = 0 - - def inc(self): - self.value += 1 - return self.value - 1 - - def dec(self): - self.value -= 1 - - -_CONNECT_DEPTH = _LEVEL() - - -class ModuleInterface(Node): - @classmethod - def GIFS(cls): - class GIFS(Node.GIFS()): - specializes = GraphInterface() - specialized = GraphInterface() - connected = GraphInterfaceModuleConnection() - - return GIFS - - @classmethod - def IFS(cls): - class IFS(Module.NodesCls(ModuleInterface)): - # workaround to help pylance - def get_all(self) -> list[ModuleInterface]: - return [cast_assert(ModuleInterface, i) for i in super().get_all()] - - return IFS - - @classmethod - def PARAMS(cls): - class PARAMS(Module.NodesCls(Parameter)): - # workaround to help pylance - def get_all(self) -> list[Parameter]: - return [cast_assert(Parameter, i) for i in super().get_all()] - - def __str__(self) -> str: - return str({p.get_hierarchy()[-1][1]: p for p in self.get_all()}) - - return PARAMS - - # TODO rename - @classmethod - def LinkDirectShallow(cls): - """ - Make link that only connects up but not down - """ - - def test(node: Node): - return not any(isinstance(p[0], cls) for p in node.get_hierarchy()[:-1]) - - class _LinkDirectShallowMif( - LinkDirectShallow(lambda link, gif: test(gif.node)) - ): ... - - return _LinkDirectShallowMif - - _LinkDirectShallow: type[_TLinkDirectShallow] | None = None - - def __init__(self) -> None: - super().__init__() - self.GIFs = ModuleInterface.GIFS()(self) - self.PARAMs = ModuleInterface.PARAMS()(self) - self.IFs = ModuleInterface.IFS()(self) - if not type(self)._LinkDirectShallow: - type(self)._LinkDirectShallow = type(self).LinkDirectShallow() - - def _connect_siblings_and_connections( - self, other: ModuleInterface, linkcls: type[Link] - ) -> ModuleInterface: - from faebryk.core.util import get_connected_mifs_with_link - - if other is self: - return self - - # Already connected - if self.is_connected_to(other): - return self - - # if link is filtered, cancel here - self._connect_across_hierarchies(other, linkcls) - if not self.is_connected_to(other): - return self - - if logger.isEnabledFor(logging.DEBUG): - logger.debug(f"MIF connection: {self} to {other}") - - def cross_connect( - s_group: dict[ModuleInterface, type[Link]], - d_group: dict[ModuleInterface, type[Link]], - hint=None, - ): - if logger.isEnabledFor(logging.DEBUG) and hint is not None: - logger.debug(f"Connect {hint} {s_group} -> {d_group}") - - for s, slink in s_group.items(): - for d, dlink in d_group.items(): - # can happen while connection trees are resolving - if s is d: - continue - link = _resolve_link_transitive([slink, dlink, linkcls]) - - s._connect_across_hierarchies(d, linkcls=link) - - def _get_connected_mifs(gif: GraphInterface): - return {k: type(v) for k, v in get_connected_mifs_with_link(gif).items()} - - # Connect to all connections - s_con = _get_connected_mifs(self.GIFs.connected) | {self: linkcls} - d_con = _get_connected_mifs(other.GIFs.connected) | {other: linkcls} - cross_connect(s_con, d_con, "connections") - - # Connect to all siblings - s_sib = ( - _get_connected_mifs(self.GIFs.specialized) - | _get_connected_mifs(self.GIFs.specializes) - | {self: linkcls} - ) - d_sib = ( - _get_connected_mifs(other.GIFs.specialized) - | _get_connected_mifs(other.GIFs.specializes) - | {other: linkcls} - ) - cross_connect(s_sib, d_sib, "siblings") - - return self - - def _on_connect(self, other: ModuleInterface): - """override to handle custom connection logic""" - ... - - def _try_connect_down(self, other: ModuleInterface, linkcls: type[Link]) -> None: - from faebryk.core.util import zip_children_by_name - - if not isinstance(other, type(self)): - return - - for _, (src, dst) in zip_children_by_name(self, other, ModuleInterface).items(): - if src is None or dst is None: - continue - src.connect(dst, linkcls=linkcls) - - def _try_connect_up(self, other: ModuleInterface) -> None: - p1 = self.get_parent() - p2 = other.get_parent() - if not ( - p1 - and p2 - and p1[0] is not p2[0] - and isinstance(p1[0], type(p2[0])) - and isinstance(p1[0], ModuleInterface) - ): - return - - src_m = p1[0] - dst_m = p2[0] - assert isinstance(dst_m, ModuleInterface) - - def _is_connected(a, b): - assert isinstance(a, ModuleInterface) - assert isinstance(b, ModuleInterface) - return a.is_connected_to(b) - - src_m_is = src_m.IFs.get_all() - dst_m_is = dst_m.IFs.get_all() - connection_map = [ - (src_i, dst_i, _is_connected(src_i, dst_i)) - for src_i, dst_i in zip(src_m_is, dst_m_is) - ] - - assert connection_map - - if not all(connected for _, _, connected in connection_map): - return - - # decide which LinkType to use here - # depends on connections between src_i & dst_i - # e.g. if any Shallow, we need to choose shallow - link = _resolve_link_transitive( - [type(sublink) for _, _, sublink in connection_map if sublink] - ) - - if logger.isEnabledFor(logging.DEBUG): - logger.debug(f"Up connect {src_m} -> {dst_m}") - src_m.connect(dst_m, linkcls=link) - - def _connect_across_hierarchies(self, other: ModuleInterface, linkcls: type[Link]): - existing_link = self.is_connected_to(other) - if existing_link: - if isinstance(existing_link, linkcls): - return - resolved = _resolve_link_duplicate([type(existing_link), linkcls]) - if resolved is type(existing_link): - return - if LINK_TB: - print(print_stack(existing_link.tb)) - raise NotImplementedError( - "Overriding existing links not implemented, tried to override " - + f"{existing_link} with {resolved}" - ) - - # level 0 connect - try: - self.GIFs.connected.connect(other.GIFs.connected, linkcls=linkcls) - except LinkFilteredException: - return - - if logger.isEnabledFor(logging.DEBUG): - logger.debug(f"{' '*2*_CONNECT_DEPTH.inc()}Connect {self} to {other}") - self._on_connect(other) - - con_depth_one = _CONNECT_DEPTH.value == 1 - recursion_error = None - try: - # level +1 (down) connect - self._try_connect_down(other, linkcls=linkcls) - - # level -1 (up) connect - self._try_connect_up(other) - - except RecursionError as e: - recursion_error = e - if not con_depth_one: - raise - - if recursion_error: - raise Exception(f"Recursion error while connecting {self} to {other}") - - _CONNECT_DEPTH.dec() - - def get_direct_connections(self) -> set[ModuleInterface]: - return { - gif.node - for gif in self.GIFs.connected.get_direct_connections() - if isinstance(gif.node, ModuleInterface) and gif.node is not self - } - - def connect(self, other: Self, linkcls=None) -> Self: - # TODO consider some type of check at the end within the graph instead - # assert type(other) is type(self) - if linkcls is None: - linkcls = LinkDirect - return self._connect_siblings_and_connections(other, linkcls=linkcls) - - def connect_via( - self, bridge: Node | Sequence[Node], other: Self | None = None, linkcls=None - ): - from faebryk.library.can_bridge import can_bridge - - bridges = [bridge] if isinstance(bridge, Node) else bridge - intf = self - for sub_bridge in bridges: - t = sub_bridge.get_trait(can_bridge) - intf.connect(t.get_in(), linkcls=linkcls) - intf = t.get_out() - - if other: - intf.connect(other, linkcls=linkcls) - - def connect_shallow(self, other: Self) -> Self: - return self.connect(other, linkcls=type(self)._LinkDirectShallow) - - def is_connected_to(self, other: ModuleInterface): - return self.GIFs.connected.is_connected(other.GIFs.connected) - - -TM = TypeVar("TM", bound="Module") - - -class _ModuleTrait(Generic[TM], _NodeTrait[TM]): ... - - -class ModuleTrait(_ModuleTrait["Module"]): ... - - -class Module(Node): - @classmethod - def GIFS(cls): - class GIFS(Node.GIFS()): - # TODO - specializes = GraphInterface() - specialized = GraphInterface() - - return GIFS - - @classmethod - def IFS(cls): - class IFS(Module.NodesCls(ModuleInterface)): - # workaround to help pylance - def get_all(self) -> list[ModuleInterface]: - return [cast_assert(ModuleInterface, i) for i in super().get_all()] - - return IFS - - @classmethod - def PARAMS(cls): - class PARAMS(Module.NodesCls(Parameter)): - # workaround to help pylance - def get_all(self) -> list[Parameter]: - return [cast_assert(Parameter, i) for i in super().get_all()] - - def __str__(self) -> str: - return str({p.get_hierarchy()[-1][1]: p for p in self.get_all()}) - - return PARAMS - - def __init__(self) -> None: - super().__init__() - - self.GIFs = Module.GIFS()(self) - self.IFs = Module.IFS()(self) - self.PARAMs = Module.PARAMS()(self) - - def get_most_special(self) -> Module: - specialers = { - specialer - for specialer_gif in self.GIFs.specialized.get_direct_connections() - if (specialer := specialer_gif.node) is not self - and isinstance(specialer, Module) - } - if not specialers: - return self - - specialest_next = unique_ref( - specialer.get_most_special() for specialer in specialers - ) - - assert ( - len(specialest_next) == 1 - ), f"Ambiguous specialest {specialest_next} for {self}" - return next(iter(specialest_next)) - - -# ----------------------------------------------------------------------------- diff --git a/src/faebryk/core/graphinterface.py b/src/faebryk/core/graphinterface.py new file mode 100644 index 00000000..47c46d66 --- /dev/null +++ b/src/faebryk/core/graphinterface.py @@ -0,0 +1,137 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import logging +from typing import Mapping, Optional, type_check_only + +from typing_extensions import Self, deprecated + +from faebryk.core.core import ID_REPR, FaebrykLibObject +from faebryk.core.graph_backends.default import GraphImpl +from faebryk.core.link import Link, LinkDirect, LinkNamedParent +from faebryk.libs.util import ( + NotNone, + try_avoid_endless_recursion, +) + +if type_check_only: + from faebryk.core.node import Node + +logger = logging.getLogger(__name__) + +Graph = GraphImpl["GraphInterface"] + + +class GraphInterface(FaebrykLibObject): + GT = Graph + + def __init__(self) -> None: + super().__init__() + self.G = self.GT() + + # can't put it into constructor + # else it needs a reference when defining IFs + self._node: Optional[Node] = None + self.name: str = type(self).__name__ + + @property + def node(self): + return NotNone(self._node) + + @node.setter + def node(self, value: Node): + self._node = value + + # Graph stuff + @property + def edges(self) -> Mapping["GraphInterface", Link]: + return self.G.get_edges(self) + + def get_links(self) -> list[Link]: + return list(self.edges.values()) + + def get_links_by_type[T: Link](self, link_type: type[T]) -> list[T]: + return [link for link in self.get_links() if isinstance(link, link_type)] + + @property + @deprecated("Use get_links") + def connections(self): + return self.get_links() + + def get_direct_connections(self) -> set["GraphInterface"]: + return set(self.edges.keys()) + + def is_connected(self, other: "GraphInterface"): + return self.G.is_connected(self, other) + + # Less graph-specific stuff + + # TODO make link trait to initialize from list + def connect(self, other: Self, linkcls=None) -> Self: + assert other is not self + + if linkcls is None: + linkcls = LinkDirect + link = linkcls([other, self]) + + _, no_path = self.G.merge(other.G) + + if not no_path: + dup = self.is_connected(other) + assert ( + not dup or type(dup) is linkcls + ), f"Already connected with different link type: {dup}" + + self.G.add_edge(self, other, link=link) + + if logger.isEnabledFor(logging.DEBUG): + logger.debug(f"GIF connection: {link}") + + return self + + def get_full_name(self, types: bool = False): + typestr = f"|{type(self).__name__}|" if types else "" + return f"{self.node.get_full_name(types=types)}.{self.name}{typestr}" + + def __str__(self) -> str: + return f"{str(self.node)}.{self.name}" + + @try_avoid_endless_recursion + def __repr__(self) -> str: + id_str = f"(@{hex(id(self))})" if ID_REPR else "" + + return ( + f"{self.get_full_name(types=True)}{id_str}" + if self._node is not None + else "| " + ) + + +class GraphInterfaceHierarchical(GraphInterface): + def __init__(self, is_parent: bool) -> None: + super().__init__() + self.is_parent = is_parent + + # TODO make consistent api with get_parent + def get_children(self) -> list[tuple[str, Node]]: + assert self.is_parent + + hier_conns = self.get_links_by_type(LinkNamedParent) + if len(hier_conns) == 0: + return [] + + return [(c.name, c.get_child().node) for c in hier_conns] + + def get_parent(self) -> tuple[Node, str] | None: + assert not self.is_parent + + conns = self.get_links_by_type(LinkNamedParent) + if not conns: + return None + assert len(conns) == 1 + conn = conns[0] + parent = conn.get_parent() + + return parent.node, conn.name + + +class GraphInterfaceSelf(GraphInterface): ... diff --git a/src/faebryk/core/link.py b/src/faebryk/core/link.py new file mode 100644 index 00000000..3e5c1e45 --- /dev/null +++ b/src/faebryk/core/link.py @@ -0,0 +1,115 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import inspect +import logging +from typing import Callable, type_check_only + +from faebryk.core.core import LINK_TB, FaebrykLibObject + +logger = logging.getLogger(__name__) + +if type_check_only: + from faebryk.core.graphinterface import GraphInterface, GraphInterfaceHierarchical + + +class Link(FaebrykLibObject): + def __init__(self) -> None: + super().__init__() + + if LINK_TB: + self.tb = inspect.stack() + + def get_connections(self) -> list["GraphInterface"]: + raise NotImplementedError + + def __eq__(self, __value: "Link") -> bool: + return set(self.get_connections()) == set(__value.get_connections()) + + def __hash__(self) -> int: + return super().__hash__() + + def __str__(self) -> str: + return ( + f"{type(self).__name__}" + f"([{', '.join(str(i) for i in self.get_connections())}])" + ) + + def __repr__(self) -> str: + return f"{type(self).__name__}()" + + +class LinkSibling(Link): + def __init__(self, interfaces: list["GraphInterface"]) -> None: + super().__init__() + self.interfaces = interfaces + + def get_connections(self) -> list["GraphInterface"]: + return self.interfaces + + +class LinkParent(Link): + def __init__(self, interfaces: list["GraphInterface"]) -> None: + super().__init__() + + assert all([isinstance(i, "GraphInterfaceHierarchical") for i in interfaces]) + # TODO rethink invariant + assert len(interfaces) == 2 + assert len([i for i in interfaces if i.is_parent]) == 1 # type: ignore + + self.interfaces: list["GraphInterfaceHierarchical"] = interfaces # type: ignore + + def get_connections(self): + return self.interfaces + + def get_parent(self): + return [i for i in self.interfaces if i.is_parent][0] + + def get_child(self): + return [i for i in self.interfaces if not i.is_parent][0] + + +class LinkNamedParent(LinkParent): + def __init__(self, name: str, interfaces: list["GraphInterface"]) -> None: + super().__init__(interfaces) + self.name = name + + @classmethod + def curry(cls, name: str): + def curried(interfaces: list["GraphInterface"]): + return cls(name, interfaces) + + return curried + + +class LinkDirect(Link): + def __init__(self, interfaces: list["GraphInterface"]) -> None: + super().__init__() + assert len(set(map(type, interfaces))) == 1 + self.interfaces = interfaces + + def get_connections(self) -> list["GraphInterface"]: + return self.interfaces + + +class LinkFilteredException(Exception): ... + + +class _TLinkDirectShallow(LinkDirect): + def __new__(cls, *args, **kwargs): + if cls is _TLinkDirectShallow: + raise TypeError( + "Can't instantiate abstract class _TLinkDirectShallow directly" + ) + return LinkDirect.__new__(cls, *args, **kwargs) + + +def LinkDirectShallow(if_filter: Callable[[LinkDirect, "GraphInterface"], bool]): + class _LinkDirectShallow(_TLinkDirectShallow): + i_filter = if_filter + + def __init__(self, interfaces: list["GraphInterface"]) -> None: + if not all(map(self.i_filter, interfaces)): + raise LinkFilteredException() + super().__init__(interfaces) + + return _LinkDirectShallow diff --git a/src/faebryk/core/module.py b/src/faebryk/core/module.py new file mode 100644 index 00000000..4572bda9 --- /dev/null +++ b/src/faebryk/core/module.py @@ -0,0 +1,36 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import logging + +from faebryk.core.graphinterface import GraphInterface +from faebryk.core.node import Node +from faebryk.core.trait import Trait +from faebryk.libs.util import unique_ref + +logger = logging.getLogger(__name__) + + +class Module(Node): + class TraitT(Trait["Module"]): ... + + specializes: GraphInterface + specialized: GraphInterface + + def get_most_special(self) -> "Module": + specialers = { + specialer + for specialer_gif in self.specialized.get_direct_connections() + if (specialer := specialer_gif.node) is not self + and isinstance(specialer, Module) + } + if not specialers: + return self + + specialest_next = unique_ref( + specialer.get_most_special() for specialer in specialers + ) + + assert ( + len(specialest_next) == 1 + ), f"Ambiguous specialest {specialest_next} for {self}" + return next(iter(specialest_next)) diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py new file mode 100644 index 00000000..57d64024 --- /dev/null +++ b/src/faebryk/core/moduleinterface.py @@ -0,0 +1,318 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import logging +from typing import ( + Iterable, + Sequence, +) + +from typing_extensions import Self + +from faebryk.core.core import LINK_TB +from faebryk.core.graphinterface import ( + GraphInterface, + GraphInterfaceHierarchical, +) +from faebryk.core.link import ( + Link, + LinkDirect, + LinkDirectShallow, + LinkFilteredException, + _TLinkDirectShallow, +) +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node +from faebryk.libs.util import print_stack + +logger = logging.getLogger(__name__) + + +# The resolve functions are really weird +# You have to look into where they are called to make sense of what they are doing +# Chain resolve is for deciding what to do in a case like this +# if1 -> link1 -> if2 -> link2 -> if3 +# This will then decide with which link if1 and if3 are connected +def _resolve_link_transitive(links: Iterable[type[Link]]) -> type[Link]: + from faebryk.libs.util import is_type_set_subclasses + + uniq = set(links) + assert uniq + + if len(uniq) == 1: + return next(iter(uniq)) + + if is_type_set_subclasses(uniq, {_TLinkDirectShallow}): + # TODO this only works if the filter is identical + raise NotImplementedError() + + if is_type_set_subclasses(uniq, {LinkDirect, _TLinkDirectShallow}): + return [u for u in uniq if issubclass(u, _TLinkDirectShallow)][0] + + raise NotImplementedError() + + +# This one resolves the case if1 -> link1 -> if2; if1 -> link2 -> if2 +def _resolve_link_duplicate(links: Iterable[type[Link]]) -> type[Link]: + from faebryk.libs.util import is_type_set_subclasses + + uniq = set(links) + assert uniq + + if len(uniq) == 1: + return next(iter(uniq)) + + if is_type_set_subclasses(uniq, {LinkDirect, _TLinkDirectShallow}): + return [u for u in uniq if not issubclass(u, _TLinkDirectShallow)][0] + + raise NotImplementedError() + + +class _LEVEL: + """connect depth counter to debug connections in ModuleInterface""" + + def __init__(self) -> None: + self.value = 0 + + def inc(self): + self.value += 1 + return self.value - 1 + + def dec(self): + self.value -= 1 + + +_CONNECT_DEPTH = _LEVEL() + + +class GraphInterfaceModuleSibling(GraphInterfaceHierarchical): ... + + +class GraphInterfaceModuleConnection(GraphInterface): ... + + +class ModuleInterface(Node): + specializes: GraphInterface + specialized: GraphInterface + connected: GraphInterfaceModuleConnection + + # TODO rename + @classmethod + def LinkDirectShallow(cls): + """ + Make link that only connects up but not down + """ + + def test(node: Node): + return not any(isinstance(p[0], cls) for p in node.get_hierarchy()[:-1]) + + class _LinkDirectShallowMif( + LinkDirectShallow(lambda link, gif: test(gif.node)) + ): ... + + return _LinkDirectShallowMif + + _LinkDirectShallow: type[_TLinkDirectShallow] | None = None + + def __finit__(self) -> None: + if not type(self)._LinkDirectShallow: + type(self)._LinkDirectShallow = type(self).LinkDirectShallow() + + def _connect_siblings_and_connections( + self, other: ModuleInterface, linkcls: type[Link] + ) -> Self: + from faebryk.core.util import get_connected_mifs_with_link + + if other is self: + return self + + # Already connected + if self.is_connected_to(other): + return self + + # if link is filtered, cancel here + self._connect_across_hierarchies(other, linkcls) + if not self.is_connected_to(other): + return self + + if logger.isEnabledFor(logging.DEBUG): + logger.debug(f"MIF connection: {self} to {other}") + + def cross_connect( + s_group: dict[ModuleInterface, type[Link]], + d_group: dict[ModuleInterface, type[Link]], + hint=None, + ): + if logger.isEnabledFor(logging.DEBUG) and hint is not None: + logger.debug(f"Connect {hint} {s_group} -> {d_group}") + + for s, slink in s_group.items(): + for d, dlink in d_group.items(): + # can happen while connection trees are resolving + if s is d: + continue + link = _resolve_link_transitive([slink, dlink, linkcls]) + + s._connect_across_hierarchies(d, linkcls=link) + + def _get_connected_mifs(gif: GraphInterface): + return {k: type(v) for k, v in get_connected_mifs_with_link(gif).items()} + + # Connect to all connections + s_con = _get_connected_mifs(self.connected) | {self: linkcls} + d_con = _get_connected_mifs(other.connected) | {other: linkcls} + cross_connect(s_con, d_con, "connections") + + # Connect to all siblings + s_sib = ( + _get_connected_mifs(self.specialized) + | _get_connected_mifs(self.specializes) + | {self: linkcls} + ) + d_sib = ( + _get_connected_mifs(other.specialized) + | _get_connected_mifs(other.specializes) + | {other: linkcls} + ) + cross_connect(s_sib, d_sib, "siblings") + + return self + + def _on_connect(self, other: ModuleInterface): + """override to handle custom connection logic""" + ... + + def _try_connect_down(self, other: ModuleInterface, linkcls: type[Link]) -> None: + from faebryk.core.util import zip_children_by_name + + if not isinstance(other, type(self)): + return + + for _, (src, dst) in zip_children_by_name(self, other, ModuleInterface).items(): + if src is None or dst is None: + continue + src.connect(dst, linkcls=linkcls) + + def _try_connect_up(self, other: ModuleInterface) -> None: + from faebryk.core.util import get_children + + p1 = self.get_parent() + p2 = other.get_parent() + if not ( + p1 + and p2 + and p1[0] is not p2[0] + and isinstance(p1[0], type(p2[0])) + and isinstance(p1[0], ModuleInterface) + ): + return + + src_m = p1[0] + dst_m = p2[0] + assert isinstance(dst_m, ModuleInterface) + + def _is_connected(a, b): + assert isinstance(a, ModuleInterface) + assert isinstance(b, ModuleInterface) + return a.is_connected_to(b) + + src_m_is = get_children(src_m, direct_only=True, types=ModuleInterface) + dst_m_is = get_children(dst_m, direct_only=True, types=ModuleInterface) + connection_map = [ + (src_i, dst_i, _is_connected(src_i, dst_i)) + for src_i, dst_i in zip(src_m_is, dst_m_is) + ] + + assert connection_map + + if not all(connected for _, _, connected in connection_map): + return + + # decide which LinkType to use here + # depends on connections between src_i & dst_i + # e.g. if any Shallow, we need to choose shallow + link = _resolve_link_transitive( + [type(sublink) for _, _, sublink in connection_map if sublink] + ) + + if logger.isEnabledFor(logging.DEBUG): + logger.debug(f"Up connect {src_m} -> {dst_m}") + src_m.connect(dst_m, linkcls=link) + + def _connect_across_hierarchies(self, other: ModuleInterface, linkcls: type[Link]): + existing_link = self.is_connected_to(other) + if existing_link: + if isinstance(existing_link, linkcls): + return + resolved = _resolve_link_duplicate([type(existing_link), linkcls]) + if resolved is type(existing_link): + return + if LINK_TB: + print(print_stack(existing_link.tb)) + raise NotImplementedError( + "Overriding existing links not implemented, tried to override " + + f"{existing_link} with {resolved}" + ) + + # level 0 connect + try: + self.connected.connect(other.connected, linkcls=linkcls) + except LinkFilteredException: + return + + if logger.isEnabledFor(logging.DEBUG): + logger.debug(f"{' '*2*_CONNECT_DEPTH.inc()}Connect {self} to {other}") + self._on_connect(other) + + con_depth_one = _CONNECT_DEPTH.value == 1 + recursion_error = None + try: + # level +1 (down) connect + self._try_connect_down(other, linkcls=linkcls) + + # level -1 (up) connect + self._try_connect_up(other) + + except RecursionError as e: + recursion_error = e + if not con_depth_one: + raise + + if recursion_error: + raise Exception(f"Recursion error while connecting {self} to {other}") + + _CONNECT_DEPTH.dec() + + def get_direct_connections(self) -> set[ModuleInterface]: + return { + gif.node + for gif in self.connected.get_direct_connections() + if isinstance(gif.node, ModuleInterface) and gif.node is not self + } + + def connect(self, other: Self, linkcls=None) -> Self: + # TODO consider some type of check at the end within the graph instead + # assert type(other) is type(self) + if linkcls is None: + linkcls = LinkDirect + return self._connect_siblings_and_connections(other, linkcls=linkcls) + + def connect_via( + self, bridge: Node | Sequence[Node], other: Self | None = None, linkcls=None + ): + from faebryk.library.can_bridge import can_bridge + + bridges = [bridge] if isinstance(bridge, Node) else bridge + intf = self + for sub_bridge in bridges: + t = sub_bridge.get_trait(can_bridge) + intf.connect(t.get_in(), linkcls=linkcls) + intf = t.get_out() + + if other: + intf.connect(other, linkcls=linkcls) + + def connect_shallow(self, other: Self) -> Self: + return self.connect(other, linkcls=type(self)._LinkDirectShallow) + + def is_connected_to(self, other: ModuleInterface): + return self.connected.is_connected(other.connected) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py new file mode 100644 index 00000000..80f2c41d --- /dev/null +++ b/src/faebryk/core/node.py @@ -0,0 +1,235 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import logging +from dataclasses import field, fields +from itertools import chain +from typing import Any, Callable, Type, overload, type_check_only + +from attr import dataclass +from deprecated import deprecated + +from faebryk.core.core import ID_REPR, FaebrykLibObject +from faebryk.core.graphinterface import ( + GraphInterface, + GraphInterfaceHierarchical, + GraphInterfaceSelf, +) +from faebryk.core.link import LinkNamedParent, LinkSibling +from faebryk.libs.util import try_avoid_endless_recursion + +if type_check_only: + from faebryk.core.trait import Trait, TraitImpl + +logger = logging.getLogger(__name__) + + +class FieldError(Exception): + pass + + +class FieldExistsError(FieldError): + pass + + +class FieldContainerError(FieldError): + pass + + +def if_list[T](if_type: type[T], n: int) -> list[T]: + return field(default_factory=lambda: [if_type() for _ in range(n)]) + + +class rt_field[T](property): + def __init__(self, fget: Callable[[T], Any]) -> None: + super().__init__() + self.func = fget + + def _construct(self, obj: T, holder: type): + self.constructed = self.func(holder, obj) + + def __get__(self, instance: Any, owner: type | None = None) -> Any: + return self.constructed() + + +def d_field(default_factory: Callable[[], Any], **kwargs): + return field(default_factory=default_factory, **kwargs) + + +# ----------------------------------------------------------------------------- + + +@dataclass +class Node(FaebrykLibObject): + runtime_anon: list["Node"] = field(default_factory=list) + runtime: dict[str, "Node"] = field(default_factory=dict) + specialized: list["Node"] = field(default_factory=list) + + self_gif: GraphInterface = d_field(GraphInterfaceSelf) + children: GraphInterfaceHierarchical = d_field( + lambda: GraphInterfaceHierarchical(is_parent=True) + ) + parent: GraphInterfaceHierarchical = d_field( + lambda: GraphInterfaceHierarchical(is_parent=False) + ) + + def __hash__(self) -> int: + raise NotImplementedError() + + def add( + self, + obj: "Node", + name: str | None = None, + container: list | dict[str, Any] | None = None, + ): + if container is None: + container = self.runtime_anon + if name: + container = self.runtime + + if name: + if not isinstance(container, dict): + raise FieldContainerError(f"Expected dict got {type(container)}") + if name in container: + raise FieldExistsError(name) + container[name] = obj + else: + if not isinstance(container, list): + raise FieldContainerError(f"Expected list got {type(container)}") + container.append(obj) + + _init: bool = False + + def __init_subclass__(cls, *, init: bool = True) -> None: + print("Called Node __subclass__", "-" * 20) + + cls_d = dataclass(init=False)(cls) + + for name, obj in chain( + # vars(cls).items(), + [(f.name, f.type) for f in fields(cls_d)], + # cls.__annotations__.items(), + [(name, f) for name, f in vars(cls).items() if isinstance(f, rt_field)], + ): + if name.startswith("_"): + continue + print(f"{cls.__qualname__}.{name} = {obj}, {type(obj)}") + + # node_fields = [ + # f + # for f in fields(cls) + # if not f.name.startswith("_") and issubclass(f.type, (Node, Node2)) + # ] + # for f in node_fields: + # print(f"{cls.__qualname__}.{f.name} = {f.type.__qualname__}") + + # NOTES: + # - first construct than call handle (for eliminating hazards) + + def __post_init__(self) -> None: + print("Called Node init", "-" * 20) + if self._init: + for base in reversed(type(self).mro()): + if hasattr(base, "__finit__"): + base.__finit__(self) + + @overload + def _handle_add(self, name: str, gif: GraphInterface): + gif.node = self + gif.name = name + gif.connect(self.self_gif, linkcls=LinkSibling) + + @overload + def _handle_add(self, name: str, node: "Node"): + assert not ( + other_p := node.get_parent() + ), f"{node} already has parent: {other_p}" + node.parent.connect(self.children, LinkNamedParent.curry(name)) + + def handle_added_to_parent(self): ... + + def get_graph(self): + return self.self_gif.G + + def get_parent(self): + return self.parent.get_parent() + + def get_name(self): + p = self.get_parent() + if not p: + raise Exception("Parent required for name") + return p[1] + + def get_hierarchy(self) -> list[tuple["Node", str]]: + parent = self.get_parent() + if not parent: + return [(self, "*")] + parent_obj, name = parent + + return parent_obj.get_hierarchy() + [(self, name)] + + def get_full_name(self, types: bool = False): + hierarchy = self.get_hierarchy() + if types: + return ".".join([f"{name}|{type(obj).__name__}" for obj, name in hierarchy]) + else: + return ".".join([f"{name}" for _, name in hierarchy]) + + @try_avoid_endless_recursion + def __str__(self) -> str: + return f"<{self.get_full_name(types=True)}>" + + @try_avoid_endless_recursion + def __repr__(self) -> str: + id_str = f"(@{hex(id(self))})" if ID_REPR else "" + return f"<{self.get_full_name(types=True)}>{id_str}" + + # Trait stuff ---------------------------------------------------------------------- + + # TODO type checking InterfaceTrait -> Interface + @deprecated("Just use add") + def add_trait[_TImpl: "TraitImpl"](self, trait: _TImpl) -> _TImpl: + from faebryk.core.trait import Trait, TraitImpl + + assert isinstance(trait, TraitImpl), ("not a traitimpl:", trait) + assert isinstance(trait, Trait) + + self.add(trait) + + return trait + + def _find(self, trait, only_implemented: bool): + from faebryk.core.util import get_children + + traits = get_children(self, direct_only=True, types=TraitImpl) + + return [ + impl + for impl in traits + if impl.implements(trait) + and (impl.is_implemented() or not only_implemented) + ] + + def del_trait(self, trait): + candidates = self._find(trait, only_implemented=False) + assert len(candidates) <= 1 + if len(candidates) == 0: + return + assert len(candidates) == 1, "{} not in {}[{}]".format(trait, type(self), self) + impl = candidates[0] + impl.parent.disconnect(impl) + + def has_trait(self, trait) -> bool: + return len(self._find(trait, only_implemented=True)) > 0 + + def get_trait[V: "Trait"](self, trait: Type[V]) -> V: + assert not issubclass( + trait, TraitImpl + ), "You need to specify the trait, not an impl" + + candidates = self._find(trait, only_implemented=True) + assert len(candidates) <= 1 + assert len(candidates) == 1, "{} not in {}[{}]".format(trait, type(self), self) + + out = candidates[0] + assert isinstance(out, trait) + return out diff --git a/src/faebryk/core/parameter.py b/src/faebryk/core/parameter.py new file mode 100644 index 00000000..494dfd3f --- /dev/null +++ b/src/faebryk/core/parameter.py @@ -0,0 +1,381 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import logging +from typing import ( + Callable, + Optional, + Sequence, +) + +from typing_extensions import Self + +from faebryk.core.graphinterface import GraphInterface +from faebryk.core.node import Node +from faebryk.libs.util import TwistArgs, is_type_pair, try_avoid_endless_recursion + +logger = logging.getLogger(__name__) + + +def _resolved[PV, O]( + func: Callable[["Parameter[PV]", "Parameter[PV]"], O], +) -> Callable[ + [ + "PV | set[PV] | tuple[PV, PV] | Parameter[PV]", + "PV | set[PV] | tuple[PV, PV] | Parameter[PV]", + ], + O, +]: + def wrap(*args): + args = [Parameter.from_literal(arg).get_most_narrow() for arg in args] + return func(*args) + + return wrap + + +class Parameter[PV](Node): + type LIT = PV | set[PV] | tuple[PV, PV] + type LIT_OR_PARAM = LIT | "Parameter[PV]" + + narrowed_by: GraphInterface + narrows: GraphInterface + + class MergeException(Exception): ... + + class SupportsSetOps: + def __contains__(self, other: "Parameter[PV].LIT_OR_PARAM") -> bool: ... + + def try_compress(self) -> "Parameter[PV]": + return self + + @classmethod + def from_literal(cls, value: LIT_OR_PARAM) -> '"Parameter[PV]"': + from faebryk.library.Constant import Constant + from faebryk.library.Range import Range + from faebryk.library.Set import Set + + if isinstance(value, Parameter): + return value + elif isinstance(value, set): + return Set(value) + elif isinstance(value, tuple): + return Range(*value) + else: + return Constant(value) + + def _merge(self, other: "Parameter[PV]") -> "Parameter[PV]": + from faebryk.library.ANY import ANY + from faebryk.library.Operation import Operation + from faebryk.library.Set import Set + from faebryk.library.TBD import TBD + + def _is_pair[T, U](type1: type[T], type2: type[U]) -> Optional[tuple[T, U]]: + return is_type_pair(self, other, type1, type2) + + if self is other: + return self + + try: + if self == other: + return self + except ValueError: + ... + + if pair := _is_pair(Parameter[PV], TBD): + return pair[0] + + if pair := _is_pair(Parameter[PV], ANY): + return pair[0] + + # TODO remove as soon as possible + if pair := _is_pair(Parameter[PV], Operation): + # TODO make MergeOperation that inherits from Operation + # and return that instead, application can check if result is MergeOperation + # if it was checking mergeability + raise self.MergeException("cant merge range with operation") + + if pair := _is_pair(Parameter[PV], Parameter[PV].SupportsSetOps): + out = self.intersect(*pair) + if isinstance(out, Operation): + raise self.MergeException("not resolvable") + if out == Set([]) and not pair[0] == pair[1] == Set([]): + raise self.MergeException("conflicting sets/ranges") + return out + + raise NotImplementedError + + def _narrowed(self, other: "Parameter[PV]"): + if self is other: + return + + if self.narrowed_by.is_connected(other.narrows): + return + self.narrowed_by.connect(other.narrows) + + @_resolved + def is_mergeable_with(self: "Parameter[PV]", other: "Parameter[PV]") -> bool: + try: + self._merge(other) + return True + except self.MergeException: + return False + except NotImplementedError: + return False + + @_resolved + def is_subset_of(self: "Parameter[PV]", other: "Parameter[PV]") -> bool: + from faebryk.library.ANY import ANY + from faebryk.library.Operation import Operation + from faebryk.library.TBD import TBD + + lhs = self + rhs = other + + def is_either_instance(t: type["Parameter[PV]"]): + return isinstance(lhs, t) or isinstance(rhs, t) + + # Not resolveable + if isinstance(rhs, ANY): + return True + if isinstance(lhs, ANY): + return False + if is_either_instance(TBD): + return False + if is_either_instance(Operation): + return False + + # Sets + return lhs & rhs == lhs + + @_resolved + def merge(self: "Parameter[PV]", other: "Parameter[PV]") -> "Parameter[PV]": + out = self._merge(other) + + self._narrowed(out) + other._narrowed(out) + + return out + + @_resolved + def override(self: "Parameter[PV]", other: "Parameter[PV]") -> "Parameter[PV]": + if not other.is_subset_of(self): + raise self.MergeException("override not possible") + + self._narrowed(other) + return other + + # TODO: replace with graph-based + @staticmethod + def arithmetic_op( + op1: "Parameter[PV]", op2: "Parameter[PV]", op: Callable + ) -> "Parameter[PV]": + from faebryk.library.ANY import ANY + from faebryk.library.Constant import Constant + from faebryk.library.Operation import Operation + from faebryk.library.Range import Range + from faebryk.library.Set import Set + from faebryk.library.TBD import TBD + + def _is_pair[T, U]( + type1: type[T], type2: type[U] + ) -> Optional[tuple[T, U, Callable]]: + if isinstance(op1, type1) and isinstance(op2, type2): + return op1, op2, op + if isinstance(op1, type2) and isinstance(op2, type1): + return op2, op1, TwistArgs(op) + + return None + + if pair := _is_pair(Constant, Constant): + return Constant(op(pair[0].value, pair[1].value)) + + if pair := _is_pair(Range, Range): + try: + p0_min, p0_max = pair[0].min, pair[0].max + p1_min, p1_max = pair[1].min, pair[1].max + except Range.MinMaxError: + return Operation(pair[:2], op) + return Range( + *( + op(lhs, rhs) + for lhs, rhs in [ + (p0_min, p1_min), + (p0_max, p1_max), + (p0_min, p1_max), + (p0_max, p1_min), + ] + ) + ) + + if pair := _is_pair(Constant, Range): + sop = pair[2] + try: + return Range(*(sop(pair[0], bound) for bound in pair[1].bounds)) + except Range.MinMaxError: + return Operation(pair[:2], op) + + if pair := _is_pair(Parameter, ANY): + sop = pair[2] + return Operation(pair[:2], sop) + + if pair := _is_pair(Parameter, Operation): + sop = pair[2] + return Operation(pair[:2], sop) + + if pair := _is_pair(Parameter, TBD): + sop = pair[2] + return Operation(pair[:2], sop) + + if pair := _is_pair(Parameter, Set): + sop = pair[2] + return Set( + Parameter.arithmetic_op(nested, pair[0], sop) + for nested in pair[1].params + ) + + raise NotImplementedError + + @staticmethod + def intersect(op1: "Parameter[PV]", op2: "Parameter[PV]") -> "Parameter[PV]": + from faebryk.library.Constant import Constant + from faebryk.library.Operation import Operation + from faebryk.library.Range import Range + from faebryk.library.Set import Set + + if op1 == op2: + return op1 + + def _is_pair[T, U]( + type1: type[T], type2: type[U] + ) -> Optional[tuple[T, U, Callable]]: + if isinstance(op1, type1) and isinstance(op2, type2): + return op1, op2, op + if isinstance(op1, type2) and isinstance(op2, type1): + return op2, op1, TwistArgs(op) + + return None + + def op(a, b): + return a & b + + # same types + if pair := _is_pair(Constant, Constant): + return Set([]) + if pair := _is_pair(Set, Set): + return Set(pair[0].params.intersection(pair[1].params)) + if pair := _is_pair(Range, Range): + try: + min_ = max(pair[0].min, pair[1].min) + max_ = min(pair[0].max, pair[1].max) + if min_ > max_: + return Set([]) + if min_ == max_: + return Constant(min_) + return Range(max_, min_) + except Range.MinMaxError: + return Operation(pair[:2], op) + + # diff types + if pair := _is_pair(Constant, Range): + try: + if pair[0] in pair[1]: + return pair[0] + else: + return Set([]) + except Range.MinMaxError: + return Operation(pair[:2], op) + if pair := _is_pair(Constant, Set): + if pair[0] in pair[1]: + return pair[0] + else: + return Set([]) + if pair := _is_pair(Range, Set): + try: + return Set(i for i in pair[1].params if i in pair[0]) + except Range.MinMaxError: + return Operation(pair[:2], op) + + return Operation((op1, op2), op) + + @_resolved + def __add__(self: "Parameter[PV]", other: "Parameter[PV]"): + return self.arithmetic_op(self, other, lambda a, b: a + b) + + @_resolved + def __sub__(self: "Parameter[PV]", other: "Parameter[PV]"): + return self.arithmetic_op(self, other, lambda a, b: a - b) + + # TODO PV | float + @_resolved + def __mul__(self: "Parameter[PV]", other: "Parameter[PV]"): + return self.arithmetic_op(self, other, lambda a, b: a * b) + + # TODO PV | float + @_resolved + def __truediv__(self: "Parameter[PV]", other: "Parameter[PV]"): + return self.arithmetic_op(self, other, lambda a, b: a / b) + + @_resolved + def __and__(self: "Parameter[PV]", other: "Parameter[PV]") -> "Parameter[PV]": + return self.intersect(self, other) + + def get_most_narrow(self) -> "Parameter[PV]": + out = self.get_narrowing_chain()[-1] + + com = out.try_compress() + if com is not out: + com = com.get_most_narrow() + out._narrowed(com) + out = com + + return out + + @staticmethod + def resolve_all(params: "Sequence[Parameter[PV]]") -> "Parameter[PV]": + from faebryk.library.TBD import TBD + + params_set = list(params) + if not params_set: + return TBD[PV]() + it = iter(params_set) + most_specific = next(it) + for param in it: + most_specific = most_specific.merge(param) + + return most_specific + + @try_avoid_endless_recursion + def __str__(self) -> str: + narrowest = self.get_most_narrow() + if narrowest is self: + return super().__str__() + return str(narrowest) + + # @try_avoid_endless_recursion + # def __repr__(self) -> str: + # narrowest = self.get_most_narrow() + # if narrowest is self: + # return super().__repr__() + # # return f"{super().__repr__()} -> {repr(narrowest)}" + # return repr(narrowest) + + def get_narrowing_chain(self) -> list["Parameter"]: + from faebryk.core.util import get_direct_connected_nodes + + out: list[Parameter] = [self] + narrowers = get_direct_connected_nodes(self.narrowed_by, Parameter) + if narrowers: + assert len(narrowers) == 1, "Narrowing tree diverged" + out += next(iter(narrowers)).get_narrowing_chain() + assert id(self) not in map(id, out[1:]), "Narrowing tree cycle" + return out + + def get_narrowed_siblings(self) -> set["Parameter"]: + from faebryk.core.util import get_direct_connected_nodes + + return get_direct_connected_nodes(self.narrows, Parameter) + + def __copy__(self) -> Self: + return type(self)() + + def __deepcopy__(self, memo) -> Self: + return self.__copy__() diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py new file mode 100644 index 00000000..ff09c35d --- /dev/null +++ b/src/faebryk/core/trait.py @@ -0,0 +1,96 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT +import logging +from abc import ABC +from typing import Generic, TypeVar, type_check_only + +from deprecated import deprecated + +from faebryk.core.core import FaebrykLibObject + +if type_check_only: + from faebryk.core.node import Node + +logger = logging.getLogger(__name__) + +if type_check_only: + from faebryk.core.node import Node + + +class Trait[T: Node]: + @classmethod + def impl(cls: type["Trait"]): + T_ = TypeVar("T_", bound=FaebrykLibObject) + + class _Impl(Generic[T_], TraitImpl[T_], cls): ... + + return _Impl[T] + + +U = TypeVar("U", bound="FaebrykLibObject") + + +class TraitImpl[U: "Node"](Node, ABC): + trait: type[Trait[U]] + + def __finit__(self) -> None: + found = False + bases = type(self).__bases__ + while not found: + for base in bases: + if not issubclass(base, TraitImpl) and issubclass(base, Trait): + self.trait = base + found = True + break + bases = [ + new_base + for base in bases + if issubclass(base, TraitImpl) + for new_base in base.__bases__ + ] + assert len(bases) > 0 + + assert type(self.trait) is type + assert issubclass(self.trait, Trait) + assert self.trait is not TraitImpl + + def handle_added_to_parent(self): + self.on_obj_set() + + def on_obj_set(self): ... + + def remove_obj(self): + self._obj = None + + @property + def obj(self) -> U: + p = self.get_parent() + if not p: + raise Exception("trait is not linked to node") + return p[0] + + @deprecated("Use obj property") + def get_obj(self) -> U: + return self.obj + + def cmp(self, other: "TraitImpl") -> tuple[bool, "TraitImpl"]: + assert type(other), TraitImpl + + # If other same or more specific + if other.implements(self.trait): + return True, other + + # If we are more specific + if self.implements(other.trait): + return True, self + + return False, self + + def implements(self, trait: type): + assert issubclass(trait, Trait) + + return issubclass(self.trait, trait) + + # override this to implement a dynamic trait + def is_implemented(self): + return True diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 75f3dc3f..90172497 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -12,20 +12,18 @@ from typing_extensions import deprecated -from faebryk.core.core import ( +from faebryk.core.graphinterface import ( Graph, GraphInterface, GraphInterfaceHierarchical, GraphInterfaceSelf, - Link, - LinkDirect, - LinkNamedParent, - Module, - ModuleInterface, - Node, - Parameter, - Trait, ) +from faebryk.core.link import Link, LinkDirect, LinkNamedParent +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node +from faebryk.core.parameter import Parameter +from faebryk.core.trait import Trait from faebryk.library.ANY import ANY from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Constant import Constant @@ -142,7 +140,7 @@ def with_same_unit(to_convert: float | int, param: Parameter | Quantity | float def bfs_node(node: Node, filter: Callable[[GraphInterface], bool]): - return get_nodes_from_gifs(node.get_graph().bfs_visit(filter, [node.GIFs.self])) + return get_nodes_from_gifs(node.get_graph().bfs_visit(filter, [node.self_gif])) def get_nodes_from_gifs(gifs: Iterable[GraphInterface]): @@ -173,7 +171,7 @@ def get_node_children_all(node: Node, include_root=True) -> list[Node]: out = bfs_node( node, lambda x: isinstance(x, (GraphInterfaceSelf, GraphInterfaceHierarchical)) - and x is not node.GIFs.parent, + and x is not node.parent, ) if not include_root: @@ -263,7 +261,7 @@ def get_net(mif: Electrical): nets = { net - for mif in get_connected_mifs(mif.GIFs.connected) + for mif in get_connected_mifs(mif.connected) if (net := get_parent_of_type(mif, Net)) is not None } @@ -305,7 +303,7 @@ def get_node_direct_mods_or_mifs(node: Node, include_mifs: bool = True): def get_node_direct_children_(node: Node): return { gif.node - for gif, link in node.get_graph().get_edges(node.GIFs.children).items() + for gif, link in node.get_graph().get_edges(node.children).items() if isinstance(link, LinkNamedParent) } @@ -477,7 +475,7 @@ def specialize_interface[T: ModuleInterface]( general.connect(special) # Establish sibling relationship - general.GIFs.specialized.connect(special.GIFs.specializes) + general.specialized.connect(special.specializes) return special @@ -521,18 +519,18 @@ def get_node_prop_matrix[N: Node](sub_type: type[N]): # continue # special.add_trait(t) - general.GIFs.specialized.connect(special.GIFs.specializes) + general.specialized.connect(special.specializes) # Attach to new parent has_parent = special.get_parent() is not None assert not has_parent or attach_to is None if not has_parent: if attach_to: - attach_to.NODEs.extend_list("specialized", special) + attach_to.add(special, container=attach_to.specialized) else: gen_parent = general.get_parent() if gen_parent: - setattr(gen_parent[0].NODEs, f"{gen_parent[1]}_specialized", special) + gen_parent[0].add(special, name=f"{gen_parent[1]}_specialized") return special @@ -579,9 +577,9 @@ def get_first_child_of_type[U: Node](node: Node, child_type: type[U]) -> U: def pretty_params(node: Module | ModuleInterface) -> str: - # TODO dont use get_all params = { - NotNone(p.get_parent())[1]: p.get_most_narrow() for p in node.PARAMs.get_all() + NotNone(p.get_parent())[1]: p.get_most_narrow() + for p in get_children(node, direct_only=True, types=Parameter) } params_str = "\n".join(f"{k}: {v}" for k, v in params.items()) From 03942615d01e8331df8619cc052d5b4b5734803a Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 22 Aug 2024 22:44:24 +0200 Subject: [PATCH 03/63] Implement handle_add --- new_holders.py | 181 --------------------------------------- new_holders_flat.py | 88 ++----------------- src/faebryk/core/node.py | 16 ++-- 3 files changed, 16 insertions(+), 269 deletions(-) delete mode 100644 new_holders.py diff --git a/new_holders.py b/new_holders.py deleted file mode 100644 index f4db4651..00000000 --- a/new_holders.py +++ /dev/null @@ -1,181 +0,0 @@ -from dataclasses import dataclass, field, fields -from typing import Any, Callable - -from faebryk.core.core import GraphInterface, ModuleInterface, Parameter, Trait -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.LED import LED -from faebryk.library.TBD import TBD -from faebryk.libs.util import times - - -class FieldExistsError(Exception): - pass - - -@dataclass(init=False) -class Holder2[T]: - runtime_anon: list[T] = field(default_factory=list) - runtime: dict[str, T] = field(default_factory=dict) - - def add(self, obj: T, name: str | None = None): - if name: - if name in self.runtime: - raise FieldExistsError(name) - self.runtime[name] = obj - self.runtime_anon.append(obj) - - -@dataclass(init=False) -class Node2[T: type[Node2]]: - class T_PARAMS(Holder2[Parameter]): - pass - - class T_NODES(Holder2["Node2"]): - pass - - class T_TRAITS(Holder2[Trait]): - pass - - class T_GIFS(Holder2[GraphInterface]): - pass - - P: T_PARAMS - N: T_NODES - T: T_TRAITS - G: T_GIFS - - _init: bool - - def __init_subclass__(cls, *, init: bool = True) -> None: - print("Called Node __subclass__", "-" * 20) - holders_types = [ - f - for name, f in vars(cls).items() - if not name.startswith("_") and issubclass(f, Holder2) - ] - - holder_fields = [ - f - for f in fields(cls) - if not f.name.startswith("_") and issubclass(f.type, Holder2) - ] - - for f in holders_types: - # setattr(cls, f, field(default_factory=getattr(cls, f))) - print("", f.__qualname__, f) - - for f in holder_fields: - print("", f"{cls.__qualname__}.{f.name}", f.type) - - def __init__(self) -> None: - print("Called Node init") - if self._init: - for base in reversed(type(self).mro()): - if hasattr(base, "__post_init__"): - base.__post_init__(self) - - -class Module2(Node2): - class T_IFS(Holder2[ModuleInterface]): - pass - - F: T_IFS - - -# TODO can we get rid of the explicit bases in the holders? - -# ----------------------------------------------------------------------------- - - -def if_list[T](if_type: type[T], n: int) -> list[T]: - return field(default_factory=lambda: [if_type() for _ in range(n)]) - - -class rt_field[T](property): - def __init__(self, fget: Callable[[Any, T], Any]) -> None: - super().__init__() - self.func = fget - - def _construct(self, obj: T, holder: type): - self.constructed = self.func(holder, obj) - - def __get__(self, instance: Any, owner: type | None = None) -> Any: - return self.constructed() - - -# ----------------------------------------------------------------------------- - - -class Diode2(Module2): - class T_PARAMS(Module2.T_PARAMS): - forward_voltage: TBD[float] - max_current: TBD[float] - current: TBD[float] - reverse_working_voltage: TBD[float] - reverse_leakage_current: TBD[float] - - class T_IFS(Module2.T_IFS): - anode: Electrical - cathode: Electrical - - class T_TRAITS(Module2.T_TRAITS): - # static trait - designator_prefix = has_designator_prefix_defined("D") - - # dynamic trait - @rt_field - def bridge(cls, obj: "Diode2"): - return can_bridge_defined(obj.F.anode, obj.F.cathode) - - P: T_PARAMS - F: T_IFS - T: T_TRAITS - - def __post_init__(self): - print("Called Diode post_init") - - # anonymous dynamic trait - # self.T.add( - # has_simple_value_representation_based_on_param( - # self.P.forward_voltage, - # lambda p: as_unit(p, "V"), - # ) - # ) - - -class LED2(Diode2): - class T_PARAMS(Diode2.T_PARAMS): - color: TBD[LED.Color] - - P: T_PARAMS - - def __post_init__(self): - print("Called LED post_init") - - -class LED2_NOINT(LED2, init=False): - def __post_init__(self): - print("Called LED_NOINT post_init") - - -class LED2_WITHEXTRAT_IFS(LED2): - class T_IFS(LED2.T_IFS): - extra = field(default_factory=lambda: times(2, Electrical)) - extra2 = if_list(Electrical, 2) - - F: T_IFS - - def __post_init__(self): - print("Called LED_WITHEXTRAT_IFS post_init") - - -print("Diode init ----") -D = Diode2() -print("LED init ----") -L = LED2() -print("LEDNOINIT init ----") -L2 = LED2_NOINT() -print("LEDEXTRA init ----") -L3 = LED2_WITHEXTRAT_IFS() diff --git a/new_holders_flat.py b/new_holders_flat.py index cfab8174..7eb22209 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -1,8 +1,7 @@ -from dataclasses import dataclass, field, fields -from itertools import chain -from typing import Any, Callable +from dataclasses import field -from faebryk.core.core import Node +from faebryk.core.module import Module +from faebryk.core.node import d_field, if_list, rt_field from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical @@ -16,87 +15,10 @@ from faebryk.libs.units import Quantity from faebryk.libs.util import times - -class FieldExistsError(Exception): - pass - - -def if_list[T](if_type: type[T], n: int) -> list[T]: - return field(default_factory=lambda: [if_type() for _ in range(n)]) - - -class rt_field[T](property): - def __init__(self, fget: Callable[[T], Any]) -> None: - super().__init__() - self.func = fget - - def _construct(self, obj: T, holder: type): - self.constructed = self.func(holder, obj) - - def __get__(self, instance: Any, owner: type | None = None) -> Any: - return self.constructed() - - -def dfield(default_factory: Callable[[], Any], **kwargs): - return field(default_factory=default_factory, **kwargs) - - -# ----------------------------------------------------------------------------- - - -@dataclass -class Node2: - runtime_anon: list["Node2"] = field(default_factory=list) - runtime: dict[str, "Node2"] = field(default_factory=dict) - - def add(self, obj: "Node2| Node", name: str | None = None): - if name: - if name in self.runtime: - raise FieldExistsError(name) - self.runtime[name] = obj - self.runtime_anon.append(obj) - - _init: bool = False - - def __init_subclass__(cls, *, init: bool = True) -> None: - print("Called Node __subclass__", "-" * 20) - - cls_d = dataclass(init=False)(cls) - - for name, obj in chain( - # vars(cls).items(), - [(f.name, f.type) for f in fields(cls_d)], - # cls.__annotations__.items(), - [(name, f) for name, f in vars(cls).items() if isinstance(f, rt_field)], - ): - if name.startswith("_"): - continue - print(f"{cls.__qualname__}.{name} = {obj}, {type(obj)}") - - # node_fields = [ - # f - # for f in fields(cls) - # if not f.name.startswith("_") and issubclass(f.type, (Node, Node2)) - # ] - # for f in node_fields: - # print(f"{cls.__qualname__}.{f.name} = {f.type.__qualname__}") - - def __post_init__(self) -> None: - print("Called Node init", "-" * 20) - if self._init: - for base in reversed(type(self).mro()): - if hasattr(base, "_init"): - base._init(self) - - -class Module2(Node2): - pass - - # ----------------------------------------------------------------------------- -class Diode2(Module2): +class Diode2(Module): forward_voltage: TBD[Quantity] max_current: TBD[Quantity] current: TBD[Quantity] @@ -107,7 +29,7 @@ class Diode2(Module2): cathode: Electrical # static trait - designator_prefix: has_designator_prefix = dfield( + designator_prefix: has_designator_prefix = d_field( lambda: has_designator_prefix_defined("D") ) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 80f2c41d..bdb7af34 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -15,7 +15,7 @@ GraphInterfaceSelf, ) from faebryk.core.link import LinkNamedParent, LinkSibling -from faebryk.libs.util import try_avoid_endless_recursion +from faebryk.libs.util import KeyErrorNotFound, find, try_avoid_endless_recursion if type_check_only: from faebryk.core.trait import Trait, TraitImpl @@ -86,6 +86,11 @@ def add( if name: container = self.runtime + try: + container_name = find(vars(self).items(), lambda x: x[1] == container)[0] + except KeyErrorNotFound: + raise FieldContainerError("Container not in fields") + if name: if not isinstance(container, dict): raise FieldContainerError(f"Expected dict got {type(container)}") @@ -96,6 +101,9 @@ def add( if not isinstance(container, list): raise FieldContainerError(f"Expected list got {type(container)}") container.append(obj) + name = f"{container_name}[{len(container) - 1}]" + + self._handle_add_node(name, obj) _init: bool = False @@ -132,14 +140,12 @@ def __post_init__(self) -> None: if hasattr(base, "__finit__"): base.__finit__(self) - @overload - def _handle_add(self, name: str, gif: GraphInterface): + def _handle_add_gif(self, name: str, gif: GraphInterface): gif.node = self gif.name = name gif.connect(self.self_gif, linkcls=LinkSibling) - @overload - def _handle_add(self, name: str, node: "Node"): + def _handle_add_node(self, name: str, node: "Node"): assert not ( other_p := node.get_parent() ), f"{node} already has parent: {other_p}" From d5e41ca1630277247138cac25598f79f5f8127e6 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 22 Aug 2024 23:20:27 +0200 Subject: [PATCH 04/63] Fix imports --- README.md | 2 +- examples/iterative_design_nand.py | 2 +- examples/minimal_led.py | 2 +- examples/pcb_layout.py | 2 +- examples/route.py | 2 +- new_holders_flat.py | 3 +- src/faebryk/core/graphinterface.py | 12 +++---- src/faebryk/core/link.py | 4 +-- src/faebryk/core/moduleinterface.py | 17 +++++----- src/faebryk/core/node.py | 16 +++++----- src/faebryk/core/parameter.py | 3 ++ src/faebryk/core/trait.py | 31 +++++++------------ src/faebryk/exporters/bom/jlcpcb.py | 2 +- .../parameters/parameters_to_file.py | 2 +- .../exporters/pcb/kicad/transformer.py | 8 ++--- src/faebryk/library/ANY.py | 8 ++--- src/faebryk/library/B4B_ZR_SM4_TF.py | 2 +- src/faebryk/library/BH1750FVI_TR.py | 2 +- src/faebryk/library/BJT.py | 2 +- src/faebryk/library/Battery.py | 2 +- src/faebryk/library/Button.py | 2 +- src/faebryk/library/ButtonCell.py | 2 +- src/faebryk/library/CBM9002A_56ILG.py | 2 +- .../CBM9002A_56ILG_Reference_Design.py | 2 +- src/faebryk/library/CH340x.py | 2 +- src/faebryk/library/Capacitor.py | 2 +- src/faebryk/library/Common_Mode_Filter.py | 2 +- src/faebryk/library/Comparator.py | 2 +- src/faebryk/library/Constant.py | 2 +- src/faebryk/library/Crystal.py | 2 +- src/faebryk/library/Crystal_Oscillator.py | 2 +- src/faebryk/library/DifferentialPair.py | 2 +- src/faebryk/library/Diode.py | 2 +- src/faebryk/library/EEPROM.py | 2 +- src/faebryk/library/ESP32.py | 2 +- src/faebryk/library/ESP32_C3.py | 2 +- src/faebryk/library/ESP32_C3_MINI_1.py | 2 +- .../ESP32_C3_MINI_1_Reference_Design.py | 2 +- src/faebryk/library/ElectricLogic.py | 8 ++--- src/faebryk/library/ElectricLogicGate.py | 2 +- src/faebryk/library/ElectricPower.py | 2 +- src/faebryk/library/Electrical.py | 10 ++---- src/faebryk/library/Ethernet.py | 2 +- src/faebryk/library/Fan.py | 2 +- src/faebryk/library/Footprint.py | 2 +- src/faebryk/library/FootprintTrait.py | 4 +-- src/faebryk/library/Fuse.py | 2 +- src/faebryk/library/GDT.py | 2 +- src/faebryk/library/HLK_LD2410B_P.py | 2 +- src/faebryk/library/Header.py | 2 +- src/faebryk/library/I2C.py | 2 +- src/faebryk/library/Inductor.py | 2 +- src/faebryk/library/JTAG.py | 2 +- src/faebryk/library/LDO.py | 2 +- src/faebryk/library/LED.py | 2 +- src/faebryk/library/LEDIndicator.py | 2 +- src/faebryk/library/Logic.py | 2 +- src/faebryk/library/Logic74xx.py | 2 +- src/faebryk/library/LogicGate.py | 2 +- src/faebryk/library/LogicOps.py | 4 +-- src/faebryk/library/M24C08_FMN6TP.py | 2 +- src/faebryk/library/MCP2221A.py | 2 +- src/faebryk/library/ME6211C33M5G_N.py | 2 +- src/faebryk/library/MOSFET.py | 2 +- src/faebryk/library/Mechanical.py | 2 +- src/faebryk/library/Mounting_Hole.py | 2 +- src/faebryk/library/MultiSPI.py | 2 +- src/faebryk/library/Net.py | 2 +- src/faebryk/library/OLED_Module.py | 2 +- src/faebryk/library/OpAmp.py | 2 +- src/faebryk/library/Operation.py | 2 +- src/faebryk/library/PJ398SM.py | 2 +- src/faebryk/library/PM1006.py | 2 +- src/faebryk/library/Pad.py | 2 +- src/faebryk/library/Potentiometer.py | 2 +- src/faebryk/library/Power.py | 2 +- src/faebryk/library/PowerSwitch.py | 2 +- src/faebryk/library/PowerSwitchMOSFET.py | 2 +- src/faebryk/library/PoweredLED.py | 2 +- src/faebryk/library/Powered_Relay.py | 2 +- src/faebryk/library/QWIIC.py | 2 +- src/faebryk/library/QWIIC_Connector.py | 2 +- src/faebryk/library/RJ45_Receptacle.py | 2 +- src/faebryk/library/RP2040.py | 2 +- .../library/RP2040_Reference_Design.py | 2 +- src/faebryk/library/RS232.py | 2 +- src/faebryk/library/RS485.py | 2 +- src/faebryk/library/RS485_Bus_Protection.py | 2 +- src/faebryk/library/Range.py | 2 +- src/faebryk/library/Relay.py | 2 +- src/faebryk/library/Resistor.py | 2 +- .../library/Resistor_Voltage_Divider.py | 2 +- src/faebryk/library/SCD40.py | 2 +- src/faebryk/library/SK9822_EC20.py | 2 +- src/faebryk/library/SNx4LVC541A.py | 2 +- src/faebryk/library/SPI.py | 2 +- src/faebryk/library/SPIFlash.py | 2 +- src/faebryk/library/SWD.py | 2 +- src/faebryk/library/SWDConnector.py | 2 +- src/faebryk/library/Sercom.py | 2 +- src/faebryk/library/Set.py | 2 +- src/faebryk/library/Switch.py | 2 +- src/faebryk/library/TBD.py | 2 +- src/faebryk/library/TD541S485H.py | 2 +- src/faebryk/library/TXS0102DCUR.py | 2 +- src/faebryk/library/TXS0102DCUR_UART.py | 2 +- src/faebryk/library/UART.py | 2 +- src/faebryk/library/UART_Base.py | 2 +- src/faebryk/library/UART_RS485.py | 2 +- src/faebryk/library/USB2514B.py | 2 +- src/faebryk/library/USB2_0.py | 2 +- src/faebryk/library/USB2_0_ESD_Protection.py | 2 +- src/faebryk/library/USB2_0_IF.py | 2 +- src/faebryk/library/USB3.py | 2 +- src/faebryk/library/USB3_IF.py | 2 +- src/faebryk/library/USB3_connector.py | 2 +- src/faebryk/library/USBLC6_2P6.py | 2 +- src/faebryk/library/USB_C.py | 2 +- src/faebryk/library/USB_C_5V_PSU.py | 2 +- src/faebryk/library/USB_C_PSU_Vertical.py | 2 +- src/faebryk/library/USB_C_PowerOnly.py | 2 +- src/faebryk/library/USB_RS485.py | 2 +- .../USB_Type_C_Receptacle_14_pin_Vertical.py | 2 +- .../library/USB_Type_C_Receptacle_16_pin.py | 2 +- .../library/USB_Type_C_Receptacle_24_pin.py | 2 +- src/faebryk/library/XL_3528RGBW_WS2812B.py | 2 +- .../library/can_attach_to_footprint.py | 4 +-- src/faebryk/library/can_be_decoupled.py | 2 +- src/faebryk/library/can_be_surge_protected.py | 2 +- src/faebryk/library/can_bridge.py | 4 +-- src/faebryk/library/can_bridge_defined.py | 2 +- src/faebryk/library/has_capacitance.py | 4 +-- src/faebryk/library/has_datasheet.py | 4 +-- .../library/has_defined_capacitance.py | 2 +- .../has_defined_descriptive_properties.py | 2 +- src/faebryk/library/has_defined_resistance.py | 2 +- .../library/has_descriptive_properties.py | 4 +-- src/faebryk/library/has_designator.py | 4 +-- src/faebryk/library/has_designator_prefix.py | 4 +-- src/faebryk/library/has_esphome_config.py | 4 +-- src/faebryk/library/has_footprint.py | 4 +-- .../library/has_footprint_requirement.py | 4 +-- src/faebryk/library/has_kicad_ref.py | 4 +-- src/faebryk/library/has_linked_pad.py | 4 +-- src/faebryk/library/has_multi_picker.py | 2 +- src/faebryk/library/has_overriden_name.py | 4 +-- src/faebryk/library/has_pcb_layout.py | 4 +-- src/faebryk/library/has_pcb_position.py | 4 +-- .../has_pcb_position_defined_relative.py | 2 +- .../library/has_pcb_routing_strategy.py | 4 +-- src/faebryk/library/has_picker.py | 4 +-- .../library/has_pin_association_heuristic.py | 4 +-- src/faebryk/library/has_resistance.py | 4 +-- .../has_simple_value_representation.py | 4 +-- ...ple_value_representation_based_on_param.py | 2 +- ...le_value_representation_based_on_params.py | 2 +- .../library/has_single_electric_reference.py | 4 +-- src/faebryk/library/is_decoupled.py | 2 +- src/faebryk/library/is_esphome_bus.py | 4 +-- .../is_representable_by_single_value.py | 4 +-- src/faebryk/library/is_surge_protected.py | 2 +- src/faebryk/library/pf_533984002.py | 2 +- src/faebryk/library/pf_74AHCT2G125.py | 2 +- src/faebryk/libs/app/checks.py | 2 +- src/faebryk/libs/app/manufacturing.py | 2 +- src/faebryk/libs/app/parameters.py | 2 +- src/faebryk/libs/app/pcb.py | 2 +- src/faebryk/libs/brightness.py | 2 +- src/faebryk/libs/e_series.py | 2 +- src/faebryk/libs/examples/buildutil.py | 2 +- src/faebryk/libs/examples/pickers.py | 2 +- src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 2 +- src/faebryk/libs/picker/jlcpcb/picker_lib.py | 2 +- src/faebryk/libs/picker/jlcpcb/pickers.py | 3 +- src/faebryk/libs/picker/lcsc.py | 2 +- src/faebryk/libs/picker/picker.py | 4 +-- src/faebryk/tools/libadd.py | 2 +- test/core/test_core.py | 2 +- test/core/test_parameters.py | 2 +- test/core/test_util.py | 2 +- test/libs/picker/test_jlcpcb.py | 2 +- 181 files changed, 251 insertions(+), 262 deletions(-) diff --git a/README.md b/README.md index c732f233..e155f6e0 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ In short faebryk is a python library that allows you to design ready-to-order el ```python import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.libs.brightness import TypicalLuminousIntensity from faebryk.libs.examples.buildutil import apply_design_to_pcb diff --git a/examples/iterative_design_nand.py b/examples/iterative_design_nand.py index e839664b..e319cbca 100644 --- a/examples/iterative_design_nand.py +++ b/examples/iterative_design_nand.py @@ -17,7 +17,7 @@ import typer import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import ( get_all_nodes_with_trait, specialize_interface, diff --git a/examples/minimal_led.py b/examples/minimal_led.py index b542d596..327590b3 100644 --- a/examples/minimal_led.py +++ b/examples/minimal_led.py @@ -10,7 +10,7 @@ import typer import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.libs.brightness import TypicalLuminousIntensity from faebryk.libs.examples.buildutil import ( apply_design_to_pcb, diff --git a/examples/pcb_layout.py b/examples/pcb_layout.py index ce064433..e68ee6ac 100644 --- a/examples/pcb_layout.py +++ b/examples/pcb_layout.py @@ -10,7 +10,7 @@ import typer import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy diff --git a/examples/route.py b/examples/route.py index cea749a5..8259b2b5 100644 --- a/examples/route.py +++ b/examples/route.py @@ -10,7 +10,7 @@ import typer import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy from faebryk.exporters.pcb.routing.util import Path diff --git a/new_holders_flat.py b/new_holders_flat.py index 7eb22209..9555d4b0 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -10,7 +10,6 @@ from faebryk.library.has_simple_value_representation_based_on_param import ( has_simple_value_representation_based_on_param, ) -from faebryk.library.LED import LED from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity from faebryk.libs.util import times @@ -51,7 +50,7 @@ def _init(self): class LED2(Diode2): - color: TBD[LED.Color] + color: TBD[float] def _init(self): print("Called LED post_init") diff --git a/src/faebryk/core/graphinterface.py b/src/faebryk/core/graphinterface.py index 47c46d66..27317095 100644 --- a/src/faebryk/core/graphinterface.py +++ b/src/faebryk/core/graphinterface.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT import logging -from typing import Mapping, Optional, type_check_only +from typing import TYPE_CHECKING, Mapping, Optional from typing_extensions import Self, deprecated @@ -13,7 +13,7 @@ try_avoid_endless_recursion, ) -if type_check_only: +if TYPE_CHECKING: from faebryk.core.node import Node logger = logging.getLogger(__name__) @@ -30,7 +30,7 @@ def __init__(self) -> None: # can't put it into constructor # else it needs a reference when defining IFs - self._node: Optional[Node] = None + self._node: Optional["Node"] = None self.name: str = type(self).__name__ @property @@ -38,7 +38,7 @@ def node(self): return NotNone(self._node) @node.setter - def node(self, value: Node): + def node(self, value: "Node"): self._node = value # Graph stuff @@ -112,7 +112,7 @@ def __init__(self, is_parent: bool) -> None: self.is_parent = is_parent # TODO make consistent api with get_parent - def get_children(self) -> list[tuple[str, Node]]: + def get_children(self) -> list[tuple[str, "Node"]]: assert self.is_parent hier_conns = self.get_links_by_type(LinkNamedParent) @@ -121,7 +121,7 @@ def get_children(self) -> list[tuple[str, Node]]: return [(c.name, c.get_child().node) for c in hier_conns] - def get_parent(self) -> tuple[Node, str] | None: + def get_parent(self) -> tuple["Node", str] | None: assert not self.is_parent conns = self.get_links_by_type(LinkNamedParent) diff --git a/src/faebryk/core/link.py b/src/faebryk/core/link.py index 3e5c1e45..94108d70 100644 --- a/src/faebryk/core/link.py +++ b/src/faebryk/core/link.py @@ -2,13 +2,13 @@ # SPDX-License-Identifier: MIT import inspect import logging -from typing import Callable, type_check_only +from typing import TYPE_CHECKING, Callable from faebryk.core.core import LINK_TB, FaebrykLibObject logger = logging.getLogger(__name__) -if type_check_only: +if TYPE_CHECKING: from faebryk.core.graphinterface import GraphInterface, GraphInterfaceHierarchical diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py index 57d64024..bbdd24a6 100644 --- a/src/faebryk/core/moduleinterface.py +++ b/src/faebryk/core/moduleinterface.py @@ -20,7 +20,6 @@ LinkFilteredException, _TLinkDirectShallow, ) -from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node from faebryk.libs.util import print_stack @@ -118,7 +117,7 @@ def __finit__(self) -> None: type(self)._LinkDirectShallow = type(self).LinkDirectShallow() def _connect_siblings_and_connections( - self, other: ModuleInterface, linkcls: type[Link] + self, other: "ModuleInterface", linkcls: type[Link] ) -> Self: from faebryk.core.util import get_connected_mifs_with_link @@ -177,11 +176,11 @@ def _get_connected_mifs(gif: GraphInterface): return self - def _on_connect(self, other: ModuleInterface): + def _on_connect(self, other: "ModuleInterface"): """override to handle custom connection logic""" ... - def _try_connect_down(self, other: ModuleInterface, linkcls: type[Link]) -> None: + def _try_connect_down(self, other: "ModuleInterface", linkcls: type[Link]) -> None: from faebryk.core.util import zip_children_by_name if not isinstance(other, type(self)): @@ -192,7 +191,7 @@ def _try_connect_down(self, other: ModuleInterface, linkcls: type[Link]) -> None continue src.connect(dst, linkcls=linkcls) - def _try_connect_up(self, other: ModuleInterface) -> None: + def _try_connect_up(self, other: "ModuleInterface") -> None: from faebryk.core.util import get_children p1 = self.get_parent() @@ -238,7 +237,9 @@ def _is_connected(a, b): logger.debug(f"Up connect {src_m} -> {dst_m}") src_m.connect(dst_m, linkcls=link) - def _connect_across_hierarchies(self, other: ModuleInterface, linkcls: type[Link]): + def _connect_across_hierarchies( + self, other: "ModuleInterface", linkcls: type[Link] + ): existing_link = self.is_connected_to(other) if existing_link: if isinstance(existing_link, linkcls): @@ -282,7 +283,7 @@ def _connect_across_hierarchies(self, other: ModuleInterface, linkcls: type[Link _CONNECT_DEPTH.dec() - def get_direct_connections(self) -> set[ModuleInterface]: + def get_direct_connections(self) -> set["ModuleInterface"]: return { gif.node for gif in self.connected.get_direct_connections() @@ -314,5 +315,5 @@ def connect_via( def connect_shallow(self, other: Self) -> Self: return self.connect(other, linkcls=type(self)._LinkDirectShallow) - def is_connected_to(self, other: ModuleInterface): + def is_connected_to(self, other: "ModuleInterface"): return self.connected.is_connected(other.connected) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index bdb7af34..99fb33c6 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -1,9 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT import logging -from dataclasses import field, fields +from dataclasses import field, fields, is_dataclass from itertools import chain -from typing import Any, Callable, Type, overload, type_check_only +from typing import TYPE_CHECKING, Any, Callable, Type from attr import dataclass from deprecated import deprecated @@ -17,7 +17,7 @@ from faebryk.core.link import LinkNamedParent, LinkSibling from faebryk.libs.util import KeyErrorNotFound, find, try_avoid_endless_recursion -if type_check_only: +if TYPE_CHECKING: from faebryk.core.trait import Trait, TraitImpl logger = logging.getLogger(__name__) @@ -109,13 +109,15 @@ def add( def __init_subclass__(cls, *, init: bool = True) -> None: print("Called Node __subclass__", "-" * 20) + super().__init_subclass__() - cls_d = dataclass(init=False)(cls) + # cls_d = dataclass(init=False, kw_only=True)(cls) + # print(is_dataclass(cls_d)) for name, obj in chain( - # vars(cls).items(), - [(f.name, f.type) for f in fields(cls_d)], - # cls.__annotations__.items(), + vars(cls).items(), + [(f.name, f.type) for f in fields(cls)] if is_dataclass(cls) else [], + cls.__annotations__.items(), [(name, f) for name, f in vars(cls).items() if isinstance(f, rt_field)], ): if name.startswith("_"): diff --git a/src/faebryk/core/parameter.py b/src/faebryk/core/parameter.py index 494dfd3f..262c8c6e 100644 --- a/src/faebryk/core/parameter.py +++ b/src/faebryk/core/parameter.py @@ -11,6 +11,7 @@ from faebryk.core.graphinterface import GraphInterface from faebryk.core.node import Node +from faebryk.core.trait import Trait from faebryk.libs.util import TwistArgs, is_type_pair, try_avoid_endless_recursion logger = logging.getLogger(__name__) @@ -36,6 +37,8 @@ class Parameter[PV](Node): type LIT = PV | set[PV] | tuple[PV, PV] type LIT_OR_PARAM = LIT | "Parameter[PV]" + class TraitT(Trait["Parameter"]): ... + narrowed_by: GraphInterface narrows: GraphInterface diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index ff09c35d..b88eff13 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -2,27 +2,20 @@ # SPDX-License-Identifier: MIT import logging from abc import ABC -from typing import Generic, TypeVar, type_check_only +from typing import TypeVar from deprecated import deprecated from faebryk.core.core import FaebrykLibObject - -if type_check_only: - from faebryk.core.node import Node +from faebryk.core.node import Node logger = logging.getLogger(__name__) -if type_check_only: - from faebryk.core.node import Node - class Trait[T: Node]: @classmethod def impl(cls: type["Trait"]): - T_ = TypeVar("T_", bound=FaebrykLibObject) - - class _Impl(Generic[T_], TraitImpl[T_], cls): ... + class _Impl[T_: Node](TraitImpl[T_], cls): ... return _Impl[T] @@ -30,8 +23,8 @@ class _Impl(Generic[T_], TraitImpl[T_], cls): ... U = TypeVar("U", bound="FaebrykLibObject") -class TraitImpl[U: "Node"](Node, ABC): - trait: type[Trait[U]] +class TraitImpl[U: Node](Node, ABC): + _trait: type[Trait[U]] def __finit__(self) -> None: found = False @@ -39,7 +32,7 @@ def __finit__(self) -> None: while not found: for base in bases: if not issubclass(base, TraitImpl) and issubclass(base, Trait): - self.trait = base + self._trait = base found = True break bases = [ @@ -50,9 +43,9 @@ def __finit__(self) -> None: ] assert len(bases) > 0 - assert type(self.trait) is type - assert issubclass(self.trait, Trait) - assert self.trait is not TraitImpl + assert type(self._trait) is type + assert issubclass(self._trait, Trait) + assert self._trait is not TraitImpl def handle_added_to_parent(self): self.on_obj_set() @@ -77,11 +70,11 @@ def cmp(self, other: "TraitImpl") -> tuple[bool, "TraitImpl"]: assert type(other), TraitImpl # If other same or more specific - if other.implements(self.trait): + if other.implements(self._trait): return True, other # If we are more specific - if self.implements(other.trait): + if self.implements(other._trait): return True, self return False, self @@ -89,7 +82,7 @@ def cmp(self, other: "TraitImpl") -> tuple[bool, "TraitImpl"]: def implements(self, trait: type): assert issubclass(trait, Trait) - return issubclass(self.trait, trait) + return issubclass(self._trait, trait) # override this to implement a dynamic trait def is_implemented(self): diff --git a/src/faebryk/exporters/bom/jlcpcb.py b/src/faebryk/exporters/bom/jlcpcb.py index ab5b9d88..2d23f06e 100644 --- a/src/faebryk/exporters/bom/jlcpcb.py +++ b/src/faebryk/exporters/bom/jlcpcb.py @@ -5,7 +5,7 @@ from dataclasses import dataclass from pathlib import Path -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_designator import has_designator from faebryk.library.has_footprint import has_footprint diff --git a/src/faebryk/exporters/parameters/parameters_to_file.py b/src/faebryk/exporters/parameters/parameters_to_file.py index 95f23ba6..b34d795c 100644 --- a/src/faebryk/exporters/parameters/parameters_to_file.py +++ b/src/faebryk/exporters/parameters/parameters_to_file.py @@ -4,7 +4,7 @@ import logging from pathlib import Path -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.core.util import get_all_modules logger = logging.getLogger(__name__) diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index 91017583..7a9b6862 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -17,8 +17,8 @@ from faebryk.core.core import ( Graph, Module, - ModuleInterfaceTrait, - ModuleTrait, + ModuleInterface.TraitT, + Module.TraitT, Node, ) from faebryk.core.util import get_all_nodes_with_trait, get_all_nodes_with_traits @@ -166,7 +166,7 @@ def get_all_geos(obj: PCB | Footprint) -> list[Geom]: class PCB_Transformer: - class has_linked_kicad_footprint(ModuleTrait): + class has_linked_kicad_footprint(Module.TraitT): """ Module has footprint (which has kicad footprint) and that footprint is found in the current PCB file. @@ -190,7 +190,7 @@ def get_fp(self): def get_transformer(self): return self.transformer - class has_linked_kicad_pad(ModuleInterfaceTrait): + class has_linked_kicad_pad(ModuleInterface.TraitT): @abstractmethod def get_pad(self) -> tuple[Footprint, list[Pad]]: ... diff --git a/src/faebryk/library/ANY.py b/src/faebryk/library/ANY.py index a563bf89..2f7e0744 100644 --- a/src/faebryk/library/ANY.py +++ b/src/faebryk/library/ANY.py @@ -1,14 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from typing import Generic, TypeVar +from faebryk.core.parameter import Parameter -from faebryk.core.core import Parameter -PV = TypeVar("PV") - - -class ANY(Generic[PV], Parameter[PV]): +class ANY[PV](Parameter[PV]): """ Allow parameter to take any value. Operations with this parameter automatically resolve to ANY too. diff --git a/src/faebryk/library/B4B_ZR_SM4_TF.py b/src/faebryk/library/B4B_ZR_SM4_TF.py index 58924a32..4d0dc329 100644 --- a/src/faebryk/library/B4B_ZR_SM4_TF.py +++ b/src/faebryk/library/B4B_ZR_SM4_TF.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 91b5a14d..52555362 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -4,7 +4,7 @@ import logging from dataclasses import dataclass, field -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/BJT.py b/src/faebryk/library/BJT.py index 4883cb16..b928939e 100644 --- a/src/faebryk/library/BJT.py +++ b/src/faebryk/library/BJT.py @@ -3,7 +3,7 @@ from enum import Enum, auto -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import ( diff --git a/src/faebryk/library/Battery.py b/src/faebryk/library/Battery.py index 39bdfc2b..f9fded1a 100644 --- a/src/faebryk/library/Battery.py +++ b/src/faebryk/library/Battery.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.ElectricPower import ElectricPower from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity diff --git a/src/faebryk/library/Button.py b/src/faebryk/library/Button.py index ddc17098..27dfe3f8 100644 --- a/src/faebryk/library/Button.py +++ b/src/faebryk/library/Button.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/ButtonCell.py b/src/faebryk/library/ButtonCell.py index 3db9ac9a..9f71f8ac 100644 --- a/src/faebryk/library/ButtonCell.py +++ b/src/faebryk/library/ButtonCell.py @@ -4,7 +4,7 @@ from enum import IntEnum, StrEnum -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.Battery import Battery from faebryk.library.Constant import Constant from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/CBM9002A_56ILG.py b/src/faebryk/library/CBM9002A_56ILG.py index df9ab85c..7079a73a 100644 --- a/src/faebryk/library/CBM9002A_56ILG.py +++ b/src/faebryk/library/CBM9002A_56ILG.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index 3a9deb15..7c66cb1e 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Capacitor import Capacitor from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG from faebryk.library.Constant import Constant diff --git a/src/faebryk/library/CH340x.py b/src/faebryk/library/CH340x.py index 85b6c663..702abb50 100644 --- a/src/faebryk/library/CH340x.py +++ b/src/faebryk/library/CH340x.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.Electrical import Electrical from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index 38c3e50a..e6a28145 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -4,7 +4,7 @@ import logging from enum import IntEnum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import ( as_unit, as_unit_with_tolerance, diff --git a/src/faebryk/library/Common_Mode_Filter.py b/src/faebryk/library/Common_Mode_Filter.py index 363102ea..c483091c 100644 --- a/src/faebryk/library/Common_Mode_Filter.py +++ b/src/faebryk/library/Common_Mode_Filter.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_defined import has_designator_defined from faebryk.libs.util import times diff --git a/src/faebryk/library/Comparator.py b/src/faebryk/library/Comparator.py index 2dac01b1..68e637dc 100644 --- a/src/faebryk/library/Comparator.py +++ b/src/faebryk/library/Comparator.py @@ -3,7 +3,7 @@ from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import as_unit from faebryk.library.Electrical import Electrical from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/Constant.py b/src/faebryk/library/Constant.py index c6d18c45..c088d9f1 100644 --- a/src/faebryk/library/Constant.py +++ b/src/faebryk/library/Constant.py @@ -3,7 +3,7 @@ from typing import Self, SupportsAbs -from faebryk.core.core import Parameter, _resolved +from faebryk.core.parameter import Parameter, _resolved from faebryk.library.is_representable_by_single_value_defined import ( is_representable_by_single_value_defined, ) diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index e4250f6b..cf1ad0cc 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.Range import Range diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 4ea746a4..09398a61 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Capacitor import Capacitor from faebryk.library.Constant import Constant from faebryk.library.Crystal import Crystal diff --git a/src/faebryk/library/DifferentialPair.py b/src/faebryk/library/DifferentialPair.py index 6796fc8e..b15a5103 100644 --- a/src/faebryk/library/DifferentialPair.py +++ b/src/faebryk/library/DifferentialPair.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Electrical import Electrical diff --git a/src/faebryk/library/Diode.py b/src/faebryk/library/Diode.py index 0734a8d3..75ae7144 100644 --- a/src/faebryk/library/Diode.py +++ b/src/faebryk/library/Diode.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index 23fdedf8..34faed39 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index d088ea8d..ce57067d 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -5,7 +5,7 @@ import typing from dataclasses import dataclass -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index a5da80a4..959a12a0 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import connect_to_all_interfaces from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.Electrical import Electrical diff --git a/src/faebryk/library/ESP32_C3_MINI_1.py b/src/faebryk/library/ESP32_C3_MINI_1.py index 09087520..87eb7958 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1.py +++ b/src/faebryk/library/ESP32_C3_MINI_1.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py index 7de845c0..996fdba1 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py +++ b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Button import Button from faebryk.library.Crystal_Oscillator import Crystal_Oscillator from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 10d716df..a8503c7f 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -9,7 +9,7 @@ Module, ModuleInterface, Node, - NodeTrait, + Trait, ) from faebryk.core.util import connect_all_interfaces from faebryk.library.can_be_surge_protected_defined import ( @@ -27,7 +27,7 @@ class ElectricLogic(Logic): - class has_pulls(NodeTrait): + class has_pulls(Trait): @abstractmethod def get_pulls(self) -> tuple[Resistor | None, Resistor | None]: ... @@ -40,7 +40,7 @@ def __init__(self, up: Resistor | None, down: Resistor | None) -> None: def get_pulls(self) -> tuple[Resistor | None, Resistor | None]: return self.up, self.down - class can_be_pulled(NodeTrait): + class can_be_pulled(Trait): @abstractmethod def pull(self, up: bool) -> Resistor: ... @@ -77,7 +77,7 @@ def pull(self, up: bool): obj.add_trait(ElectricLogic.has_pulls_defined(up_r, down_r)) return resistor - # class can_be_buffered(NodeTrait): + # class can_be_buffered(Trait): # @abstractmethod # def buffer(self): # ... diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index cb66ff46..7b8daec4 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -3,7 +3,7 @@ from typing import TypeVar -from faebryk.core.core import Module, TraitImpl +from faebryk.core.module import Module, TraitImpl from faebryk.core.util import specialize_interface from faebryk.library.Constant import Constant from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/ElectricPower.py b/src/faebryk/library/ElectricPower.py index f2d91ffb..9f6128b0 100644 --- a/src/faebryk/library/ElectricPower.py +++ b/src/faebryk/library/ElectricPower.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined from faebryk.library.can_be_surge_protected_defined import ( can_be_surge_protected_defined, diff --git a/src/faebryk/library/Electrical.py b/src/faebryk/library/Electrical.py index 7cc8d992..a0e5a41a 100644 --- a/src/faebryk/library/Electrical.py +++ b/src/faebryk/library/Electrical.py @@ -1,16 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity class Electrical(ModuleInterface): - def __init__(self) -> None: - super().__init__() - - class PARAMS(ModuleInterface.PARAMS()): - potential = TBD[Quantity]() - - self.PARAMs = PARAMS(self) + potential: TBD[Quantity] diff --git a/src/faebryk/library/Ethernet.py b/src/faebryk/library/Ethernet.py index 0bd0ec17..5596e1ff 100644 --- a/src/faebryk/library/Ethernet.py +++ b/src/faebryk/library/Ethernet.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.DifferentialPair import DifferentialPair diff --git a/src/faebryk/library/Fan.py b/src/faebryk/library/Fan.py index 5b24f7e5..84f9f46d 100644 --- a/src/faebryk/library/Fan.py +++ b/src/faebryk/library/Fan.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index 45e14012..ed0454e2 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface, Node +from faebryk.core.module import Module, ModuleInterface, Node class Footprint(Module): diff --git a/src/faebryk/library/FootprintTrait.py b/src/faebryk/library/FootprintTrait.py index 24016c51..c640c8cd 100644 --- a/src/faebryk/library/FootprintTrait.py +++ b/src/faebryk/library/FootprintTrait.py @@ -4,14 +4,14 @@ from typing import Generic, TypeVar from faebryk.core.core import ( - _ModuleTrait, + _Module.TraitT, ) from faebryk.library.Footprint import Footprint TF = TypeVar("TF", bound="Footprint") -class _FootprintTrait(Generic[TF], _ModuleTrait[TF]): ... +class _FootprintTrait(Generic[TF], _Module.TraitT[TF]): ... class FootprintTrait(_FootprintTrait["Footprint"]): ... diff --git a/src/faebryk/library/Fuse.py b/src/faebryk/library/Fuse.py index 04b5b789..f8eaf40f 100644 --- a/src/faebryk/library/Fuse.py +++ b/src/faebryk/library/Fuse.py @@ -4,7 +4,7 @@ import logging from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_symmetrically import ( can_attach_to_footprint_symmetrically, ) diff --git a/src/faebryk/library/GDT.py b/src/faebryk/library/GDT.py index cfb7ba6e..d44a4d0e 100644 --- a/src/faebryk/library/GDT.py +++ b/src/faebryk/library/GDT.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index 51ef13bc..55a9110c 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/Header.py b/src/faebryk/library/Header.py index f5029053..68203db8 100644 --- a/src/faebryk/library/Header.py +++ b/src/faebryk/library/Header.py @@ -3,7 +3,7 @@ from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Constant import Constant from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/I2C.py b/src/faebryk/library/I2C.py index a4bfa54a..c7e9caf5 100644 --- a/src/faebryk/library/I2C.py +++ b/src/faebryk/library/I2C.py @@ -3,7 +3,7 @@ import logging from enum import Enum -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.has_single_electric_reference_defined import ( has_single_electric_reference_defined, diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index df13a4ab..155c5e11 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import ( as_unit, as_unit_with_tolerance, diff --git a/src/faebryk/library/JTAG.py b/src/faebryk/library/JTAG.py index 041e8f57..6ca22c18 100644 --- a/src/faebryk/library/JTAG.py +++ b/src/faebryk/library/JTAG.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.has_single_electric_reference_defined import ( diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index ca84b12e..67854d51 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -3,7 +3,7 @@ from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import as_unit, as_unit_with_tolerance from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.can_bridge_defined import can_bridge_defined diff --git a/src/faebryk/library/LED.py b/src/faebryk/library/LED.py index 264f847d..93f73412 100644 --- a/src/faebryk/library/LED.py +++ b/src/faebryk/library/LED.py @@ -4,7 +4,7 @@ from enum import Enum, auto -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.Diode import Diode from faebryk.library.Electrical import Electrical from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/LEDIndicator.py b/src/faebryk/library/LEDIndicator.py index 80103fac..084b7b79 100644 --- a/src/faebryk/library/LEDIndicator.py +++ b/src/faebryk/library/LEDIndicator.py @@ -1,6 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricPower import ElectricPower from faebryk.library.PoweredLED import PoweredLED diff --git a/src/faebryk/library/Logic.py b/src/faebryk/library/Logic.py index 848b5deb..da3c6806 100644 --- a/src/faebryk/library/Logic.py +++ b/src/faebryk/library/Logic.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Range import Range diff --git a/src/faebryk/library/Logic74xx.py b/src/faebryk/library/Logic74xx.py index 3c12afca..2b727b7a 100644 --- a/src/faebryk/library/Logic74xx.py +++ b/src/faebryk/library/Logic74xx.py @@ -4,7 +4,7 @@ from enum import Enum, auto from typing import Callable, Sequence -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricLogicGate import ElectricLogicGate from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/LogicGate.py b/src/faebryk/library/LogicGate.py index 9c145a74..e7db7fc2 100644 --- a/src/faebryk/library/LogicGate.py +++ b/src/faebryk/library/LogicGate.py @@ -3,7 +3,7 @@ from typing import Sequence, TypeVar -from faebryk.core.core import Module, TraitImpl +from faebryk.core.module import Module, TraitImpl from faebryk.library.Constant import Constant from faebryk.library.Logic import Logic from faebryk.library.LogicOps import LogicOps diff --git a/src/faebryk/library/LogicOps.py b/src/faebryk/library/LogicOps.py index 5aec6622..965e9e98 100644 --- a/src/faebryk/library/LogicOps.py +++ b/src/faebryk/library/LogicOps.py @@ -4,14 +4,14 @@ from abc import abstractmethod from typing import TypeVar -from faebryk.core.core import NodeTrait +from faebryk.core.core import Trait from faebryk.library.Logic import Logic T = TypeVar("T", bound=Logic) class LogicOps: - class can_logic(NodeTrait): + class can_logic(Trait): @abstractmethod def op(self, *ins: Logic) -> Logic: ... diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index e52f35bd..fcd54a8c 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 53a9c93a..184f6827 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index 5748764f..178d0de2 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import connect_to_all_interfaces from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, diff --git a/src/faebryk/library/MOSFET.py b/src/faebryk/library/MOSFET.py index 67a2c344..da02d3d0 100644 --- a/src/faebryk/library/MOSFET.py +++ b/src/faebryk/library/MOSFET.py @@ -3,7 +3,7 @@ from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/Mechanical.py b/src/faebryk/library/Mechanical.py index 5f13ae48..4cca33fb 100644 --- a/src/faebryk/library/Mechanical.py +++ b/src/faebryk/library/Mechanical.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface class Mechanical(ModuleInterface): ... diff --git a/src/faebryk/library/Mounting_Hole.py b/src/faebryk/library/Mounting_Hole.py index fab77341..7873cb69 100644 --- a/src/faebryk/library/Mounting_Hole.py +++ b/src/faebryk/library/Mounting_Hole.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_symmetrically import ( can_attach_to_footprint_symmetrically, ) diff --git a/src/faebryk/library/MultiSPI.py b/src/faebryk/library/MultiSPI.py index 065938e9..d76c5dec 100644 --- a/src/faebryk/library/MultiSPI.py +++ b/src/faebryk/library/MultiSPI.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.libs.util import times diff --git a/src/faebryk/library/Net.py b/src/faebryk/library/Net.py index 2d195b32..2b9dd5e1 100644 --- a/src/faebryk/library/Net.py +++ b/src/faebryk/library/Net.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import get_connected_mifs, get_parent_of_type from faebryk.library.Electrical import Electrical from faebryk.library.Footprint import Footprint diff --git a/src/faebryk/library/OLED_Module.py b/src/faebryk/library/OLED_Module.py index 7360594f..67e57d7b 100644 --- a/src/faebryk/library/OLED_Module.py +++ b/src/faebryk/library/OLED_Module.py @@ -4,7 +4,7 @@ import logging from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/OpAmp.py b/src/faebryk/library/OpAmp.py index a0cad8b4..dcdbe941 100644 --- a/src/faebryk/library/OpAmp.py +++ b/src/faebryk/library/OpAmp.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import as_unit from faebryk.library.Electrical import Electrical from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/Operation.py b/src/faebryk/library/Operation.py index 4dfdac7b..8bb9829e 100644 --- a/src/faebryk/library/Operation.py +++ b/src/faebryk/library/Operation.py @@ -5,7 +5,7 @@ import typing from textwrap import indent -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.libs.util import TwistArgs, find, try_avoid_endless_recursion logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/PJ398SM.py b/src/faebryk/library/PJ398SM.py index 12f1ba46..3651cb2e 100644 --- a/src/faebryk/library/PJ398SM.py +++ b/src/faebryk/library/PJ398SM.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import ( has_designator_prefix_defined, diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index 351f6652..ec759099 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.library.Constant import Constant from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_datasheet_defined import has_datasheet_defined diff --git a/src/faebryk/library/Pad.py b/src/faebryk/library/Pad.py index e41cf884..849c7274 100644 --- a/src/faebryk/library/Pad.py +++ b/src/faebryk/library/Pad.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.util import get_parent_of_type from faebryk.library.Electrical import Electrical from faebryk.library.Footprint import Footprint diff --git a/src/faebryk/library/Potentiometer.py b/src/faebryk/library/Potentiometer.py index 1bb6642b..b97b3976 100644 --- a/src/faebryk/library/Potentiometer.py +++ b/src/faebryk/library/Potentiometer.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.Resistor import Resistor from faebryk.library.TBD import TBD diff --git a/src/faebryk/library/Power.py b/src/faebryk/library/Power.py index 4a6e546c..dc973407 100644 --- a/src/faebryk/library/Power.py +++ b/src/faebryk/library/Power.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface class Power(ModuleInterface): ... diff --git a/src/faebryk/library/PowerSwitch.py b/src/faebryk/library/PowerSwitch.py index 102ac2b9..18516964 100644 --- a/src/faebryk/library/PowerSwitch.py +++ b/src/faebryk/library/PowerSwitch.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_switch_power_defined import can_switch_power_defined from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/PowerSwitchMOSFET.py b/src/faebryk/library/PowerSwitchMOSFET.py index 42a72fc2..3d60a8b8 100644 --- a/src/faebryk/library/PowerSwitchMOSFET.py +++ b/src/faebryk/library/PowerSwitchMOSFET.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Constant import Constant from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.MOSFET import MOSFET diff --git a/src/faebryk/library/PoweredLED.py b/src/faebryk/library/PoweredLED.py index fbb73001..9304d462 100644 --- a/src/faebryk/library/PoweredLED.py +++ b/src/faebryk/library/PoweredLED.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.ElectricPower import ElectricPower from faebryk.library.LED import LED diff --git a/src/faebryk/library/Powered_Relay.py b/src/faebryk/library/Powered_Relay.py index 855bc3d3..9f7f144e 100644 --- a/src/faebryk/library/Powered_Relay.py +++ b/src/faebryk/library/Powered_Relay.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Diode import Diode from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/QWIIC.py b/src/faebryk/library/QWIIC.py index 12831bbf..3b1aa2fb 100644 --- a/src/faebryk/library/QWIIC.py +++ b/src/faebryk/library/QWIIC.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Constant import Constant from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_datasheet_defined import has_datasheet_defined diff --git a/src/faebryk/library/QWIIC_Connector.py b/src/faebryk/library/QWIIC_Connector.py index 48bc1e82..9d4491f9 100644 --- a/src/faebryk/library/QWIIC_Connector.py +++ b/src/faebryk/library/QWIIC_Connector.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.I2C import I2C diff --git a/src/faebryk/library/RJ45_Receptacle.py b/src/faebryk/library/RJ45_Receptacle.py index aec77159..d6d3ceee 100644 --- a/src/faebryk/library/RJ45_Receptacle.py +++ b/src/faebryk/library/RJ45_Receptacle.py @@ -3,7 +3,7 @@ from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.TBD import TBD diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index 0f998e3e..9868facd 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index f40e9c07..ee6471e8 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Constant import Constant from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_datasheet_defined import has_datasheet_defined diff --git a/src/faebryk/library/RS232.py b/src/faebryk/library/RS232.py index 3f67a49e..bc44b0cb 100644 --- a/src/faebryk/library/RS232.py +++ b/src/faebryk/library/RS232.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.has_single_electric_reference_defined import ( has_single_electric_reference_defined, diff --git a/src/faebryk/library/RS485.py b/src/faebryk/library/RS485.py index 33e61b3c..c7947ea1 100644 --- a/src/faebryk/library/RS485.py +++ b/src/faebryk/library/RS485.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.DifferentialPair import DifferentialPair diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 8ac32dc2..b8f68677 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy diff --git a/src/faebryk/library/Range.py b/src/faebryk/library/Range.py index a44b49ff..37928733 100644 --- a/src/faebryk/library/Range.py +++ b/src/faebryk/library/Range.py @@ -4,7 +4,7 @@ from math import inf from typing import Any, Protocol, Self -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter class _SupportsRangeOps(Protocol): diff --git a/src/faebryk/library/Relay.py b/src/faebryk/library/Relay.py index 4d10f74f..22375d6e 100644 --- a/src/faebryk/library/Relay.py +++ b/src/faebryk/library/Relay.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.TBD import TBD diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index 5836b53d..f22e873c 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -3,7 +3,7 @@ from math import sqrt -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.core.util import ( as_unit, as_unit_with_tolerance, diff --git a/src/faebryk/library/Resistor_Voltage_Divider.py b/src/faebryk/library/Resistor_Voltage_Divider.py index be63e5b6..32d2a18e 100644 --- a/src/faebryk/library/Resistor_Voltage_Divider.py +++ b/src/faebryk/library/Resistor_Voltage_Divider.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.Resistor import Resistor diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index 438ee6cc..65406986 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/SK9822_EC20.py b/src/faebryk/library/SK9822_EC20.py index d37fb275..1202012d 100644 --- a/src/faebryk/library/SK9822_EC20.py +++ b/src/faebryk/library/SK9822_EC20.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index 76ee8c0d..5d6fdaa3 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.libs.units import P from faebryk.libs.util import times diff --git a/src/faebryk/library/SPI.py b/src/faebryk/library/SPI.py index c0b31c2a..5401a186 100644 --- a/src/faebryk/library/SPI.py +++ b/src/faebryk/library/SPI.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Electrical import Electrical diff --git a/src/faebryk/library/SPIFlash.py b/src/faebryk/library/SPIFlash.py index b2e73590..8603e3c8 100644 --- a/src/faebryk/library/SPIFlash.py +++ b/src/faebryk/library/SPIFlash.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.MultiSPI import MultiSPI diff --git a/src/faebryk/library/SWD.py b/src/faebryk/library/SWD.py index b8750acc..dfe34dd0 100644 --- a/src/faebryk/library/SWD.py +++ b/src/faebryk/library/SWD.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.has_single_electric_reference_defined import ( has_single_electric_reference_defined, diff --git a/src/faebryk/library/SWDConnector.py b/src/faebryk/library/SWDConnector.py index b6c67179..0a1aeb88 100644 --- a/src/faebryk/library/SWDConnector.py +++ b/src/faebryk/library/SWDConnector.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricPower import ElectricPower from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/Sercom.py b/src/faebryk/library/Sercom.py index 011c56da..3dd5aa99 100644 --- a/src/faebryk/library/Sercom.py +++ b/src/faebryk/library/Sercom.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.has_single_electric_reference_defined import ( has_single_electric_reference_defined, diff --git a/src/faebryk/library/Set.py b/src/faebryk/library/Set.py index cd6796a1..41ca9f41 100644 --- a/src/faebryk/library/Set.py +++ b/src/faebryk/library/Set.py @@ -3,7 +3,7 @@ from typing import Iterable, Self -from faebryk.core.core import Parameter, _resolved +from faebryk.core.parameter import Parameter, _resolved class Set[PV](Parameter[PV], Parameter[PV].SupportsSetOps): diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index 4312e879..84a25fd1 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -4,7 +4,7 @@ from functools import cache from typing import Generic, TypeGuard, TypeVar -from faebryk.core.core import Module, ModuleInterface +from faebryk.core.module import Module, ModuleInterface from faebryk.library.can_attach_to_footprint_symmetrically import ( can_attach_to_footprint_symmetrically, ) diff --git a/src/faebryk/library/TBD.py b/src/faebryk/library/TBD.py index 1303c0d2..0b34cfc5 100644 --- a/src/faebryk/library/TBD.py +++ b/src/faebryk/library/TBD.py @@ -4,7 +4,7 @@ from textwrap import indent from typing import Generic, TypeVar -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter PV = TypeVar("PV") diff --git a/src/faebryk/library/TD541S485H.py b/src/faebryk/library/TD541S485H.py index d07f92bf..5777c5ea 100644 --- a/src/faebryk/library/TD541S485H.py +++ b/src/faebryk/library/TD541S485H.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index 9f3c5e82..1e83ae96 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/TXS0102DCUR_UART.py b/src/faebryk/library/TXS0102DCUR_UART.py index b2b717b3..f5f352af 100644 --- a/src/faebryk/library/TXS0102DCUR_UART.py +++ b/src/faebryk/library/TXS0102DCUR_UART.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.ElectricPower import ElectricPower from faebryk.library.TXS0102DCUR import TXS0102DCUR from faebryk.library.UART_Base import UART_Base diff --git a/src/faebryk/library/UART.py b/src/faebryk/library/UART.py index 3e6caa1c..8a4ff5b3 100644 --- a/src/faebryk/library/UART.py +++ b/src/faebryk/library/UART.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Electrical import Electrical from faebryk.library.UART_Base import UART_Base diff --git a/src/faebryk/library/UART_Base.py b/src/faebryk/library/UART_Base.py index 0e04e179..f12f67be 100644 --- a/src/faebryk/library/UART_Base.py +++ b/src/faebryk/library/UART_Base.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.has_single_electric_reference_defined import ( has_single_electric_reference_defined, diff --git a/src/faebryk/library/UART_RS485.py b/src/faebryk/library/UART_RS485.py index 15d58dae..ea651c2b 100644 --- a/src/faebryk/library/UART_RS485.py +++ b/src/faebryk/library/UART_RS485.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.Electrical import Electrical from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index f2dbb6bd..edcd77ff 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -4,7 +4,7 @@ import logging from enum import Enum, auto -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.DifferentialPair import DifferentialPair from faebryk.library.Electrical import Electrical diff --git a/src/faebryk/library/USB2_0.py b/src/faebryk/library/USB2_0.py index 1f45ddba..ae993f4d 100644 --- a/src/faebryk/library/USB2_0.py +++ b/src/faebryk/library/USB2_0.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Range import Range from faebryk.library.USB2_0_IF import USB2_0_IF diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index cdb680ea..ef8c1fe6 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_be_decoupled import can_be_decoupled from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/src/faebryk/library/USB2_0_IF.py b/src/faebryk/library/USB2_0_IF.py index 83f477a3..14394c18 100644 --- a/src/faebryk/library/USB2_0_IF.py +++ b/src/faebryk/library/USB2_0_IF.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.DifferentialPair import DifferentialPair from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/USB3.py b/src/faebryk/library/USB3.py index 178183e7..805e742b 100644 --- a/src/faebryk/library/USB3.py +++ b/src/faebryk/library/USB3.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Range import Range from faebryk.library.USB3_IF import USB3_IF from faebryk.libs.units import P diff --git a/src/faebryk/library/USB3_IF.py b/src/faebryk/library/USB3_IF.py index 30dc4441..b1bf46ed 100644 --- a/src/faebryk/library/USB3_IF.py +++ b/src/faebryk/library/USB3_IF.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.DifferentialPair import DifferentialPair from faebryk.library.Electrical import Electrical from faebryk.library.USB2_0_IF import USB2_0_IF diff --git a/src/faebryk/library/USB3_connector.py b/src/faebryk/library/USB3_connector.py index 44c3a6b4..cb006f75 100644 --- a/src/faebryk/library/USB3_connector.py +++ b/src/faebryk/library/USB3_connector.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.Range import Range diff --git a/src/faebryk/library/USBLC6_2P6.py b/src/faebryk/library/USBLC6_2P6.py index 8d741074..f26d7056 100644 --- a/src/faebryk/library/USBLC6_2P6.py +++ b/src/faebryk/library/USBLC6_2P6.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/USB_C.py b/src/faebryk/library/USB_C.py index 9144d962..b0c0164f 100644 --- a/src/faebryk/library/USB_C.py +++ b/src/faebryk/library/USB_C.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.DifferentialPair import DifferentialPair from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index 97256dbd..bdc5dce7 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.Constant import Constant from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.ElectricPower import ElectricPower diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index 77e2e9d8..e19fbdc3 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import connect_all_interfaces from faebryk.library.Capacitor import Capacitor from faebryk.library.Constant import Constant diff --git a/src/faebryk/library/USB_C_PowerOnly.py b/src/faebryk/library/USB_C_PowerOnly.py index af52054e..34219374 100644 --- a/src/faebryk/library/USB_C_PowerOnly.py +++ b/src/faebryk/library/USB_C_PowerOnly.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.can_be_surge_protected_defined import ( can_be_surge_protected_defined, ) diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index 27c67a75..42dd2b93 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.CH340x import CH340x from faebryk.library.Range import Range from faebryk.library.Resistor import Resistor diff --git a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py index 24fb4f9b..1dec95ae 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py index d2ffd712..1f94cac2 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py index 317bc22d..0eba0598 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index 2dd9f973..27785937 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/can_attach_to_footprint.py b/src/faebryk/library/can_attach_to_footprint.py index 7594320f..a436d88e 100644 --- a/src/faebryk/library/can_attach_to_footprint.py +++ b/src/faebryk/library/can_attach_to_footprint.py @@ -3,10 +3,10 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module from faebryk.library.Footprint import Footprint -class can_attach_to_footprint(ModuleTrait): +class can_attach_to_footprint(Module.TraitT): @abstractmethod def attach(self, footprint: Footprint): ... diff --git a/src/faebryk/library/can_be_decoupled.py b/src/faebryk/library/can_be_decoupled.py index 31c62ba7..706f0f4d 100644 --- a/src/faebryk/library/can_be_decoupled.py +++ b/src/faebryk/library/can_be_decoupled.py @@ -4,7 +4,7 @@ import logging from abc import abstractmethod -from faebryk.core.core import Trait +from faebryk.core.trait import Trait from faebryk.library.Capacitor import Capacitor logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/can_be_surge_protected.py b/src/faebryk/library/can_be_surge_protected.py index 1b124ae4..86f41720 100644 --- a/src/faebryk/library/can_be_surge_protected.py +++ b/src/faebryk/library/can_be_surge_protected.py @@ -5,7 +5,7 @@ from abc import abstractmethod from typing import Sequence -from faebryk.core.core import Trait +from faebryk.core.trait import Trait from faebryk.library.TVS import TVS logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/can_bridge.py b/src/faebryk/library/can_bridge.py index 6de41f25..3204d27b 100644 --- a/src/faebryk/library/can_bridge.py +++ b/src/faebryk/library/can_bridge.py @@ -4,10 +4,10 @@ from abc import abstractmethod from typing import Any -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class can_bridge(ModuleTrait): +class can_bridge(Module.TraitT): def bridge(self, _in, out): _in.connect(self.get_in()) out.connect(self.get_out()) diff --git a/src/faebryk/library/can_bridge_defined.py b/src/faebryk/library/can_bridge_defined.py index 6f798eaa..3fb1a294 100644 --- a/src/faebryk/library/can_bridge_defined.py +++ b/src/faebryk/library/can_bridge_defined.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleInterface +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.can_bridge import can_bridge diff --git a/src/faebryk/library/has_capacitance.py b/src/faebryk/library/has_capacitance.py index f05dc2a5..126991ce 100644 --- a/src/faebryk/library/has_capacitance.py +++ b/src/faebryk/library/has_capacitance.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait, Parameter +from faebryk.core.module import Module, Parameter -class has_capacitance(ModuleTrait): +class has_capacitance(Module.TraitT): @abstractmethod def get_capacitance(self) -> Parameter: ... diff --git a/src/faebryk/library/has_datasheet.py b/src/faebryk/library/has_datasheet.py index db9b6af7..28a55f2a 100644 --- a/src/faebryk/library/has_datasheet.py +++ b/src/faebryk/library/has_datasheet.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_datasheet(ModuleTrait): +class has_datasheet(Module.TraitT): @abstractmethod def get_datasheet(self) -> str: ... diff --git a/src/faebryk/library/has_defined_capacitance.py b/src/faebryk/library/has_defined_capacitance.py index e24a83a6..d6dcc072 100644 --- a/src/faebryk/library/has_defined_capacitance.py +++ b/src/faebryk/library/has_defined_capacitance.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.has_capacitance import has_capacitance diff --git a/src/faebryk/library/has_defined_descriptive_properties.py b/src/faebryk/library/has_defined_descriptive_properties.py index 4eade1ff..f1d818d0 100644 --- a/src/faebryk/library/has_defined_descriptive_properties.py +++ b/src/faebryk/library/has_defined_descriptive_properties.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.has_descriptive_properties import has_descriptive_properties diff --git a/src/faebryk/library/has_defined_resistance.py b/src/faebryk/library/has_defined_resistance.py index c8c5b5ac..54c086c9 100644 --- a/src/faebryk/library/has_defined_resistance.py +++ b/src/faebryk/library/has_defined_resistance.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.has_resistance import has_resistance diff --git a/src/faebryk/library/has_descriptive_properties.py b/src/faebryk/library/has_descriptive_properties.py index 8292e34b..67ddf128 100644 --- a/src/faebryk/library/has_descriptive_properties.py +++ b/src/faebryk/library/has_descriptive_properties.py @@ -1,10 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_descriptive_properties(ModuleTrait): +class has_descriptive_properties(Module.TraitT): def get_properties(self) -> dict[str, str]: raise NotImplementedError() diff --git a/src/faebryk/library/has_designator.py b/src/faebryk/library/has_designator.py index 5946d6d8..fc75c365 100644 --- a/src/faebryk/library/has_designator.py +++ b/src/faebryk/library/has_designator.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_designator(ModuleTrait): +class has_designator(Module.TraitT): @abstractmethod def get_designator(self) -> str: ... diff --git a/src/faebryk/library/has_designator_prefix.py b/src/faebryk/library/has_designator_prefix.py index 82b77ebd..5d28121c 100644 --- a/src/faebryk/library/has_designator_prefix.py +++ b/src/faebryk/library/has_designator_prefix.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_designator_prefix(ModuleTrait): +class has_designator_prefix(Module.TraitT): @abstractmethod def get_prefix(self) -> str: ... diff --git a/src/faebryk/library/has_esphome_config.py b/src/faebryk/library/has_esphome_config.py index f031f079..3a2a6f6e 100644 --- a/src/faebryk/library/has_esphome_config.py +++ b/src/faebryk/library/has_esphome_config.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import NodeTrait +from faebryk.core.core import Trait -class has_esphome_config(NodeTrait): +class has_esphome_config(Trait): @abstractmethod def get_config(self) -> dict: ... diff --git a/src/faebryk/library/has_footprint.py b/src/faebryk/library/has_footprint.py index 95c2a8a8..180ca786 100644 --- a/src/faebryk/library/has_footprint.py +++ b/src/faebryk/library/has_footprint.py @@ -3,10 +3,10 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module from faebryk.library.Footprint import Footprint -class has_footprint(ModuleTrait): +class has_footprint(Module.TraitT): @abstractmethod def get_footprint(self) -> Footprint: ... diff --git a/src/faebryk/library/has_footprint_requirement.py b/src/faebryk/library/has_footprint_requirement.py index 3ba93324..34f40446 100644 --- a/src/faebryk/library/has_footprint_requirement.py +++ b/src/faebryk/library/has_footprint_requirement.py @@ -4,10 +4,10 @@ from abc import abstractmethod from typing import Sequence -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_footprint_requirement(ModuleTrait): +class has_footprint_requirement(Module.TraitT): @abstractmethod def get_footprint_requirement(self) -> Sequence[tuple[str, int]]: """ diff --git a/src/faebryk/library/has_kicad_ref.py b/src/faebryk/library/has_kicad_ref.py index 95c531b1..0a2e475c 100644 --- a/src/faebryk/library/has_kicad_ref.py +++ b/src/faebryk/library/has_kicad_ref.py @@ -1,9 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import NodeTrait +from faebryk.core.core import Trait -class has_kicad_ref(NodeTrait): +class has_kicad_ref(Trait): def get_ref(self) -> str: raise NotImplementedError() diff --git a/src/faebryk/library/has_linked_pad.py b/src/faebryk/library/has_linked_pad.py index d8d29bb6..408bef5e 100644 --- a/src/faebryk/library/has_linked_pad.py +++ b/src/faebryk/library/has_linked_pad.py @@ -4,11 +4,11 @@ from abc import abstractmethod from faebryk.core.core import ( - ModuleInterfaceTrait, + ModuleInterface.TraitT, ) from faebryk.library.Pad import Pad -class has_linked_pad(ModuleInterfaceTrait): +class has_linked_pad(ModuleInterface.TraitT): @abstractmethod def get_pad(self) -> Pad: ... diff --git a/src/faebryk/library/has_multi_picker.py b/src/faebryk/library/has_multi_picker.py index a0761996..f9225e40 100644 --- a/src/faebryk/library/has_multi_picker.py +++ b/src/faebryk/library/has_multi_picker.py @@ -6,7 +6,7 @@ from abc import abstractmethod from typing import Callable, Mapping -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.has_picker import has_picker from faebryk.libs.picker.picker import PickError diff --git a/src/faebryk/library/has_overriden_name.py b/src/faebryk/library/has_overriden_name.py index 8f9991f4..b7693e4b 100644 --- a/src/faebryk/library/has_overriden_name.py +++ b/src/faebryk/library/has_overriden_name.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_overriden_name(ModuleTrait): +class has_overriden_name(Module.TraitT): @abstractmethod def get_name(self) -> str: ... diff --git a/src/faebryk/library/has_pcb_layout.py b/src/faebryk/library/has_pcb_layout.py index 44f76af8..d760ff25 100644 --- a/src/faebryk/library/has_pcb_layout.py +++ b/src/faebryk/library/has_pcb_layout.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_pcb_layout(ModuleTrait): +class has_pcb_layout(Module.TraitT): @abstractmethod def apply(self): ... diff --git a/src/faebryk/library/has_pcb_position.py b/src/faebryk/library/has_pcb_position.py index 47b190e3..ca4b621d 100644 --- a/src/faebryk/library/has_pcb_position.py +++ b/src/faebryk/library/has_pcb_position.py @@ -4,10 +4,10 @@ from abc import abstractmethod from enum import IntEnum -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_pcb_position(ModuleTrait): +class has_pcb_position(Module.TraitT): class layer_type(IntEnum): NONE = 0 TOP_LAYER = -1 diff --git a/src/faebryk/library/has_pcb_position_defined_relative.py b/src/faebryk/library/has_pcb_position_defined_relative.py index 1202bd5a..59a6d825 100644 --- a/src/faebryk/library/has_pcb_position_defined_relative.py +++ b/src/faebryk/library/has_pcb_position_defined_relative.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.has_pcb_position import has_pcb_position diff --git a/src/faebryk/library/has_pcb_routing_strategy.py b/src/faebryk/library/has_pcb_routing_strategy.py index 7062952e..873a7afd 100644 --- a/src/faebryk/library/has_pcb_routing_strategy.py +++ b/src/faebryk/library/has_pcb_routing_strategy.py @@ -3,13 +3,13 @@ from abc import abstractmethod -from faebryk.core.core import NodeTrait +from faebryk.core.core import Trait from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import Route # TODO remove transformer from here -class has_pcb_routing_strategy(NodeTrait): +class has_pcb_routing_strategy(Trait): @abstractmethod def calculate(self, transformer: PCB_Transformer) -> list[Route]: ... diff --git a/src/faebryk/library/has_picker.py b/src/faebryk/library/has_picker.py index c3d27bfb..14046934 100644 --- a/src/faebryk/library/has_picker.py +++ b/src/faebryk/library/has_picker.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_picker(ModuleTrait): +class has_picker(Module.TraitT): @abstractmethod def pick(self) -> None: ... diff --git a/src/faebryk/library/has_pin_association_heuristic.py b/src/faebryk/library/has_pin_association_heuristic.py index 352d4197..5943cc60 100644 --- a/src/faebryk/library/has_pin_association_heuristic.py +++ b/src/faebryk/library/has_pin_association_heuristic.py @@ -3,11 +3,11 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module from faebryk.library.Electrical import Electrical -class has_pin_association_heuristic(ModuleTrait): +class has_pin_association_heuristic(Module.TraitT): class PinMatchException(Exception): ... """ diff --git a/src/faebryk/library/has_resistance.py b/src/faebryk/library/has_resistance.py index 4a4ad56f..69f70443 100644 --- a/src/faebryk/library/has_resistance.py +++ b/src/faebryk/library/has_resistance.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait, Parameter +from faebryk.core.module import Module, Parameter -class has_resistance(ModuleTrait): +class has_resistance(Module.TraitT): @abstractmethod def get_resistance(self) -> Parameter: ... diff --git a/src/faebryk/library/has_simple_value_representation.py b/src/faebryk/library/has_simple_value_representation.py index b1e27d23..7f12d288 100644 --- a/src/faebryk/library/has_simple_value_representation.py +++ b/src/faebryk/library/has_simple_value_representation.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ModuleTrait +from faebryk.core.module import Module -class has_simple_value_representation(ModuleTrait): +class has_simple_value_representation(Module.TraitT): @abstractmethod def get_value(self) -> str: ... diff --git a/src/faebryk/library/has_simple_value_representation_based_on_param.py b/src/faebryk/library/has_simple_value_representation_based_on_param.py index 4a315330..c43aa769 100644 --- a/src/faebryk/library/has_simple_value_representation_based_on_param.py +++ b/src/faebryk/library/has_simple_value_representation_based_on_param.py @@ -3,7 +3,7 @@ from typing import Callable -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.Constant import Constant from faebryk.library.has_simple_value_representation import ( has_simple_value_representation, diff --git a/src/faebryk/library/has_simple_value_representation_based_on_params.py b/src/faebryk/library/has_simple_value_representation_based_on_params.py index 4df048fb..80ead29b 100644 --- a/src/faebryk/library/has_simple_value_representation_based_on_params.py +++ b/src/faebryk/library/has_simple_value_representation_based_on_params.py @@ -3,7 +3,7 @@ from typing import Callable, Sequence -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.has_simple_value_representation import ( has_simple_value_representation, ) diff --git a/src/faebryk/library/has_single_electric_reference.py b/src/faebryk/library/has_single_electric_reference.py index bdcf8e43..9fddcb64 100644 --- a/src/faebryk/library/has_single_electric_reference.py +++ b/src/faebryk/library/has_single_electric_reference.py @@ -4,10 +4,10 @@ from abc import abstractmethod -from faebryk.core.core import NodeTrait +from faebryk.core.core import Trait from faebryk.library.ElectricPower import ElectricPower -class has_single_electric_reference(NodeTrait): +class has_single_electric_reference(Trait): @abstractmethod def get_reference(self) -> ElectricPower: ... diff --git a/src/faebryk/library/is_decoupled.py b/src/faebryk/library/is_decoupled.py index 09309897..899fa7bb 100644 --- a/src/faebryk/library/is_decoupled.py +++ b/src/faebryk/library/is_decoupled.py @@ -4,7 +4,7 @@ import logging from abc import abstractmethod -from faebryk.core.core import Trait +from faebryk.core.trait import Trait from faebryk.library.Capacitor import Capacitor logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/is_esphome_bus.py b/src/faebryk/library/is_esphome_bus.py index 3a3bca21..aca39db3 100644 --- a/src/faebryk/library/is_esphome_bus.py +++ b/src/faebryk/library/is_esphome_bus.py @@ -3,11 +3,11 @@ from abc import abstractmethod -from faebryk.core.core import ModuleInterface, ModuleInterfaceTrait +from faebryk.core.moduleinterface import ModuleInterface, ModuleInterface.TraitT from faebryk.libs.util import find -class is_esphome_bus(ModuleInterfaceTrait): +class is_esphome_bus(ModuleInterface.TraitT): ... @abstractmethod diff --git a/src/faebryk/library/is_representable_by_single_value.py b/src/faebryk/library/is_representable_by_single_value.py index f6173206..e5c1cfdc 100644 --- a/src/faebryk/library/is_representable_by_single_value.py +++ b/src/faebryk/library/is_representable_by_single_value.py @@ -3,9 +3,9 @@ from abc import abstractmethod -from faebryk.core.core import ParameterTrait +from faebryk.core.parameter import Parameter -class is_representable_by_single_value(ParameterTrait): +class is_representable_by_single_value(Parameter.TraitT): @abstractmethod def get_single_representing_value(self): ... diff --git a/src/faebryk/library/is_surge_protected.py b/src/faebryk/library/is_surge_protected.py index 54e62b82..7b2d3d37 100644 --- a/src/faebryk/library/is_surge_protected.py +++ b/src/faebryk/library/is_surge_protected.py @@ -5,7 +5,7 @@ from abc import abstractmethod from typing import Sequence -from faebryk.core.core import Trait +from faebryk.core.trait import Trait from faebryk.library.TVS import TVS logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index 7257b839..54945283 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/library/pf_74AHCT2G125.py b/src/faebryk/library/pf_74AHCT2G125.py index 1206ac5c..86c4323e 100644 --- a/src/faebryk/library/pf_74AHCT2G125.py +++ b/src/faebryk/library/pf_74AHCT2G125.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) diff --git a/src/faebryk/libs/app/checks.py b/src/faebryk/libs/app/checks.py index 18aef218..76957107 100644 --- a/src/faebryk/libs/app/checks.py +++ b/src/faebryk/libs/app/checks.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.graph import Graph from faebryk.libs.app.erc import simple_erc diff --git a/src/faebryk/libs/app/manufacturing.py b/src/faebryk/libs/app/manufacturing.py index b89a0996..a3070dda 100644 --- a/src/faebryk/libs/app/manufacturing.py +++ b/src/faebryk/libs/app/manufacturing.py @@ -4,7 +4,7 @@ import logging from pathlib import Path -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import get_all_modules from faebryk.exporters.bom.jlcpcb import write_bom_jlcpcb from faebryk.exporters.pcb.kicad.artifacts import ( diff --git a/src/faebryk/libs/app/parameters.py b/src/faebryk/libs/app/parameters.py index 0a783601..1fb3a9ed 100644 --- a/src/faebryk/libs/app/parameters.py +++ b/src/faebryk/libs/app/parameters.py @@ -3,7 +3,7 @@ import logging -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import get_all_modules from faebryk.library.ANY import ANY from faebryk.library.TBD import TBD diff --git a/src/faebryk/libs/app/pcb.py b/src/faebryk/libs/app/pcb.py index daa4e4e8..27880e46 100644 --- a/src/faebryk/libs/app/pcb.py +++ b/src/faebryk/libs/app/pcb.py @@ -7,7 +7,7 @@ from pathlib import Path from typing import Any, Callable -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.graph import Graph from faebryk.core.util import get_node_tree, iter_tree_by_depth from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer diff --git a/src/faebryk/libs/brightness.py b/src/faebryk/libs/brightness.py index 1a16a7be..6c3a016c 100644 --- a/src/faebryk/libs/brightness.py +++ b/src/faebryk/libs/brightness.py @@ -4,7 +4,7 @@ from copy import copy from enum import Enum -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.library.Constant import Constant from faebryk.library.Range import Range from faebryk.libs.units import P, Quantity diff --git a/src/faebryk/libs/e_series.py b/src/faebryk/libs/e_series.py index 65a70fb7..a3990712 100644 --- a/src/faebryk/libs/e_series.py +++ b/src/faebryk/libs/e_series.py @@ -3,7 +3,7 @@ from typing import Tuple import faebryk.library._F as F -from faebryk.core.core import Parameter +from faebryk.core.parameter import Parameter from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) diff --git a/src/faebryk/libs/examples/buildutil.py b/src/faebryk/libs/examples/buildutil.py index cab76811..8176293f 100644 --- a/src/faebryk/libs/examples/buildutil.py +++ b/src/faebryk/libs/examples/buildutil.py @@ -6,7 +6,7 @@ from pathlib import Path import faebryk.libs.picker.lcsc as lcsc -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import get_all_modules from faebryk.exporters.visualize.graph import render_sidebyside from faebryk.libs.app.checks import run_checks diff --git a/src/faebryk/libs/examples/pickers.py b/src/faebryk/libs/examples/pickers.py index 52773700..16410df2 100644 --- a/src/faebryk/libs/examples/pickers.py +++ b/src/faebryk/libs/examples/pickers.py @@ -8,7 +8,7 @@ import logging import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.core.util import specialize_module from faebryk.library._F import Constant, Range from faebryk.library.Switch import _TSwitch diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index ccf9f9d1..1bdeca58 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -21,7 +21,7 @@ from tortoise.models import Model import faebryk.library._F as F -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.core.util import pretty_param_tree, pretty_params from faebryk.library.Set import Set from faebryk.libs.e_series import ( diff --git a/src/faebryk/libs/picker/jlcpcb/picker_lib.py b/src/faebryk/libs/picker/jlcpcb/picker_lib.py index 04d6a07b..a3682302 100644 --- a/src/faebryk/libs/picker/jlcpcb/picker_lib.py +++ b/src/faebryk/libs/picker/jlcpcb/picker_lib.py @@ -3,7 +3,7 @@ from typing import Callable import faebryk.library._F as F -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.libs.e_series import E_SERIES_VALUES from faebryk.libs.picker.jlcpcb.jlcpcb import ( ComponentQuery, diff --git a/src/faebryk/libs/picker/jlcpcb/pickers.py b/src/faebryk/libs/picker/jlcpcb/pickers.py index c24a74c9..0e1d4ca1 100644 --- a/src/faebryk/libs/picker/jlcpcb/pickers.py +++ b/src/faebryk/libs/picker/jlcpcb/pickers.py @@ -2,7 +2,7 @@ import faebryk.library._F as F import faebryk.libs.picker.jlcpcb.picker_lib as P -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.libs.picker.jlcpcb.jlcpcb import JLCPCB_DB, ComponentQuery from faebryk.libs.picker.picker import PickError @@ -24,6 +24,7 @@ class StaticJLCPCBPartPicker(F.has_multi_picker.Picker): Use this if you want to specify a specific part to the multi-picker eg. a default switch """ + def __init__( self, *, diff --git a/src/faebryk/libs/picker/lcsc.py b/src/faebryk/libs/picker/lcsc.py index 5d0cb12c..2e89c9af 100644 --- a/src/faebryk/libs/picker/lcsc.py +++ b/src/faebryk/libs/picker/lcsc.py @@ -14,7 +14,7 @@ from easyeda2kicad.kicad.export_kicad_3d_model import Exporter3dModelKicad from easyeda2kicad.kicad.export_kicad_footprint import ExporterFootprintKicad -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.library.can_attach_to_footprint import can_attach_to_footprint from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index edab5b05..20691cbf 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -12,7 +12,7 @@ from rich.progress import Progress -from faebryk.core.core import Module, ModuleInterface, ModuleTrait, Parameter +from faebryk.core.module import Module, ModuleInterface, Module.TraitT, Parameter from faebryk.core.util import ( get_all_modules, get_children, @@ -113,7 +113,7 @@ def __init__(self, module: Module, options: list[PickerOption]): super().__init__(message, module) -class has_part_picked(ModuleTrait): +class has_part_picked(Module.TraitT): @abstractmethod def get_part(self) -> Part: ... diff --git a/src/faebryk/tools/libadd.py b/src/faebryk/tools/libadd.py index d48b936a..96ea458d 100644 --- a/src/faebryk/tools/libadd.py +++ b/src/faebryk/tools/libadd.py @@ -144,7 +144,7 @@ def trait(ctx: typer.Context, defined: bool = False): import logging from abc import abstractmethod - from faebryk.core.core import Trait + from faebryk.core.trait import Trait logger = logging.getLogger(__name__) diff --git a/test/core/test_core.py b/test/core/test_core.py index 622da9c5..aef4e4e9 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -10,7 +10,7 @@ class TestTraits(unittest.TestCase): def test_equality(self): - from faebryk.core.core import Trait + from faebryk.core.trait import Trait class _trait1(Trait): pass diff --git a/test/core/test_parameters.py b/test/core/test_parameters.py index 78d64490..253abae2 100644 --- a/test/core/test_parameters.py +++ b/test/core/test_parameters.py @@ -6,7 +6,7 @@ from operator import add from typing import TypeVar -from faebryk.core.core import Module, Parameter +from faebryk.core.module import Module, Parameter from faebryk.core.core import logger as core_logger from faebryk.core.util import specialize_module from faebryk.library.ANY import ANY diff --git a/test/core/test_util.py b/test/core/test_util.py index b8d419fc..79e17192 100644 --- a/test/core/test_util.py +++ b/test/core/test_util.py @@ -5,7 +5,7 @@ from enum import StrEnum from typing import Iterable -from faebryk.core.core import Module, ModuleInterface, Node, Parameter +from faebryk.core.module import Module, ModuleInterface, Node, Parameter from faebryk.core.util import get_children, get_node_tree, iter_tree_by_depth diff --git a/test/libs/picker/test_jlcpcb.py b/test/libs/picker/test_jlcpcb.py index a30e6c41..4d659d21 100644 --- a/test/libs/picker/test_jlcpcb.py +++ b/test/libs/picker/test_jlcpcb.py @@ -7,7 +7,7 @@ import faebryk.library._F as F import faebryk.libs.picker.lcsc as lcsc -from faebryk.core.core import Module +from faebryk.core.module import Module from faebryk.libs.logging import setup_basic_logging from faebryk.libs.picker.jlcpcb.jlcpcb import JLCPCB_DB from faebryk.libs.picker.jlcpcb.pickers import add_jlcpcb_pickers From 76be49b9c70e3f54a9064b6300179bcc788aad41 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 22 Aug 2024 23:41:43 +0200 Subject: [PATCH 05/63] No dataclass --- new_holders_flat.py | 16 +++++++-------- src/faebryk/core/node.py | 43 +++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/new_holders_flat.py b/new_holders_flat.py index 9555d4b0..b87bf3c8 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -37,8 +37,8 @@ class Diode2(Module): def bridge(self): return can_bridge_defined(self.anode, self.cathode) - def _init(self): - print("Called Diode post_init") + def __finit__(self): + print("Called Diode __finit__") # anonymous dynamic trait self.add( @@ -52,21 +52,21 @@ def _init(self): class LED2(Diode2): color: TBD[float] - def _init(self): - print("Called LED post_init") + def __finit__(self): + print("Called LED __finit__") class LED2_NOINT(LED2, init=False): - def _init(self): - print("Called LED_NOINT post_init") + def __finit__(self): + print("Called LED_NOINT __finit__") class LED2_WITHEXTRAT_IFS(LED2): extra: list[Electrical] = field(default_factory=lambda: times(2, Electrical)) extra2: list[Electrical] = if_list(Electrical, 2) - def _init(self): - print("Called LED_WITHEXTRAT_IFS post_init") + def __finit__(self): + print("Called LED_WITHEXTRAT_IFS __finit__") print("Diode init ----") diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 99fb33c6..d09d1fa0 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT import logging -from dataclasses import field, fields, is_dataclass +from dataclasses import Field, field, fields, is_dataclass from itertools import chain from typing import TYPE_CHECKING, Any, Callable, Type @@ -58,13 +58,12 @@ def d_field(default_factory: Callable[[], Any], **kwargs): # ----------------------------------------------------------------------------- -@dataclass class Node(FaebrykLibObject): - runtime_anon: list["Node"] = field(default_factory=list) - runtime: dict[str, "Node"] = field(default_factory=dict) - specialized: list["Node"] = field(default_factory=list) + runtime_anon: list["Node"] + runtime: dict[str, "Node"] + specialized: list["Node"] - self_gif: GraphInterface = d_field(GraphInterfaceSelf) + self_gif: GraphInterface children: GraphInterfaceHierarchical = d_field( lambda: GraphInterfaceHierarchical(is_parent=True) ) @@ -72,6 +71,8 @@ class Node(FaebrykLibObject): lambda: GraphInterfaceHierarchical(is_parent=False) ) + _init: bool = False + def __hash__(self) -> int: raise NotImplementedError() @@ -105,37 +106,33 @@ def add( self._handle_add_node(name, obj) - _init: bool = False - def __init_subclass__(cls, *, init: bool = True) -> None: - print("Called Node __subclass__", "-" * 20) + print("Called Node __subclass__", "-" * 20, cls.__qualname__) super().__init_subclass__() - # cls_d = dataclass(init=False, kw_only=True)(cls) - # print(is_dataclass(cls_d)) + cls._init = init for name, obj in chain( - vars(cls).items(), [(f.name, f.type) for f in fields(cls)] if is_dataclass(cls) else [], - cls.__annotations__.items(), - [(name, f) for name, f in vars(cls).items() if isinstance(f, rt_field)], + *[ + base.__annotations__.items() + for base in cls.__mro__ + if hasattr(base, "__annotations__") + ], + [ + (name, f) + for name, f in vars(cls).items() + if isinstance(f, (rt_field, Field)) + ], ): if name.startswith("_"): continue print(f"{cls.__qualname__}.{name} = {obj}, {type(obj)}") - # node_fields = [ - # f - # for f in fields(cls) - # if not f.name.startswith("_") and issubclass(f.type, (Node, Node2)) - # ] - # for f in node_fields: - # print(f"{cls.__qualname__}.{f.name} = {f.type.__qualname__}") - # NOTES: # - first construct than call handle (for eliminating hazards) - def __post_init__(self) -> None: + def __init__(self) -> None: print("Called Node init", "-" * 20) if self._init: for base in reversed(type(self).mro()): From 57516b659d61ca15055ca68f804439fd1909b7d1 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 23 Aug 2024 04:01:09 +0200 Subject: [PATCH 06/63] Implement field setup --- new_holders_flat.py | 64 +++-- src/faebryk/core/link.py | 3 +- src/faebryk/core/moduleinterface.py | 3 + src/faebryk/core/node.py | 232 +++++++++++++++--- src/faebryk/core/trait.py | 4 +- .../exporters/pcb/kicad/transformer.py | 17 +- src/faebryk/library/Diode.py | 1 + src/faebryk/library/Footprint.py | 7 +- src/faebryk/library/FootprintTrait.py | 17 -- src/faebryk/library/has_linked_pad.py | 4 +- src/faebryk/library/is_esphome_bus.py | 2 +- src/faebryk/libs/app/checks.py | 2 +- src/faebryk/libs/app/pcb.py | 2 +- src/faebryk/libs/picker/picker.py | 4 +- test/core/test_parameters.py | 2 +- 15 files changed, 264 insertions(+), 100 deletions(-) delete mode 100644 src/faebryk/library/FootprintTrait.py diff --git a/new_holders_flat.py b/new_holders_flat.py index b87bf3c8..561eb2b3 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -1,15 +1,13 @@ from dataclasses import field +import typer + from faebryk.core.module import Module from faebryk.core.node import d_field, if_list, rt_field -from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation_based_on_param import ( - has_simple_value_representation_based_on_param, -) from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity from faebryk.libs.util import times @@ -27,6 +25,8 @@ class Diode2(Module): anode: Electrical cathode: Electrical + XXXXX: Electrical = d_field(Electrical) + # static trait designator_prefix: has_designator_prefix = d_field( lambda: has_designator_prefix_defined("D") @@ -37,43 +37,55 @@ class Diode2(Module): def bridge(self): return can_bridge_defined(self.anode, self.cathode) - def __finit__(self): - print("Called Diode __finit__") + def __preinit__(self): + print("Called Diode __preinit__") # anonymous dynamic trait - self.add( - has_simple_value_representation_based_on_param( - self.forward_voltage, - lambda p: as_unit(p, "V"), - ) # type: ignore - ) + # self.add( + # has_simple_value_representation_based_on_param( + # self.forward_voltage, + # lambda p: as_unit(p, "V"), + # ) # type: ignore + # ) class LED2(Diode2): color: TBD[float] - def __finit__(self): - print("Called LED __finit__") + def __preinit__(self): + print("Called LED __preinit__") class LED2_NOINT(LED2, init=False): - def __finit__(self): - print("Called LED_NOINT __finit__") + def __preinit__(self): + print("Called LED_NOINT __preinit__") class LED2_WITHEXTRAT_IFS(LED2): extra: list[Electrical] = field(default_factory=lambda: times(2, Electrical)) extra2: list[Electrical] = if_list(Electrical, 2) - def __finit__(self): - print("Called LED_WITHEXTRAT_IFS __finit__") + @rt_field + def bridge(self): + return can_bridge_defined(self.extra2[0], self.extra2[1]) + + def __preinit__(self): + print("Called LED_WITHEXTRAT_IFS __preinit__") + + +def main(): + print("Diode init ----") + _D = Diode2() + print("LED init ----") + _L = LED2() + print("LEDNOINIT init ----") + L2 = LED2_NOINT() + print("LEDEXTRA init ----") + L3 = LED2_WITHEXTRAT_IFS() + + L3.cathode.connect(L2.cathode) + + assert L3.cathode.is_connected_to(L2.cathode) -print("Diode init ----") -D = Diode2() -print("LED init ----") -L = LED2() -print("LEDNOINIT init ----") -L2 = LED2_NOINT() -print("LEDEXTRA init ----") -L3 = LED2_WITHEXTRAT_IFS() +typer.run(main) diff --git a/src/faebryk/core/link.py b/src/faebryk/core/link.py index 94108d70..d8920dee 100644 --- a/src/faebryk/core/link.py +++ b/src/faebryk/core/link.py @@ -50,8 +50,9 @@ def get_connections(self) -> list["GraphInterface"]: class LinkParent(Link): def __init__(self, interfaces: list["GraphInterface"]) -> None: super().__init__() + from faebryk.core.graphinterface import GraphInterfaceHierarchical - assert all([isinstance(i, "GraphInterfaceHierarchical") for i in interfaces]) + assert all([isinstance(i, GraphInterfaceHierarchical) for i in interfaces]) # TODO rethink invariant assert len(interfaces) == 2 assert len([i for i in interfaces if i.is_parent]) == 1 # type: ignore diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py index bbdd24a6..765ecf84 100644 --- a/src/faebryk/core/moduleinterface.py +++ b/src/faebryk/core/moduleinterface.py @@ -21,6 +21,7 @@ _TLinkDirectShallow, ) from faebryk.core.node import Node +from faebryk.core.trait import Trait from faebryk.libs.util import print_stack logger = logging.getLogger(__name__) @@ -90,6 +91,8 @@ class GraphInterfaceModuleConnection(GraphInterface): ... class ModuleInterface(Node): + class TraitT(Trait["ModuleInterface"]): ... + specializes: GraphInterface specialized: GraphInterface connected: GraphInterfaceModuleConnection diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index d09d1fa0..7252d4c0 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -1,11 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT import logging -from dataclasses import Field, field, fields, is_dataclass from itertools import chain -from typing import TYPE_CHECKING, Any, Callable, Type +from typing import TYPE_CHECKING, Any, Callable, Type, get_args, get_origin -from attr import dataclass from deprecated import deprecated from faebryk.core.core import ID_REPR, FaebrykLibObject @@ -15,7 +13,7 @@ GraphInterfaceSelf, ) from faebryk.core.link import LinkNamedParent, LinkSibling -from faebryk.libs.util import KeyErrorNotFound, find, try_avoid_endless_recursion +from faebryk.libs.util import KeyErrorNotFound, find, times, try_avoid_endless_recursion if TYPE_CHECKING: from faebryk.core.trait import Trait, TraitImpl @@ -36,34 +34,46 @@ class FieldContainerError(FieldError): def if_list[T](if_type: type[T], n: int) -> list[T]: - return field(default_factory=lambda: [if_type() for _ in range(n)]) + return d_field(lambda: times(n, if_type)) -class rt_field[T](property): +class f_field: + pass + + +class rt_field[T](property, f_field): def __init__(self, fget: Callable[[T], Any]) -> None: super().__init__() self.func = fget - def _construct(self, obj: T, holder: type): - self.constructed = self.func(holder, obj) + def _construct(self, obj: T): + self.constructed = self.func(obj) + return self.constructed def __get__(self, instance: Any, owner: type | None = None) -> Any: - return self.constructed() + return self.constructed + + +class _d_field[T](f_field): + def __init__(self, default_factory: Callable[[], T]) -> None: + self.type = None + self.default_factory = default_factory -def d_field(default_factory: Callable[[], Any], **kwargs): - return field(default_factory=default_factory, **kwargs) +def d_field[T](default_factory: Callable[[], T]) -> T: + return _d_field(default_factory) # type: ignore # ----------------------------------------------------------------------------- +# @dataclass(init=False, kw_only=True) class Node(FaebrykLibObject): runtime_anon: list["Node"] runtime: dict[str, "Node"] specialized: list["Node"] - self_gif: GraphInterface + self_gif: GraphInterfaceSelf children: GraphInterfaceHierarchical = d_field( lambda: GraphInterfaceHierarchical(is_parent=True) ) @@ -74,7 +84,8 @@ class Node(FaebrykLibObject): _init: bool = False def __hash__(self) -> int: - raise NotImplementedError() + # TODO proper hash + return hash(id(self)) def add( self, @@ -107,42 +118,189 @@ def add( self._handle_add_node(name, obj) def __init_subclass__(cls, *, init: bool = True) -> None: - print("Called Node __subclass__", "-" * 20, cls.__qualname__) super().__init_subclass__() - cls._init = init - for name, obj in chain( - [(f.name, f.type) for f in fields(cls)] if is_dataclass(cls) else [], - *[ - base.__annotations__.items() - for base in cls.__mro__ - if hasattr(base, "__annotations__") - ], - [ - (name, f) - for name, f in vars(cls).items() - if isinstance(f, (rt_field, Field)) - ], - ): - if name.startswith("_"): - continue - print(f"{cls.__qualname__}.{name} = {obj}, {type(obj)}") + def _setup_fields(self, cls): + def all_vars(cls): + return {k: v for c in reversed(cls.__mro__) for k, v in vars(c).items()} + + def all_anno(cls): + return { + k: v + for c in reversed(cls.__mro__) + if hasattr(c, "__annotations__") + for k, v in c.__annotations__.items() + } + + LL_Types = (Node, GraphInterface) + + annos = all_anno(cls) + vars_ = all_vars(cls) + for name, obj in vars_.items(): + if isinstance(obj, _d_field): + obj.type = annos[name] + + def is_node_field(obj): + def is_genalias_node(obj): + origin = get_origin(obj) + assert origin is not None + + if issubclass(origin, LL_Types): + return True + + if issubclass(origin, (list, dict)): + arg = get_args(obj)[-1] + return is_node_field(arg) + + if isinstance(obj, LL_Types): + raise FieldError("Node instances not allowed") + + if isinstance(obj, str): + return obj in [L.__name__ for L in LL_Types] + + if isinstance(obj, type): + return issubclass(obj, LL_Types) + + if isinstance(obj, _d_field): + t = obj.type + if isinstance(t, type): + return issubclass(t, LL_Types) + + if get_origin(t): + return is_genalias_node(t) + + if get_origin(obj): + return is_genalias_node(obj) + + if isinstance(obj, rt_field): + return True + + return False + + clsfields_unf = { + name: obj + for name, obj in chain( + [(name, f) for name, f in annos.items()], + [(name, f) for name, f in vars_.items() if isinstance(f, f_field)], + ) + if not name.startswith("_") + } + + clsfields = { + name: obj for name, obj in clsfields_unf.items() if is_node_field(obj) + } + + # for name, obj in clsfields_unf.items(): + # if isinstance(obj, _d_field): + # obj = obj.type + # filtered = name not in clsfields + # filtered_str = " FILTERED" if filtered else "" + # print( + # f"{cls.__qualname__+"."+name+filtered_str:<60} = {str(obj):<70} " + # "| {type(obj)}" + # ) + + objects: dict[str, Node | GraphInterface] = {} + + def append(name, inst): + if isinstance(inst, LL_Types): + objects[name] = inst + elif isinstance(inst, list): + for i, obj in enumerate(inst): + objects[f"{name}[{i}]"] = obj + elif isinstance(inst, dict): + for k, obj in inst.items(): + objects[f"{name}[{k}]"] = obj + + return inst + + def setup_field(name, obj): + def setup_gen_alias(name, obj): + origin = get_origin(obj) + assert origin + if isinstance(origin, type): + setattr(self, name, append(name, origin())) + return + raise NotImplementedError(origin) + + if isinstance(obj, str): + raise NotImplementedError() + + if get_origin(obj): + setup_gen_alias(name, obj) + return + + if isinstance(obj, _d_field): + t = obj.type + + if isinstance(obj, _d_field): + inst = append(name, obj.default_factory()) + setattr(self, name, inst) + return + + if isinstance(t, type): + setattr(self, name, append(name, t())) + return - # NOTES: - # - first construct than call handle (for eliminating hazards) + if get_origin(t): + setup_gen_alias(name, t) + return + + raise NotImplementedError() + + if isinstance(obj, type): + setattr(self, name, append(name, obj())) + return + + if isinstance(obj, rt_field): + append(name, obj._construct(self)) + return + + raise NotImplementedError() + + for name, obj in clsfields.items(): + setup_field(name, obj) + + return objects, clsfields def __init__(self) -> None: - print("Called Node init", "-" * 20) + cls = type(self) + # print(f"Called Node init {cls.__qualname__:<20} {'-' * 80}") + + # check if accidentally added a node instance instead of field + node_instances = [f for f in vars(cls).values() if isinstance(f, Node)] + if node_instances: + raise FieldError(f"Node instances not allowed: {node_instances}") + + # Construct Fields + objects, _ = self._setup_fields(cls) + + # Add Fields to Node + for name, obj in sorted( + objects.items(), key=lambda x: isinstance(x[1], GraphInterfaceSelf) + ): + if isinstance(obj, GraphInterface): + self._handle_add_gif(name, obj) + elif isinstance(obj, Node): + self._handle_add_node(name, obj) + else: + assert False + + # Call 2-stage constructors if self._init: for base in reversed(type(self).mro()): - if hasattr(base, "__finit__"): - base.__finit__(self) + if hasattr(base, "__preinit__"): + base.__preinit__(self) + for base in reversed(type(self).mro()): + if hasattr(base, "__postinit__"): + base.__postinit__(self) def _handle_add_gif(self, name: str, gif: GraphInterface): gif.node = self gif.name = name - gif.connect(self.self_gif, linkcls=LinkSibling) + if not isinstance(gif, GraphInterfaceSelf): + gif.connect(self.self_gif, linkcls=LinkSibling) def _handle_add_node(self, name: str, node: "Node"): assert not ( diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index b88eff13..e629ffd3 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -12,7 +12,7 @@ logger = logging.getLogger(__name__) -class Trait[T: Node]: +class Trait[T: Node](Node): @classmethod def impl(cls: type["Trait"]): class _Impl[T_: Node](TraitImpl[T_], cls): ... @@ -23,7 +23,7 @@ class _Impl[T_: Node](TraitImpl[T_], cls): ... U = TypeVar("U", bound="FaebrykLibObject") -class TraitImpl[U: Node](Node, ABC): +class TraitImpl[U: Node](ABC): _trait: type[Trait[U]] def __finit__(self) -> None: diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index 7a9b6862..cb313668 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -14,14 +14,15 @@ from shapely import Polygon from typing_extensions import deprecated -from faebryk.core.core import ( - Graph, - Module, - ModuleInterface.TraitT, - Module.TraitT, - Node, +from faebryk.core.graphinterface import Graph +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node +from faebryk.core.util import ( + get_all_nodes_with_trait, + get_all_nodes_with_traits, + get_children, ) -from faebryk.core.util import get_all_nodes_with_trait, get_all_nodes_with_traits from faebryk.library.Electrical import Electrical from faebryk.library.Footprint import ( Footprint as FFootprint, @@ -259,7 +260,7 @@ def attach(self): node.add_trait(self.has_linked_kicad_footprint_defined(fp, self)) pin_names = g_fp.get_trait(has_kicad_footprint).get_pin_names() - for fpad in g_fp.IFs.get_all(): + for fpad in get_children(g_fp, direct_only=True, types=ModuleInterface): pads = [ pad for pad in fp.pads diff --git a/src/faebryk/library/Diode.py b/src/faebryk/library/Diode.py index 75ae7144..b8650d65 100644 --- a/src/faebryk/library/Diode.py +++ b/src/faebryk/library/Diode.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module +from faebryk.core.parameter import Parameter from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index ed0454e2..20eb2449 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -2,10 +2,15 @@ # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface, Node +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node +from faebryk.core.trait import Trait class Footprint(Module): + class TraitT(Trait["Footprint"]): ... + def __init__(self) -> None: super().__init__() diff --git a/src/faebryk/library/FootprintTrait.py b/src/faebryk/library/FootprintTrait.py deleted file mode 100644 index c640c8cd..00000000 --- a/src/faebryk/library/FootprintTrait.py +++ /dev/null @@ -1,17 +0,0 @@ -# This file is part of the faebryk project -# SPDX-License-Identifier: MIT - -from typing import Generic, TypeVar - -from faebryk.core.core import ( - _Module.TraitT, -) -from faebryk.library.Footprint import Footprint - -TF = TypeVar("TF", bound="Footprint") - - -class _FootprintTrait(Generic[TF], _Module.TraitT[TF]): ... - - -class FootprintTrait(_FootprintTrait["Footprint"]): ... diff --git a/src/faebryk/library/has_linked_pad.py b/src/faebryk/library/has_linked_pad.py index 408bef5e..74fcb3a5 100644 --- a/src/faebryk/library/has_linked_pad.py +++ b/src/faebryk/library/has_linked_pad.py @@ -3,9 +3,7 @@ from abc import abstractmethod -from faebryk.core.core import ( - ModuleInterface.TraitT, -) +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Pad import Pad diff --git a/src/faebryk/library/is_esphome_bus.py b/src/faebryk/library/is_esphome_bus.py index aca39db3..d42104a2 100644 --- a/src/faebryk/library/is_esphome_bus.py +++ b/src/faebryk/library/is_esphome_bus.py @@ -3,7 +3,7 @@ from abc import abstractmethod -from faebryk.core.moduleinterface import ModuleInterface, ModuleInterface.TraitT +from faebryk.core.moduleinterface import ModuleInterface from faebryk.libs.util import find diff --git a/src/faebryk/libs/app/checks.py b/src/faebryk/libs/app/checks.py index 76957107..44439aaf 100644 --- a/src/faebryk/libs/app/checks.py +++ b/src/faebryk/libs/app/checks.py @@ -2,8 +2,8 @@ # SPDX-License-Identifier: MIT -from faebryk.core.module import Module from faebryk.core.graph import Graph +from faebryk.core.module import Module from faebryk.libs.app.erc import simple_erc diff --git a/src/faebryk/libs/app/pcb.py b/src/faebryk/libs/app/pcb.py index 27880e46..a90e7b44 100644 --- a/src/faebryk/libs/app/pcb.py +++ b/src/faebryk/libs/app/pcb.py @@ -7,8 +7,8 @@ from pathlib import Path from typing import Any, Callable -from faebryk.core.module import Module from faebryk.core.graph import Graph +from faebryk.core.module import Module from faebryk.core.util import get_node_tree, iter_tree_by_depth from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import apply_route_in_pcb diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index 20691cbf..b7218045 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -12,7 +12,9 @@ from rich.progress import Progress -from faebryk.core.module import Module, ModuleInterface, Module.TraitT, Parameter +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.parameter import Parameter from faebryk.core.util import ( get_all_modules, get_children, diff --git a/test/core/test_parameters.py b/test/core/test_parameters.py index 253abae2..8c1c2977 100644 --- a/test/core/test_parameters.py +++ b/test/core/test_parameters.py @@ -6,8 +6,8 @@ from operator import add from typing import TypeVar -from faebryk.core.module import Module, Parameter from faebryk.core.core import logger as core_logger +from faebryk.core.module import Module, Parameter from faebryk.core.util import specialize_module from faebryk.library.ANY import ANY from faebryk.library.Constant import Constant From d75d0249f39965935d71a95e5bd722f30a4819c2 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 23 Aug 2024 04:42:36 +0200 Subject: [PATCH 07/63] Remove trait generic --- new_holders_flat.py | 28 +++++++++++++++++----------- src/faebryk/core/module.py | 2 +- src/faebryk/core/moduleinterface.py | 2 +- src/faebryk/core/node.py | 12 +++++++++--- src/faebryk/core/parameter.py | 2 +- src/faebryk/core/trait.py | 23 +++++++++-------------- 6 files changed, 38 insertions(+), 31 deletions(-) diff --git a/new_holders_flat.py b/new_holders_flat.py index 561eb2b3..bebea1bf 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -4,12 +4,18 @@ from faebryk.core.module import Module from faebryk.core.node import d_field, if_list, rt_field +from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined +from faebryk.library.has_simple_value_representation import ( + has_simple_value_representation, +) +from faebryk.library.has_simple_value_representation_based_on_param import ( + has_simple_value_representation_based_on_param, +) from faebryk.library.TBD import TBD -from faebryk.libs.units import Quantity +from faebryk.libs.units import P, Quantity from faebryk.libs.util import times # ----------------------------------------------------------------------------- @@ -25,10 +31,8 @@ class Diode2(Module): anode: Electrical cathode: Electrical - XXXXX: Electrical = d_field(Electrical) - # static trait - designator_prefix: has_designator_prefix = d_field( + designator_prefix: has_designator_prefix_defined = d_field( lambda: has_designator_prefix_defined("D") ) @@ -41,12 +45,12 @@ def __preinit__(self): print("Called Diode __preinit__") # anonymous dynamic trait - # self.add( - # has_simple_value_representation_based_on_param( - # self.forward_voltage, - # lambda p: as_unit(p, "V"), - # ) # type: ignore - # ) + self.add( + has_simple_value_representation_based_on_param( + self.forward_voltage, + lambda p: as_unit(p, "V"), + ) + ) class LED2(Diode2): @@ -86,6 +90,8 @@ def main(): L3.cathode.connect(L2.cathode) assert L3.cathode.is_connected_to(L2.cathode) + L3.forward_voltage.merge(5 * P.V) + L3.get_trait(has_simple_value_representation).get_value() typer.run(main) diff --git a/src/faebryk/core/module.py b/src/faebryk/core/module.py index 4572bda9..f4137f98 100644 --- a/src/faebryk/core/module.py +++ b/src/faebryk/core/module.py @@ -11,7 +11,7 @@ class Module(Node): - class TraitT(Trait["Module"]): ... + class TraitT(Trait): ... specializes: GraphInterface specialized: GraphInterface diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py index 765ecf84..bc14a7bb 100644 --- a/src/faebryk/core/moduleinterface.py +++ b/src/faebryk/core/moduleinterface.py @@ -91,7 +91,7 @@ class GraphInterfaceModuleConnection(GraphInterface): ... class ModuleInterface(Node): - class TraitT(Trait["ModuleInterface"]): ... + class TraitT(Trait): ... specializes: GraphInterface specialized: GraphInterface diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 7252d4c0..8a6999c8 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -99,7 +99,7 @@ def add( container = self.runtime try: - container_name = find(vars(self).items(), lambda x: x[1] == container)[0] + container_name = find(vars(self).items(), lambda x: x[1] is container)[0] except KeyErrorNotFound: raise FieldContainerError("Container not in fields") @@ -296,6 +296,9 @@ def __init__(self) -> None: if hasattr(base, "__postinit__"): base.__postinit__(self) + def __preinit__(self): ... + def __postinit__(self): ... + def _handle_add_gif(self, name: str, gif: GraphInterface): gif.node = self gif.name = name @@ -361,13 +364,14 @@ def add_trait[_TImpl: "TraitImpl"](self, trait: _TImpl) -> _TImpl: return trait def _find(self, trait, only_implemented: bool): + from faebryk.core.trait import TraitImpl from faebryk.core.util import get_children - traits = get_children(self, direct_only=True, types=TraitImpl) + impls = get_children(self, direct_only=True, types=TraitImpl) return [ impl - for impl in traits + for impl in impls if impl.implements(trait) and (impl.is_implemented() or not only_implemented) ] @@ -385,6 +389,8 @@ def has_trait(self, trait) -> bool: return len(self._find(trait, only_implemented=True)) > 0 def get_trait[V: "Trait"](self, trait: Type[V]) -> V: + from faebryk.core.trait import TraitImpl + assert not issubclass( trait, TraitImpl ), "You need to specify the trait, not an impl" diff --git a/src/faebryk/core/parameter.py b/src/faebryk/core/parameter.py index 262c8c6e..9137b42c 100644 --- a/src/faebryk/core/parameter.py +++ b/src/faebryk/core/parameter.py @@ -37,7 +37,7 @@ class Parameter[PV](Node): type LIT = PV | set[PV] | tuple[PV, PV] type LIT_OR_PARAM = LIT | "Parameter[PV]" - class TraitT(Trait["Parameter"]): ... + class TraitT(Trait): ... narrowed_by: GraphInterface narrows: GraphInterface diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index e629ffd3..13eb91fa 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -2,31 +2,26 @@ # SPDX-License-Identifier: MIT import logging from abc import ABC -from typing import TypeVar from deprecated import deprecated -from faebryk.core.core import FaebrykLibObject from faebryk.core.node import Node logger = logging.getLogger(__name__) -class Trait[T: Node](Node): +class Trait(Node): @classmethod - def impl(cls: type["Trait"]): - class _Impl[T_: Node](TraitImpl[T_], cls): ... + def impl[T: "Trait"](cls: type[T]): + class _Impl(TraitImpl, cls): ... - return _Impl[T] + return _Impl -U = TypeVar("U", bound="FaebrykLibObject") +class TraitImpl(ABC): + _trait: type[Trait] - -class TraitImpl[U: Node](ABC): - _trait: type[Trait[U]] - - def __finit__(self) -> None: + def __preinit__(self) -> None: found = False bases = type(self).__bases__ while not found: @@ -56,14 +51,14 @@ def remove_obj(self): self._obj = None @property - def obj(self) -> U: + def obj(self) -> Node: p = self.get_parent() if not p: raise Exception("trait is not linked to node") return p[0] @deprecated("Use obj property") - def get_obj(self) -> U: + def get_obj(self) -> Node: return self.obj def cmp(self, other: "TraitImpl") -> tuple[bool, "TraitImpl"]: From 3bb76ce201720595dcee5d60a2c82e50232fc393 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 23 Aug 2024 04:50:52 +0200 Subject: [PATCH 08/63] Remove footprinttrait & GIFs usage --- src/faebryk/core/node.py | 1 - src/faebryk/exporters/netlist/graph.py | 14 +- src/faebryk/exporters/pcb/routing/util.py | 2 +- src/faebryk/exporters/visualize/graph.py | 537 ------------------- src/faebryk/library/Net.py | 2 +- src/faebryk/library/_F.py | 1 - src/faebryk/library/can_attach_via_pinmap.py | 4 +- src/faebryk/library/has_equal_pins.py | 4 +- src/faebryk/library/has_footprint_impl.py | 8 +- src/faebryk/library/has_kicad_footprint.py | 4 +- test/core/test_core.py | 20 +- 11 files changed, 28 insertions(+), 569 deletions(-) delete mode 100644 src/faebryk/exporters/visualize/graph.py diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 8a6999c8..69b789d8 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -67,7 +67,6 @@ def d_field[T](default_factory: Callable[[], T]) -> T: # ----------------------------------------------------------------------------- -# @dataclass(init=False, kw_only=True) class Node(FaebrykLibObject): runtime_anon: list["Node"] runtime: dict[str, "Node"] diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index c4026ba2..3cacfd10 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -6,14 +6,16 @@ import networkx as nx -from faebryk.core.core import Graph, Module +from faebryk.core.graphinterface import Graph +from faebryk.core.module import Module from faebryk.core.util import ( get_all_nodes_with_trait, + get_children, get_connected_mifs, ) from faebryk.exporters.netlist.netlist import T2Netlist from faebryk.library.Electrical import Electrical -from faebryk.library.FootprintTrait import FootprintTrait +from faebryk.library.Footprint import Footprint from faebryk.library.has_defined_descriptive_properties import ( has_defined_descriptive_properties, ) @@ -31,7 +33,7 @@ logger = logging.getLogger(__name__) -class can_represent_kicad_footprint(FootprintTrait): +class can_represent_kicad_footprint(Footprint.TraitT): kicad_footprint = T2Netlist.Component @abstractmethod @@ -110,7 +112,7 @@ def get_kicad_obj(self): def add_or_get_net(interface: Electrical): - mifs = get_connected_mifs(interface.GIFs.connected) + mifs = get_connected_mifs(interface.connected) nets = { p[0] for mif in mifs @@ -151,7 +153,5 @@ def attach_nets_and_kicad_info(g: Graph): for fp in node_fps.values(): # TODO use graph - for mif in fp.IFs.get_all(): - if not isinstance(mif, Pad): - continue + for mif in get_children(fp, direct_only=True, types=Pad): add_or_get_net(mif.IFs.net) diff --git a/src/faebryk/exporters/pcb/routing/util.py b/src/faebryk/exporters/pcb/routing/util.py index b9b1ffe2..7e17d461 100644 --- a/src/faebryk/exporters/pcb/routing/util.py +++ b/src/faebryk/exporters/pcb/routing/util.py @@ -188,7 +188,7 @@ def get_internal_nets_of_node( from faebryk.libs.util import groupby if isinstance(node, Net): - return {node: get_connected_mifs(node.IFs.part_of.GIFs.connected)} + return {node: get_connected_mifs(node.IFs.part_of.connected)} mifs = {n for n in get_all_nodes(node) + [node] if isinstance(n, Electrical)} nets = groupby(mifs, lambda mif: get_net(mif)) diff --git a/src/faebryk/exporters/visualize/graph.py b/src/faebryk/exporters/visualize/graph.py deleted file mode 100644 index cb38ac1b..00000000 --- a/src/faebryk/exporters/visualize/graph.py +++ /dev/null @@ -1,537 +0,0 @@ -# This file is part of the faebryk project -# SPDX-License-Identifier: MIT - -import logging -from copy import copy - -import networkx as nx - -from faebryk.core.core import ( - GraphInterface, - GraphInterfaceHierarchical, - GraphInterfaceModuleConnection, - GraphInterfaceModuleSibling, - GraphInterfaceSelf, - Link, - LinkDirect, - LinkNamedParent, - LinkSibling, - Node, -) -from faebryk.library.Electrical import Electrical -from faebryk.libs.util import cast_assert - -logger = logging.getLogger(__name__) - - -def _direction_to_str(direction: tuple[GraphInterface, GraphInterface] | None): - if direction is None: - return str(direction) - return [str(x) for x in direction] - - -def merge(G: nx.Graph, root: GraphInterface, group: set[GraphInterface]) -> nx.Graph: - if len(group) == 0: - return G - - nodes = set(G.nodes) - to_merge = group - {root} - assert root in group - - Gout = nx.Graph(G.subgraph(nodes - to_merge)) - assert group.issubset(nodes) - - # find connections to the outside (of group) to move to root node - edges: dict[GraphInterface, dict] = {} - for n in to_merge: - for d in set(G[n]) - group: - # TODO also merge links - data = dict(G.get_edge_data(n, d)) - - # connection to representative - if d not in edges: - edges[d] = {"merged": []} - e = edges[d] - - # Direction - direction = data["direction"] - direction_new = None - if direction is not None: - direction_new = tuple( - intf if intf is not n else root for intf in direction - ) - - e["merged"].extend(data["merged"]) - - if "direction" not in e: - e["direction"] = direction_new - if direction_new is not None and e["direction"] != direction_new: - e["direction"] = None - - Gout.add_edges_from([(root, d, data) for d, data in edges.items()]) - # print("Merge:", len(G.nodes), root, len(group), "->", len(Gout.nodes)) - return Gout - - -# TODO untested -def make_abstract(G: nx.Graph, root: Node) -> nx.Graph: - merged_ifs = _get_all_sub_GIFs(G, root) - assert all(map(lambda n: n in G.nodes, merged_ifs)) - - # Remove to be merged ifs from graph - Gout = G.copy() - Gout.remove_nodes_from(merged_ifs) - - node = Node() - edges: list[tuple[GraphInterface, GraphInterface, dict]] = [] - - for child in [root] + _get_children(G, root): - gifs = _get_neighbor_gifs(G, child.GIFs.self) - for gif in gifs: - if gif.name not in [x.name for x in node.GIFs.get_all()]: - # TODO not sure if thats ok or needed - copied_gif = copy(gif) - copied_gif.connections = [] - setattr(node.GIFs, gif.name, copied_gif) - node_gif = getattr(node.GIFs, gif.name) - assert isinstance(node_gif, GraphInterface) - - for e in G[gif]: - assert isinstance(e, GraphInterface) - if e in merged_ifs: - continue - data = dict(G.get_edge_data(gif, e)) - - direction = data["direction"] - if direction is not None: - direction_new = tuple( - intf if intf is not gif else node_gif for intf in direction - ) - print( - "Replace", - _direction_to_str(direction), - _direction_to_str(direction_new), - ) - data["direction"] = direction_new - - # connection to representative - edges.append((e, node_gif, data)) - - Gout.add_nodes_from(node.GIFs.get_all()) - Gout.add_edges_from([(e, node_gif, d) for e, node_gif, d in edges]) - - return Gout - - -def merge_sub(G: nx.Graph, node: Node): - return merge(G, node.GIFs.self, set(_get_all_sub_GIFs(G, node))) - - -def _get_neighbor_gifs(G: nx.Graph, gif: GraphInterface) -> list[GraphInterface]: - if gif not in G: - return [] - return [cast_assert(GraphInterface, x) for x in G[gif]] - - -def _get_neighbor_nodes(G: nx.Graph, gif: GraphInterface) -> list[Node]: - if gif not in G: - return [] - return [ - n - for neighbor_gif in G[gif] - if (n := cast_assert(GraphInterface, neighbor_gif).node) is not gif.node - ] - - -def _get_all_sub_GIFs(G: nx.Graph, node: Node) -> list[GraphInterface]: - node_if = node.GIFs.self - - if node_if not in G: - return [] - - out: list[GraphInterface] = [node_if] - # all siblings - out.extend(_get_neighbor_gifs(G, node_if)) - # all gifs of children - for c in _get_children(G, node, recursive=False): - out.extend(_get_all_sub_GIFs(G, c)) - return out - - -def _get_parents(G: nx.Graph, node: Node, recursive=True) -> list[Node]: - node_if = node.GIFs.self - - parent_if = [ - x - for x in _get_neighbor_gifs(G, node_if) - if isinstance(x, GraphInterfaceHierarchical) and not x.is_parent - ] - assert len(parent_if) == 1 - - parent_if = parent_if[0] - - parents = _get_neighbor_nodes(G, parent_if) - if len(parents) == 0: - return parents - if not recursive: - return parents - - return parents + [ - p - for direct_p in parents - for p in _get_parents(G, direct_p, recursive=recursive) - ] - - -def _get_children(G: nx.Graph, node: Node, recursive=True) -> list[Node]: - node_if = node.GIFs.self - - children_if = [ - x - for x in _get_neighbor_gifs(G, node_if) - if isinstance(x, GraphInterfaceHierarchical) and x.is_parent - ] - assert len(children_if) == 1 - children_if = children_if[0] - - children = _get_neighbor_nodes(G, children_if) - if len(children) == 0: - return children - if not recursive: - return children - - return children + [ - c - for direct_c in children - for c in _get_children(G, direct_c, recursive=recursive) - ] - - -def _get_top_level_nodes(G: nx.Graph, level: int): - # print(level, "-" * 40) - top_nodes: set[Node] = set() - - for i in G.nodes: - assert isinstance(i, GraphInterface) - if not isinstance(i, GraphInterfaceSelf): - continue - - n = i.node - # find top-level nodes - if len(_get_parents(G, n, recursive=False)) > 0: - continue - - # get children deep in hierarchy - targets: list[Node] = [n] - for i in range(level): - targets = [ - i for _n in targets for i in _get_children(G, _n, recursive=False) - ] - for t in targets: - top_nodes.add(t) - - # print("Top", level, top_nodes) - return top_nodes - - -def _add_node(G: nx.Graph, node: Node): - G_ = node.get_graph().G - tag_with_info(G_) - G.add_nodes_from(G_.nodes) - G.add_edges_from(G_.edges(data=True)) - - -def sub_graph(G: nx.Graph, nodes: list[Node]): - """ - Merge all GIFs that are not part of the specified nodes into the highest level - representantive that is not a parent of nodes. - """ - - # no duplicate - assert len(set(nodes)) == len(nodes) - - gifs = {gif for node in nodes for gif in _get_all_sub_GIFs(G, node)} - other_gifs: set[GraphInterface] = set(G.nodes) - gifs - - G_ = G.copy() - - # Detach from parents - for n in nodes: - ps = _get_parents(G, n, recursive=False) - for p in ps: - G_.remove_edge(n.GIFs.parent, p.GIFs.children) - - # Make representing node for rest of graph - repr_node = Node() - repr_gif = GraphInterface() - repr_node.GIFs.sub_conns = repr_gif - _add_node(G_, repr_node) - root = repr_gif - other_gifs.add(root) - - Gout = merge(G_, root, other_gifs) - - return Gout - - -def sub_tree(G: nx.Graph, nodes: list[Node]): - return G.subgraph([gif for node in nodes for gif in _get_all_sub_GIFs(G, node)]) - - -def node_graph(G: nx.Graph, level: int) -> nx.Graph: - Gout = G - for n in _get_top_level_nodes(G, level): - Gout = merge_sub(Gout, n) - return Gout - - -def tag_with_info(G: nx.Graph): - for t0, t1, d in G.edges(data=True): - link = d["link"] - assert isinstance(link, Link) - - # Direction - direction = None - if isinstance(link, LinkNamedParent): - assert link.get_parent() in [t0, t1] - assert link.get_child() in [t0, t1] - direction = (link.get_parent(), link.get_child()) - elif isinstance(link, LinkSibling): - assert isinstance(t0, GraphInterfaceSelf) or isinstance( - t1, GraphInterfaceSelf - ) - direction = (t0, t1) if isinstance(t0, GraphInterfaceSelf) else (t1, t0) - - d["direction"] = direction - - # Merged info - d["merged"] = [d] - - -def render_graph(G: nx.Graph, ax=None): - import matplotlib.pyplot as plt - - DIRECTIONAL = False - MULTI = True - assert not DIRECTIONAL or not MULTI - - if DIRECTIONAL: - G_ = nx.DiGraph() - G_.add_nodes_from(G) - for t0, t1, d in G.edges(data=True): - assert isinstance(t0, GraphInterface) - assert isinstance(t1, GraphInterface) - assert isinstance(d, dict) - - direction = d.get("direction") - if direction is None: - G_.add_edge(t0, t1, **d) - G_.add_edge(t1, t0, **d) - else: - assert t0 in direction and t1 in direction - G_.add_edge(*direction, **d) - - G = G_ - - if MULTI: - G_ = nx.MultiDiGraph() - G_.add_nodes_from(G) - for t0, t1, d in G.edges(data=True): - assert isinstance(t0, GraphInterface) - assert isinstance(t1, GraphInterface) - assert isinstance(d, dict) - - for d_ in d["merged"]: - G_.add_edge(t0, t1, **d_, root=d) - - G = G_ - - for t0, t1, d in G.edges(data=True): - assert isinstance(d, dict) - - merged: list[dict] = d["merged"] - - def params_for_link(link): - color = "#000000" - weight = 1 - - if isinstance(link, LinkSibling): - color = "#000000" # black - weight = 100 - elif isinstance(link, LinkNamedParent): - color = "#FF0000" # red - weight = 40 - elif isinstance(link, LinkDirect) and all( - isinstance(c.node, Electrical) for c in link.get_connections() - ): - color = "#00FF00" # green - weight = 1 - elif isinstance(link, LinkDirect) and all( - isinstance(c, GraphInterfaceModuleSibling) - for c in link.get_connections() - ): - color = "#AD139D" # purple-like - weight = 40 - elif isinstance(link, LinkDirect) and all( - isinstance(c, GraphInterfaceModuleConnection) - for c in link.get_connections() - ): - color = "#C1BE0F" # yellow-like - weight = 1 - else: - color = "#1BD0D3" # turqoise-like - weight = 10 - - return color, weight - - params = [params_for_link(m["link"]) for m in merged] - param = max(params, key=lambda x: x[1]) - - d["color"], d["weight"] = param - - # Draw - layout = nx.spring_layout(G.to_undirected(as_view=True)) - nx.draw_networkx_nodes(G, ax=ax, pos=layout, node_size=150) - # nx.draw_networkx_edges( - # G, - # ax=ax, - # pos=layout, - # # edgelist=G.edges, - # edge_color=[c for _, __, c in G.edges.data("color")] # type: ignore - # # edge_color=color_edges_by_type(G.edges(data=True)), - # ) - - def dir_to_arrow(t0, t1, data): - direction = d["root"].get("direction") - if direction is None: - return "-" - assert t0 in direction and t1 in direction - return "<-" if direction == (t0, t1) else "->" - - pos = layout - for t0, t1, k, d in G.edges(data=True, keys=True): - ax.annotate( - "", - xy=pos[t0], - xycoords="data", - xytext=pos[t1], - textcoords="data", - arrowprops=dict( - arrowstyle=dir_to_arrow(t0, t1, d), - color=d["color"], - shrinkA=5, - shrinkB=5, - patchA=None, - patchB=None, - connectionstyle=f"arc3,rad={0.1 * k}", - ), - ) - - # nx.draw_networkx_edges( - # G, pos=layout, edgelist=intra_comp_edges, edge_color="#0000FF" - # ) - - nodes: list[GraphInterface] = list(G.nodes) - vertex_names = { - vertex: f"{type(vertex.node).__name__}.{vertex.name}" - + ( - f"|{vertex.node.get_full_name()}" - if isinstance(vertex, GraphInterfaceSelf) and vertex.node is not None - else "" - ) - for vertex in nodes - } - nx.draw_networkx_labels(G, ax=ax, pos=layout, labels=vertex_names, font_size=10) - - # nx.draw_networkx_edge_labels( - # G, - # pos=layout, - # edge_labels=intra_edge_dict, - # font_size=10, - # rotate=False, - # bbox=dict(fc="blue"), - # font_color="white", - # ) - - return plt - - -def render_sidebyside(G: nx.Graph, nodes: list[Node] | None = None, depth=2): - tag_with_info(G) - - import matplotlib.pyplot as plt - - if nodes is not None: - G = sub_tree(G, nodes) - - # fig = plt.figure() - fig, axs = plt.subplots(1, depth + 1) - fig.subplots_adjust(0, 0, 1, 1) - # plt.subplot(111) - for i in range(depth + 1): - nG = node_graph(G, i) - render_graph(nG, ax=axs[i] if depth > 0 else axs) - - # render_graph(G, ax=axs[-1]) - return plt - - -def render_matrix( - G: nx.Graph, - nodes_rows: list[list[Node]], - depth=2, - min_depth=0, - show_full=True, - show_non_sum=True, -): - tag_with_info(G) - - import matplotlib.pyplot as plt - - _nodes_rows: list[list[Node] | None] = list(nodes_rows) - if show_full: - _nodes_rows.append(None) - - depths: list[int | None] = list(range(min_depth, depth + 1)) - if show_non_sum: - depths.append(None) - - row_cnt = len(_nodes_rows) - col_cnt = len(depths) - fig, _axs = plt.subplots(row_cnt, col_cnt) - - def axs(row, col): - if row_cnt > 1 and col_cnt > 1: - return _axs[row, col] - if col_cnt > 1: - return _axs[col] - if row_cnt > 1: - return _axs[row] - return _axs - - for j, nodes in enumerate(_nodes_rows): - Gn = G - if nodes is not None: - # Gn = sub_tree(G, nodes) - Gn = sub_graph(Gn, nodes) - - for i, level in enumerate(depths): - ax = axs(j, i) - - if level is not None: - nG = node_graph(Gn, level) - # print(Gn, "->", nG) - else: - nG = Gn - - render_graph(nG, ax=ax) - - # ax.set_title( - # f"row={j if nodes is not None else 'full'}" - # f"depth={i if level is not None else 'full'}", - # fontsize=8, - # ) - - plt.tight_layout() - fig.subplots_adjust(0, 0, 1, 1) - return plt diff --git a/src/faebryk/library/Net.py b/src/faebryk/library/Net.py index 2b9dd5e1..46633e43 100644 --- a/src/faebryk/library/Net.py +++ b/src/faebryk/library/Net.py @@ -61,7 +61,7 @@ def get_fps(self): def get_connected_interfaces(self): return { mif - for mif in get_connected_mifs(self.IFs.part_of.GIFs.connected) + for mif in get_connected_mifs(self.IFs.part_of.connected) if isinstance(mif, type(self.IFs.part_of)) } diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 56fd2718..b7a6aa12 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -48,7 +48,6 @@ from faebryk.library.Ethernet import Ethernet from faebryk.library.Fan import Fan from faebryk.library.Footprint import Footprint -from faebryk.library.FootprintTrait import FootprintTrait from faebryk.library.Fuse import Fuse from faebryk.library.GDT import GDT from faebryk.library.GenericBusProtection import GenericBusProtection diff --git a/src/faebryk/library/can_attach_via_pinmap.py b/src/faebryk/library/can_attach_via_pinmap.py index 595b3cc3..e5a3496d 100644 --- a/src/faebryk/library/can_attach_via_pinmap.py +++ b/src/faebryk/library/can_attach_via_pinmap.py @@ -4,9 +4,9 @@ from abc import abstractmethod from faebryk.library.Electrical import Electrical -from faebryk.library.FootprintTrait import FootprintTrait +from faebryk.library.Footprint import Footprint -class can_attach_via_pinmap(FootprintTrait): +class can_attach_via_pinmap(Footprint.TraitT): @abstractmethod def attach(self, pinmap: dict[str, Electrical]): ... diff --git a/src/faebryk/library/has_equal_pins.py b/src/faebryk/library/has_equal_pins.py index 59a05585..e2abf942 100644 --- a/src/faebryk/library/has_equal_pins.py +++ b/src/faebryk/library/has_equal_pins.py @@ -3,10 +3,10 @@ from abc import abstractmethod -from faebryk.library.FootprintTrait import FootprintTrait +from faebryk.library.Footprint import Footprint from faebryk.library.Pad import Pad -class has_equal_pins(FootprintTrait): +class has_equal_pins(Footprint.TraitT): @abstractmethod def get_pin_map(self) -> dict[Pad, str]: ... diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index 711dc77d..a272ca89 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -3,7 +3,7 @@ from abc import abstractmethod -from faebryk.core.core import LinkNamedParent +from faebryk.core.link import LinkNamedParent from faebryk.library.Footprint import Footprint from faebryk.library.has_footprint import has_footprint @@ -14,12 +14,10 @@ def __init__(self) -> None: super().__init__() def set_footprint(self, fp: Footprint): - self.get_obj().GIFs.children.connect( - fp.GIFs.parent, LinkNamedParent.curry("footprint") - ) + self.get_obj().children.connect(fp.parent, LinkNamedParent.curry("footprint")) def get_footprint(self) -> Footprint: - children = self.get_obj().GIFs.children.get_children() + children = self.get_obj().children.get_children() fps = [c for _, c in children if isinstance(c, Footprint)] assert len(fps) == 1, f"candidates: {fps}" return fps[0] diff --git a/src/faebryk/library/has_kicad_footprint.py b/src/faebryk/library/has_kicad_footprint.py index bb992b8a..473b5abd 100644 --- a/src/faebryk/library/has_kicad_footprint.py +++ b/src/faebryk/library/has_kicad_footprint.py @@ -3,11 +3,11 @@ from abc import abstractmethod -from faebryk.library.FootprintTrait import FootprintTrait +from faebryk.library.Footprint import Footprint from faebryk.library.Pad import Pad -class has_kicad_footprint(FootprintTrait): +class has_kicad_footprint(Footprint.TraitT): @abstractmethod def get_kicad_footprint(self) -> str: ... diff --git a/test/core/test_core.py b/test/core/test_core.py index aef4e4e9..8612105d 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -6,6 +6,8 @@ from typing import cast from faebryk.core.core import LinkDirect, LinkParent, LinkSibling, TraitImpl +from faebryk.core.node import Node +from faebryk.core.trait import Trait class TestTraits(unittest.TestCase): @@ -82,9 +84,7 @@ def assertCmpFalse(one, two): assertCmpTrue(impl_1_1(), impl1()) def test_obj_traits(self): - from faebryk.core.core import FaebrykLibObject, Trait - - obj = FaebrykLibObject() + obj = Node() class trait1(Trait): @abstractmethod @@ -159,7 +159,7 @@ class impl2(trait2.impl()): class TestGraph(unittest.TestCase): def test_gifs(self): - from faebryk.core.core import GraphInterface as GIF + from faebryk.core.graphinterface import GraphInterface as GIF gif1 = GIF() gif2 = GIF() @@ -184,17 +184,17 @@ class linkcls(LinkDirect): self.assertEqual(gif1.G, gif2.G) def test_node_gifs(self): - from faebryk.core.core import Node + from faebryk.core.node import Node n1 = Node() - self.assertIsInstance(n1.GIFs.self.is_connected(n1.GIFs.parent), LinkSibling) - self.assertIsInstance(n1.GIFs.self.is_connected(n1.GIFs.children), LinkSibling) + self.assertIsInstance(n1.self_gif.is_connected(n1.parent), LinkSibling) + self.assertIsInstance(n1.self_gif.is_connected(n1.children), LinkSibling) n2 = Node() - n1.NODEs.n2 = n2 + n1.add(n2, name="n2") - self.assertIsInstance(n1.GIFs.children.is_connected(n2.GIFs.parent), LinkParent) + self.assertIsInstance(n1.children.is_connected(n2.parent), LinkParent) print(n1.get_graph()) @@ -203,7 +203,7 @@ def test_node_gifs(self): assert p is not None self.assertIs(p[0], n1) - self.assertEqual(n1.GIFs.self.G, n2.GIFs.self.G) + self.assertEqual(n1.self_gif.G, n2.self_gif.G) if __name__ == "__main__": From fcf2ce61e333b51f7f72efa4e6f5a4f2e6c9c18b Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 23 Aug 2024 20:28:19 +0200 Subject: [PATCH 09/63] Add L.py & f_field --- new_holders_flat.py | 19 ++++-- src/faebryk/core/node.py | 26 ++++++-- src/faebryk/library/B4B_ZR_SM4_TF.py | 59 +++++++------------ src/faebryk/library/Button.py | 2 +- src/faebryk/library/CBM9002A_56ILG.py | 10 ++-- .../CBM9002A_56ILG_Reference_Design.py | 10 ++-- src/faebryk/library/Capacitor.py | 2 +- src/faebryk/library/Common_Mode_Filter.py | 4 +- src/faebryk/library/Crystal.py | 2 +- src/faebryk/library/Crystal_Oscillator.py | 2 +- src/faebryk/library/DIP.py | 2 +- src/faebryk/library/EEPROM.py | 2 +- src/faebryk/library/ESP32.py | 22 +++---- src/faebryk/library/ESP32_C3.py | 4 +- src/faebryk/library/ESP32_C3_MINI_1.py | 2 +- src/faebryk/library/ElectricLogicGate.py | 4 +- src/faebryk/library/Footprint.py | 2 +- src/faebryk/library/Fuse.py | 2 +- src/faebryk/library/GenericBusProtection.py | 2 +- src/faebryk/library/Header.py | 2 +- src/faebryk/library/Inductor.py | 2 +- src/faebryk/library/KicadFootprint.py | 2 +- src/faebryk/library/LogicGate.py | 4 +- src/faebryk/library/M24C08_FMN6TP.py | 2 +- src/faebryk/library/MCP2221A.py | 2 +- src/faebryk/library/MultiSPI.py | 2 +- src/faebryk/library/Potentiometer.py | 4 +- src/faebryk/library/QFN.py | 2 +- src/faebryk/library/RJ45_Receptacle.py | 2 +- src/faebryk/library/RP2040.py | 2 +- .../library/RP2040_Reference_Design.py | 2 +- src/faebryk/library/RS485_Bus_Protection.py | 6 +- src/faebryk/library/Resistor.py | 2 +- .../library/Resistor_Voltage_Divider.py | 4 +- src/faebryk/library/SMDTwoPin.py | 2 +- src/faebryk/library/SNx4LVC541A.py | 6 +- src/faebryk/library/SOIC.py | 2 +- src/faebryk/library/Sercom.py | 2 +- src/faebryk/library/Switch.py | 2 +- src/faebryk/library/TXS0102DCUR.py | 2 +- src/faebryk/library/USB2514B.py | 16 ++--- src/faebryk/library/USB2_0_ESD_Protection.py | 2 +- src/faebryk/library/USB_C_5V_PSU.py | 2 +- src/faebryk/library/USB_C_PSU_Vertical.py | 2 +- src/faebryk/library/USB_RS485.py | 2 +- .../library/USB_Type_C_Receptacle_24_pin.py | 4 +- .../library/has_designator_prefix_defined.py | 1 + src/faebryk/library/pf_533984002.py | 4 +- src/faebryk/libs/library/L.py | 9 +++ src/faebryk/libs/util.py | 10 ++++ 50 files changed, 157 insertions(+), 129 deletions(-) create mode 100644 src/faebryk/libs/library/L.py diff --git a/new_holders_flat.py b/new_holders_flat.py index bebea1bf..5a70cf50 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -4,9 +4,11 @@ from faebryk.core.module import Module from faebryk.core.node import d_field, if_list, rt_field +from faebryk.core.parameter import Parameter from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical +from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.has_simple_value_representation import ( has_simple_value_representation, @@ -15,6 +17,7 @@ has_simple_value_representation_based_on_param, ) from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity from faebryk.libs.util import times @@ -28,13 +31,19 @@ class Diode2(Module): reverse_working_voltage: TBD[Quantity] reverse_leakage_current: TBD[Quantity] + # static param + bla_voltage: Parameter[Quantity] = L.d_field(lambda: 5 * P.V) + # bla_dep: Parameter[Quantity] = L.rt_field(lambda self: self.bla_voltage) + anode: Electrical cathode: Electrical # static trait - designator_prefix: has_designator_prefix_defined = d_field( - lambda: has_designator_prefix_defined("D") - ) + designator_prefix = L.f_field(has_designator_prefix_defined)("D") + + @L.rt_field + def bla_dep2(self): + return self.bla_voltage + (10 * P.V) # dynamic trait @rt_field @@ -67,7 +76,7 @@ def __preinit__(self): class LED2_WITHEXTRAT_IFS(LED2): extra: list[Electrical] = field(default_factory=lambda: times(2, Electrical)) - extra2: list[Electrical] = if_list(Electrical, 2) + extra2: list[Electrical] = if_list(2, Electrical) @rt_field def bridge(self): @@ -93,5 +102,7 @@ def main(): L3.forward_voltage.merge(5 * P.V) L3.get_trait(has_simple_value_representation).get_value() + assert L3.designator_prefix.prefix == "D" + typer.run(main) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 69b789d8..2e09f7ab 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -33,15 +33,15 @@ class FieldContainerError(FieldError): pass -def if_list[T](if_type: type[T], n: int) -> list[T]: +def if_list[T](n: int, if_type: type[T]) -> list[T]: return d_field(lambda: times(n, if_type)) -class f_field: +class fab_field: pass -class rt_field[T](property, f_field): +class rt_field[T](property, fab_field): def __init__(self, fget: Callable[[T], Any]) -> None: super().__init__() self.func = fget @@ -54,7 +54,7 @@ def __get__(self, instance: Any, owner: type | None = None) -> Any: return self.constructed -class _d_field[T](f_field): +class _d_field[T](fab_field): def __init__(self, default_factory: Callable[[], T]) -> None: self.type = None self.default_factory = default_factory @@ -64,6 +64,20 @@ def d_field[T](default_factory: Callable[[], T]) -> T: return _d_field(default_factory) # type: ignore +def f_field[T, **P](con: Callable[P, T]) -> Callable[P, T]: + assert isinstance(con, type) + + def _(*args: P.args, **kwargs: P.kwargs) -> Callable[[], T]: + def __() -> T: + return con(*args, **kwargs) + + out = _d_field(__) + out.type = con + return out + + return _ + + # ----------------------------------------------------------------------------- @@ -137,7 +151,7 @@ def all_anno(cls): annos = all_anno(cls) vars_ = all_vars(cls) for name, obj in vars_.items(): - if isinstance(obj, _d_field): + if isinstance(obj, _d_field) and obj.type is None: obj.type = annos[name] def is_node_field(obj): @@ -181,7 +195,7 @@ def is_genalias_node(obj): name: obj for name, obj in chain( [(name, f) for name, f in annos.items()], - [(name, f) for name, f in vars_.items() if isinstance(f, f_field)], + [(name, f) for name, f in vars_.items() if isinstance(f, fab_field)], ) if not name.startswith("_") } diff --git a/src/faebryk/library/B4B_ZR_SM4_TF.py b/src/faebryk/library/B4B_ZR_SM4_TF.py index 4d0dc329..5aaf64ad 100644 --- a/src/faebryk/library/B4B_ZR_SM4_TF.py +++ b/src/faebryk/library/B4B_ZR_SM4_TF.py @@ -1,46 +1,29 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F +import faebryk.libs.library.L as L from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.libs.util import times class B4B_ZR_SM4_TF(Module): - def __init__(self) -> None: - super().__init__() - - class _IFs(Module.IFS()): - pin = times(4, Electrical) - mount = times(2, Electrical) - - self.IFs = _IFs(self) - - x = self.IFs - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.pin[0], - "2": x.pin[1], - "3": x.pin[2], - "4": x.pin[3], - "5": x.mount[0], - "6": x.mount[1], - } - ) + pin = L.if_list(4, F.Electrical) + mount = L.if_list(2, F.Electrical) + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2304140030_BOOMELE-Boom-Precision-Elec-1-5-4P_C145997.pdf" + ) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") + + @L.rt_field + def can_attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "1": self.pin[0], + "2": self.pin[1], + "3": self.pin[2], + "4": self.pin[3], + "5": self.mount[0], + "6": self.mount[1], + } ) - - self.add_trait( - has_datasheet_defined( - "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2304140030_BOOMELE-Boom-Precision-Elec-1-5-4P_C145997.pdf" - ) - ) - - self.add_trait(has_designator_prefix_defined("J")) diff --git a/src/faebryk/library/Button.py b/src/faebryk/library/Button.py index 27dfe3f8..d389a893 100644 --- a/src/faebryk/library/Button.py +++ b/src/faebryk/library/Button.py @@ -21,7 +21,7 @@ class _NODEs(Module.NODES()): ... self.NODEs = _NODEs(self) class _IFs(Module.IFS()): - unnamed = times(2, Electrical) + unnamed = L.if_list(2, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/CBM9002A_56ILG.py b/src/faebryk/library/CBM9002A_56ILG.py index 7079a73a..4a4d57c1 100644 --- a/src/faebryk/library/CBM9002A_56ILG.py +++ b/src/faebryk/library/CBM9002A_56ILG.py @@ -34,17 +34,17 @@ class _PARAMs(Module.PARAMS()): ... self.PARAMs = _PARAMs(self) class _IFS(Module.IFS()): - PA = times(8, ElectricLogic) - PB = times(8, ElectricLogic) - PD = times(8, ElectricLogic) + PA = L.if_list(8, ElectricLogic) + PB = L.if_list(8, ElectricLogic) + PD = L.if_list(8, ElectricLogic) usb = USB2_0() i2c = I2C() avcc = ElectricPower() vcc = ElectricPower() - rdy = times(2, ElectricLogic) - ctl = times(3, ElectricLogic) + rdy = L.if_list(2, ElectricLogic) + ctl = L.if_list(3, ElectricLogic) reset = ElectricLogic() wakeup = ElectricLogic() diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index 7c66cb1e..04def958 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -40,17 +40,17 @@ class _PARAMs(Module.PARAMS()): ... self.PARAMs = _PARAMs(self) class _IFS(Module.IFS()): - PA = times(8, ElectricLogic) - PB = times(8, ElectricLogic) - PD = times(8, ElectricLogic) + PA = L.if_list(8, ElectricLogic) + PB = L.if_list(8, ElectricLogic) + PD = L.if_list(8, ElectricLogic) usb = USB2_0() i2c = I2C() avcc = ElectricPower() vcc = ElectricPower() - rdy = times(2, ElectricLogic) - ctl = times(3, ElectricLogic) + rdy = L.if_list(2, ElectricLogic) + ctl = L.if_list(3, ElectricLogic) reset = ElectricLogic() wakeup = ElectricLogic() diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index e6a28145..928a5fc8 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -41,7 +41,7 @@ def __init__(self): super().__init__() class _IFs(Module.IFS()): - unnamed = times(2, Electrical) + unnamed = L.if_list(2, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/Common_Mode_Filter.py b/src/faebryk/library/Common_Mode_Filter.py index c483091c..a7bc8692 100644 --- a/src/faebryk/library/Common_Mode_Filter.py +++ b/src/faebryk/library/Common_Mode_Filter.py @@ -20,8 +20,8 @@ class _NODEs(Module.NODES()): ... self.NODEs = _NODEs(self) class _IFs(Module.IFS()): - c_a = times(2, Electrical) - c_b = times(2, Electrical) + c_a = L.if_list(2, Electrical) + c_b = L.if_list(2, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index cf1ad0cc..ce4a9a46 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -30,7 +30,7 @@ class _PARAMs(Module.PARAMS()): class _IFs(Module.IFS()): gnd = Electrical() - unnamed = times(2, Electrical) + unnamed = L.if_list(2, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 09398a61..9aca6d29 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -22,7 +22,7 @@ def __init__(self): # ---------------------------------------- class _NODEs(Module.NODES()): crystal = Crystal() - capacitors = times(2, Capacitor) + capacitors = L.if_list(2, Capacitor) self.NODEs = _NODEs(self) diff --git a/src/faebryk/library/DIP.py b/src/faebryk/library/DIP.py index 88995041..58f20b9c 100644 --- a/src/faebryk/library/DIP.py +++ b/src/faebryk/library/DIP.py @@ -14,7 +14,7 @@ def __init__(self, pin_cnt: int, spacing: Quantity, long_pads: bool) -> None: super().__init__() class _IFs(Footprint.IFS()): - pins = times(pin_cnt, Pad) + pins = L.if_list(pin_cnt, Pad) self.IFs = _IFs(self) from faebryk.library.has_kicad_footprint_equal_ifs import ( diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index 34faed39..d7a75d23 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -44,7 +44,7 @@ class _IFs(Module.IFS()): power = ElectricPower() i2c = I2C() write_protect = ElectricLogic() - address = times(3, ElectricLogic) + address = L.if_list(3, ElectricLogic) self.IFs = _IFs(self) diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index ce57067d..05fbce3d 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -32,7 +32,7 @@ def __init__(self, channel_count: int) -> None: super().__init__() class IFS(ModuleInterface.IFS()): - CHANNELS = times(channel_count, Electrical) + CHANNELS = L.if_list(channel_count, Electrical) self.IFs = IFS(self) @@ -42,7 +42,7 @@ def __init__(self): super().__init__() class IFS(ModuleInterface.IFS()): - DATA = times(4, Electrical) + DATA = L.if_list(4, Electrical) CLK = Electrical() CMD = Electrical() GND = Electrical() @@ -55,8 +55,8 @@ def __init__(self): super().__init__() class IFS(ModuleInterface.IFS()): - TXD = times(4, Electrical) - RXD = times(4, Electrical) + TXD = L.if_list(4, Electrical) + RXD = L.if_list(4, Electrical) TX_CLK = Electrical() RX_CLK = Electrical() TX_EN = Electrical() @@ -156,20 +156,20 @@ class IFS(Module.IFS()): GND = Electrical() # High Level Functions - I2C = times(2, I2C) + I2C = L.if_list(2, I2C) SDIO_SLAVE = _ESP_SDIO() - SDIO_HOST = times(2, _ESP_SDIO) + SDIO_HOST = L.if_list(2, _ESP_SDIO) UART = UART_Base() JTAG = JTAG() - TOUCH = times(10, Electrical) - GPIO = times(40 - 6, Electrical) - RTC_GPIO = times(18, Electrical) + TOUCH = L.if_list(10, Electrical) + GPIO = L.if_list(40 - 6, Electrical) + RTC_GPIO = L.if_list(18, Electrical) ADC = [ None, _ESP_ADC(channel_count=8), _ESP_ADC(channel_count=10), ] - SPI = times(4, _ESP32_SPI) + SPI = L.if_list(4, _ESP32_SPI) EMAC = _ESP32_EMAC() # Power @@ -324,7 +324,7 @@ def __init__(self, input: Electrical, *outputs: Electrical) -> None: class _IFS(Module.IFS()): IN = Electrical() - OUT = times(len(outputs), Electrical) + OUT = L.if_list(len(outputs), Electrical) self.IFs = _IFS(self) diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 959a12a0..37ef6871 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -41,11 +41,11 @@ class _IFs(Module.IFS()): enable = ElectricLogic() xtal_p = Electrical() xtal_n = Electrical() - gpio = times(22, ElectricLogic) + gpio = L.if_list(22, ElectricLogic) # TODO: map peripherals to GPIOs with pinmux usb = USB2_0() i2c = I2C() - uart = times(2, UART_Base) + uart = L.if_list(2, UART_Base) # ... etc self.IFs = _IFs(self) diff --git a/src/faebryk/library/ESP32_C3_MINI_1.py b/src/faebryk/library/ESP32_C3_MINI_1.py index 87eb7958..380f1c1b 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1.py +++ b/src/faebryk/library/ESP32_C3_MINI_1.py @@ -38,7 +38,7 @@ class _NODEs(Module.NODES()): class _IFs(Module.IFS()): rf_output = Electrical() chip_enable = ElectricLogic() - gpio = times( + gpio = L.if_list( 22, ElectricLogic ) # TODO: Only GPIO 0 to 10 and 18, 19 are exposed uart = UART_Base() diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index 7b8daec4..bef7672f 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -26,8 +26,8 @@ def __init__( self.IFs_logic = self.IFs class IFS(Module.IFS()): - inputs = times(input_cnt, ElectricLogic) - outputs = times(output_cnt, ElectricLogic) + inputs = L.if_list(input_cnt, ElectricLogic) + outputs = L.if_list(output_cnt, ElectricLogic) self.IFs = IFS(self) diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index 20eb2449..0e979f95 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -9,7 +9,7 @@ class Footprint(Module): - class TraitT(Trait["Footprint"]): ... + class TraitT(Trait): ... def __init__(self) -> None: super().__init__() diff --git a/src/faebryk/library/Fuse.py b/src/faebryk/library/Fuse.py index f8eaf40f..97105133 100644 --- a/src/faebryk/library/Fuse.py +++ b/src/faebryk/library/Fuse.py @@ -33,7 +33,7 @@ def __init__(self): super().__init__() class _IFs(Module.IFS()): - unnamed = times(2, Electrical) + unnamed = L.if_list(2, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index 613a5f97..869975b2 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -53,7 +53,7 @@ def get_mifs(bus: T, mif_type: type[U]) -> list[U]: ) class _NODEs(Module.NODES()): - fuse = times(len(power), Fuse) + fuse = L.if_list(len(power), Fuse) self.NODEs = _NODEs(self) diff --git a/src/faebryk/library/Header.py b/src/faebryk/library/Header.py index 68203db8..20999bdf 100644 --- a/src/faebryk/library/Header.py +++ b/src/faebryk/library/Header.py @@ -38,7 +38,7 @@ class _NODEs(Module.NODES()): ... self.NODEs = _NODEs(self) class _IFs(Module.IFS()): - unnamed = times(horizonal_pin_count * vertical_pin_count, Electrical) + unnamed = L.if_list(horizonal_pin_count * vertical_pin_count, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index 155c5e11..af96074c 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -28,7 +28,7 @@ def __init__( super().__init__() class _IFs(super().IFS()): - unnamed = times(2, Electrical) + unnamed = L.if_list(2, Electrical) self.IFs = _IFs(self) self.add_trait(can_bridge_defined(*self.IFs.unnamed)) diff --git a/src/faebryk/library/KicadFootprint.py b/src/faebryk/library/KicadFootprint.py index 22e76a9b..7da44d3c 100644 --- a/src/faebryk/library/KicadFootprint.py +++ b/src/faebryk/library/KicadFootprint.py @@ -15,7 +15,7 @@ def __init__(self, kicad_identifier: str, pin_names: list[str]) -> None: unique_pin_names = sorted(set(pin_names)) class _IFS(Footprint.IFS()): - pins = times(len(unique_pin_names), Pad) + pins = L.if_list(len(unique_pin_names), Pad) pin_names_sorted = list(enumerate(unique_pin_names)) diff --git a/src/faebryk/library/LogicGate.py b/src/faebryk/library/LogicGate.py index e7db7fc2..42f2d8f6 100644 --- a/src/faebryk/library/LogicGate.py +++ b/src/faebryk/library/LogicGate.py @@ -58,8 +58,8 @@ def __init__( super().__init__() class IFS(Module.IFS()): - inputs = times(input_cnt, Logic) - outputs = times(output_cnt, Logic) + inputs = L.if_list(input_cnt, Logic) + outputs = L.if_list(output_cnt, Logic) self.IFs = IFS(self) diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index fcd54a8c..2b961950 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -33,7 +33,7 @@ class _IFs(Module.IFS()): power = ElectricPower() data = I2C() nwc = ElectricLogic() - e = times(3, ElectricLogic) + e = L.if_list(3, ElectricLogic) self.IFs = _IFs(self) diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 184f6827..32081f81 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -30,7 +30,7 @@ class _IFs(Module.IFS()): power_vusb = ElectricPower() uart = UART_Base() i2c = I2C() - gpio = times(4, Electrical) + gpio = L.if_list(4, Electrical) reset = ElectricLogic() usb = USB2_0() diff --git a/src/faebryk/library/MultiSPI.py b/src/faebryk/library/MultiSPI.py index d76c5dec..65c95d6a 100644 --- a/src/faebryk/library/MultiSPI.py +++ b/src/faebryk/library/MultiSPI.py @@ -12,7 +12,7 @@ def __init__(self, data_lane_count: int) -> None: class IFS(ModuleInterface.IFS()): clk = ElectricLogic() - data = times(data_lane_count, ElectricLogic) + data = L.if_list(data_lane_count, ElectricLogic) cs = ElectricLogic() self.IFs = IFS(self) diff --git a/src/faebryk/library/Potentiometer.py b/src/faebryk/library/Potentiometer.py index b97b3976..c4fa8bbd 100644 --- a/src/faebryk/library/Potentiometer.py +++ b/src/faebryk/library/Potentiometer.py @@ -14,7 +14,7 @@ def __init__(self) -> None: super().__init__() class _IFs(Module.IFS()): - resistors = times(2, Electrical) + resistors = L.if_list(2, Electrical) wiper = Electrical() self.IFs = _IFs(self) @@ -25,7 +25,7 @@ class _PARAMs(Module.PARAMS()): self.PARAMs = _PARAMs(self) class _NODEs(Module.NODES()): - resistors = times(2, Resistor) + resistors = L.if_list(2, Resistor) self.NODEs = _NODEs(self) diff --git a/src/faebryk/library/QFN.py b/src/faebryk/library/QFN.py index b55d0b72..7767ab4f 100644 --- a/src/faebryk/library/QFN.py +++ b/src/faebryk/library/QFN.py @@ -22,7 +22,7 @@ def __init__( super().__init__() class _IFs(Footprint.IFS()): - pins = times(pin_cnt, Pad) + pins = L.if_list(pin_cnt, Pad) self.IFs = _IFs(self) assert exposed_thermal_pad_cnt > 0 or not has_thermal_vias diff --git a/src/faebryk/library/RJ45_Receptacle.py b/src/faebryk/library/RJ45_Receptacle.py index d6d3ceee..77fda9ab 100644 --- a/src/faebryk/library/RJ45_Receptacle.py +++ b/src/faebryk/library/RJ45_Receptacle.py @@ -20,7 +20,7 @@ def __init__(self) -> None: # interfaces class _IFs(Module.IFS()): - pin = times(8, Electrical) + pin = L.if_list(8, Electrical) shield = Electrical() self.IFs = _IFs(self) diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index 9868facd..8174a622 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -35,7 +35,7 @@ class _IFs(Module.IFS()): vreg_in = ElectricPower() vreg_out = ElectricPower() power_vusb = ElectricPower() - gpio = times(30, Electrical) + gpio = L.if_list(30, Electrical) run = ElectricLogic() usb = USB2_0() qspi = MultiSPI(data_lane_count=4) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index ee6471e8..4a5b7a85 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -40,7 +40,7 @@ class _NODES(Module.NODES()): rp2040 = RP2040() flash = SPIFlash() led = PoweredLED() - usb_current_limmit_resistor = times(2, Resistor) + usb_current_limmit_resistor = L.if_list(2, Resistor) # TODO: add crystal oscillator # TODO: add voltage divider with switch # TODO: add boot button diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index b8f68677..8cba9573 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -46,15 +46,15 @@ def __init__(self, termination: bool = True, polarization: bool = True) -> None: class _NODEs(Module.NODES()): gdt = GDT() tvs = TVS() - current_limmiter_resistors = times(2, Resistor) + current_limmiter_resistors = L.if_list(2, Resistor) common_mode_filter = Common_Mode_Filter() gnd_couple_resistor = Resistor() gnd_couple_capacitor = Capacitor() - clamping_diodes = times(2, Diode) + clamping_diodes = L.if_list(2, Diode) if termination: termination_resistor = Resistor() if polarization: - polarization_resistors = times(2, Resistor) + polarization_resistors = L.if_list(2, Resistor) self.NODEs = _NODEs(self) diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index f22e873c..2a17b478 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -29,7 +29,7 @@ def __init__(self): super().__init__() class _IFs(super().IFS()): - unnamed = times(2, Electrical) + unnamed = L.if_list(2, Electrical) self.IFs = _IFs(self) self.add_trait(can_bridge_defined(*self.IFs.unnamed)) diff --git a/src/faebryk/library/Resistor_Voltage_Divider.py b/src/faebryk/library/Resistor_Voltage_Divider.py index 32d2a18e..5f83a3b6 100644 --- a/src/faebryk/library/Resistor_Voltage_Divider.py +++ b/src/faebryk/library/Resistor_Voltage_Divider.py @@ -19,12 +19,12 @@ def __init__(self) -> None: super().__init__() class _NODEs(Module.NODES()): - resistor = times(2, Resistor) + resistor = L.if_list(2, Resistor) self.NODEs = _NODEs(self) class _IFs(Module.IFS()): - node = times(3, Electrical) + node = L.if_list(3, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index befcad5b..8e43a554 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -27,7 +27,7 @@ def __init__(self, type: Type) -> None: super().__init__() class _IFs(Footprint.IFS()): - pins = times(2, Pad) + pins = L.if_list(2, Pad) self.IFs = _IFs(self) from faebryk.library.has_kicad_footprint_equal_ifs import ( diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index 5d6fdaa3..4a31b059 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -25,12 +25,12 @@ class _PARAMs(Module.PARAMS()): ... self.PARAMs = _PARAMs(self) class _IFs(Module.IFS()): - A = times(8, F.ElectricLogic) - Y = times(8, F.ElectricLogic) + A = L.if_list(8, F.ElectricLogic) + Y = L.if_list(8, F.ElectricLogic) vcc = F.ElectricPower() - OE = times(2, F.ElectricLogic) + OE = L.if_list(2, F.ElectricLogic) self.IFs = _IFs(self) diff --git a/src/faebryk/library/SOIC.py b/src/faebryk/library/SOIC.py index 402eab2f..21e6086a 100644 --- a/src/faebryk/library/SOIC.py +++ b/src/faebryk/library/SOIC.py @@ -19,7 +19,7 @@ def __init__( super().__init__() class _IFs(Footprint.IFS()): - pins = times(pin_cnt, Pad) + pins = L.if_list(pin_cnt, Pad) self.IFs = _IFs(self) from faebryk.library.has_kicad_footprint_equal_ifs import ( diff --git a/src/faebryk/library/Sercom.py b/src/faebryk/library/Sercom.py index 3dd5aa99..3b8872f1 100644 --- a/src/faebryk/library/Sercom.py +++ b/src/faebryk/library/Sercom.py @@ -14,7 +14,7 @@ def __init__(self) -> None: super().__init__() class IFS(Module.IFS()): - unnamed = times(4, ElectricLogic) + unnamed = L.if_list(4, ElectricLogic) self.IFs = IFS(self) diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index 84a25fd1..ebc26df5 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -37,7 +37,7 @@ def __init__(self) -> None: self.add_trait(can_attach_to_footprint_symmetrically()) class _IFs(super().IFS()): - unnamed = times(2, interface_type) + unnamed = L.if_list(2, interface_type) self.IFs = _IFs(self) self.add_trait(can_bridge_defined(*self.IFs.unnamed)) diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index 1e83ae96..3edb87c8 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -45,7 +45,7 @@ class _IFs(Module.IFS()): self.IFs = _IFs(self) class _NODEs(Module.NODES()): - shifters = times(2, self._BidirectionalLevelShifter) + shifters = L.if_list(2, self._BidirectionalLevelShifter) self.NODEs = _NODEs(self) diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index edcd77ff..902657dc 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -42,7 +42,7 @@ class _IFs(Module.IFS()): VBUS_DET = Electrical() - usb_downstream = times(4, DifferentialPair) + usb_downstream = L.if_list(4, DifferentialPair) usb_upstream = DifferentialPair() XTALIN = Electrical() @@ -52,18 +52,18 @@ class _IFs(Module.IFS()): SUSP_IND = ElectricLogic() RESET_N = Electrical() RBIAS = Electrical() - NON_REM = times(2, ElectricLogic) + NON_REM = L.if_list(2, ElectricLogic) LOCAL_PWR = Electrical() CLKIN = Electrical() - CFG_SEL = times(2, ElectricLogic) + CFG_SEL = L.if_list(2, ElectricLogic) HS_IND = ElectricLogic() - PRTPWR = times(4, ElectricLogic) - PRT_DIS_P = times(4, ElectricLogic) - PRT_DIS_M = times(4, ElectricLogic) - OCS_N = times(4, ElectricLogic) - BC_EN = times(4, ElectricLogic) + PRTPWR = L.if_list(4, ElectricLogic) + PRT_DIS_P = L.if_list(4, ElectricLogic) + PRT_DIS_M = L.if_list(4, ElectricLogic) + OCS_N = L.if_list(4, ElectricLogic) + BC_EN = L.if_list(4, ElectricLogic) i2c = I2C() diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index ef8c1fe6..b2ab25e8 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -25,7 +25,7 @@ class _NODEs(Module.NODES()): ... self.NODEs = _NODEs(self) class _IFs(Module.IFS()): - usb = times(2, USB2_0) + usb = L.if_list(2, USB2_0) self.IFs = _IFs(self) diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index bdc5dce7..e53d39a2 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -27,7 +27,7 @@ class _IFs(Module.IFS()): # components class _NODEs(Module.NODES()): - configuration_resistors = times( + configuration_resistors = L.if_list( 2, lambda: Resistor().builder( lambda r: r.PARAMs.resistance.merge(Constant(5.1 * P.kohm)) diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index e19fbdc3..86014e44 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -33,7 +33,7 @@ class _NODEs(Module.NODES()): usb_connector = ( USB_Type_C_Receptacle_14_pin_Vertical() ) # TODO: make generic - configuration_resistors = times(2, Resistor) + configuration_resistors = L.if_list(2, Resistor) gnd_resistor = Resistor() gnd_capacitor = Capacitor() esd = USB2_0_ESD_Protection() diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index 42dd2b93..353d3c0d 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -24,7 +24,7 @@ class _NODEs(Module.NODES()): usb_uart = CH340x() uart_rs485 = UART_RS485() termination = Resistor() - polarization = times(2, Resistor) + polarization = L.if_list(2, Resistor) self.NODEs = _NODEs(self) diff --git a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py index 0eba0598..9d1ac9cf 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py @@ -28,8 +28,8 @@ class _IFs(Module.IFS()): sbu2 = Electrical() shield = Electrical() # power - gnd = times(4, Electrical) - vbus = times(4, Electrical) + gnd = L.if_list(4, Electrical) + vbus = L.if_list(4, Electrical) # diffpairs: p, n rx1 = DifferentialPair() rx2 = DifferentialPair() diff --git a/src/faebryk/library/has_designator_prefix_defined.py b/src/faebryk/library/has_designator_prefix_defined.py index 89c5ea38..40742fe9 100644 --- a/src/faebryk/library/has_designator_prefix_defined.py +++ b/src/faebryk/library/has_designator_prefix_defined.py @@ -1,6 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +# import faebryk.library._F as F from faebryk.library.has_designator_prefix import has_designator_prefix diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index 54945283..c941f5e6 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -19,8 +19,8 @@ def __init__(self) -> None: # interfaces class _IFs(Module.IFS()): - pin = times(2, Electrical) - mount = times(2, Electrical) + pin = L.if_list(2, Electrical) + mount = L.if_list(2, Electrical) self.IFs = _IFs(self) diff --git a/src/faebryk/libs/library/L.py b/src/faebryk/libs/library/L.py new file mode 100644 index 00000000..261567ff --- /dev/null +++ b/src/faebryk/libs/library/L.py @@ -0,0 +1,9 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT + +import logging + +logger = logging.getLogger(__name__) + +from faebryk.core.module import Module +from faebryk.core.node import d_field, if_list, rt_field, f_field diff --git a/src/faebryk/libs/util.py b/src/faebryk/libs/util.py index 85531dfa..8f68a717 100644 --- a/src/faebryk/libs/util.py +++ b/src/faebryk/libs/util.py @@ -787,3 +787,13 @@ async def get_page(page: int): yield r page += 1 + + +def factory[T, **P](con: Callable[P, T]) -> Callable[P, Callable[[], T]]: + def _(*args: P.args, **kwargs: P.kwargs) -> Callable[[], T]: + def __() -> T: + return con(*args, **kwargs) + + return __ + + return _ From 64d2b9f0d135996ac8bcbced512dffb39ffd7558 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 23 Aug 2024 21:00:47 +0200 Subject: [PATCH 10/63] Replace init with new --- new_holders_flat.py | 8 +++----- src/faebryk/core/node.py | 8 +++++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/new_holders_flat.py b/new_holders_flat.py index 5a70cf50..cc603b0d 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -3,12 +3,10 @@ import typer from faebryk.core.module import Module -from faebryk.core.node import d_field, if_list, rt_field from faebryk.core.parameter import Parameter from faebryk.core.util import as_unit from faebryk.library.can_bridge_defined import can_bridge_defined from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.has_simple_value_representation import ( has_simple_value_representation, @@ -46,7 +44,7 @@ def bla_dep2(self): return self.bla_voltage + (10 * P.V) # dynamic trait - @rt_field + @L.rt_field def bridge(self): return can_bridge_defined(self.anode, self.cathode) @@ -76,9 +74,9 @@ def __preinit__(self): class LED2_WITHEXTRAT_IFS(LED2): extra: list[Electrical] = field(default_factory=lambda: times(2, Electrical)) - extra2: list[Electrical] = if_list(2, Electrical) + extra2: list[Electrical] = L.if_list(2, Electrical) - @rt_field + @L.rt_field def bridge(self): return can_bridge_defined(self.extra2[0], self.extra2[1]) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 2e09f7ab..07e6ac29 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -277,7 +277,12 @@ def setup_gen_alias(name, obj): return objects, clsfields - def __init__(self) -> None: + def __new__(cls, *args, **kwargs): + out = super().__new__(cls) + out._setup() + return out + + def _setup(self) -> None: cls = type(self) # print(f"Called Node init {cls.__qualname__:<20} {'-' * 80}") @@ -309,6 +314,7 @@ def __init__(self) -> None: if hasattr(base, "__postinit__"): base.__postinit__(self) + def __init__(self): ... def __preinit__(self): ... def __postinit__(self): ... From 0509cce908b80c5f002742dc9afce457c906e4ff Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Sat, 24 Aug 2024 01:23:26 +0200 Subject: [PATCH 11/63] Inbetween lib refactor commit --- src/faebryk/core/node.py | 6 + src/faebryk/library/ANY.py | 5 +- src/faebryk/library/BH1750FVI_TR.py | 93 ++---- src/faebryk/library/BJT.py | 72 ++--- src/faebryk/library/Battery.py | 26 +- src/faebryk/library/Button.py | 28 +- src/faebryk/library/ButtonCell.py | 40 +-- src/faebryk/library/CBM9002A_56ILG.py | 112 +++---- .../CBM9002A_56ILG_Reference_Design.py | 153 ++++------ src/faebryk/library/CD4011.py | 19 +- src/faebryk/library/CH340x.py | 55 ++-- src/faebryk/library/Capacitor.py | 81 ++--- src/faebryk/library/Common_Mode_Filter.py | 25 +- src/faebryk/library/Comparator.py | 73 ++--- src/faebryk/library/Constant.py | 10 +- src/faebryk/library/Crystal.py | 73 ++--- src/faebryk/library/Crystal_Oscillator.py | 83 +++-- src/faebryk/library/DIP.py | 38 +-- src/faebryk/library/DifferentialPair.py | 12 +- src/faebryk/library/Diode.py | 82 ++--- src/faebryk/library/EEPROM.py | 59 ++-- src/faebryk/library/ESP32.py | 288 ++++++++---------- src/faebryk/library/ESP32_C3.py | 141 ++++----- src/faebryk/library/ESP32_C3_MINI_1.py | 84 +++-- .../ESP32_C3_MINI_1_Reference_Design.py | 48 ++- src/faebryk/library/ElectricLogic.py | 172 +++++------ src/faebryk/library/ElectricLogicGate.py | 45 ++- src/faebryk/library/ElectricLogicGates.py | 39 ++- src/faebryk/library/ElectricPower.py | 65 ++-- src/faebryk/library/Electrical.py | 4 +- src/faebryk/library/Ethernet.py | 11 +- src/faebryk/library/Fan.py | 13 +- src/faebryk/library/Footprint.py | 4 - src/faebryk/library/Fuse.py | 36 +-- src/faebryk/library/GDT.py | 31 +- src/faebryk/library/GenericBusProtection.py | 50 ++- src/faebryk/library/HLK_LD2410B_P.py | 60 ++-- src/faebryk/library/Header.py | 30 +- src/faebryk/library/I2C.py | 38 +-- src/faebryk/library/Inductor.py | 51 ++-- src/faebryk/library/JTAG.py | 37 +-- src/faebryk/library/KicadFootprint.py | 16 +- src/faebryk/library/LDO.py | 100 +++--- src/faebryk/library/LED.py | 51 ++-- src/faebryk/library/LEDIndicator.py | 21 +- src/faebryk/library/Logic.py | 13 +- src/faebryk/library/Logic74xx.py | 48 +-- src/faebryk/library/LogicGate.py | 17 +- src/faebryk/library/LogicGates.py | 19 +- src/faebryk/library/LogicOps.py | 2 +- src/faebryk/library/M24C08_FMN6TP.py | 72 ++--- src/faebryk/library/MCP2221A.py | 39 +-- src/faebryk/library/ME6211C33M5G_N.py | 52 ++-- src/faebryk/library/MOSFET.py | 47 ++- src/faebryk/library/Mounting_Hole.py | 29 +- src/faebryk/library/MultiSPI.py | 14 +- src/faebryk/library/Net.py | 19 +- src/faebryk/library/OLED_Module.py | 31 +- src/faebryk/library/OpAmp.py | 74 ++--- src/faebryk/library/PJ398SM.py | 19 +- src/faebryk/library/PM1006.py | 30 +- src/faebryk/library/Pad.py | 27 +- src/faebryk/library/Potentiometer.py | 38 +-- src/faebryk/library/PowerSwitch.py | 17 +- src/faebryk/library/PowerSwitchMOSFET.py | 32 +- src/faebryk/library/PowerSwitchStatic.py | 10 +- src/faebryk/library/PoweredLED.py | 31 +- src/faebryk/library/Powered_Relay.py | 81 ++--- src/faebryk/library/QFN.py | 12 +- src/faebryk/library/QWIIC.py | 26 +- src/faebryk/library/QWIIC_Connector.py | 19 +- src/faebryk/library/RJ45_Receptacle.py | 22 +- src/faebryk/library/RP2040.py | 74 ++--- .../library/RP2040_Reference_Design.py | 76 ++--- src/faebryk/library/RS232.py | 17 +- src/faebryk/library/RS485.py | 9 +- src/faebryk/library/RS485_Bus_Protection.py | 154 ++++------ src/faebryk/library/Relay.py | 44 ++- src/faebryk/library/Resistor.py | 82 +++-- .../library/Resistor_Voltage_Divider.py | 33 +- src/faebryk/library/SCD40.py | 56 ++-- src/faebryk/library/SK9822_EC20.py | 52 ++-- src/faebryk/library/SMDTwoPin.py | 14 +- src/faebryk/library/SNx4LVC541A.py | 24 +- src/faebryk/library/SOIC.py | 12 +- src/faebryk/library/SPI.py | 15 +- src/faebryk/library/SPIFlash.py | 21 +- src/faebryk/library/SWD.py | 29 +- src/faebryk/library/SWDConnector.py | 33 +- src/faebryk/library/Sercom.py | 17 +- src/faebryk/library/Set.py | 8 +- src/faebryk/library/Switch.py | 21 +- src/faebryk/library/TBD.py | 3 - src/faebryk/library/TD541S485H.py | 68 ++--- src/faebryk/library/TI_CD4011BE.py | 64 ++-- src/faebryk/library/TVS.py | 11 +- src/faebryk/library/TXS0102DCUR.py | 66 ++-- src/faebryk/library/TXS0102DCUR_UART.py | 40 +-- src/faebryk/library/UART.py | 18 +- src/faebryk/library/UART_Base.py | 25 +- src/faebryk/library/UART_RS485.py | 37 +-- src/faebryk/library/USB2514B.py | 117 +++---- src/faebryk/library/USB2_0.py | 14 +- src/faebryk/library/USB2_0_ESD_Protection.py | 47 +-- src/faebryk/library/USB2_0_IF.py | 13 +- src/faebryk/library/USB3.py | 19 +- src/faebryk/library/USB3_IF.py | 17 +- src/faebryk/library/USB3_connector.py | 29 +- src/faebryk/library/USBLC6_2P6.py | 30 +- src/faebryk/library/USB_C.py | 33 +- src/faebryk/library/USB_C_5V_PSU.py | 48 ++- src/faebryk/library/USB_C_PSU_Vertical.py | 82 ++--- src/faebryk/library/USB_C_PowerOnly.py | 47 ++- src/faebryk/library/USB_RS485.py | 73 ++--- .../USB_Type_C_Receptacle_14_pin_Vertical.py | 60 ++-- .../library/USB_Type_C_Receptacle_16_pin.py | 57 ++-- .../library/USB_Type_C_Receptacle_24_pin.py | 89 +++--- src/faebryk/library/XL_3528RGBW_WS2812B.py | 52 ++-- .../library/can_attach_to_footprint.py | 3 +- .../can_attach_to_footprint_symmetrically.py | 16 +- .../can_attach_to_footprint_via_pinmap.py | 10 +- src/faebryk/library/can_attach_via_pinmap.py | 7 +- .../library/can_attach_via_pinmap_equal.py | 6 +- .../library/can_attach_via_pinmap_pinlist.py | 6 +- src/faebryk/library/can_be_decoupled.py | 4 +- .../library/can_be_decoupled_defined.py | 11 +- src/faebryk/library/can_be_surge_protected.py | 2 +- .../library/can_be_surge_protected_defined.py | 9 +- src/faebryk/library/can_bridge_defined.py | 1 - src/faebryk/library/can_switch_power.py | 5 +- .../library/can_switch_power_defined.py | 17 +- src/faebryk/library/has_datasheet_defined.py | 2 - .../library/has_defined_capacitance.py | 1 - .../has_defined_descriptive_properties.py | 1 - src/faebryk/library/has_defined_footprint.py | 5 +- src/faebryk/library/has_defined_kicad_ref.py | 2 - src/faebryk/library/has_defined_resistance.py | 1 - src/faebryk/library/has_designator_defined.py | 2 - .../library/has_designator_prefix_defined.py | 1 - src/faebryk/library/has_equal_pins.py | 5 +- src/faebryk/library/has_equal_pins_in_ifs.py | 5 +- .../library/has_esphome_config_defined.py | 3 - src/faebryk/library/has_footprint.py | 3 +- src/faebryk/library/has_footprint_impl.py | 11 +- .../has_footprint_requirement_defined.py | 1 - src/faebryk/library/has_kicad_footprint.py | 5 +- .../library/has_kicad_footprint_equal_ifs.py | 4 - .../has_kicad_footprint_equal_ifs_defined.py | 2 - .../library/has_kicad_manual_footprint.py | 3 - src/faebryk/library/has_linked_pad.py | 1 - src/faebryk/library/has_linked_pad_defined.py | 4 - src/faebryk/library/has_multi_picker.py | 5 +- .../library/has_overriden_name_defined.py | 2 - src/faebryk/library/has_pcb_layout_defined.py | 1 - .../library/has_pcb_position_defined.py | 2 - .../has_pcb_position_defined_relative.py | 1 - ...pcb_position_defined_relative_to_parent.py | 1 - .../library/has_pcb_routing_strategy.py | 3 +- ...pcb_routing_strategy_greedy_direct_line.py | 2 +- .../has_pcb_routing_strategy_manual.py | 7 +- .../has_pcb_routing_strategy_via_to_layer.py | 5 +- .../library/has_pin_association_heuristic.py | 3 +- ..._pin_association_heuristic_lookup_table.py | 6 +- ...ple_value_representation_based_on_param.py | 10 +- ...le_value_representation_based_on_params.py | 3 - ...has_simple_value_representation_defined.py | 4 - .../library/has_single_connection_impl.py | 2 - .../library/has_single_electric_reference.py | 3 +- .../has_single_electric_reference_defined.py | 8 +- src/faebryk/library/is_decoupled.py | 4 +- src/faebryk/library/is_decoupled_nodes.py | 8 +- src/faebryk/library/is_esphome_bus_defined.py | 3 - ...s_representable_by_single_value_defined.py | 4 - src/faebryk/library/is_surge_protected.py | 2 +- .../library/is_surge_protected_defined.py | 2 - src/faebryk/library/pf_533984002.py | 27 +- src/faebryk/library/pf_74AHCT2G125.py | 55 ++-- src/faebryk/libs/library/L.py | 2 +- 178 files changed, 2173 insertions(+), 3531 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 07e6ac29..5eccc6dd 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -130,6 +130,12 @@ def add( self._handle_add_node(name, obj) + def add_to_container[T: Node]( + self, n: int, factory: Callable[[], T], container: list[T] + ): + for _ in range(n): + self.add(factory(), container=container) + def __init_subclass__(cls, *, init: bool = True) -> None: super().__init_subclass__() cls._init = init diff --git a/src/faebryk/library/ANY.py b/src/faebryk/library/ANY.py index 2f7e0744..c8b7421d 100644 --- a/src/faebryk/library/ANY.py +++ b/src/faebryk/library/ANY.py @@ -8,12 +8,9 @@ class ANY[PV](Parameter[PV]): """ Allow parameter to take any value. Operations with this parameter automatically resolve to ANY too. - Don't mistake with TBD. + Don't mistake with F.TBD. """ - def __init__(self) -> None: - super().__init__() - def __eq__(self, __value: object) -> bool: if isinstance(__value, ANY): return True diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 52555362..631ef0e4 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -4,28 +4,8 @@ import logging from dataclasses import dataclass, field +import faebryk.library._F as F from faebryk.core.module import Module, Parameter -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Capacitor import Capacitor -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.I2C import I2C -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.Range import Range -from faebryk.library.Resistor import Resistor -from faebryk.library.TBD import TBD from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -34,20 +14,20 @@ class BH1750FVI_TR(Module): @dataclass class _bh1750_esphome_config(has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=TBD) + update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: super().__init__() def get_config(self) -> dict: assert isinstance( - self.update_interval_s, Constant + self.update_interval_s, F.Constant ), "No update interval set!" obj = self.get_obj() assert isinstance(obj, BH1750FVI_TR) - i2c = is_esphome_bus.find_connected_bus(obj.IFs.i2c) + i2c = is_esphome_bus.find_connected_bus(obj.i2c) return { "sensor": [ @@ -66,54 +46,47 @@ def set_address(self, addr: int): # ADDR = ‘H’ ( ADDR ≧ 0.7VCC ) “1011100“ # ADDR = 'L' ( ADDR ≦ 0.3VCC ) “0100011“ ... - # assert addr < (1 << len(self.IFs.e)) + # assert addr < (1 << len(self.e)) - # for i, e in enumerate(self.IFs.e): + # for i, e in enumerate(self.e): # e.set(addr & (1 << i) != 0) - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): - dvi_capacitor = Capacitor() - dvi_resistor = Resistor() - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() - addr = ElectricLogic() - dvi = ElectricLogic() - ep = ElectricLogic() - i2c = I2C() + dvi_capacitor : F.Capacitor + dvi_resistor : F.Resistor + - self.IFs = _IFs(self) + power: F.ElectricPower + addr: F.ElectricLogic + dvi: F.ElectricLogic + ep: F.ElectricLogic + i2c = I2C() - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) - self.NODEs.dvi_capacitor.PARAMs.capacitance.merge(1 * P.uF) - self.NODEs.dvi_resistor.PARAMs.resistance.merge(1 * P.kohm) + self.dvi_capacitor.capacitance.merge(1 * P.uF) + self.dvi_resistor.resistance.merge(1 * P.kohm) - self.IFs.i2c.terminate() + self.i2c.terminate() - self.IFs.i2c.PARAMs.frequency.merge( + self.i2c.frequency.merge( I2C.define_max_frequency_capability(I2C.SpeedMode.fast_speed) ) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": self.IFs.power.IFs.hv, - "2": self.IFs.addr.IFs.signal, - "3": self.IFs.power.IFs.lv, - "4": self.IFs.i2c.IFs.sda.IFs.signal, - "5": self.IFs.dvi.IFs.signal, - "6": self.IFs.i2c.IFs.scl.IFs.signal, - "7": self.IFs.ep.IFs.signal, + "1": self.power.hv, + "2": self.addr.signal, + "3": self.power.lv, + "4": self.i2c.sda.signal, + "5": self.dvi.signal, + "6": self.i2c.scl.signal, + "7": self.ep.signal, } ) ) @@ -125,18 +98,16 @@ class _PARAMs(Module.PARAMS()): ... ) # set constraints - self.IFs.power.PARAMs.voltage.merge(Range(2.4 * P.V, 3.6 * P.V)) + self.power.voltage.merge(F.Range(2.4 * P.V, 3.6 * P.V)) # internal connections - ref = ElectricLogic.connect_all_module_references(self) + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) - ref.connect(self.IFs.power) + ref.connect(self.power) - self.IFs.power.get_trait(can_be_decoupled).decouple().PARAMs.capacitance.merge( - 0.1 * P.uF - ) - # TODO: self.IFs.dvi.low_pass(self.IF.dvi_capacitor, self.IF.dvi_resistor) + self.power.get_trait(can_be_decoupled).decouple().capacitance.merge(0.1 * P.uF) + # TODO: self.dvi.low_pass(self.IF.dvi_capacitor, self.IF.dvi_resistor) - # self.IFs.i2c.add_trait(is_esphome_bus.impl()()) + # self.i2c.add_trait(is_esphome_bus.impl()()) self.esphome = self._bh1750_esphome_config() self.add_trait(self.esphome) diff --git a/src/faebryk/library/BJT.py b/src/faebryk/library/BJT.py index b928939e..cf1c603f 100644 --- a/src/faebryk/library/BJT.py +++ b/src/faebryk/library/BJT.py @@ -3,16 +3,11 @@ from enum import Enum, auto -from faebryk.core.module import Module, Parameter -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.has_pin_association_heuristic_lookup_table import ( - has_pin_association_heuristic_lookup_table, -) -from faebryk.library.TBD import TBD +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.node import rt_field +from faebryk.core.parameter import Parameter +from faebryk.libs.library import L class BJT(Module): @@ -27,38 +22,27 @@ class OperationRegion(Enum): SATURATION = auto() CUT_OFF = auto() - def __init__( - self, - doping_type: Parameter[DopingType], - operation_region: Parameter[OperationRegion], - ): - super().__init__() - - class _PARAMs(super().PARAMS()): - doping_type = TBD[self.DopingType]() - operation_region = TBD[self.OperationRegion]() - - self.PARAMs = _PARAMs(self) - self.PARAMs.doping_type.merge(doping_type) - self.PARAMs.operation_region.merge(operation_region) - - class _IFs(super().IFS()): - emitter = Electrical() - base = Electrical() - collector = Electrical() - - self.IFs = _IFs(self) - - self.add_trait(has_designator_prefix_defined("Q")) - self.add_trait(can_bridge_defined(self.IFs.collector, self.IFs.emitter)) - self.add_trait( - has_pin_association_heuristic_lookup_table( - mapping={ - self.IFs.emitter: ["E", "Emitter"], - self.IFs.base: ["B", "Base"], - self.IFs.collector: ["C", "Collector"], - }, - accept_prefix=False, - case_sensitive=False, - ) + doping_type: Parameter[DopingType] + operation_region: Parameter[OperationRegion] + + emitter: F.Electrical + base: F.Electrical + collector: F.Electrical + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("Q") + + @rt_field + def can_bridge(self): + return F.can_bridge_defined(self.collector, self.emitter) + + @rt_field + def pin_association_heuristic(self): + return F.has_pin_association_heuristic_lookup_table( + mapping={ + self.emitter: ["E", "Emitter"], + self.base: ["B", "Base"], + self.collector: ["C", "Collector"], + }, + accept_prefix=False, + case_sensitive=False, ) diff --git a/src/faebryk/library/Battery.py b/src/faebryk/library/Battery.py index f9fded1a..688f3dd6 100644 --- a/src/faebryk/library/Battery.py +++ b/src/faebryk/library/Battery.py @@ -2,29 +2,17 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F +import faebryk.libs.library.L as L from faebryk.core.module import Module -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity class Battery(Module): - @classmethod - def PARAMS(cls): - class _PARAMs(super().PARAMS()): - voltage = TBD[Quantity]() - capacity = TBD[Quantity]() + voltage: F.TBD[Quantity] + capacity: F.TBD[Quantity] - return _PARAMs + power: F.ElectricPower - def __init__(self) -> None: - super().__init__() - - class _IFs(Module.IFS()): - power = ElectricPower() - - self.IFs = _IFs(self) - - self.PARAMs = self.PARAMS()(self) - - self.IFs.power.PARAMs.voltage.merge(self.PARAMs.voltage) + def __preinit__(self) -> None: + self.power.voltage.merge(self.voltage) diff --git a/src/faebryk/library/Button.py b/src/faebryk/library/Button.py index d389a893..6a41d491 100644 --- a/src/faebryk/library/Button.py +++ b/src/faebryk/library/Button.py @@ -3,32 +3,18 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.libs.util import times +from faebryk.libs.library import L logger = logging.getLogger(__name__) class Button(Module): - def __init__(self) -> None: - super().__init__() + unnamed = L.if_list(2, F.Electrical) - class _NODEs(Module.NODES()): ... + designator_prefix = L.f_field(F.has_designator_prefix_defined)("S") - self.NODEs = _NODEs(self) - - class _IFs(Module.IFS()): - unnamed = L.if_list(2, Electrical) - - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - self.add_trait(has_designator_prefix_defined("S")) - - self.add_trait(can_bridge_defined(self.IFs.unnamed[0], self.IFs.unnamed[1])) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.unnamed[0], self.unnamed[1]) diff --git a/src/faebryk/library/ButtonCell.py b/src/faebryk/library/ButtonCell.py index 9f71f8ac..c0b3eae2 100644 --- a/src/faebryk/library/ButtonCell.py +++ b/src/faebryk/library/ButtonCell.py @@ -4,15 +4,13 @@ from enum import IntEnum, StrEnum +import faebryk.library._F as F from faebryk.core.parameter import Parameter -from faebryk.library.Battery import Battery -from faebryk.library.Constant import Constant -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import P -class ButtonCell(Battery): +class ButtonCell(F.Battery): class Material(StrEnum): Alkaline = "L" SilverOxide = "S" @@ -25,13 +23,13 @@ class Material(StrEnum): @property def voltage(self) -> Parameter: return { - self.Alkaline: Constant(1.5 * P.V), - self.SilverOxide: Constant(1.55 * P.V), - self.ZincAir: Constant(1.65 * P.V), - self.Lithium: Constant(3.0 * P.V), - self.Mercury: Constant(1.35 * P.V), - self.NickelCadmium: Constant(1.2 * P.V), - self.NickelMetalHydride: Constant(1.2 * P.V), + self.Alkaline: F.Constant(1.5 * P.V), + self.SilverOxide: F.Constant(1.55 * P.V), + self.ZincAir: F.Constant(1.65 * P.V), + self.Lithium: F.Constant(3.0 * P.V), + self.Mercury: F.Constant(1.35 * P.V), + self.NickelCadmium: F.Constant(1.2 * P.V), + self.NickelMetalHydride: F.Constant(1.2 * P.V), }[self] class Shape(StrEnum): @@ -55,18 +53,10 @@ class Size(IntEnum): N_2430 = 2430 N_2450 = 2450 - def __init__(self) -> None: - super().__init__() + material = F.TBD[Material] + shape = F.TBD[Shape] + size = F.TBD[Size] - class _PARAMs(Battery.PARAMS()): - material = TBD[self.Material]() - shape = TBD[self.Shape]() - size = TBD[self.Size]() + designator_prefix = L.f_field(F.has_designator_prefix_defined)("B") - self.PARAMs = _PARAMs(self) - - self.add_trait(has_designator_prefix_defined("B")) - - self.inherit() - - # TODO merge voltage with material voltage + # TODO merge voltage with material voltage diff --git a/src/faebryk/library/CBM9002A_56ILG.py b/src/faebryk/library/CBM9002A_56ILG.py index 4a4d57c1..81ab71f9 100644 --- a/src/faebryk/library/CBM9002A_56ILG.py +++ b/src/faebryk/library/CBM9002A_56ILG.py @@ -1,19 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.I2C import I2C -from faebryk.library.USB2_0 import USB2_0 -from faebryk.libs.util import times +from faebryk.libs.library import L class CBM9002A_56ILG(Module): @@ -23,63 +13,45 @@ class CBM9002A_56ILG(Module): Cypress Semicon CY7C68013A-56L Clone """ - def __init__(self): - super().__init__() - - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - class _IFS(Module.IFS()): - PA = L.if_list(8, ElectricLogic) - PB = L.if_list(8, ElectricLogic) - PD = L.if_list(8, ElectricLogic) - usb = USB2_0() - i2c = I2C() - - avcc = ElectricPower() - vcc = ElectricPower() - - rdy = L.if_list(2, ElectricLogic) - ctl = L.if_list(3, ElectricLogic) - reset = ElectricLogic() - wakeup = ElectricLogic() - - ifclk = ElectricLogic() - clkout = ElectricLogic() - xtalin = Electrical() - xtalout = Electrical() - - self.IFs = _IFS(self) - - # ---------------------------------------- - # traits - # ---------------------------------------- - self.add_trait(has_designator_prefix_defined("U")) - self.add_trait( - has_datasheet_defined( - "https://corebai.com/Data/corebai/upload/file/20240201/CBM9002A.pdf" - ) - ) - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + PA = L.if_list(8, F.ElectricLogic) + PB = L.if_list(8, F.ElectricLogic) + PD = L.if_list(8, F.ElectricLogic) + usb: F.USB2_0 + i2c: F.I2C + + avcc: F.ElectricPower + vcc: F.ElectricPower + + rdy = L.if_list(2, F.ElectricLogic) + ctl = L.if_list(3, F.ElectricLogic) + reset: F.ElectricLogic + wakeup: F.ElectricLogic + + ifclk: F.ElectricLogic + clkout: F.ElectricLogic + xtalin: F.Electrical + xtalout: F.Electrical + + # ---------------------------------------- + # traits + # ---------------------------------------- + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://corebai.com/Data/corebai/upload/file/20240201/CBM9002A.pdf" + ) + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) - # ---------------------------------------- - # aliases - # ---------------------------------------- - - # ---------------------------------------- - # connections - # ---------------------------------------- - self.IFs.avcc.get_trait(can_be_decoupled).decouple() # TODO: decouple all pins - self.IFs.vcc.get_trait(can_be_decoupled).decouple() # TODO: decouple all pins - - # ---------------------------------------- - # Parameters - # ---------------------------------------- + # ---------------------------------------- + # connections + # ---------------------------------------- + def __preinit__(self): + self.avcc.decoupled.decouple() # TODO: decouple all pins + self.vcc.decoupled.decouple() # TODO: decouple all pins diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index 04def958..c392d6cd 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -1,19 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.Capacitor import Capacitor -from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG -from faebryk.library.Constant import Constant -from faebryk.library.Crystal_Oscillator import Crystal_Oscillator -from faebryk.library.Diode import Diode -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.I2C import I2C -from faebryk.library.USB2_0 import USB2_0 +from faebryk.core.util import connect_module_mifs_by_name +from faebryk.libs.library import L from faebryk.libs.units import P -from faebryk.libs.util import times class CBM9002A_56ILG_Reference_Design(Module): @@ -21,101 +13,60 @@ class CBM9002A_56ILG_Reference_Design(Module): Minimal working example for the CBM9002A_56ILG """ - def __init__(self): - super().__init__() - - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - class _NODEs(Module.NODES()): - mcu = CBM9002A_56ILG() - reset_diode = Diode() - reset_lowpass_cap = Capacitor() - oscillator = Crystal_Oscillator() - - self.NODEs = _NODEs(self) - - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - class _IFS(Module.IFS()): - PA = L.if_list(8, ElectricLogic) - PB = L.if_list(8, ElectricLogic) - PD = L.if_list(8, ElectricLogic) - usb = USB2_0() - i2c = I2C() - - avcc = ElectricPower() - vcc = ElectricPower() - - rdy = L.if_list(2, ElectricLogic) - ctl = L.if_list(3, ElectricLogic) - reset = ElectricLogic() - wakeup = ElectricLogic() - - ifclk = ElectricLogic() - clkout = ElectricLogic() - xtalin = Electrical() - xtalout = Electrical() - - self.IFs = _IFS(self) - - # ---------------------------------------- - # traits - # ---------------------------------------- - - # ---------------------------------------- - # aliases - # ---------------------------------------- - gnd = self.IFs.vcc.IFs.lv - - # ---------------------------------------- - # connections - # ---------------------------------------- - # connect all mcu IFs to this module IFs - for i, interface in enumerate(self.IFs.PA): - interface.connect(self.NODEs.mcu.IFs.PA[i]) - for i, interface in enumerate(self.IFs.PB): - interface.connect(self.NODEs.mcu.IFs.PB[i]) - for i, interface in enumerate(self.IFs.PD): - interface.connect(self.NODEs.mcu.IFs.PD[i]) - self.IFs.usb.connect(self.NODEs.mcu.IFs.usb) - self.IFs.i2c.connect(self.NODEs.mcu.IFs.i2c) - self.IFs.avcc.connect(self.NODEs.mcu.IFs.avcc) - self.IFs.vcc.connect(self.NODEs.mcu.IFs.vcc) - for i, interface in enumerate(self.IFs.rdy): - interface.connect(self.NODEs.mcu.IFs.rdy[i]) - for i, interface in enumerate(self.IFs.ctl): - interface.connect(self.NODEs.mcu.IFs.ctl[i]) - self.IFs.reset.connect(self.NODEs.mcu.IFs.reset) - self.IFs.wakeup.connect(self.NODEs.mcu.IFs.wakeup) - self.IFs.ifclk.connect(self.NODEs.mcu.IFs.ifclk) - self.IFs.clkout.connect(self.NODEs.mcu.IFs.clkout) - self.IFs.xtalin.connect(self.NODEs.mcu.IFs.xtalin) - self.IFs.xtalout.connect(self.NODEs.mcu.IFs.xtalout) - - self.IFs.reset.IFs.signal.connect_via( - self.NODEs.reset_lowpass_cap, gnd + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + mcu: F.CBM9002A_56ILG + reset_diode: F.Diode + reset_lowpass_cap: F.Capacitor + oscillator: F.Crystal_Oscillator + + PA = L.if_list(8, F.ElectricLogic) + PB = L.if_list(8, F.ElectricLogic) + PD = L.if_list(8, F.ElectricLogic) + usb: F.USB2_0 + i2c: F.I2C + + avcc: F.ElectricPower + vcc: F.ElectricPower + + rdy = L.if_list(2, F.ElectricLogic) + ctl = L.if_list(3, F.ElectricLogic) + reset: F.ElectricLogic + wakeup: F.ElectricLogic + + ifclk: F.ElectricLogic + clkout: F.ElectricLogic + xtalin: F.Electrical + xtalout: F.Electrical + + # ---------------------------------------- + # traits + # ---------------------------------------- + + # ---------------------------------------- + # connections + # ---------------------------------------- + def __preinit__(self): + gnd = self.vcc.lv + + connect_module_mifs_by_name(self, self.mcu, allow_partial=True) + + self.reset.signal.connect_via( + self.reset_lowpass_cap, gnd ) # TODO: should come from a low pass for electric logic - self.IFs.reset.get_trait(ElectricLogic.can_be_pulled).pull(up=True) - self.IFs.reset.IFs.signal.connect_via( - self.NODEs.reset_diode, self.IFs.vcc.IFs.hv - ) + self.reset.pulled.pull(up=True) + self.reset.signal.connect_via(self.reset_diode, self.vcc.hv) # crystal oscillator - self.NODEs.oscillator.IFs.power.connect(self.IFs.vcc) - self.NODEs.oscillator.IFs.n.connect(self.IFs.xtalin) - self.NODEs.oscillator.IFs.p.connect(self.IFs.xtalout) + self.oscillator.power.connect(self.vcc) + self.oscillator.n.connect(self.xtalin) + self.oscillator.p.connect(self.xtalout) # ---------------------------------------- # Parameters # ---------------------------------------- - self.NODEs.reset_lowpass_cap.PARAMs.capacitance.merge(Constant(1 * P.uF)) + self.reset_lowpass_cap.capacitance.merge(F.Constant(1 * P.uF)) - self.NODEs.oscillator.NODEs.crystal.PARAMs.frequency.merge( - Constant(24 * P.Mhertz) - ) - self.NODEs.oscillator.NODEs.crystal.PARAMs.load_impedance.merge( - Constant(12 * P.pohm) - ) + self.oscillator.crystal.frequency.merge(F.Constant(24 * P.Mhertz)) + self.oscillator.crystal.load_impedance.merge(F.Constant(12 * P.pohm)) diff --git a/src/faebryk/library/CD4011.py b/src/faebryk/library/CD4011.py index 7d74c868..cc2b3353 100644 --- a/src/faebryk/library/CD4011.py +++ b/src/faebryk/library/CD4011.py @@ -1,18 +1,19 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogicGates import ElectricLogicGates -from faebryk.library.has_simple_value_representation_defined import ( - has_simple_value_representation_defined, -) -from faebryk.library.Logic74xx import Logic74xx +import faebryk.library._F as F +from faebryk.libs.library import L -class CD4011(Logic74xx): +class CD4011(F.Logic74xx): def __init__(self): super().__init__( - [lambda: ElectricLogicGates.NAND(input_cnt=Constant(2)) for _ in range(4)] + [ + lambda: F.ElectricLogicGates.NAND(input_cnt=F.Constant(2)) + for _ in range(4) + ] ) - self.add_trait(has_simple_value_representation_defined("cd4011")) + simple_value_representation = L.f_field(F.has_simple_value_representation_defined)( + "cd4011" + ) diff --git a/src/faebryk/library/CH340x.py b/src/faebryk/library/CH340x.py index 702abb50..d159ae4a 100644 --- a/src/faebryk/library/CH340x.py +++ b/src/faebryk/library/CH340x.py @@ -3,53 +3,32 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.Range import Range -from faebryk.library.UART import UART -from faebryk.library.USB2_0 import USB2_0 +from faebryk.libs.library import L from faebryk.libs.units import P logger = logging.getLogger(__name__) class CH340x(Module): - def __init__(self) -> None: - super().__init__() + usb: F.USB2_0 + uart: F.UART + tnow: F.Electrical + gpio_power: F.ElectricPower - class _NODEs(Module.NODES()): ... + designator = L.f_field(F.has_designator_prefix_defined)("U") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://wch-ic.com/downloads/file/79.html" + ) - self.NODEs = _NODEs(self) + def __preinit__(self): + self.gpio_power.lv.connect(self.usb.usb_if.buspower.lv) - class _IFs(Module.IFS()): - usb = USB2_0() - uart = UART() - tnow = Electrical() - gpio_power = ElectricPower() + self.gpio_power.voltage.merge(F.Range(0 * P.V, 5.3 * P.V)) + self.gpio_power.decoupled.decouple() + self.usb.usb_if.buspower.voltage.merge(F.Range(4 * P.V, 5.3 * P.V)) - self.IFs = _IFs(self) + self.usb.usb_if.buspower.decoupled.decouple() - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - self.IFs.gpio_power.IFs.lv.connect(self.IFs.usb.IFs.usb_if.IFs.buspower.IFs.lv) - - self.IFs.gpio_power.PARAMs.voltage.merge(Range(0 * P.V, 5.3 * P.V)) - self.IFs.gpio_power.get_trait(can_be_decoupled).decouple() - self.IFs.usb.IFs.usb_if.IFs.buspower.PARAMs.voltage.merge( - Range(4 * P.V, 5.3 * P.V) - ) - - self.add_trait(has_designator_prefix_defined("U")) - self.add_trait( - has_datasheet_defined("https://wch-ic.com/downloads/file/79.html") - ) - - self.IFs.usb.IFs.usb_if.IFs.buspower.get_trait(can_be_decoupled).decouple() - - self.IFs.gpio_power.IFs.lv.connect(self.IFs.usb.IFs.usb_if.IFs.buspower.IFs.lv) + self.gpio_power.lv.connect(self.usb.usb_if.buspower.lv) diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index 928a5fc8..81b4ada2 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -4,24 +4,15 @@ import logging from enum import IntEnum, auto +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import ( as_unit, as_unit_with_tolerance, enum_parameter_representation, ) -from faebryk.library.can_attach_to_footprint_symmetrically import ( - can_attach_to_footprint_symmetrically, -) -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation_based_on_params import ( - has_simple_value_representation_based_on_params, -) -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import Quantity -from faebryk.libs.util import times logger = logging.getLogger(__name__) @@ -37,41 +28,35 @@ class TemperatureCoefficient(IntEnum): X8R = auto() C0G = auto() - def __init__(self): - super().__init__() - - class _IFs(Module.IFS()): - unnamed = L.if_list(2, Electrical) - - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): - capacitance = TBD[Quantity]() - rated_voltage = TBD[Quantity]() - temperature_coefficient = TBD[Capacitor.TemperatureCoefficient]() - - self.PARAMs = _PARAMs(self) - - self.add_trait(can_bridge_defined(*self.IFs.unnamed)) - - self.add_trait( - has_simple_value_representation_based_on_params( - ( - self.PARAMs.capacitance, - self.PARAMs.rated_voltage, - self.PARAMs.temperature_coefficient, - ), - lambda ps: " ".join( - filter( - None, - [ - as_unit_with_tolerance(ps[0], "F"), - as_unit(ps[1], "V"), - enum_parameter_representation(ps[2].get_most_narrow()), - ], - ) - ), - ) + unnamed = L.if_list(2, F.Electrical) + + capacitance = F.TBD[Quantity]() + rated_voltage = F.TBD[Quantity]() + temperature_coefficient = F.TBD[TemperatureCoefficient]() + + attach_to_footprint: F.can_attach_to_footprint_symmetrically + designator_prefix = L.f_field(F.has_designator_prefix_defined)("C") + + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(*self.unnamed) + + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_params( + ( + self.capacitance, + self.rated_voltage, + self.temperature_coefficient, + ), + lambda ps: " ".join( + filter( + None, + [ + as_unit_with_tolerance(ps[0], "F"), + as_unit(ps[1], "V"), + enum_parameter_representation(ps[2].get_most_narrow()), + ], + ) + ), ) - self.add_trait(can_attach_to_footprint_symmetrically()) - self.add_trait(has_designator_prefix_defined("C")) diff --git a/src/faebryk/library/Common_Mode_Filter.py b/src/faebryk/library/Common_Mode_Filter.py index a7bc8692..f85c1466 100644 --- a/src/faebryk/library/Common_Mode_Filter.py +++ b/src/faebryk/library/Common_Mode_Filter.py @@ -3,30 +3,15 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_defined import has_designator_defined -from faebryk.libs.util import times +from faebryk.libs.library import L logger = logging.getLogger(__name__) class Common_Mode_Filter(Module): - def __init__(self) -> None: - super().__init__() + c_a = L.if_list(2, F.Electrical) + c_b = L.if_list(2, F.Electrical) - class _NODEs(Module.NODES()): ... - - self.NODEs = _NODEs(self) - - class _IFs(Module.IFS()): - c_a = L.if_list(2, Electrical) - c_b = L.if_list(2, Electrical) - - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - self.add_trait(has_designator_defined("FL")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("FL") diff --git a/src/faebryk/library/Comparator.py b/src/faebryk/library/Comparator.py index 68e637dc..3cf3dd0a 100644 --- a/src/faebryk/library/Comparator.py +++ b/src/faebryk/library/Comparator.py @@ -3,15 +3,10 @@ from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import as_unit -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation_based_on_params import ( - has_simple_value_representation_based_on_params, -) -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -21,40 +16,32 @@ class OutputType(Enum): PushPull = auto() OpenDrain = auto() - def __init__(self): - super().__init__() - - class _PARAMs(self.PARAMS()): - common_mode_rejection_ratio = TBD[Quantity]() - input_bias_current = TBD[Quantity]() - input_hysteresis_voltage = TBD[Quantity]() - input_offset_voltage = TBD[Quantity]() - propagation_delay = TBD[Quantity]() - output_type = TBD[Comparator.OutputType]() - - self.PARAMs = _PARAMs(self) - - class _IFs(super().IFS()): - power = ElectricPower() - inverting_input = Electrical() - non_inverting_input = Electrical() - output = Electrical() - - self.IFs = _IFs(self) - - self.add_trait( - has_simple_value_representation_based_on_params( - [ - self.PARAMs.common_mode_rejection_ratio, - self.PARAMs.input_bias_current, - self.PARAMs.input_hysteresis_voltage, - self.PARAMs.input_offset_voltage, - self.PARAMs.propagation_delay, - ], - lambda p: ( - f"{p[0]} CMRR, {as_unit(p[1], 'A')} Ib, {as_unit(p[2], 'V')} Vhys, " - f"{as_unit(p[3], 'V')} Vos, {as_unit(p[4], 's')} tpd" - ), - ) + common_mode_rejection_ratio: F.TBD[Quantity] + input_bias_current: F.TBD[Quantity] + input_hysteresis_voltage: F.TBD[Quantity] + input_offset_voltage: F.TBD[Quantity] + propagation_delay: F.TBD[Quantity] + output_type: F.TBD[F.Comparator.OutputType] + + power: F.ElectricPower + inverting_input: F.Electrical + non_inverting_input: F.Electrical + output: F.Electrical + + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_params( + [ + self.common_mode_rejection_ratio, + self.input_bias_current, + self.input_hysteresis_voltage, + self.input_offset_voltage, + self.propagation_delay, + ], + lambda p: ( + f"{p[0]} CMRR, {as_unit(p[1], 'A')} Ib, {as_unit(p[2], 'V')} Vhys, " + f"{as_unit(p[3], 'V')} Vos, {as_unit(p[4], 's')} tpd" + ), ) - self.add_trait(has_designator_prefix_defined("U")) + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/Constant.py b/src/faebryk/library/Constant.py index c088d9f1..66be93bd 100644 --- a/src/faebryk/library/Constant.py +++ b/src/faebryk/library/Constant.py @@ -3,20 +3,22 @@ from typing import Self, SupportsAbs +import faebryk.library._F as F from faebryk.core.parameter import Parameter, _resolved -from faebryk.library.is_representable_by_single_value_defined import ( - is_representable_by_single_value_defined, -) +from faebryk.libs.library import L from faebryk.libs.units import Quantity class Constant[PV](Parameter[PV], Parameter[PV].SupportsSetOps): type LIT_OR_PARAM = Parameter[PV].LIT_OR_PARAM + @L.rt_field + def representable_by_single_value(self): + return F.is_representable_by_single_value_defined(self.value) + def __init__(self, value: LIT_OR_PARAM) -> None: super().__init__() self.value = value - self.add_trait(is_representable_by_single_value_defined(self.value)) def _pretty_val(self): val = repr(self.value) diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index ce4a9a46..8a1963bc 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -1,52 +1,37 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.Range import Range -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import Quantity -from faebryk.libs.util import times class Crystal(Module): - def __init__(self): - super().__init__() - - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - class _PARAMs(Module.PARAMS()): - frequency = TBD[Quantity]() - frequency_tolerance = TBD[Range]() - frequency_temperature_tolerance = TBD[Range]() - frequency_ageing = TBD[Range]() - equivalent_series_resistance = TBD[Quantity]() - shunt_capacitance = TBD[Quantity]() - load_impedance = TBD[Quantity]() - - self.PARAMs = _PARAMs(self) - - class _IFs(Module.IFS()): - gnd = Electrical() - unnamed = L.if_list(2, Electrical) - - self.IFs = _IFs(self) - - # ---------------------------------------- - # parameters - # ---------------------------------------- - - # ---------------------------------------- - # traits - # ---------------------------------------- - self.add_trait(has_designator_prefix_defined("XTAL")) - - # ---------------------------------------- - # aliases - # ---------------------------------------- - - # ---------------------------------------- - # connections - # ---------------------------------------- + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + + frequency: F.TBD[Quantity] + frequency_tolerance: F.TBD[F.Range] + frequency_temperature_tolerance: F.TBD[F.Range] + frequency_ageing: F.TBD[F.Range] + equivalent_series_resistance: F.TBD[Quantity] + shunt_capacitance: F.TBD[Quantity] + load_impedance: F.TBD[Quantity] + + gnd: F.Electrical + unnamed = L.if_list(2, F.Electrical) + + # ---------------------------------------- + # parameters + # ---------------------------------------- + + # ---------------------------------------- + # traits + # ---------------------------------------- + designator = L.f_field(F.has_designator_prefix_defined)("XTAL") + + # ---------------------------------------- + # connections + # ---------------------------------------- diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 9aca6d29..53954d25 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -2,53 +2,44 @@ # SPDX-License-Identifier: MIT +from copy import copy + +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.Capacitor import Capacitor -from faebryk.library.Constant import Constant -from faebryk.library.Crystal import Crystal -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.Range import Range +from faebryk.libs.library import L from faebryk.libs.units import P -from faebryk.libs.util import times class Crystal_Oscillator(Module): - def __init__(self): - super().__init__() - - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - class _NODEs(Module.NODES()): - crystal = Crystal() - capacitors = L.if_list(2, Capacitor) - - self.NODEs = _NODEs(self) - - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - class _IFs(Module.IFS()): - power = ElectricPower() - p = Electrical() - n = Electrical() - - self.IFs = _IFs(self) - - # ---------------------------------------- - # parameters - # ---------------------------------------- - # https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ - STRAY_CAPACITANCE = Range(1 * P.nF, 5 * P.nF) - load_capacitance = self.NODEs.crystal.PARAMs.load_impedance - capacitance = Constant(2 * P.dimesionless) * ( - load_capacitance - STRAY_CAPACITANCE + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + crystal: F.Crystal + capacitors = L.if_list(2, F.Capacitor) + + power: F.ElectricPower + p: F.Electrical + n: F.Electrical + + # ---------------------------------------- + # parameters + # ---------------------------------------- + # https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ + _STRAY_CAPACITANCE = F.Range(1 * P.nF, 5 * P.nF) + + @L.rt_field + def load_capacitance(self): + return self.crystal.load_impedance + + @L.rt_field + def capacitance(self): + return F.Constant(2 * P.dimesionless) * ( + self.load_capacitance - copy(self._STRAY_CAPACITANCE) ) - for cap in self.NODEs.capacitors: - cap.PARAMs.capacitance.merge(capacitance) + def __preinit__(self): + for cap in self.capacitors: + cap.capacitance.merge(self.capacitance) # ---------------------------------------- # traits @@ -57,14 +48,14 @@ class _IFs(Module.IFS()): # ---------------------------------------- # aliases # ---------------------------------------- - gnd = self.IFs.power.IFs.lv + gnd = self.power.lv # ---------------------------------------- # connections # ---------------------------------------- - self.NODEs.crystal.IFs.gnd.connect(gnd) - self.NODEs.crystal.IFs.unnamed[0].connect_via(self.NODEs.capacitors[0], gnd) - self.NODEs.crystal.IFs.unnamed[1].connect_via(self.NODEs.capacitors[1], gnd) + self.crystal.gnd.connect(gnd) + self.crystal.unnamed[0].connect_via(self.capacitors[0], gnd) + self.crystal.unnamed[1].connect_via(self.capacitors[1], gnd) - self.NODEs.crystal.IFs.unnamed[0].connect(self.IFs.n) - self.NODEs.crystal.IFs.unnamed[1].connect(self.IFs.p) + self.crystal.unnamed[0].connect(self.n) + self.crystal.unnamed[1].connect(self.p) diff --git a/src/faebryk/library/DIP.py b/src/faebryk/library/DIP.py index 58f20b9c..0fb97f9d 100644 --- a/src/faebryk/library/DIP.py +++ b/src/faebryk/library/DIP.py @@ -1,35 +1,35 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -from faebryk.library.Footprint import Footprint -from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -from faebryk.library.Pad import Pad + +import faebryk.library._F as F +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity -from faebryk.libs.util import times -class DIP(Footprint): +class DIP(F.Footprint): + pins = L.if_list(0, F.Pad) + def __init__(self, pin_cnt: int, spacing: Quantity, long_pads: bool) -> None: super().__init__() - class _IFs(Footprint.IFS()): - pins = L.if_list(pin_cnt, Pad) + self.add_to_container(pin_cnt, F.Pad, self.pins) - self.IFs = _IFs(self) - from faebryk.library.has_kicad_footprint_equal_ifs import ( - has_kicad_footprint_equal_ifs, - ) + self.spacing = spacing + self.long_pads = long_pads - class _has_kicad_footprint(has_kicad_footprint_equal_ifs): + @L.rt_field + def kicad_footprint(self): + class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): @staticmethod def get_kicad_footprint() -> str: return "Package_DIP:DIP-{leads}_W{spacing:.2f}mm{longpads}".format( - leads=pin_cnt, - spacing=spacing.to(P.mm).m, - longpads="_LongPads" if long_pads else "", + leads=len(self.pins), + spacing=self.spacing.to(P.mm).m, + longpads="_LongPads" if self.long_pads else "", ) - self.add_trait(_has_kicad_footprint()) - self.add_trait(has_equal_pins_in_ifs()) - self.add_trait(can_attach_via_pinmap_equal()) + return _has_kicad_footprint + + equal_pins_in_ifs: F.has_equal_pins_in_ifs + attach_via_pinmap: F.can_attach_via_pinmap_equal diff --git a/src/faebryk/library/DifferentialPair.py b/src/faebryk/library/DifferentialPair.py index b15a5103..82ccdb03 100644 --- a/src/faebryk/library/DifferentialPair.py +++ b/src/faebryk/library/DifferentialPair.py @@ -1,16 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Electrical import Electrical class DifferentialPair(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - - class NODES(ModuleInterface.NODES()): - p = Electrical() - n = Electrical() - - self.IFs = NODES(self) + p: F.Electrical + n: F.Electrical diff --git a/src/faebryk/library/Diode.py b/src/faebryk/library/Diode.py index b8650d65..bcb74d77 100644 --- a/src/faebryk/library/Diode.py +++ b/src/faebryk/library/Diode.py @@ -1,65 +1,49 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.parameter import Parameter from faebryk.core.util import as_unit -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_pin_association_heuristic_lookup_table import ( - has_pin_association_heuristic_lookup_table, -) -from faebryk.library.has_simple_value_representation_based_on_param import ( - has_simple_value_representation_based_on_param, -) -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import Quantity class Diode(Module): - @classmethod - def PARAMS(cls): - class _PARAMs(super().PARAMS()): - forward_voltage = TBD[Quantity]() - max_current = TBD[Quantity]() - current = TBD[Quantity]() - reverse_working_voltage = TBD[Quantity]() - reverse_leakage_current = TBD[Quantity]() - - return _PARAMs - - def __init__(self): - super().__init__() - - self.PARAMs = self.PARAMS()(self) - - class _IFs(super().IFS()): - anode = Electrical() - cathode = Electrical() - - self.IFs = _IFs(self) - - self.add_trait(can_bridge_defined(self.IFs.anode, self.IFs.cathode)) - self.add_trait( - has_simple_value_representation_based_on_param( - self.PARAMs.forward_voltage, - lambda p: as_unit(p, "V"), - ) + forward_voltage: F.TBD[Quantity] + max_current: F.TBD[Quantity] + current: F.TBD[Quantity] + reverse_working_voltage: F.TBD[Quantity] + reverse_leakage_current: F.TBD[Quantity] + + anode: F.Electrical + cathode: F.Electrical + + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.anode, self.cathode) + + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_param( + self.forward_voltage, + lambda p: as_unit(p, "V"), ) - self.add_trait(has_designator_prefix_defined("D")) - self.add_trait( - has_pin_association_heuristic_lookup_table( - mapping={ - self.IFs.anode: ["A", "Anode", "+"], - self.IFs.cathode: ["K", "C", "Cathode", "-"], - }, - accept_prefix=False, - case_sensitive=False, - ) + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("D") + + @L.rt_field + def pin_association_heuristic(self): + return F.has_pin_association_heuristic_lookup_table( + mapping={ + self.anode: ["A", "Anode", "+"], + self.cathode: ["K", "C", "Cathode", "-"], + }, + accept_prefix=False, + case_sensitive=False, ) def get_needed_series_resistance_for_current_limit( self, input_voltage_V: Parameter[Quantity] ) -> Parameter[Quantity]: - return (input_voltage_V - self.PARAMs.forward_voltage) / self.PARAMs.current + return (input_voltage_V - self.forward_voltage) / self.current diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index d7a75d23..534935fc 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -1,18 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.I2C import I2C -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import Quantity -from faebryk.libs.util import times class EEPROM(Module): @@ -24,42 +16,37 @@ def set_address(self, addr: int): """ Configure the address of the EEPROM by setting the address pins. """ - assert addr < (1 << len(self.IFs.address)) + assert addr < (1 << len(self.address)) - for i, e in enumerate(self.IFs.address): + for i, e in enumerate(self.address): e.set(addr & (1 << i) != 0) - def __init__(self): - super().__init__() + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - class _PARAMs(Module.PARAMS()): - memory_size = TBD[Quantity]() + memory_size: F.TBD[Quantity] - self.PARAMs = _PARAMs(self) + power: F.ElectricPower + i2c = F.I2C() + write_protect: F.ElectricLogic + address = L.if_list(3, F.ElectricLogic) - class _IFs(Module.IFS()): - power = ElectricPower() - i2c = I2C() - write_protect = ElectricLogic() - address = L.if_list(3, ElectricLogic) + # ---------------------------------------- + # traits + # ---------------------------------------- - self.IFs = _IFs(self) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - # ---------------------------------------- - # traits - # ---------------------------------------- - self.add_trait(has_designator_prefix_defined("U")) - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) + def __preinit__(self): # ---------------------------------------- # connections # ---------------------------------------- - self.IFs.power.get_trait(can_be_decoupled).decouple() - self.IFs.i2c.terminate() + self.power.decoupled.decouple() + self.i2c.terminate() diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index 05fbce3d..b7d7cba3 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -6,22 +6,14 @@ from dataclasses import dataclass from faebryk.core.module import Module, ModuleInterface -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_defined_footprint import has_defined_footprint -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation_defined import ( - has_simple_value_representation_defined, -) -from faebryk.library.I2C import I2C -from faebryk.library.JTAG import JTAG -from faebryk.library.QFN import QFN -from faebryk.library.UART_Base import UART_Base + + + + + + from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) @@ -31,129 +23,113 @@ class _ESP_ADC(ModuleInterface): def __init__(self, channel_count: int) -> None: super().__init__() - class IFS(ModuleInterface.IFS()): - CHANNELS = L.if_list(channel_count, Electrical) - self.IFs = IFS(self) + CHANNELS = L.if_list(channel_count, F.Electrical) class _ESP_SDIO(ModuleInterface): - def __init__(self): - super().__init__() - class IFS(ModuleInterface.IFS()): - DATA = L.if_list(4, Electrical) - CLK = Electrical() - CMD = Electrical() - GND = Electrical() - self.IFs = IFS(self) + DATA = L.if_list(4, F.Electrical) + CLK: F.Electrical + CMD: F.Electrical + GND: F.Electrical class _ESP32_EMAC(ModuleInterface): - def __init__(self): - super().__init__() - class IFS(ModuleInterface.IFS()): - TXD = L.if_list(4, Electrical) - RXD = L.if_list(4, Electrical) - TX_CLK = Electrical() - RX_CLK = Electrical() - TX_EN = Electrical() - RX_ER = Electrical() - RX_DV = Electrical() - CLK_OUT = Electrical() - CLK_OUT_180 = Electrical() - TX_ER = Electrical() - MDC_out = Electrical() - MDI_in = Electrical() - MDO_out = Electrical() - CRS_out = Electrical() - COL_out = Electrical() - - self.IFs = IFS(self) + + TXD = L.if_list(4, F.Electrical) + RXD = L.if_list(4, F.Electrical) + TX_CLK: F.Electrical + RX_CLK: F.Electrical + TX_EN: F.Electrical + RX_ER: F.Electrical + RX_DV: F.Electrical + CLK_OUT: F.Electrical + CLK_OUT_180: F.Electrical + TX_ER: F.Electrical + MDC_out: F.Electrical + MDI_in: F.Electrical + MDO_out: F.Electrical + CRS_out: F.Electrical + COL_out: F.Electrical class _ESP32_SPI(ModuleInterface): - def __init__(self): - super().__init__() - class IFS(ModuleInterface.IFS()): - D = Electrical() - Q = Electrical() - WP = Electrical() - HD = Electrical() - CS = Electrical() + D: F.Electrical + Q: F.Electrical + WP: F.Electrical + HD: F.Electrical - CLK = Electrical() - GND = Electrical() + CS: F.Electrical - self.IFs = IFS(self) + CLK: F.Electrical + GND: F.Electrical class ESP32(Module): - def __init__(self): - super().__init__() self.add_trait(has_simple_value_representation_defined("ESP32")) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + - class IFS(Module.IFS()): # Analog - VDDA0 = Electrical() - LNA_IN = Electrical() - VDD3P30 = Electrical() - VDD3P31 = Electrical() - SENSOR_VP = Electrical() + VDDA0: F.Electrical + LNA_IN: F.Electrical + VDD3P30: F.Electrical + VDD3P31: F.Electrical + SENSOR_VP: F.Electrical # VDD3P3_RTC - SENSOR_CAPP = Electrical() - SENSOR_CAPN = Electrical() - SENSOR_VN = Electrical() - CHIP_PU = Electrical() - VDET_1 = Electrical() - VDET_2 = Electrical() - _32K_XP = Electrical() - _32K_XN = Electrical() - GPIO25 = Electrical() - GPIO26 = Electrical() - GPIO27 = Electrical() - MTMS = Electrical() - MTDI = Electrical() - VDD3P3_RTC = Electrical() - MTCK = Electrical() - MTDO = Electrical() - GPIO2 = Electrical() - GPIO0 = Electrical() - GPIO4 = Electrical() + SENSOR_CAPP: F.Electrical + SENSOR_CAPN: F.Electrical + SENSOR_VN: F.Electrical + CHIP_PU: F.Electrical + VDET_1: F.Electrical + VDET_2: F.Electrical + _32K_XP: F.Electrical + _32K_XN: F.Electrical + GPIO25: F.Electrical + GPIO26: F.Electrical + GPIO27: F.Electrical + MTMS: F.Electrical + MTDI: F.Electrical + VDD3P3_RTC: F.Electrical + MTCK: F.Electrical + MTDO: F.Electrical + GPIO2: F.Electrical + GPIO0: F.Electrical + GPIO4: F.Electrical # VDD_SDIO - GPIO16 = Electrical() - VDD_SDIO = Electrical() - GPIO17 = Electrical() - SD_DATA_2 = Electrical() - SD_DATA_3 = Electrical() - SD_CMD = Electrical() - SD_CLK = Electrical() - SD_DATA_0 = Electrical() - SD_DATA_1 = Electrical() + GPIO16: F.Electrical + VDD_SDIO: F.Electrical + GPIO17: F.Electrical + SD_DATA_2: F.Electrical + SD_DATA_3: F.Electrical + SD_CMD: F.Electrical + SD_CLK: F.Electrical + SD_DATA_0: F.Electrical + SD_DATA_1: F.Electrical # VDD3P3_CPU - GPIO5 = Electrical() - GPIO18 = Electrical() - GPIO23 = Electrical() - VDD3P3_CPU = Electrical() - GPIO19 = Electrical() - GPIO22 = Electrical() - U0RXD = Electrical() - U0TXD = Electrical() - GPIO21 = Electrical() + GPIO5: F.Electrical + GPIO18: F.Electrical + GPIO23: F.Electrical + VDD3P3_CPU: F.Electrical + GPIO19: F.Electrical + GPIO22: F.Electrical + U0RXD: F.Electrical + U0TXD: F.Electrical + GPIO21: F.Electrical # Analog - VDDA1 = Electrical() - XTAL_N = Electrical() - XTAL_P = Electrical() - VDDA2 = Electrical() - CAP2 = Electrical() - CAP1 = Electrical() - GND = Electrical() + VDDA1: F.Electrical + XTAL_N: F.Electrical + XTAL_P: F.Electrical + VDDA2: F.Electrical + CAP2: F.Electrical + CAP1: F.Electrical + GND: F.Electrical # High Level Functions I2C = L.if_list(2, I2C) @@ -161,9 +137,9 @@ class IFS(Module.IFS()): SDIO_HOST = L.if_list(2, _ESP_SDIO) UART = UART_Base() JTAG = JTAG() - TOUCH = L.if_list(10, Electrical) - GPIO = L.if_list(40 - 6, Electrical) - RTC_GPIO = L.if_list(18, Electrical) + TOUCH = L.if_list(10, F.Electrical) + GPIO = L.if_list(40 - 6, F.Electrical) + RTC_GPIO = L.if_list(18, F.Electrical) ADC = [ None, _ESP_ADC(channel_count=8), @@ -173,14 +149,12 @@ class IFS(Module.IFS()): EMAC = _ESP32_EMAC() # Power - POWER_RTC = ElectricPower() - POWER_CPU = ElectricPower() - POWER_SDIO = ElectricPower() - POWER_ANALOG = ElectricPower() + POWER_RTC: F.ElectricPower + POWER_CPU: F.ElectricPower + POWER_SDIO: F.ElectricPower + POWER_ANALOG: F.ElectricPower - self.IFs = IFS(self) - - x = self.IFs + x = self self.pinmap = { # Analog "1": x.VDDA0, @@ -240,23 +214,23 @@ class IFS(Module.IFS()): self.add_trait(can_attach_to_footprint_via_pinmap(self.pinmap)) # SPI0 is connected to SPI1 (Arbiter) - x.SPI[0].IFs.Q.connect(x.SPI[1].IFs.Q) - x.SPI[0].IFs.D.connect(x.SPI[1].IFs.D) - x.SPI[0].IFs.HD.connect(x.SPI[1].IFs.HD) - x.SPI[0].IFs.WP.connect(x.SPI[1].IFs.WP) - x.SPI[0].IFs.CLK.connect(x.SPI[1].IFs.CLK) - x.SPI[0].IFs.CS.connect(x.SPI[1].NODES.CS) - - x.POWER_RTC.IFs.hv.connect(x.VDD3P3_RTC) - x.POWER_RTC.IFs.lv.connect(x.GND) - x.POWER_CPU.IFs.hv.connect(x.VDD3P3_CPU) - x.POWER_CPU.IFs.lv.connect(x.GND) - x.POWER_SDIO.IFs.hv.connect(x.VDD_SDIO) - x.POWER_SDIO.IFs.lv.connect(x.GND) - x.POWER_ANALOG.IFs.hv.connect(x.VDDA0) - x.POWER_ANALOG.IFs.hv.connect(x.VDDA1) - x.POWER_ANALOG.IFs.hv.connect(x.VDDA2) - x.POWER_ANALOG.IFs.lv.connect(x.GND) + x.SPI[0].Q.connect(x.SPI[1].Q) + x.SPI[0].D.connect(x.SPI[1].D) + x.SPI[0].HD.connect(x.SPI[1].HD) + x.SPI[0].WP.connect(x.SPI[1].WP) + x.SPI[0].CLK.connect(x.SPI[1].CLK) + x.SPI[0].CS.connect(x.SPI[1].NODES.CS) + + x.POWER_RTC.hv.connect(x.VDD3P3_RTC) + x.POWER_RTC.lv.connect(x.GND) + x.POWER_CPU.hv.connect(x.VDD3P3_CPU) + x.POWER_CPU.lv.connect(x.GND) + x.POWER_SDIO.hv.connect(x.VDD_SDIO) + x.POWER_SDIO.lv.connect(x.GND) + x.POWER_ANALOG.hv.connect(x.VDDA0) + x.POWER_ANALOG.hv.connect(x.VDDA1) + x.POWER_ANALOG.hv.connect(x.VDDA2) + x.POWER_ANALOG.lv.connect(x.GND) self.pinmux = _ESP32_Pinmux(self) @@ -264,12 +238,10 @@ def get_gpio(self, idx: int): filtered = [20, 24, 28, 29, 30, 31] # count of elements in filtered that are smaller than idx: offset = len([x for x in filtered if x < idx]) - return self.IFs.GPIO[idx - offset] + return self.GPIO[idx - offset] class _ESP32_D0WD(ESP32): - def __init__(self): - super().__init__() self.add_trait( has_defined_footprint( @@ -297,7 +269,7 @@ class _ESP32_D0WDR2_V3(_ESP32_D0WD): @dataclass(frozen=True) class _Function: - interface: Electrical + interface: F.Electrical name: str type: "typing.Any" @@ -319,26 +291,24 @@ class _Pad: class _Mux(Module): - def __init__(self, input: Electrical, *outputs: Electrical) -> None: + def __init__(self, input: F.Electrical, *outputs: F.Electrical) -> None: super().__init__() - class _IFS(Module.IFS()): - IN = Electrical() - OUT = L.if_list(len(outputs), Electrical) - self.IFs = _IFS(self) + IN: F.Electrical + OUT = L.if_list(len(outputs), F.Electrical) - input.connect(self.IFs.IN) - self.map = dict(zip(outputs, self.IFs.OUT)) + input.connect(self.IN) + self.map = dict(zip(outputs, self.OUT)) for o1, o2 in self.map.items(): o1.connect(o2) - def select(self, output: Electrical): - self.IFs.IN.connect(self.map[output]) + def select(self, output: F.Electrical): + self.IN.connect(self.map[output]) def _matrix(esp32: ESP32): - x = esp32.IFs + x = esp32 # fmt: off return [ @@ -371,12 +341,12 @@ def _matrix(esp32: ESP32): 1 : _Function(x.ADC[2].CHANNELS[5], "ADC2_CH5", None), # noqa: E501 2 : _Function(x.TOUCH[5], "TOUCH5", None), # noqa: E501 3 : _Function(x.RTC_GPIO[15], "RTC_GPIO15", None), # noqa: E501 - 5 : _Function(x.JTAG.IFs.tdi.IFs.signal, "MTDI", "I1"), # noqa: E501 - 6 : _Function(x.SPI[2].IFs.Q, "HSPIQ", "I/O/T"), # noqa: E501 + 5 : _Function(x.JTAG.tdi.signal, "MTDI", "I1"), # noqa: E501 + 6 : _Function(x.SPI[2].Q, "HSPIQ", "I/O/T"), # noqa: E501 7 : _Function(esp32.get_gpio(12), "GPIO12", "I/O/T"), # noqa: E501 - 8 : _Function(x.SDIO_HOST[1].IFs.DATA[2], "HS2_DATA2", "I1/O/T"), # noqa: E501 - 9 : _Function(x.SDIO_SLAVE.IFs.DATA[2], "SD_DATA2", "I1/O/T"), # noqa: E501 - 10: _Function(x.EMAC.IFs.TXD[3], "EMAC_TXD3", "O") # noqa: E501 + 8 : _Function(x.SDIO_HOST[1].DATA[2], "HS2_DATA2", "I1/O/T"), # noqa: E501 + 9 : _Function(x.SDIO_SLAVE.DATA[2], "SD_DATA2", "I1/O/T"), # noqa: E501 + 10: _Function(x.EMAC.TXD[3], "EMAC_TXD3", "O") # noqa: E501 }), # noqa: E501 ] # fmt: on @@ -387,7 +357,7 @@ def __init__(self, esp32: ESP32) -> None: default_function = 5 self.matrix = _matrix(esp32) - class _NODES(ModuleInterface.NODES()): + MUXES = [ _Mux( esp32.pinmap[str(pad.interface)], @@ -396,8 +366,6 @@ class _NODES(ModuleInterface.NODES()): for pad in self.matrix ] - self.NODEs = _NODES(self) - for pad in self.matrix: if len(pad.functions.items()) == 0: continue @@ -412,7 +380,7 @@ def _mux(self, function: _Function, pad: _Pad): # assert (pad.current_function == None), "Already set" pad.current_function = function - self.NODEs.MUXES[self.matrix.index(pad)].select(function.interface) + self.MUXES[self.matrix.index(pad)].select(function.interface) def mux(self, internal: ModuleInterface, pad: ModuleInterface): # Check if combination legal diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 37ef6871..75215d47 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -5,18 +5,10 @@ from faebryk.core.module import Module from faebryk.core.util import connect_to_all_interfaces -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.I2C import I2C -from faebryk.library.Range import Range -from faebryk.library.UART_Base import UART_Base -from faebryk.library.USB2_0 import USB2_0 + + from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) @@ -24,93 +16,88 @@ class ESP32_C3(Module): """ESP32-C3""" - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - vdd3p3_cpu = ElectricPower() - vdd3p3_rtc = ElectricPower() - vdd_spi = ElectricPower() - vdd3p3 = ElectricPower() - vdda = ElectricPower() - lna_in = Electrical() - enable = ElectricLogic() - xtal_p = Electrical() - xtal_n = Electrical() - gpio = L.if_list(22, ElectricLogic) + + + vdd3p3_cpu: F.ElectricPower + vdd3p3_rtc: F.ElectricPower + vdd_spi: F.ElectricPower + vdd3p3: F.ElectricPower + vdda: F.ElectricPower + lna_in: F.Electrical + enable: F.ElectricLogic + xtal_p: F.Electrical + xtal_n: F.Electrical + gpio = L.if_list(22, F.ElectricLogic) # TODO: map peripherals to GPIOs with pinmux usb = USB2_0() i2c = I2C() uart = L.if_list(2, UART_Base) # ... etc - self.IFs = _IFs(self) - - x = self.IFs + x = self # https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#uart for ser in x.uart: - ser.PARAMs.baud.merge(Range(0, 5000000)) + ser.baud.merge(F.Range(0, 5000000)) # connect all logic references # TODO: set correctly for each power domain - # ref = ElectricLogic.connect_all_module_references(self) + # ref = F.ElectricLogic.connect_all_module_references(self) # self.add_trait(has_single_electric_reference_defined(ref)) # set power domain constraints to recommended operating conditions - for power_domain in [self.IFs.vdd3p3_rtc, self.IFs.vdd3p3, self.IFs.vdda]: - power_domain.PARAMs.voltage.merge(Range.from_center(3.3 * P.V, 0.3 * P.V)) - self.IFs.vdd3p3_cpu.PARAMs.voltage.merge( - Range(3.0 * P.V, 3.6 * P.V) + for power_domain in [self.vdd3p3_rtc, self.vdd3p3, self.vdda]: + power_domain.voltage.merge(F.Range.from_center(3.3 * P.V, 0.3 * P.V)) + self.vdd3p3_cpu.voltage.merge( + F.Range(3.0 * P.V, 3.6 * P.V) ) # TODO: max 3.3V when writing eFuses - self.IFs.vdd_spi.PARAMs.voltage.merge( - Range.from_center(3.3 * P.V, 0.3 * P.V) + self.vdd_spi.voltage.merge( + F.Range.from_center(3.3 * P.V, 0.3 * P.V) ) # TODO: when configured as input # connect all grounds to eachother and power connect_to_all_interfaces( - self.IFs.vdd3p3.IFs.lv, + self.vdd3p3.lv, [ - self.IFs.vdd3p3_cpu.IFs.lv, - self.IFs.vdd3p3_rtc.IFs.lv, - self.IFs.vdda.IFs.lv, - self.IFs.vdd_spi.IFs.lv, + self.vdd3p3_cpu.lv, + self.vdd3p3_rtc.lv, + self.vdda.lv, + self.vdd_spi.lv, ], ) # connect decoupling caps to power domains - self.IFs.vdd3p3.get_trait(can_be_decoupled).decouple() - self.IFs.vdd3p3_cpu.get_trait(can_be_decoupled).decouple() - self.IFs.vdd3p3_rtc.get_trait(can_be_decoupled).decouple() - self.IFs.vdda.get_trait(can_be_decoupled).decouple() - self.IFs.vdd_spi.get_trait(can_be_decoupled).decouple() + self.vdd3p3.get_trait(can_be_decoupled).decouple() + self.vdd3p3_cpu.get_trait(can_be_decoupled).decouple() + self.vdd3p3_rtc.get_trait(can_be_decoupled).decouple() + self.vdda.get_trait(can_be_decoupled).decouple() + self.vdd_spi.get_trait(can_be_decoupled).decouple() # rc delay circuit on enable pin for startup delay # https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf page 24 # noqa E501 # TODO: add lowpass filter - # self.IFs.enable.IFs.signal.connect_via( - # self.NODEs.en_rc_capacitor, self.IFs.pwr3v3.IFs.lv + # self.enable.signal.connect_via( + # self.en_rc_capacitor, self.pwr3v3.lv # ) - self.IFs.enable.get_trait(ElectricLogic.can_be_pulled).pull( + self.enable.get_trait(F.ElectricLogic.can_be_pulled).pull( up=True ) # TODO: combine with lowpass filter # set default boot mode to "SPI Boot mode" (gpio = N.C. or HIGH) # https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf page 25 # noqa E501 # TODO: make configurable - self.IFs.gpio[8].get_trait(ElectricLogic.can_be_pulled).pull( + self.gpio[8].get_trait(F.ElectricLogic.can_be_pulled).pull( up=True ) # boot_resistors[0] - self.IFs.gpio[2].get_trait(ElectricLogic.can_be_pulled).pull( + self.gpio[2].get_trait(F.ElectricLogic.can_be_pulled).pull( up=True ) # boot_resistors[1] # TODO: gpio[9] has an internal pull-up at boot = SPI-Boot - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( has_datasheet_defined( @@ -121,15 +108,15 @@ class _IFs(Module.IFS()): # TODO: Fix this # # set mux states # # UART 1 - # self.set_mux(x.gpio[20], self.IFs.serial[1].IFs.rx) - # self.set_mux(x.gpio[21], self.IFs.serial[1].IFs.tx) + # self.set_mux(x.gpio[20], self.serial[1].rx) + # self.set_mux(x.gpio[21], self.serial[1].tx) # # UART 0 - # self.set_mux(x.gpio[0], self.IFs.serial[0].IFs.rx) - # self.set_mux(x.gpio[1], self.IFs.serial[0].IFs.tx) + # self.set_mux(x.gpio[0], self.serial[0].rx) + # self.set_mux(x.gpio[1], self.serial[0].tx) # # I2C - # self.set_mux(x.gpio[4], self.IFs.i2c.IFs.scl) - # self.set_mux(x.gpio[5], self.IFs.i2c.IFs.sda) + # self.set_mux(x.gpio[4], self.i2c.scl) + # self.set_mux(x.gpio[5], self.i2c.sda) # class _uart_esphome_config(has_esphome_config.impl()): # def get_config(self_) -> dict: @@ -140,18 +127,18 @@ class _IFs(Module.IFS()): # "uart": [ # { # "id": obj.get_trait(is_esphome_bus).get_bus_id(), - # "baud_rate": get_parameter_max(obj.PARAMs.baud), + # "baud_rate": get_parameter_max(obj.baud), # } # ] # } # try: - # config["uart"][0]["rx_pin"] = self.get_mux_pin(obj.IFs.rx)[1] + # config["uart"][0]["rx_pin"] = self.get_mux_pin(obj.rx)[1] # except IndexError: # ... # try: - # config["uart"][0]["tx_pin"] = self.get_mux_pin(obj.IFs.tx)[1] + # config["uart"][0]["tx_pin"] = self.get_mux_pin(obj.tx)[1] # except IndexError: # ... @@ -168,8 +155,8 @@ class _IFs(Module.IFS()): # assert isinstance(obj, I2C) # try: - # sda = self.get_mux_pin(obj.IFs.sda)[1] - # scl = self.get_mux_pin(obj.IFs.scl)[1] + # sda = self.get_mux_pin(obj.sda)[1] + # scl = self.get_mux_pin(obj.scl)[1] # except IndexError: # # Not in use if pinmux is not set # return {} @@ -178,7 +165,7 @@ class _IFs(Module.IFS()): # "i2c": [ # { # "id": obj.get_trait(is_esphome_bus).get_bus_id(), - # "frequency": int(get_parameter_max(obj.PARAMs.frequency)), # noqa: E501 + # "frequency": int(get_parameter_max(obj.frequency)), # noqa: E501 # "sda": sda, # "scl": scl, # } @@ -187,18 +174,18 @@ class _IFs(Module.IFS()): # return config - # for serial in self.IFs.serial: + # for serial in self.serial: # serial.add_trait( - # is_esphome_bus_defined(f"uart_{self.IFs.serial.index(serial)}") + # is_esphome_bus_defined(f"uart_{self.serial.index(serial)}") # ) # serial.add_trait(_uart_esphome_config()) - # for i, gpio in enumerate(self.IFs.gpio): + # for i, gpio in enumerate(self.gpio): # gpio.add_trait(is_esphome_bus_defined(f"GPIO{i}")) - # self.IFs.i2c.add_trait(is_esphome_bus_defined("i2c_0")) - # self.IFs.i2c.add_trait(_i2c_esphome_config()) - # self.IFs.i2c.PARAMs.frequency.merge( + # self.i2c.add_trait(is_esphome_bus_defined("i2c_0")) + # self.i2c.add_trait(_i2c_esphome_config()) + # self.i2c.frequency.merge( # Set( # [ # I2C.define_max_frequency_capability(speed) @@ -208,7 +195,7 @@ class _IFs(Module.IFS()): # ] # ] # + [ - # Range(10 * P.khertz, 800 * P.khertz) + # F.Range(10 * P.khertz, 800 * P.khertz) # ], # TODO: should be range 200k-800k, but breaks parameter merge # ) # ) @@ -229,16 +216,16 @@ class _IFs(Module.IFS()): # ) # very simple mux that uses pinmap - # def set_mux(self, gpio: ElectricLogic, target: ElectricLogic): + # def set_mux(self, gpio: F.ElectricLogic, target: F.ElectricLogic): # """Careful not checked""" # pin, _ = self.get_mux_pin(gpio) - # self.pinmap[pin] = target.IFs.signal + # self.pinmap[pin] = target.signal - # def get_mux_pin(self, target: ElectricLogic) -> tuple[str, int]: + # def get_mux_pin(self, target: F.ElectricLogic) -> tuple[str, int]: # """Returns pin & gpio number""" - # pin = [k for k, v in self.pinmap.items() if v == target.IFs.signal][0] + # pin = [k for k, v in self.pinmap.items() if v == target.signal][0] # gpio = self.pinmap_default[pin] # gpio_index = [ - # i for i, g in enumerate(self.IFs.gpio) if g.IFs.signal == gpio + # i for i, g in enumerate(self.gpio) if g.signal == gpio # ][0] # return pin, gpio_index diff --git a/src/faebryk/library/ESP32_C3_MINI_1.py b/src/faebryk/library/ESP32_C3_MINI_1.py index 380f1c1b..554e4d79 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1.py +++ b/src/faebryk/library/ESP32_C3_MINI_1.py @@ -4,21 +4,12 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.ESP32_C3 import ESP32_C3 -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.UART_Base import UART_Base -from faebryk.libs.util import times + + + + + + logger = logging.getLogger(__name__) @@ -26,72 +17,67 @@ class ESP32_C3_MINI_1(Module): """ESP32-C3-MINI-1 module""" - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): + + esp32_c3 = ESP32_C3() # TODO: add components as described in the datasheet - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - rf_output = Electrical() - chip_enable = ElectricLogic() + rf_output: F.Electrical + chip_enable: F.ElectricLogic gpio = L.if_list( - 22, ElectricLogic + 22, F.ElectricLogic ) # TODO: Only GPIO 0 to 10 and 18, 19 are exposed uart = UART_Base() - vdd3v3 = ElectricPower() - - self.IFs = _IFs(self) + vdd3v3: F.ElectricPower # TODO: connect all components (nodes) # connect all logic references - ref = ElectricLogic.connect_all_module_references(self) + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) # connect power decoupling caps - self.IFs.vdd3v3.get_trait(can_be_decoupled).decouple() + self.vdd3v3.get_trait(can_be_decoupled).decouple() - for i, gpio in enumerate(self.IFs.gpio): - gpio.connect(self.NODEs.esp32_c3.IFs.gpio[i]) + for i, gpio in enumerate(self.gpio): + gpio.connect(self.esp32_c3.gpio[i]) - gnd = self.IFs.vdd3v3.IFs.lv + gnd = self.vdd3v3.lv self.pinmap_default = { "1": gnd, "2": gnd, - "3": self.IFs.vdd3v3.IFs.hv, + "3": self.vdd3v3.hv, # 4 is not connected - "5": self.IFs.gpio[2].IFs.signal, - "6": self.IFs.gpio[3].IFs.signal, + "5": self.gpio[2].signal, + "6": self.gpio[3].signal, # 7 is not connected - "8": self.IFs.chip_enable.IFs.signal, + "8": self.chip_enable.signal, # 9 is not connected # 10 is not connected "11": gnd, - "12": self.IFs.gpio[0].IFs.signal, - "13": self.IFs.gpio[1].IFs.signal, + "12": self.gpio[0].signal, + "13": self.gpio[1].signal, "14": gnd, # 15 is not connected - "16": self.IFs.gpio[10].IFs.signal, + "16": self.gpio[10].signal, # 17 is not connected - "18": self.IFs.gpio[4].IFs.signal, - "19": self.IFs.gpio[5].IFs.signal, - "20": self.IFs.gpio[6].IFs.signal, - "21": self.IFs.gpio[7].IFs.signal, - "22": self.IFs.gpio[8].IFs.signal, - "23": self.IFs.gpio[9].IFs.signal, + "18": self.gpio[4].signal, + "19": self.gpio[5].signal, + "20": self.gpio[6].signal, + "21": self.gpio[7].signal, + "22": self.gpio[8].signal, + "23": self.gpio[9].signal, # 24 is not connected # 25 is not connected - "26": self.IFs.gpio[18].IFs.signal, - "27": self.IFs.gpio[19].IFs.signal, + "26": self.gpio[18].signal, + "27": self.gpio[19].signal, # 28 is not connected # 29 is not connected - "30": self.IFs.uart.IFs.rx.IFs.signal, - "31": self.IFs.uart.IFs.tx.IFs.signal, + "30": self.uart.rx.signal, + "31": self.uart.tx.signal, # 32 is not connected # 33 is not connected # 34 is not connected @@ -130,7 +116,7 @@ class _IFs(Module.IFS()): # TODO: set the following in the pinmux # UART0 gpio 20/21 - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( has_datasheet_defined( diff --git a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py index 996fdba1..0333f425 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py +++ b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py @@ -3,14 +3,9 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.Button import Button -from faebryk.library.Crystal_Oscillator import Crystal_Oscillator -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 -from faebryk.library.JTAG import JTAG -from faebryk.library.UART_Base import UART_Base -from faebryk.library.USB2_0 import USB2_0 + logger = logging.getLogger(__name__) @@ -18,55 +13,46 @@ class ESP32_C3_MINI_1_Reference_Design(Module): """ESP32_C3_MINI_1 Module reference design""" - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): + + esp32_c3_mini_1 = ESP32_C3_MINI_1() # TODO make switch debounced - boot_switch = Button() # TODO: this cannot be picked Switch(Electrical) - reset_switch = Button() # TODO: this cannot be picked Switch(Electrical) + boot_switch = Button() # TODO: this cannot be picked Switch(F.Electrical) + reset_switch = Button() # TODO: this cannot be picked Switch(F.Electrical) low_speed_crystal_clock = Crystal_Oscillator() - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - vdd3v3 = ElectricPower() + vdd3v3: F.ElectricPower uart = UART_Base() jtag = JTAG() usb = USB2_0() - self.IFs = _IFs(self) - - gnd = self.IFs.vdd3v3.IFs.lv + gnd = self.vdd3v3.lv # connect power - self.IFs.vdd3v3.connect(self.NODEs.esp32_c3_mini_1.IFs.vdd3v3) + self.vdd3v3.connect(self.esp32_c3_mini_1.vdd3v3) # TODO: set default boot mode (GPIO[8] pull up with 10k resistor) + (GPIO[2] pull up with 10k resistor) # noqa: E501 # boot and enable switches # TODO: Fix bridging of (boot and reset) switches - # self.NODEs.esp32_c3_mini_1.IFs.chip_enable.connect_via( - # self.NODEs.boot_switch, gnd + # self.esp32_c3_mini_1.chip_enable.connect_via( + # self.boot_switch, gnd # ) # TODO: lowpass chip_enable - # self.IFs.gpio[9].connect_via(self.NODEs.reset_switch, gnd) + # self.gpio[9].connect_via(self.reset_switch, gnd) # connect low speed crystal oscillator - self.NODEs.low_speed_crystal_clock.IFs.n.connect( - self.NODEs.esp32_c3_mini_1.IFs.gpio[0].IFs.signal - ) - self.NODEs.low_speed_crystal_clock.IFs.p.connect( - self.NODEs.esp32_c3_mini_1.IFs.gpio[1].IFs.signal - ) - self.NODEs.low_speed_crystal_clock.IFs.power.IFs.lv.connect(gnd) + self.low_speed_crystal_clock.n.connect(self.esp32_c3_mini_1.gpio[0].signal) + self.low_speed_crystal_clock.p.connect(self.esp32_c3_mini_1.gpio[1].signal) + self.low_speed_crystal_clock.power.lv.connect(gnd) # TODO: set the following in the pinmux # jtag gpio 4,5,6,7 # USB gpio 18,19 # connect USB - self.IFs.usb.connect(self.NODEs.esp32_c3_mini_1.NODEs.esp32_c3.IFs.usb) + self.usb.connect(self.esp32_c3_mini_1.esp32_c3.usb) # connect UART[0] - self.IFs.uart.connect(self.NODEs.esp32_c3_mini_1.NODEs.esp32_c3.IFs.uart[0]) + self.uart.connect(self.esp32_c3_mini_1.esp32_c3.uart[0]) diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index a8503c7f..318a92b2 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -5,47 +5,34 @@ from enum import Enum, auto from typing import Iterable, Self -from faebryk.core.core import ( - Module, - ModuleInterface, - Node, - Trait, -) -from faebryk.core.util import connect_all_interfaces -from faebryk.library.can_be_surge_protected_defined import ( - can_be_surge_protected_defined, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_single_electric_reference import has_single_electric_reference -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.Logic import Logic -from faebryk.library.Resistor import Resistor -from faebryk.library.TBD import TBD - - -class ElectricLogic(Logic): - class has_pulls(Trait): +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node +from faebryk.core.util import connect_all_interfaces, get_children +from faebryk.libs.library import L + + +class ElectricLogic(F.Logic): + class has_pulls(F.Logic.TraitT): @abstractmethod - def get_pulls(self) -> tuple[Resistor | None, Resistor | None]: ... + def get_pulls(self) -> tuple[F.Resistor | None, F.Resistor | None]: ... class has_pulls_defined(has_pulls.impl()): - def __init__(self, up: Resistor | None, down: Resistor | None) -> None: + def __init__(self, up: F.Resistor | None, down: F.Resistor | None) -> None: super().__init__() self.up = up self.down = down - def get_pulls(self) -> tuple[Resistor | None, Resistor | None]: + def get_pulls(self) -> tuple[F.Resistor | None, F.Resistor | None]: return self.up, self.down - class can_be_pulled(Trait): + class can_be_pulled(F.Logic.TraitT): @abstractmethod - def pull(self, up: bool) -> Resistor: ... + def pull(self, up: bool) -> F.Resistor: ... class can_be_pulled_defined(can_be_pulled.impl()): - def __init__(self, signal: Electrical, ref: ElectricPower) -> None: + def __init__(self, signal: F.Electrical, ref: F.ElectricPower) -> None: super().__init__() self.ref = ref self.signal = signal @@ -54,27 +41,25 @@ def pull(self, up: bool): obj = self.get_obj() up_r, down_r = None, None - if obj.has_trait(ElectricLogic.has_pulls): - up_r, down_r = obj.get_trait(ElectricLogic.has_pulls).get_pulls() + if obj.has_trait(F.ElectricLogic.has_pulls): + up_r, down_r = obj.get_trait(F.ElectricLogic.has_pulls).get_pulls() if up and up_r: return up_r if not up and down_r: return down_r - resistor = Resistor() + resistor = F.Resistor() if up: - obj.NODEs.pull_up = resistor + obj.add(resistor, "pull_up") up_r = resistor else: - obj.NODEs.pull_down = resistor + obj.add(resistor, "pull_down") down_r = resistor - self.signal.connect_via( - resistor, self.ref.IFs.hv if up else self.ref.IFs.lv - ) + self.signal.connect_via(resistor, self.ref.hv if up else self.ref.lv) - obj.add_trait(ElectricLogic.has_pulls_defined(up_r, down_r)) + obj.add_trait(F.ElectricLogic.has_pulls_defined(up_r, down_r)) return resistor # class can_be_buffered(Trait): @@ -84,111 +69,102 @@ def pull(self, up: bool): # # # class can_be_buffered_defined(can_be_buffered.impl()): - # def __init__(self, signal: "ElectricLogic") -> None: + # def __init__(self, signal: "F.ElectricLogic") -> None: # super().__init__() # self.signal = signal # # def buffer(self): # obj = self.get_obj() # - # if hasattr(obj.NODEs, "buffer"): - # return cast_assert(SignalBuffer, getattr(obj.NODEs, "buffer")) + # if hasattr(obj, "buffer"): + # return cast_assert(SignalBuffer, getattr(obj, "buffer")) # # buffer = SignalBuffer() - # obj.NODEs.buffer = buffer - # self.signal.connect(buffer.NODEs.logic_in) + # obj.buffer = buffer + # self.signal.connect(buffer.logic_in) # - # return buffer.NODEs.logic_out + # return buffer.logic_out class PushPull(Enum): PUSH_PULL = auto() OPEN_DRAIN = auto() OPEN_SOURCE = auto() - def __init__(self) -> None: - super().__init__() - - class PARAMS(Logic.PARAMS()): - push_pull = TBD[ElectricLogic.PushPull]() - - self.PARAMs = PARAMS(self) + push_pull: F.TBD[F.ElectricLogic.PushPull] + reference: F.ElectricPower + signal: F.Electrical - class IFS(Logic.NODES()): - reference = ElectricPower() - signal = Electrical() + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined(self.reference) - self.IFs = IFS(self) - - class _can_be_surge_protected_defined(can_be_surge_protected_defined): + @L.rt_field + def surge_protected(self): + class _can_be_surge_protected_defined(F.can_be_surge_protected_defined): def protect(_self): return [ tvs.builder( - lambda t: t.PARAMs.reverse_working_voltage.merge( - self.IFs.reference.PARAMs.voltage + lambda t: t.reverse_working_voltage.merge( + self.reference.voltage ) ) for tvs in super().protect() ] - self.add_trait(has_single_electric_reference_defined(self.IFs.reference)) - self.add_trait( - _can_be_surge_protected_defined(self.IFs.reference.IFs.lv, self.IFs.signal) - ) - self.add_trait( - ElectricLogic.can_be_pulled_defined( - self.IFs.signal, - self.IFs.reference, - ) - ) + return _can_be_surge_protected_defined(self.reference.lv, self.signal) + + @L.rt_field + def pulled(self): + return F.ElectricLogic.can_be_pulled_defined(self.signal, self.reference) - def connect_to_electric(self, signal: Electrical, reference: ElectricPower): - self.IFs.reference.connect(reference) - self.IFs.signal.connect(signal) + def connect_to_electric(self, signal: F.Electrical, reference: F.ElectricPower): + self.reference.connect(reference) + self.signal.connect(signal) return self - def connect_reference(self, reference: ElectricPower, invert: bool = False): + def connect_reference(self, reference: F.ElectricPower, invert: bool = False): if invert: # TODO raise NotImplementedError() - # inverted = ElectricPower() - # inverted.NODEs.lv.connect(reference.NODEs.hv) - # inverted.NODEs.hv.connect(reference.NODEs.lv) + # inverted : F.ElectricPower + # inverted.lv.connect(reference.hv) + # inverted.hv.connect(reference.lv) # reference = inverted - self.IFs.reference.connect(reference) + self.reference.connect(reference) - def connect_references(self, other: "ElectricLogic", invert: bool = False): - self.connect_reference(other.IFs.reference, invert=invert) + def connect_references(self, other: "F.ElectricLogic", invert: bool = False): + self.connect_reference(other.reference, invert=invert) def set(self, on: bool): super().set(on) - r = self.IFs.reference.IFs - self.IFs.signal.connect(r.hv if on else r.lv) + r = self.reference + self.signal.connect(r.hv if on else r.lv) def set_weak(self, on: bool): return self.get_trait(self.can_be_pulled).pull(up=on) @staticmethod - def connect_all_references(ifs: Iterable["ElectricLogic"]) -> ElectricPower: - out = connect_all_interfaces([x.IFs.reference for x in ifs]) + def connect_all_references(ifs: Iterable["F.ElectricLogic"]) -> F.ElectricPower: + out = connect_all_interfaces([x.reference for x in ifs]) assert out return out @staticmethod def connect_all_node_references( nodes: Iterable[Node], gnd_only=False - ) -> ElectricPower: - # TODO check if any child contains ElectricLogic which is not connected + ) -> F.ElectricPower: + # TODO check if any child contains F.ElectricLogic which is not connected # e.g find them in graph and check if any has parent without "single reference" refs = { - x.get_trait(has_single_electric_reference).get_reference() + x.get_trait(F.has_single_electric_reference).get_reference() for x in nodes - if x.has_trait(has_single_electric_reference) - } | {x for x in nodes if isinstance(x, ElectricPower)} + if x.has_trait(F.has_single_electric_reference) + } | {x for x in nodes if isinstance(x, F.ElectricPower)} assert refs if gnd_only: - connect_all_interfaces({r.IFs.lv for r in refs}) + connect_all_interfaces({r.lv for r in refs}) return next(iter(refs)) connect_all_interfaces(refs) @@ -197,13 +173,13 @@ def connect_all_node_references( @classmethod def connect_all_module_references( cls, node: Module | ModuleInterface, gnd_only=False - ) -> ElectricPower: + ) -> F.ElectricPower: return cls.connect_all_node_references( - node.IFs.get_all() + node.NODEs.get_all(), + get_children(node, direct_only=True, types=(Module, ModuleInterface)), gnd_only=gnd_only, ) - # def connect_shallow(self, other: "ElectricLogic"): + # def connect_shallow(self, other: "F.ElectricLogic"): # self.connect( # other, # linkcls=self.LinkDirectShallowLogic, @@ -212,10 +188,10 @@ def connect_all_module_references( def connect_via_bridge( self, bridge: Module, up: bool, bridge_ref_to_signal: bool = False ): - target = self.IFs.reference.IFs.hv if up else self.IFs.reference.IFs.lv + target = self.reference.hv if up else self.reference.lv if bridge_ref_to_signal: - return target.connect_via(bridge, self.IFs.signal) - return self.IFs.signal.connect_via(bridge, target) + return target.connect_via(bridge, self.signal) + return self.signal.connect_via(bridge, target) def connect_shallow( self, @@ -229,10 +205,10 @@ def connect_shallow( # TODO make custom LinkDirectShallow that also allows the specified params if signal: - self.IFs.signal.connect(other.IFs.signal) + self.signal.connect(other.signal) if reference: - self.IFs.reference.connect(other.IFs.reference) + self.reference.connect(other.reference) if lv: - self.IFs.reference.IFs.lv.connect(other.IFs.reference.IFs.lv) + self.reference.lv.connect(other.reference.lv) return super().connect_shallow(other) diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index bef7672f..c4d0098c 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -3,41 +3,38 @@ from typing import TypeVar -from faebryk.core.module import Module, TraitImpl +import faebryk.library._F as F +from faebryk.core.trait import TraitImpl from faebryk.core.util import specialize_interface -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.Logic import Logic -from faebryk.library.LogicGate import LogicGate -from faebryk.libs.util import times +from faebryk.libs.library import L -T = TypeVar("T", bound=Logic) +T = TypeVar("T", bound=F.Logic) -class ElectricLogicGate(LogicGate): +class ElectricLogicGate(F.LogicGate): + inputs = L.if_list(0, F.ElectricLogic) + outputs = L.if_list(0, F.ElectricLogic) + def __init__( - self, input_cnt: Constant[int], output_cnt: Constant[int], *functions: TraitImpl + self, + input_cnt: F.Constant[int], + output_cnt: F.Constant[int], + *functions: TraitImpl, ) -> None: super().__init__(input_cnt, output_cnt, *functions) - self.IFs_logic = self.IFs - - class IFS(Module.IFS()): - inputs = L.if_list(input_cnt, ElectricLogic) - outputs = L.if_list(output_cnt, ElectricLogic) + self.add_to_container(int(input_cnt), F.ElectricLogic, self.inputs) + self.add_to_container(int(output_cnt), F.ElectricLogic, self.outputs) - self.IFs = IFS(self) + self_logic = self - for in_if_l, in_if_el in zip(self.IFs_logic.inputs, self.IFs.inputs): + for in_if_l, in_if_el in zip(self_logic.inputs, self.inputs): specialize_interface(in_if_l, in_if_el) - for out_if_l, out_if_el in zip(self.IFs_logic.outputs, self.IFs.outputs): + for out_if_l, out_if_el in zip(self_logic.outputs, self.outputs): specialize_interface(out_if_l, out_if_el) - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) diff --git a/src/faebryk/library/ElectricLogicGates.py b/src/faebryk/library/ElectricLogicGates.py index 9e860fbd..e2cf9217 100644 --- a/src/faebryk/library/ElectricLogicGates.py +++ b/src/faebryk/library/ElectricLogicGates.py @@ -3,27 +3,26 @@ from typing import TypeVar -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogicGate import ElectricLogicGate -from faebryk.library.Logic import Logic -from faebryk.library.LogicGate import LogicGate +import faebryk.library._F as F -T = TypeVar("T", bound=Logic) +T = TypeVar("T", bound=F.Logic) class ElectricLogicGates: - class OR(ElectricLogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_or_gate()) - - class NOR(ElectricLogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_nor_gate()) - - class NAND(ElectricLogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_nand_gate()) - - class XOR(ElectricLogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_xor_gate()) + class OR(F.ElectricLogicGate): + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_or_gate()) + + class NOR(F.ElectricLogicGate): + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_nor_gate()) + + class NAND(F.ElectricLogicGate): + def __init__(self, input_cnt: F.Constant[int]): + super().__init__( + input_cnt, F.Constant(1), F.LogicGate.can_logic_nand_gate() + ) + + class XOR(F.ElectricLogicGate): + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_xor_gate()) diff --git a/src/faebryk/library/ElectricPower.py b/src/faebryk/library/ElectricPower.py index 9f6128b0..9fd43830 100644 --- a/src/faebryk/library/ElectricPower.py +++ b/src/faebryk/library/ElectricPower.py @@ -2,83 +2,66 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined -from faebryk.library.can_be_surge_protected_defined import ( - can_be_surge_protected_defined, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.Power import Power -from faebryk.library.Range import Range -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity -class ElectricPower(Power): - class can_be_decoupled_power(can_be_decoupled_defined): +class ElectricPower(F.Power): + class can_be_decoupled_power(F.can_be_decoupled_defined): def __init__(self) -> None: ... def on_obj_set(self): - super().__init__(hv=self.get_obj().IFs.hv, lv=self.get_obj().IFs.lv) + super().__init__(hv=self.get_obj().hv, lv=self.get_obj().lv) def decouple(self): return ( super() .decouple() .builder( - lambda c: c.PARAMs.rated_voltage.merge( - Range(0 * P.V, self.get_obj().PARAMs.voltage * 2.0) + lambda c: c.rated_voltage.merge( + F.Range(0 * P.V, self.get_obj().voltage * 2.0) ) ) ) - class can_be_surge_protected_power(can_be_surge_protected_defined): + class can_be_surge_protected_power(F.can_be_surge_protected_defined): def __init__(self) -> None: ... def on_obj_set(self): - super().__init__(self.get_obj().IFs.lv, self.get_obj().IFs.hv) + super().__init__(self.get_obj().lv, self.get_obj().hv) def protect(self): return [ tvs.builder( - lambda t: t.PARAMs.reverse_working_voltage.merge( - self.get_obj().PARAMs.voltage - ) + lambda t: t.reverse_working_voltage.merge(self.get_obj().voltage) ) for tvs in super().protect() ] - def __init__(self) -> None: - super().__init__() - - class IFS(Power.IFS()): - hv = Electrical() - lv = Electrical() + hv: F.Electrical + lv: F.Electrical - self.IFs = IFS(self) + voltage: F.TBD[Quantity] - class PARAMS(Power.PARAMS()): - voltage = TBD[Quantity]() + surge_protected: can_be_surge_protected_power + decoupled: can_be_decoupled_power - self.PARAMs = PARAMS(self) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined(self) - # self.PARAMs.voltage.merge( - # self.NODEs.hv.PARAMs.potential - self.NODEs.lv.PARAMs.potential + def __preinit__(self) -> None: + ... + # self.voltage.merge( + # self.hv.potential - self.lv.potential # ) - self.add_trait(ElectricPower.can_be_surge_protected_power()) - self.add_trait(ElectricPower.can_be_decoupled_power()) - - from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, - ) - - self.add_trait(has_single_electric_reference_defined(self)) - def _on_connect(self, other: ModuleInterface) -> None: super()._on_connect(other) - if not isinstance(other, ElectricPower): + if not isinstance(other, F.ElectricPower): return - self.PARAMs.voltage.merge(other.PARAMs.voltage) + self.voltage.merge(other.voltage) diff --git a/src/faebryk/library/Electrical.py b/src/faebryk/library/Electrical.py index a0e5a41a..fb2046f0 100644 --- a/src/faebryk/library/Electrical.py +++ b/src/faebryk/library/Electrical.py @@ -1,10 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity class Electrical(ModuleInterface): - potential: TBD[Quantity] + potential: F.TBD[Quantity] diff --git a/src/faebryk/library/Ethernet.py b/src/faebryk/library/Ethernet.py index 5596e1ff..a57740ac 100644 --- a/src/faebryk/library/Ethernet.py +++ b/src/faebryk/library/Ethernet.py @@ -2,15 +2,8 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module, ModuleInterface -from faebryk.library.DifferentialPair import DifferentialPair class Ethernet(ModuleInterface): - def __init__(self) -> None: - super().__init__() - - class IFS(Module.IFS()): - tx = DifferentialPair() - rx = DifferentialPair() - - self.IFs = IFS(self) + tx = DifferentialPair() + rx = DifferentialPair() diff --git a/src/faebryk/library/Fan.py b/src/faebryk/library/Fan.py index 84f9f46d..6914422b 100644 --- a/src/faebryk/library/Fan.py +++ b/src/faebryk/library/Fan.py @@ -2,18 +2,7 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.ElectricPower import ElectricPower class Fan(Module): - def __init__(self) -> None: - super().__init__() - - class _IFs(Module.IFS()): - power = ElectricPower() - - self.IFs = _IFs(self) - - class _NODEs(Module.NODES()): ... - - self.NODEs = _NODEs(self) + power: F.ElectricPower diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index 0e979f95..63380e3b 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -11,15 +11,11 @@ class Footprint(Module): class TraitT(Trait): ... - def __init__(self) -> None: - super().__init__() - @staticmethod def get_footprint_of_parent( intf: ModuleInterface, ) -> "tuple[Node, Footprint]": from faebryk.core.util import get_parent_with_trait - from faebryk.library.has_footprint import has_footprint parent, trait = get_parent_with_trait(intf, has_footprint) return parent, trait.get_footprint() diff --git a/src/faebryk/library/Fuse.py b/src/faebryk/library/Fuse.py index 97105133..1e34d039 100644 --- a/src/faebryk/library/Fuse.py +++ b/src/faebryk/library/Fuse.py @@ -5,17 +5,13 @@ from enum import Enum, auto from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_symmetrically import ( - can_attach_to_footprint_symmetrically, -) -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.TBD import TBD + + + + + from faebryk.libs.units import Quantity -from faebryk.libs.util import times + logger = logging.getLogger(__name__) @@ -29,21 +25,17 @@ class ResponseType(Enum): SLOW = auto() FAST = auto() - def __init__(self): - super().__init__() - class _IFs(Module.IFS()): - unnamed = L.if_list(2, Electrical) - self.IFs = _IFs(self) + unnamed = L.if_list(2, F.Electrical) - class _PARAMs(Module.PARAMS()): - fuse_type = TBD[Fuse.FuseType]() - response_type = TBD[Fuse.ResponseType]() - trip_current = TBD[Quantity]() - self.PARAMs = _PARAMs(self) + fuse_type : F.TBD[Fuse.FuseType] + response_type : F.TBD[Fuse.ResponseType] + trip_current : F.TBD[Quantity] self.add_trait(can_attach_to_footprint_symmetrically()) - self.add_trait(can_bridge_defined(self.IFs.unnamed[0], self.IFs.unnamed[1])) - self.add_trait(has_designator_prefix_defined("F")) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.unnamed[0], self.unnamed[1]) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("F") diff --git a/src/faebryk/library/GDT.py b/src/faebryk/library/GDT.py index d44a4d0e..628b6730 100644 --- a/src/faebryk/library/GDT.py +++ b/src/faebryk/library/GDT.py @@ -4,36 +4,29 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) class GDT(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - common = Electrical() - tube_1 = Electrical() - tube_2 = Electrical() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): - dc_breakdown_voltage = TBD[Quantity]() - impulse_discharge_current = TBD[Quantity]() + common: F.Electrical + tube_1: F.Electrical + tube_2: F.Electrical + - self.PARAMs = _PARAMs(self) + dc_breakdown_voltage : F.TBD[Quantity] + impulse_discharge_current : F.TBD[Quantity] - self.add_trait(can_bridge_defined(self.IFs.tube_1, self.IFs.tube_2)) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.tube_1, self.tube_2) - self.add_trait(has_designator_prefix_defined("GDT")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("GDT") diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index 869975b2..69cd9ce4 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -7,13 +7,9 @@ Module, ModuleInterface, ) -from faebryk.library.can_be_surge_protected import can_be_surge_protected -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.Fuse import Fuse -from faebryk.libs.util import times + + + T = TypeVar("T", bound=ModuleInterface) @@ -22,63 +18,59 @@ class GenericBusProtection(Generic[T], Module): def __init__(self, bus_factory: Callable[[], T]) -> None: super().__init__() - class _IFs(Module.IFS()): + bus_unprotected = bus_factory() bus_protected = bus_factory() - self.IFs = _IFs(self) - U = TypeVar("U", bound=ModuleInterface) def get_mifs(bus: T, mif_type: type[U]) -> list[U]: - return [i for i in bus.IFs.get_all() if isinstance(i, mif_type)] + return [i for i in bus.get_all() if isinstance(i, mif_type)] raw = list( zip( - get_mifs(self.IFs.bus_unprotected, Electrical), - get_mifs(self.IFs.bus_protected, Electrical), + get_mifs(self.bus_unprotected, F.Electrical), + get_mifs(self.bus_protected, F.Electrical), ) ) signals = list( zip( - get_mifs(self.IFs.bus_unprotected, ElectricLogic), - get_mifs(self.IFs.bus_protected, ElectricLogic), + get_mifs(self.bus_unprotected, F.ElectricLogic), + get_mifs(self.bus_protected, F.ElectricLogic), ) ) power = list( zip( - get_mifs(self.IFs.bus_unprotected, ElectricPower), - get_mifs(self.IFs.bus_protected, ElectricPower), + get_mifs(self.bus_unprotected, F.ElectricPower), + get_mifs(self.bus_protected, F.ElectricPower), ) ) - class _NODEs(Module.NODES()): - fuse = L.if_list(len(power), Fuse) - self.NODEs = _NODEs(self) + fuse = L.if_list(len(power), Fuse) # Pass through except hv for power_unprotected, power_protected in power: - power_unprotected.IFs.lv.connect(power_protected.IFs.lv) + power_unprotected.lv.connect(power_protected.lv) for logic_unprotected, logic_protected in signals: logic_unprotected.connect_shallow(logic_protected, signal=True, lv=True) for raw_unprotected, raw_protected in raw: raw_unprotected.connect(raw_protected) # Fuse - for (power_unprotected, power_protected), fuse in zip(power, self.NODEs.fuse): - power_unprotected.IFs.hv.connect_via(fuse, power_protected.IFs.hv) + for (power_unprotected, power_protected), fuse in zip(power, self.fuse): + power_unprotected.hv.connect_via(fuse, power_protected.hv) # TODO maybe shallow connect? - power_protected.PARAMs.voltage.merge(power_unprotected.PARAMs.voltage) + power_protected.voltage.merge(power_unprotected.voltage) # TVS - if self.IFs.bus_protected.has_trait(can_be_surge_protected): - self.IFs.bus_protected.get_trait(can_be_surge_protected).protect() + if self.bus_protected.has_trait(can_be_surge_protected): + self.bus_protected.get_trait(can_be_surge_protected).protect() else: for line_unprotected, line_protected in signals + power + raw: line_protected.get_trait(can_be_surge_protected).protect() # TODO add shallow connect - self.add_trait( - can_bridge_defined(self.IFs.bus_unprotected, self.IFs.bus_protected) - ) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.bus_unprotected, self.bus_protected) diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index 55a9110c..d38fa668 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -4,43 +4,34 @@ from dataclasses import dataclass, field from faebryk.core.module import Module, Parameter -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.TBD import TBD -from faebryk.library.UART_Base import UART_Base + + + + + + + + from faebryk.libs.units import P class HLK_LD2410B_P(Module): @dataclass class _ld2410b_esphome_config(has_esphome_config.impl()): - throttle_ms: Parameter = field(default_factory=TBD) + throttle_ms: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: super().__init__() def get_config(self) -> dict: - assert isinstance(self.throttle_ms, Constant), "No update interval set!" + assert isinstance(self.throttle_ms, F.Constant), "No update interval set!" obj = self.get_obj() assert isinstance(obj, HLK_LD2410B_P), "This is not an HLK_LD2410B_P!" uart_candidates = { mif - for mif in obj.IFs.uart.get_direct_connections() + for mif in obj.uart.get_direct_connections() if mif.has_trait(is_esphome_bus) and mif.has_trait(has_esphome_config) } @@ -75,35 +66,32 @@ def get_config(self) -> dict: ], } - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - power = ElectricPower() - uart = UART_Base() - out = ElectricLogic() - self.IFs = _IFs(self) + power: F.ElectricPower + uart = UART_Base() + out: F.ElectricLogic - x = self.IFs + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { - "5": x.power.IFs.hv, - "4": x.power.IFs.lv, - "3": x.uart.IFs.rx.IFs.signal, - "2": x.uart.IFs.tx.IFs.signal, - "1": x.out.IFs.signal, + "5": x.power.hv, + "4": x.power.lv, + "3": x.uart.rx.signal, + "2": x.uart.tx.signal, + "1": x.out.signal, } ) ) # connect all logic references - ref = ElectricLogic.connect_all_module_references(self, gnd_only=True) + ref = F.ElectricLogic.connect_all_module_references(self, gnd_only=True) self.add_trait(has_single_electric_reference_defined(ref)) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.esphome = self._ld2410b_esphome_config() self.add_trait(self.esphome) @@ -114,4 +102,4 @@ class _IFs(Module.IFS()): ) ) - self.IFs.uart.PARAMs.baud.merge(Constant(256 * P.kbaud)) + self.uart.baud.merge(F.Constant(256 * P.kbaud)) diff --git a/src/faebryk/library/Header.py b/src/faebryk/library/Header.py index 20999bdf..53772d98 100644 --- a/src/faebryk/library/Header.py +++ b/src/faebryk/library/Header.py @@ -4,12 +4,10 @@ from enum import Enum, auto from faebryk.core.module import Module -from faebryk.library.Constant import Constant -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity -from faebryk.libs.util import times + class Header(Module): @@ -33,23 +31,17 @@ def __init__( ) -> None: super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - unnamed = L.if_list(horizonal_pin_count * vertical_pin_count, Electrical) - self.IFs = _IFs(self) + unnamed = L.if_list(horizonal_pin_count * vertical_pin_count, F.Electrical) - class _PARAMs(Module.PARAMS()): - pin_pitch = TBD[Quantity]() - pin_type = TBD[self.PinType]() - pad_type = TBD[self.PadType]() - angle = TBD[self.Angle]() - pin_count_horizonal = Constant(horizonal_pin_count) - pin_count_vertical = Constant(vertical_pin_count) - self.PARAMs = _PARAMs(self) + pin_pitch : F.TBD[Quantity] + pin_type : F.TBD[self.PinType] + pad_type : F.TBD[self.PadType] + angle : F.TBD[self.Angle] + pin_count_horizonal = F.Constant(horizonal_pin_count) + pin_count_vertical = F.Constant(vertical_pin_count) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/I2C.py b/src/faebryk/library/I2C.py index c7e9caf5..d2e2428f 100644 --- a/src/faebryk/library/I2C.py +++ b/src/faebryk/library/I2C.py @@ -3,46 +3,36 @@ import logging from enum import Enum +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.Range import Range -from faebryk.library.TBD import TBD +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity logger = logging.getLogger(__name__) class I2C(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) + scl: F.ElectricLogic + sda: F.ElectricLogic - class IFS(ModuleInterface.IFS()): - scl = ElectricLogic() - sda = ElectricLogic() + frequency: F.TBD[Quantity] - self.IFs = IFS(self) - - class PARAMS(ModuleInterface.PARAMS()): - frequency = TBD[Quantity]() - - self.PARAMs = PARAMS(self) - - ref = ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) def terminate(self): # TODO: https://www.ti.com/lit/an/slva689/slva689.pdf - self.IFs.sda.get_trait(ElectricLogic.can_be_pulled).pull(up=True) - self.IFs.scl.get_trait(ElectricLogic.can_be_pulled).pull(up=True) + self.sda.get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.scl.get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) def _on_connect(self, other: "I2C"): super()._on_connect(other) - self.PARAMs.frequency.merge(other.PARAMs.frequency) + self.frequency.merge(other.frequency) class SpeedMode(Enum): low_speed = 10 * P.khertz @@ -52,4 +42,4 @@ class SpeedMode(Enum): @staticmethod def define_max_frequency_capability(mode: SpeedMode): - return Range(I2C.SpeedMode.low_speed, mode) + return F.Range(I2C.SpeedMode.low_speed, mode) diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index af96074c..0f27f7e6 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -7,18 +7,13 @@ as_unit, as_unit_with_tolerance, ) -from faebryk.library.can_attach_to_footprint_symmetrically import ( - can_attach_to_footprint_symmetrically, -) -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation_based_on_params import ( - has_simple_value_representation_based_on_params, -) -from faebryk.library.TBD import TBD + + + + + from faebryk.libs.units import Quantity -from faebryk.libs.util import times + class Inductor(Module): @@ -27,28 +22,28 @@ def __init__( ): super().__init__() - class _IFs(super().IFS()): - unnamed = L.if_list(2, Electrical) - self.IFs = _IFs(self) - self.add_trait(can_bridge_defined(*self.IFs.unnamed)) + unnamed = L.if_list(2, F.Electrical) + + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(*self.unnamed) - class _PARAMs(super().PARAMS()): - inductance = TBD[Quantity]() - self_resonant_frequency = TBD[Quantity]() - rated_current = TBD[Quantity]() - dc_resistance = TBD[Quantity]() - self.PARAMs = _PARAMs(self) + inductance : F.TBD[Quantity] + self_resonant_frequency : F.TBD[Quantity] + rated_current : F.TBD[Quantity] + dc_resistance : F.TBD[Quantity] self.add_trait(can_attach_to_footprint_symmetrically()) - self.add_trait( - has_simple_value_representation_based_on_params( + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_params( ( - self.PARAMs.inductance, - self.PARAMs.self_resonant_frequency, - self.PARAMs.rated_current, - self.PARAMs.dc_resistance, + self.inductance, + self.self_resonant_frequency, + self.rated_current, + self.dc_resistance, ), lambda ps: " ".join( filter( @@ -63,4 +58,4 @@ class _PARAMs(super().PARAMS()): ), ) ) - self.add_trait(has_designator_prefix_defined("L")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("L") diff --git a/src/faebryk/library/JTAG.py b/src/faebryk/library/JTAG.py index 6ca22c18..9dc0b835 100644 --- a/src/faebryk/library/JTAG.py +++ b/src/faebryk/library/JTAG.py @@ -2,28 +2,23 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) + + + class JTAG(ModuleInterface): - def __init__(self) -> None: - super().__init__() - - class IFS(ModuleInterface.IFS()): - dbgrq = ElectricLogic() - tdo = ElectricLogic() - tdi = ElectricLogic() - tms = ElectricLogic() - tck = ElectricLogic() - n_trst = ElectricLogic() - n_reset = ElectricLogic() - vtref = Electrical() - - self.IFs = IFS(self) - - ref = ElectricLogic.connect_all_module_references(self) + + + + dbgrq: F.ElectricLogic + tdo: F.ElectricLogic + tdi: F.ElectricLogic + tms: F.ElectricLogic + tck: F.ElectricLogic + n_trst: F.ElectricLogic + n_reset: F.ElectricLogic + vtref: F.Electrical + + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) diff --git a/src/faebryk/library/KicadFootprint.py b/src/faebryk/library/KicadFootprint.py index 7da44d3c..04a5ad28 100644 --- a/src/faebryk/library/KicadFootprint.py +++ b/src/faebryk/library/KicadFootprint.py @@ -1,34 +1,30 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist -from faebryk.library.Footprint import Footprint -from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint -from faebryk.library.Pad import Pad -from faebryk.libs.util import times -class KicadFootprint(Footprint): + + +class KicadF.Footprint(Footprint): def __init__(self, kicad_identifier: str, pin_names: list[str]) -> None: super().__init__() unique_pin_names = sorted(set(pin_names)) - class _IFS(Footprint.IFS()): + pins = L.if_list(len(unique_pin_names), Pad) pin_names_sorted = list(enumerate(unique_pin_names)) - self.IFs = _IFS(self) self.add_trait( can_attach_via_pinmap_pinlist( - {pin_name: self.IFs.pins[i] for i, pin_name in pin_names_sorted} + {pin_name: self.pins[i] for i, pin_name in pin_names_sorted} ) ) self.add_trait( has_kicad_manual_footprint( kicad_identifier, - {self.IFs.pins[i]: pin_name for i, pin_name in pin_names_sorted}, + {self.pins[i]: pin_name for i, pin_name in pin_names_sorted}, ) ) diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index 67854d51..33d34686 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -5,18 +5,11 @@ from faebryk.core.module import Module from faebryk.core.util import as_unit, as_unit_with_tolerance -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_pin_association_heuristic_lookup_table import ( - has_pin_association_heuristic_lookup_table, -) -from faebryk.library.has_simple_value_representation_based_on_params import ( - has_simple_value_representation_based_on_params, -) -from faebryk.library.TBD import TBD + + + + + from faebryk.libs.units import Quantity @@ -29,56 +22,51 @@ class OutputPolarity(Enum): POSITIVE = auto() NEGATIVE = auto() - @classmethod - def PARAMS(cls): - class _PARAMs(super().PARAMS()): - max_input_voltage = TBD[Quantity]() - output_voltage = TBD[Quantity]() - output_polarity = TBD[LDO.OutputPolarity]() - output_type = TBD[LDO.OutputType]() - output_current = TBD[Quantity]() - psrr = TBD[Quantity]() - dropout_voltage = TBD[Quantity]() - quiescent_current = TBD[Quantity]() - return _PARAMs + max_input_voltage : F.TBD[Quantity] + output_voltage : F.TBD[Quantity] + output_polarity : F.TBD[LDO.OutputPolarity] + output_type : F.TBD[LDO.OutputType] + output_current : F.TBD[Quantity] + psrr : F.TBD[Quantity] + dropout_voltage : F.TBD[Quantity] + quiescent_current : F.TBD[Quantity] + - def __init__(self): - super().__init__() - self.PARAMs = self.PARAMS()(self) - class _IFs(super().IFS()): - enable = ElectricLogic() - power_in = ElectricPower() - power_out = ElectricPower() - self.IFs = _IFs(self) + enable: F.ElectricLogic + power_in: F.ElectricPower + power_out: F.ElectricPower - self.IFs.power_in.PARAMs.voltage.merge(self.PARAMs.max_input_voltage) - self.IFs.power_out.PARAMs.voltage.merge(self.PARAMs.output_voltage) + self.power_in.voltage.merge(self.max_input_voltage) + self.power_out.voltage.merge(self.output_voltage) - self.IFs.power_in.get_trait(can_be_decoupled).decouple() - self.IFs.power_out.get_trait(can_be_decoupled).decouple() + self.power_in.get_trait(can_be_decoupled).decouple() + self.power_out.get_trait(can_be_decoupled).decouple() - self.IFs.enable.IFs.reference.connect(self.IFs.power_in) - if self.PARAMs.output_polarity == self.OutputPolarity.POSITIVE: - self.IFs.power_in.IFs.lv.connect(self.IFs.power_out.IFs.lv) + self.enable.reference.connect(self.power_in) + if self.output_polarity == self.OutputPolarity.POSITIVE: + self.power_in.lv.connect(self.power_out.lv) else: - self.IFs.power_in.IFs.hv.connect(self.IFs.power_out.IFs.hv) + self.power_in.hv.connect(self.power_out.hv) - self.add_trait(can_bridge_defined(self.IFs.power_in, self.IFs.power_out)) - self.add_trait( - has_simple_value_representation_based_on_params( + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.power_in, self.power_out) + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_params( ( - self.PARAMs.output_polarity, - self.PARAMs.output_type, - self.PARAMs.output_voltage, - self.PARAMs.output_current, - self.PARAMs.psrr, - self.PARAMs.dropout_voltage, - self.PARAMs.max_input_voltage, - self.PARAMs.quiescent_current, + self.output_polarity, + self.output_type, + self.output_voltage, + self.output_current, + self.psrr, + self.dropout_voltage, + self.max_input_voltage, + self.quiescent_current, ), lambda ps: "LDO " + " ".join( @@ -93,14 +81,14 @@ class _IFs(super().IFS()): ), ) ) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( has_pin_association_heuristic_lookup_table( mapping={ - self.IFs.power_in.IFs.hv: ["Vin", "Vi", "in"], - self.IFs.power_out.IFs.hv: ["Vout", "Vo", "out"], - self.IFs.power_in.IFs.lv: ["GND", "V-"], - self.IFs.enable.IFs.signal: ["EN", "Enable"], + self.power_in.hv: ["Vin", "Vi", "in"], + self.power_out.hv: ["Vout", "Vo", "out"], + self.power_in.lv: ["GND", "V-"], + self.enable.signal: ["EN", "Enable"], }, accept_prefix=False, case_sensitive=False, diff --git a/src/faebryk/library/LED.py b/src/faebryk/library/LED.py index 93f73412..7a1f480b 100644 --- a/src/faebryk/library/LED.py +++ b/src/faebryk/library/LED.py @@ -5,11 +5,8 @@ from enum import Enum, auto from faebryk.core.parameter import Parameter -from faebryk.library.Diode import Diode -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.Resistor import Resistor -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity @@ -22,57 +19,43 @@ class Color(Enum): YELLOW = auto() WHITE = auto() - @classmethod - def PARAMS(cls): - class _PARAMs(super().PARAMS()): - brightness = TBD[Quantity]() - max_brightness = TBD[Quantity]() - color = TBD[cls.Color]() - - return _PARAMs + brightness: F.TBD[Quantity] + max_brightness: F.TBD[Quantity] + color: F.TBD[cls.Color] - def __init__(self) -> None: - super().__init__() - - self.PARAMs = self.PARAMS()(self) - - self.PARAMs.current.merge( - self.PARAMs.brightness - / self.PARAMs.max_brightness - * self.PARAMs.max_current - ) + self.current.merge(self.brightness / self.max_brightness * self.max_current) self.inherit() - # self.PARAMs.brightness.merge( - # Range(0 * P.millicandela, self.PARAMs.max_brightness) + # self.brightness.merge( + # F.Range(0 * P.millicandela, self.max_brightness) # ) def set_intensity(self, intensity: Parameter[Quantity]) -> None: - self.PARAMs.brightness.merge(intensity * self.PARAMs.max_brightness) + self.brightness.merge(intensity * self.max_brightness) def connect_via_current_limiting_resistor( self, input_voltage: Parameter[Quantity], - resistor: Resistor, - target: Electrical, + resistor: F.Resistor, + target: F.Electrical, low_side: bool, ): if low_side: - self.IFs.cathode.connect_via(resistor, target) + self.cathode.connect_via(resistor, target) else: - self.IFs.anode.connect_via(resistor, target) + self.anode.connect_via(resistor, target) - resistor.PARAMs.resistance.merge( + resistor.resistance.merge( self.get_needed_series_resistance_for_current_limit(input_voltage), ) def connect_via_current_limiting_resistor_to_power( - self, resistor: Resistor, power: ElectricPower, low_side: bool + self, resistor: F.Resistor, power: F.ElectricPower, low_side: bool ): self.connect_via_current_limiting_resistor( - power.PARAMs.voltage, + power.voltage, resistor, - power.IFs.lv if low_side else power.IFs.hv, + power.lv if low_side else power.hv, low_side, ) diff --git a/src/faebryk/library/LEDIndicator.py b/src/faebryk/library/LEDIndicator.py index 084b7b79..ea8c420c 100644 --- a/src/faebryk/library/LEDIndicator.py +++ b/src/faebryk/library/LEDIndicator.py @@ -1,30 +1,21 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.PoweredLED import PoweredLED -from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET class LEDIndicator(Module): - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - logic_in = ElectricLogic() - power_in = ElectricPower() - self.IFs = _IFs(self) + logic_in: F.ElectricLogic + power_in: F.ElectricPower # components - class _NODEs(Module.NODES()): + led = PoweredLED() # TODO make generic power_switch = PowerSwitchMOSFET(lowside=True, normally_closed=False) - self.NODEs = _NODEs(self) - - self.IFs.power_in.connect_via(self.NODEs.power_switch, self.NODEs.led.IFs.power) - self.NODEs.power_switch.IFs.logic_in.connect(self.IFs.logic_in) + self.power_in.connect_via(self.power_switch, self.led.power) + self.power_switch.logic_in.connect(self.logic_in) diff --git a/src/faebryk/library/Logic.py b/src/faebryk/library/Logic.py index da3c6806..77604ced 100644 --- a/src/faebryk/library/Logic.py +++ b/src/faebryk/library/Logic.py @@ -2,21 +2,12 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Range import Range class Logic(ModuleInterface): @staticmethod def PARAMS(): - class _PARAMS(ModuleInterface.PARAMS()): - state = Range(False, True) - - return _PARAMS - - def __init__(self) -> None: - super().__init__() - - self.PARAMs = self.PARAMS() + state = F.Range(False, True) def set(self, on: bool): - self.PARAMs.state.merge(on) + self.state.merge(on) diff --git a/src/faebryk/library/Logic74xx.py b/src/faebryk/library/Logic74xx.py index 2b727b7a..4308d965 100644 --- a/src/faebryk/library/Logic74xx.py +++ b/src/faebryk/library/Logic74xx.py @@ -4,17 +4,9 @@ from enum import Enum, auto from typing import Callable, Sequence +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricLogicGate import ElectricLogicGate -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.TBD import TBD +from faebryk.libs.library import L class Logic74xx(Module): @@ -57,31 +49,21 @@ class Family(Enum): TTL = auto() CD4000 = auto() + power: F.ElectricPower + logic_family: F.TBD[Family] + gates = L.if_list(0, F.ElectricLogicGate) + + designator = L.f_field(F.has_designator_prefix_defined)("U") + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined(self) + def __init__( self, - gates_factory: Sequence[Callable[[], ElectricLogicGate]], + gates_factory: Sequence[Callable[[], F.ElectricLogicGate]], ) -> None: super().__init__() - class _IFs(Module.IFS()): - power = ElectricPower() - - self.IFs = _IFs(self) - - class _NODEs(Module.NODES()): - gates = [g() for g in gates_factory] - - self.NODEs = _NODEs(self) - - class _PARAMs(Module.PARAMS()): - logic_family = TBD[Logic74xx.Family]() - - self.PARAMs = _PARAMs(self) - - self.add_trait(has_designator_prefix_defined("U")) - - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) - ) + for g in gates_factory: + self.add(g(), container=self.gates) diff --git a/src/faebryk/library/LogicGate.py b/src/faebryk/library/LogicGate.py index 42f2d8f6..80f50cfe 100644 --- a/src/faebryk/library/LogicGate.py +++ b/src/faebryk/library/LogicGate.py @@ -4,10 +4,9 @@ from typing import Sequence, TypeVar from faebryk.core.module import Module, TraitImpl -from faebryk.library.Constant import Constant -from faebryk.library.Logic import Logic -from faebryk.library.LogicOps import LogicOps -from faebryk.libs.util import times + + + T = TypeVar("T", bound=Logic) @@ -51,18 +50,16 @@ def xor(self, *ins: Logic): def __init__( self, - input_cnt: Constant[int], - output_cnt: Constant[int], + input_cnt: F.Constant[int], + output_cnt: F.Constant[int], *functions: TraitImpl, ) -> None: super().__init__() - class IFS(Module.IFS()): + inputs = L.if_list(input_cnt, Logic) outputs = L.if_list(output_cnt, Logic) - self.IFs = IFS(self) - for f in functions: self.add_trait(f) @@ -76,4 +73,4 @@ def op_( return out def op(self, *ins: Logic): - return self.op_(ins, self.IFs.inputs, self.IFs.outputs) + return self.op_(ins, self.inputs, self.outputs) diff --git a/src/faebryk/library/LogicGates.py b/src/faebryk/library/LogicGates.py index d051194a..bfb986b3 100644 --- a/src/faebryk/library/LogicGates.py +++ b/src/faebryk/library/LogicGates.py @@ -3,26 +3,23 @@ from typing import TypeVar -from faebryk.library.Constant import Constant -from faebryk.library.Logic import Logic -from faebryk.library.LogicGate import LogicGate T = TypeVar("T", bound=Logic) class LogicGates: class OR(LogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_or_gate()) + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_or_gate()) class NOR(LogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_nor_gate()) + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_nor_gate()) class NAND(LogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_nand_gate()) + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_nand_gate()) class XOR(LogicGate): - def __init__(self, input_cnt: Constant[int]): - super().__init__(input_cnt, Constant(1), LogicGate.can_logic_xor_gate()) + def __init__(self, input_cnt: F.Constant[int]): + super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_xor_gate()) diff --git a/src/faebryk/library/LogicOps.py b/src/faebryk/library/LogicOps.py index 965e9e98..02ae0b95 100644 --- a/src/faebryk/library/LogicOps.py +++ b/src/faebryk/library/LogicOps.py @@ -5,7 +5,7 @@ from typing import TypeVar from faebryk.core.core import Trait -from faebryk.library.Logic import Logic + T = TypeVar("T", bound=Logic) diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index 2b961950..2b4ddf41 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -4,68 +4,58 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.I2C import I2C -from faebryk.library.SOIC import SOIC + + + + + + + from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) # TODO remove generic stuff into EEPROM/i2c device etc class M24C08_FMN6TP(Module): - def __init__(self) -> None: - super().__init__() - class _IFs(Module.IFS()): - power = ElectricPower() - data = I2C() - nwc = ElectricLogic() - e = L.if_list(3, ElectricLogic) - self.IFs = _IFs(self) - x = self.IFs + power: F.ElectricPower + data = I2C() + nwc: F.ElectricLogic + e = L.if_list(3, F.ElectricLogic) + + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": x.e[0].IFs.signal, - "2": x.e[1].IFs.signal, - "3": x.e[2].IFs.signal, - "4": x.power.IFs.lv, - "5": x.data.IFs.sda.IFs.signal, - "6": x.data.IFs.scl.IFs.signal, - "7": x.nwc.IFs.signal, - "8": x.power.IFs.hv, + "1": x.e[0].signal, + "2": x.e[1].signal, + "3": x.e[2].signal, + "4": x.power.lv, + "5": x.data.sda.signal, + "6": x.data.scl.signal, + "7": x.nwc.signal, + "8": x.power.hv, } ) ).attach(SOIC(8, size_xy=(3.9 * P.mm, 4.9 * P.mm), pitch=1.27 * P.mm)) - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) - self.IFs.data.terminate() - self.IFs.power.get_trait(can_be_decoupled).decouple() + self.data.terminate() + self.power.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") def set_address(self, addr: int): - assert addr < (1 << len(self.IFs.e)) + assert addr < (1 << len(self.e)) - for i, e in enumerate(self.IFs.e): + for i, e in enumerate(self.e): e.set(addr & (1 << i) != 0) diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 32081f81..563a1619 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -4,45 +4,32 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.I2C import I2C -from faebryk.library.UART_Base import UART_Base -from faebryk.library.USB2_0 import USB2_0 -from faebryk.libs.util import times + + + logger = logging.getLogger(__name__) class MCP2221A(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() - power_vusb = ElectricPower() + + + power: F.ElectricPower + power_vusb: F.ElectricPower uart = UART_Base() i2c = I2C() - gpio = L.if_list(4, Electrical) - reset = ElectricLogic() + gpio = L.if_list(4, F.Electrical) + reset: F.ElectricLogic usb = USB2_0() - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) - self.IFs.power.get_trait(can_be_decoupled).decouple() - self.IFs.power_vusb.get_trait(can_be_decoupled).decouple() + self.power.get_trait(can_be_decoupled).decouple() + self.power_vusb.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.IFs.power.IFs.lv.connect(self.IFs.power_vusb.IFs.lv) + self.power.lv.connect(self.power_vusb.lv) diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index 178d0de2..49a01340 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -3,17 +3,11 @@ from faebryk.core.module import Module from faebryk.core.util import connect_to_all_interfaces -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.Range import Range + + + + + from faebryk.libs.units import P @@ -26,42 +20,34 @@ def __init__(self, default_enabled: bool = True) -> None: super().__init__() # interfaces - class _IFs(Module.IFS()): - power_in = ElectricPower() - power_out = ElectricPower() - enable = Electrical() - self.IFs = _IFs(self) + power_in: F.ElectricPower + power_out: F.ElectricPower + enable: F.Electrical # components - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) # set constraints - self.IFs.power_out.PARAMs.voltage.merge( - Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V) - ) + self.power_out.voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) # connect decouple capacitor - self.IFs.power_in.get_trait(can_be_decoupled).decouple() - self.IFs.power_out.get_trait(can_be_decoupled).decouple() + self.power_in.get_trait(can_be_decoupled).decouple() + self.power_out.get_trait(can_be_decoupled).decouple() # LDO in & out share gnd reference - self.IFs.power_in.IFs.lv.connect(self.IFs.power_out.IFs.lv) + self.power_in.lv.connect(self.power_out.lv) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": self.IFs.power_in.IFs.hv, - "2": self.IFs.power_in.IFs.lv, - "3": self.IFs.enable, - "5": self.IFs.power_out.IFs.hv, + "1": self.power_in.hv, + "2": self.power_in.lv, + "3": self.enable, + "5": self.power_out.hv, } ) ) @@ -73,6 +59,6 @@ class _PARAMs(Module.PARAMS()): ... ) if default_enabled: - self.IFs.enable.connect(self.IFs.power_in.IFs.hv) + self.enable.connect(self.power_in.hv) - connect_to_all_interfaces(self.IFs.power_in.IFs.lv, [self.IFs.power_out.IFs.lv]) + connect_to_all_interfaces(self.power_in.lv, [self.power_out.lv]) diff --git a/src/faebryk/library/MOSFET.py b/src/faebryk/library/MOSFET.py index da02d3d0..1ffd7f45 100644 --- a/src/faebryk/library/MOSFET.py +++ b/src/faebryk/library/MOSFET.py @@ -4,13 +4,10 @@ from enum import Enum, auto from faebryk.core.module import Module -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_pin_association_heuristic_lookup_table import ( - has_pin_association_heuristic_lookup_table, -) -from faebryk.library.TBD import TBD + + + + from faebryk.libs.units import Quantity @@ -23,36 +20,32 @@ class SaturationType(Enum): ENHANCEMENT = auto() DEPLETION = auto() - def __init__(self): - super().__init__() - class _PARAMs(Module.PARAMS()): - channel_type = TBD[MOSFET.ChannelType]() - saturation_type = TBD[MOSFET.SaturationType]() - gate_source_threshold_voltage = TBD[Quantity]() - max_drain_source_voltage = TBD[Quantity]() - max_continuous_drain_current = TBD[Quantity]() - on_resistance = TBD[Quantity]() - self.PARAMs = _PARAMs(self) + channel_type : F.TBD[MOSFET.ChannelType] + saturation_type : F.TBD[MOSFET.SaturationType] + gate_source_threshold_voltage : F.TBD[Quantity] + max_drain_source_voltage : F.TBD[Quantity] + max_continuous_drain_current : F.TBD[Quantity] + on_resistance : F.TBD[Quantity] - class _IFs(Module.IFS()): - source = Electrical() - gate = Electrical() - drain = Electrical() - self.IFs = _IFs(self) + source: F.Electrical + gate: F.Electrical + drain: F.Electrical - self.add_trait(has_designator_prefix_defined("Q")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("Q") # TODO pretty confusing - self.add_trait(can_bridge_defined(in_if=self.IFs.source, out_if=self.IFs.drain)) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(in_if=self.source, out_if=self.drain) self.add_trait( has_pin_association_heuristic_lookup_table( mapping={ - self.IFs.source: ["S", "Source"], - self.IFs.gate: ["G", "Gate"], - self.IFs.drain: ["D", "Drain"], + self.source: ["S", "Source"], + self.gate: ["G", "Gate"], + self.drain: ["D", "Drain"], }, accept_prefix=False, case_sensitive=False, diff --git a/src/faebryk/library/Mounting_Hole.py b/src/faebryk/library/Mounting_Hole.py index 7873cb69..6801e0c9 100644 --- a/src/faebryk/library/Mounting_Hole.py +++ b/src/faebryk/library/Mounting_Hole.py @@ -4,38 +4,31 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_symmetrically import ( - can_attach_to_footprint_symmetrically, -) -from faebryk.library.Constant import Constant -from faebryk.library.has_defined_footprint import has_defined_footprint -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.KicadFootprint import KicadFootprint -from faebryk.library.TBD import TBD + + + + + + from faebryk.libs.units import P, Quantity logger = logging.getLogger(__name__) class Mounting_Hole(Module): - def __init__(self) -> None: - super().__init__() - class PARAMs(Module.PARAMS()): - diameter = TBD[Quantity]() - self.PARAMs = PARAMs(self) + + diameter : F.TBD[Quantity] self.add_trait(can_attach_to_footprint_symmetrically()) - self.add_trait(has_designator_prefix_defined("H")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("H") # Only 3.2mm supported for now - self.PARAMs.diameter.merge(Constant(3.2 * P.mm)) + self.diameter.merge(F.Constant(3.2 * P.mm)) self.add_trait( has_defined_footprint( - KicadFootprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) + KicadF.Footprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) ) ) diff --git a/src/faebryk/library/MultiSPI.py b/src/faebryk/library/MultiSPI.py index 65c95d6a..83698953 100644 --- a/src/faebryk/library/MultiSPI.py +++ b/src/faebryk/library/MultiSPI.py @@ -2,21 +2,17 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.libs.util import times + + class MultiSPI(ModuleInterface): def __init__(self, data_lane_count: int) -> None: super().__init__() - class IFS(ModuleInterface.IFS()): - clk = ElectricLogic() - data = L.if_list(data_lane_count, ElectricLogic) - cs = ElectricLogic() - self.IFs = IFS(self) + clk: F.ElectricLogic + data = L.if_list(data_lane_count, F.ElectricLogic) + cs: F.ElectricLogic - class PARAMS(ModuleInterface.PARAMS()): ... - self.PARAMs = PARAMS(self) diff --git a/src/faebryk/library/Net.py b/src/faebryk/library/Net.py index 46633e43..9ea63b20 100644 --- a/src/faebryk/library/Net.py +++ b/src/faebryk/library/Net.py @@ -5,23 +5,16 @@ from faebryk.core.module import Module from faebryk.core.util import get_connected_mifs, get_parent_of_type -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import Footprint -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.Pad import Pad + logger = logging.getLogger(__name__) class Net(Module): - def __init__(self) -> None: - super().__init__() - class _IFs(super().IFS()): - part_of = Electrical() - self.IFs = _IFs(self) + + part_of: F.Electrical class _(has_overriden_name.impl()): def get_name(_self): @@ -53,7 +46,7 @@ def get_fps(self): return { pad: fp for mif in self.get_connected_interfaces() - if (fp := get_parent_of_type(mif, Footprint)) is not None + if (fp := get_parent_of_type(mif, F.Footprint)) is not None and (pad := get_parent_of_type(mif, Pad)) is not None } @@ -61,8 +54,8 @@ def get_fps(self): def get_connected_interfaces(self): return { mif - for mif in get_connected_mifs(self.IFs.part_of.connected) - if isinstance(mif, type(self.IFs.part_of)) + for mif in get_connected_mifs(self.part_of.connected) + if isinstance(mif, type(self.part_of)) } def __repr__(self) -> str: diff --git a/src/faebryk/library/OLED_Module.py b/src/faebryk/library/OLED_Module.py index 67e57d7b..f07e76b2 100644 --- a/src/faebryk/library/OLED_Module.py +++ b/src/faebryk/library/OLED_Module.py @@ -5,12 +5,8 @@ from enum import Enum, auto from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.I2C import I2C -from faebryk.library.Range import Range -from faebryk.library.TBD import TBD + + from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -27,27 +23,20 @@ class DisplayController(Enum): SSD1315 = auto() SSD1306 = auto() - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() - i2c = I2C() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): - resolution = TBD[self.Resolution]() - display_controller = TBD[self.DisplayController]() + power: F.ElectricPower + i2c = I2C() + - self.PARAMs = _PARAMs(self) + resolution : F.TBD[self.Resolution] + display_controller : F.TBD[self.DisplayController] - self.IFs.power.PARAMs.voltage.merge(Range(3.0 * P.V, 5 * P.V)) + self.power.voltage.merge(F.Range(3.0 * P.V, 5 * P.V)) - self.IFs.power.get_trait(can_be_decoupled).decouple() + self.power.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("OLED")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("OLED") diff --git a/src/faebryk/library/OpAmp.py b/src/faebryk/library/OpAmp.py index dcdbe941..e2012775 100644 --- a/src/faebryk/library/OpAmp.py +++ b/src/faebryk/library/OpAmp.py @@ -3,52 +3,42 @@ from faebryk.core.module import Module from faebryk.core.util import as_unit -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_pin_association_heuristic_lookup_table import ( - has_pin_association_heuristic_lookup_table, -) -from faebryk.library.has_simple_value_representation_based_on_params import ( - has_simple_value_representation_based_on_params, -) -from faebryk.library.TBD import TBD + + + + + from faebryk.libs.units import Quantity class OpAmp(Module): - def __init__(self): - super().__init__() - class _PARAMs(self.PARAMS()): - bandwidth = TBD[Quantity]() - common_mode_rejection_ratio = TBD[Quantity]() - input_bias_current = TBD[Quantity]() - input_offset_voltage = TBD[Quantity]() - gain_bandwidth_product = TBD[Quantity]() - output_current = TBD[Quantity]() - slew_rate = TBD[Quantity]() - self.PARAMs = _PARAMs(self) + bandwidth : F.TBD[Quantity] + common_mode_rejection_ratio : F.TBD[Quantity] + input_bias_current : F.TBD[Quantity] + input_offset_voltage : F.TBD[Quantity] + gain_bandwidth_product : F.TBD[Quantity] + output_current : F.TBD[Quantity] + slew_rate : F.TBD[Quantity] - class _IFs(super().IFS()): - power = ElectricPower() - inverting_input = Electrical() - non_inverting_input = Electrical() - output = Electrical() - self.IFs = _IFs(self) + power: F.ElectricPower + inverting_input: F.Electrical + non_inverting_input: F.Electrical + output: F.Electrical - self.add_trait( - has_simple_value_representation_based_on_params( + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_params( [ - self.PARAMs.bandwidth, - self.PARAMs.common_mode_rejection_ratio, - self.PARAMs.input_bias_current, - self.PARAMs.input_offset_voltage, - self.PARAMs.gain_bandwidth_product, - self.PARAMs.output_current, - self.PARAMs.slew_rate, + self.bandwidth, + self.common_mode_rejection_ratio, + self.input_bias_current, + self.input_offset_voltage, + self.gain_bandwidth_product, + self.output_current, + self.slew_rate, ], lambda p: ( f"{as_unit(p[0], 'Hz')} BW, {p[1]} CMRR, {as_unit(p[2], 'A')} Ib, " @@ -60,14 +50,14 @@ class _IFs(super().IFS()): self.add_trait( has_pin_association_heuristic_lookup_table( mapping={ - self.IFs.power.IFs.hv: ["V+", "Vcc", "Vdd"], - self.IFs.power.IFs.lv: ["V-", "Vee", "Vss", "GND"], - self.IFs.inverting_input: ["-", "IN-"], - self.IFs.non_inverting_input: ["+", "IN+"], - self.IFs.output: ["OUT"], + self.power.hv: ["V+", "Vcc", "Vdd"], + self.power.lv: ["V-", "Vee", "Vss", "GND"], + self.inverting_input: ["-", "IN-"], + self.non_inverting_input: ["+", "IN+"], + self.output: ["OUT"], }, accept_prefix=False, case_sensitive=False, ) ) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/PJ398SM.py b/src/faebryk/library/PJ398SM.py index 3651cb2e..fe635c96 100644 --- a/src/faebryk/library/PJ398SM.py +++ b/src/faebryk/library/PJ398SM.py @@ -2,21 +2,16 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) + + class PJ398SM(Module): - def __init__(self) -> None: - super().__init__() - class _IFs(Module.IFS()): - tip = Electrical() - sleeve = Electrical() - switch = Electrical() - self.IFs = _IFs(self) - self.add_trait(has_designator_prefix_defined("J")) + tip: F.Electrical + sleeve: F.Electrical + switch: F.Electrical + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index ec759099..20590ecd 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -4,14 +4,8 @@ from dataclasses import dataclass, field from faebryk.core.module import Module, Parameter -from faebryk.library.Constant import Constant -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.Range import Range -from faebryk.library.TBD import TBD -from faebryk.library.UART_Base import UART_Base + + from faebryk.libs.units import P @@ -34,20 +28,20 @@ class PM1006(Module): @dataclass class _pm1006_esphome_config(has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=TBD) + update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: super().__init__() def get_config(self) -> dict: assert isinstance( - self.update_interval_s, Constant + self.update_interval_s, F.Constant ), "No update interval set!" obj = self.get_obj() assert isinstance(obj, PM1006), "This is not an PM1006!" - uart = is_esphome_bus.find_connected_bus(obj.IFs.data) + uart = is_esphome_bus.find_connected_bus(obj.data) return { "sensor": [ @@ -59,19 +53,11 @@ def get_config(self) -> dict: ] } - def __init__(self) -> None: - super().__init__() - - class _IFs(Module.IFS()): - power = ElectricPower() + power: F.ElectricPower data = UART_Base() - self.IFs = _IFs(self) - # components - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) # --------------------------------------------------------------------- self.add_trait( @@ -84,6 +70,6 @@ class _NODEs(Module.NODES()): ... self.add_trait(self.esphome) # --------------------------------------------------------------------- - self.IFs.power.PARAMs.voltage.merge(Range.from_center(5, 0.2)) + self.power.voltage.merge(F.Range.from_center(5, 0.2)) - self.IFs.data.PARAMs.baud.merge(Constant(9600 * P.baud)) + self.data.baud.merge(F.Constant(9600 * P.baud)) diff --git a/src/faebryk/library/Pad.py b/src/faebryk/library/Pad.py index 849c7274..a82b0677 100644 --- a/src/faebryk/library/Pad.py +++ b/src/faebryk/library/Pad.py @@ -4,24 +4,17 @@ from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.util import get_parent_of_type -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import Footprint class Pad(ModuleInterface): - def __init__(self) -> None: - super().__init__() - class _IFS(super().IFS()): - net = Electrical() - pcb = ModuleInterface() - self.IFs = _IFS(self) - def attach(self, intf: Electrical): - from faebryk.library.has_linked_pad_defined import has_linked_pad_defined + net: F.Electrical + pcb = ModuleInterface() - self.IFs.net.connect(intf) + def attach(self, intf: F.Electrical): + self.net.connect(intf) intf.add_trait(has_linked_pad_defined(self)) @staticmethod @@ -37,23 +30,21 @@ def find_pad_for_intf_with_parent_that_has_footprint_unique( def find_pad_for_intf_with_parent_that_has_footprint( intf: ModuleInterface, ) -> list["Pad"]: - from faebryk.library.has_linked_pad import has_linked_pad - # This only finds directly attached pads # -> misses from parents / children nodes if intf.has_trait(has_linked_pad): return [intf.get_trait(has_linked_pad).get_pad()] # This is a bit slower, but finds them all - _, footprint = Footprint.get_footprint_of_parent(intf) + _, footprint = F.Footprint.get_footprint_of_parent(intf) pads = [ pad - for pad in footprint.IFs.get_all() - if isinstance(pad, Pad) and pad.IFs.net.is_connected_to(intf) is not None + for pad in footprint.get_all() + if isinstance(pad, Pad) and pad.net.is_connected_to(intf) is not None ] return pads - def get_fp(self) -> Footprint: - fp = get_parent_of_type(self, Footprint) + def get_fp(self) -> F.Footprint: + fp = get_parent_of_type(self, F.Footprint) assert fp return fp diff --git a/src/faebryk/library/Potentiometer.py b/src/faebryk/library/Potentiometer.py index c4fa8bbd..06527b50 100644 --- a/src/faebryk/library/Potentiometer.py +++ b/src/faebryk/library/Potentiometer.py @@ -2,42 +2,34 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.Resistor import Resistor -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity -from faebryk.libs.util import times + class Potentiometer(Module): - def __init__(self) -> None: - super().__init__() - class _IFs(Module.IFS()): - resistors = L.if_list(2, Electrical) - wiper = Electrical() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): - total_resistance = TBD[Quantity]() + resistors = L.if_list(2, F.Electrical) + wiper: F.Electrical + - self.PARAMs = _PARAMs(self) + total_resistance : F.TBD[Quantity] - class _NODEs(Module.NODES()): - resistors = L.if_list(2, Resistor) - self.NODEs = _NODEs(self) + resistors = L.if_list(2, F.Resistor) - for i, resistor in enumerate(self.NODEs.resistors): - self.IFs.resistors[i].connect_via(resistor, self.IFs.wiper) + for i, resistor in enumerate(self.resistors): + self.resistors[i].connect_via(resistor, self.wiper) # TODO use range(0, total_resistance) - resistor.PARAMs.resistance.merge(self.PARAMs.total_resistance) + resistor.resistance.merge(self.total_resistance) def connect_as_voltage_divider( - self, high: Electrical, low: Electrical, out: Electrical + self, high: F.Electrical, low: F.Electrical, out: F.Electrical ): - self.IFs.resistors[0].connect(high) - self.IFs.resistors[1].connect(low) - self.IFs.wiper.connect(out) + self.resistors[0].connect(high) + self.resistors[1].connect(low) + self.wiper.connect(out) diff --git a/src/faebryk/library/PowerSwitch.py b/src/faebryk/library/PowerSwitch.py index 18516964..57a901c2 100644 --- a/src/faebryk/library/PowerSwitch.py +++ b/src/faebryk/library/PowerSwitch.py @@ -2,9 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_switch_power_defined import can_switch_power_defined -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower class PowerSwitch(Module): @@ -20,19 +17,15 @@ def __init__(self, normally_closed: bool) -> None: self.normally_closed = normally_closed - class _IFs(Module.IFS()): - logic_in = ElectricLogic() - power_in = ElectricPower() - switched_power_out = ElectricPower() - self.IFs = _IFs(self) + logic_in: F.ElectricLogic + power_in: F.ElectricPower + switched_power_out: F.ElectricPower self.add_trait( can_switch_power_defined( - self.IFs.power_in, self.IFs.switched_power_out, self.IFs.logic_in + self.power_in, self.switched_power_out, self.logic_in ) ) - self.IFs.switched_power_out.PARAMs.voltage.merge( - self.IFs.power_in.PARAMs.voltage - ) + self.switched_power_out.voltage.merge(self.power_in.voltage) diff --git a/src/faebryk/library/PowerSwitchMOSFET.py b/src/faebryk/library/PowerSwitchMOSFET.py index 3d60a8b8..3f76fda5 100644 --- a/src/faebryk/library/PowerSwitchMOSFET.py +++ b/src/faebryk/library/PowerSwitchMOSFET.py @@ -2,10 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.MOSFET import MOSFET -from faebryk.library.PowerSwitch import PowerSwitch class PowerSwitchMOSFET(PowerSwitch): @@ -21,21 +17,17 @@ def __init__(self, lowside: bool, normally_closed: bool) -> None: self.lowside = lowside # components - class _NODEs(Module.NODES()): - mosfet = MOSFET() - self.NODEs = _NODEs(self) + mosfet = MOSFET() - self.NODEs.mosfet.PARAMs.channel_type.merge( - Constant( + self.mosfet.channel_type.merge( + F.Constant( MOSFET.ChannelType.N_CHANNEL if lowside else MOSFET.ChannelType.P_CHANNEL ) ) - self.NODEs.mosfet.PARAMs.saturation_type.merge( - Constant(MOSFET.SaturationType.ENHANCEMENT) - ) + self.mosfet.saturation_type.merge(F.Constant(MOSFET.SaturationType.ENHANCEMENT)) # pull gate # lowside normally_closed pull up @@ -43,24 +35,20 @@ class _NODEs(Module.NODES()): # True False False # False True False # False False True - self.IFs.logic_in.get_trait(ElectricLogic.can_be_pulled).pull( + self.logic_in.get_trait(F.ElectricLogic.can_be_pulled).pull( lowside == normally_closed ) # connect gate to logic - self.IFs.logic_in.IFs.signal.connect(self.NODEs.mosfet.IFs.gate) + self.logic_in.signal.connect(self.mosfet.gate) # passthrough non-switched side, bridge switched side if lowside: - self.IFs.power_in.IFs.hv.connect(self.IFs.switched_power_out.IFs.hv) - self.IFs.power_in.IFs.lv.connect_via( - self.NODEs.mosfet, self.IFs.switched_power_out.IFs.lv - ) + self.power_in.hv.connect(self.switched_power_out.hv) + self.power_in.lv.connect_via(self.mosfet, self.switched_power_out.lv) else: - self.IFs.power_in.IFs.lv.connect(self.IFs.switched_power_out.IFs.lv) - self.IFs.power_in.IFs.hv.connect_via( - self.NODEs.mosfet, self.IFs.switched_power_out.IFs.hv - ) + self.power_in.lv.connect(self.switched_power_out.lv) + self.power_in.hv.connect_via(self.mosfet, self.switched_power_out.hv) # TODO do more with logic # e.g check reference being same as power diff --git a/src/faebryk/library/PowerSwitchStatic.py b/src/faebryk/library/PowerSwitchStatic.py index 62c21d2e..b00c183f 100644 --- a/src/faebryk/library/PowerSwitchStatic.py +++ b/src/faebryk/library/PowerSwitchStatic.py @@ -1,19 +1,17 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.PowerSwitch import PowerSwitch - class PowerSwitchStatic(PowerSwitch): """ A power switch that bridges power through statically - This is useful when transforming an ElectricLogic to an ElectricPower + This is useful when transforming an F.ElectricLogic to an F.ElectricPower """ def __init__(self) -> None: super().__init__(normally_closed=False) - self.IFs.power_in.connect(self.IFs.switched_power_out) - self.IFs.logic_in.connect_reference(self.IFs.power_in) - self.IFs.logic_in.set(True) + self.power_in.connect(self.switched_power_out) + self.logic_in.connect_reference(self.power_in) + self.logic_in.set(True) diff --git a/src/faebryk/library/PoweredLED.py b/src/faebryk/library/PoweredLED.py index 9304d462..eb52005b 100644 --- a/src/faebryk/library/PoweredLED.py +++ b/src/faebryk/library/PoweredLED.py @@ -2,33 +2,26 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.LED import LED -from faebryk.library.Resistor import Resistor class PoweredLED(Module): - def __init__(self) -> None: - super().__init__() - class _IFs(Module.IFS()): - power = ElectricPower() - self.IFs = _IFs(self) - class _NODEs(Module.NODES()): - current_limiting_resistor = Resistor() - led = LED() + power: F.ElectricPower + - self.NODEs = _NODEs(self) + current_limiting_resistor : F.Resistor + led = LED() - self.IFs.power.IFs.hv.connect(self.NODEs.led.IFs.anode) - self.NODEs.led.connect_via_current_limiting_resistor_to_power( - self.NODEs.current_limiting_resistor, - self.IFs.power, + self.power.hv.connect(self.led.anode) + self.led.connect_via_current_limiting_resistor_to_power( + self.current_limiting_resistor, + self.power, low_side=True, ) - self.add_trait(can_bridge_defined(self.IFs.power.IFs.hv, self.IFs.power.IFs.lv)) - self.NODEs.current_limiting_resistor.allow_removal_if_zero() + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.power.hv, self.power.lv) + self.current_limiting_resistor.allow_removal_if_zero() diff --git a/src/faebryk/library/Powered_Relay.py b/src/faebryk/library/Powered_Relay.py index 9f7f144e..a0922a26 100644 --- a/src/faebryk/library/Powered_Relay.py +++ b/src/faebryk/library/Powered_Relay.py @@ -4,65 +4,44 @@ import logging from faebryk.core.module import Module -from faebryk.library.Diode import Diode -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.PoweredLED import PoweredLED -from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET -from faebryk.library.Relay import Relay + logger = logging.getLogger(__name__) class Powered_Relay(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): + + relay = Relay() indicator = PoweredLED() flyback_diode = Diode() relay_driver = PowerSwitchMOSFET(lowside=True, normally_closed=False) - self.NODEs = _NODEs(self) - - class _IFs(Module.IFS()): - switch_a_nc = Electrical() - switch_a_common = Electrical() - switch_a_no = Electrical() - switch_b_no = Electrical() - switch_b_common = Electrical() - switch_b_nc = Electrical() - enable = ElectricLogic() - power = ElectricPower() - - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) - - self.NODEs.relay.IFs.switch_a_common.connect(self.IFs.switch_a_common) - self.NODEs.relay.IFs.switch_a_nc.connect(self.IFs.switch_a_nc) - self.NODEs.relay.IFs.switch_a_no.connect(self.IFs.switch_a_no) - self.NODEs.relay.IFs.switch_b_common.connect(self.IFs.switch_b_common) - self.NODEs.relay.IFs.switch_b_nc.connect(self.IFs.switch_b_nc) - self.NODEs.relay.IFs.switch_b_no.connect(self.IFs.switch_b_no) - - self.NODEs.relay_driver.IFs.power_in.connect(self.IFs.power) - self.NODEs.relay_driver.IFs.logic_in.connect(self.IFs.enable) - self.NODEs.relay_driver.IFs.switched_power_out.IFs.lv.connect( - self.NODEs.relay.IFs.coil_n - ) - self.NODEs.relay_driver.IFs.switched_power_out.IFs.hv.connect( - self.NODEs.relay.IFs.coil_p - ) - - self.NODEs.relay.IFs.coil_n.connect_via( - self.NODEs.flyback_diode, self.NODEs.relay.IFs.coil_p - ) - - self.NODEs.indicator.IFs.power.connect( - self.NODEs.relay_driver.IFs.switched_power_out - ) + + switch_a_nc: F.Electrical + switch_a_common: F.Electrical + switch_a_no: F.Electrical + switch_b_no: F.Electrical + switch_b_common: F.Electrical + switch_b_nc: F.Electrical + enable: F.ElectricLogic + power: F.ElectricPower + + + + self.relay.switch_a_common.connect(self.switch_a_common) + self.relay.switch_a_nc.connect(self.switch_a_nc) + self.relay.switch_a_no.connect(self.switch_a_no) + self.relay.switch_b_common.connect(self.switch_b_common) + self.relay.switch_b_nc.connect(self.switch_b_nc) + self.relay.switch_b_no.connect(self.switch_b_no) + + self.relay_driver.power_in.connect(self.power) + self.relay_driver.logic_in.connect(self.enable) + self.relay_driver.switched_power_out.lv.connect(self.relay.coil_n) + self.relay_driver.switched_power_out.hv.connect(self.relay.coil_p) + + self.relay.coil_n.connect_via(self.flyback_diode, self.relay.coil_p) + + self.indicator.power.connect(self.relay_driver.switched_power_out) diff --git a/src/faebryk/library/QFN.py b/src/faebryk/library/QFN.py index 7767ab4f..23e021f0 100644 --- a/src/faebryk/library/QFN.py +++ b/src/faebryk/library/QFN.py @@ -1,15 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -from faebryk.library.Footprint import Footprint -from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -from faebryk.library.Pad import Pad + from faebryk.libs.units import P, Quantity -from faebryk.libs.util import times -class QFN(Footprint): + +class QFN(F.Footprint): def __init__( self, pin_cnt: int, @@ -21,10 +18,9 @@ def __init__( ) -> None: super().__init__() - class _IFs(Footprint.IFS()): + pins = L.if_list(pin_cnt, Pad) - self.IFs = _IFs(self) assert exposed_thermal_pad_cnt > 0 or not has_thermal_vias assert ( exposed_thermal_pad_dimensions[0] < size_xy[0] diff --git a/src/faebryk/library/QWIIC.py b/src/faebryk/library/QWIIC.py index 3b1aa2fb..15da1e12 100644 --- a/src/faebryk/library/QWIIC.py +++ b/src/faebryk/library/QWIIC.py @@ -2,13 +2,10 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.Constant import Constant -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.I2C import I2C + + + + from faebryk.libs.units import P @@ -18,20 +15,17 @@ class QWIIC(Module): Delivers 3.3V power + I2C over JST SH 1mm pitch 4 pin connectors """ - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - i2c = I2C() - power = ElectricPower() - self.IFs = _IFs(self) + i2c = I2C() + power: F.ElectricPower # set constraints - self.IFs.power.PARAMs.voltage.merge(Constant(3.3 * P.V)) - # TODO: self.IFs.power.PARAMs.source_current.merge(Constant(226 * P.mA)) + self.power.voltage.merge(F.Constant(3.3 * P.V)) + # TODO: self.power.source_current.merge(F.Constant(226 * P.mA)) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") self.add_trait(has_datasheet_defined("https://www.sparkfun.com/qwiic")) diff --git a/src/faebryk/library/QWIIC_Connector.py b/src/faebryk/library/QWIIC_Connector.py index 9d4491f9..de73f6bc 100644 --- a/src/faebryk/library/QWIIC_Connector.py +++ b/src/faebryk/library/QWIIC_Connector.py @@ -4,29 +4,20 @@ import logging from faebryk.core.module import Module -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.I2C import I2C + logger = logging.getLogger(__name__) class QWIIC_Connector(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() - i2c = I2C() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): ... + power: F.ElectricPower + i2c = I2C() + - self.PARAMs = _PARAMs(self) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/RJ45_Receptacle.py b/src/faebryk/library/RJ45_Receptacle.py index 77fda9ab..8cc46063 100644 --- a/src/faebryk/library/RJ45_Receptacle.py +++ b/src/faebryk/library/RJ45_Receptacle.py @@ -4,10 +4,9 @@ from enum import Enum, auto from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.TBD import TBD -from faebryk.libs.util import times + + + class RJ45_Receptacle(Module): @@ -15,19 +14,14 @@ class Mounting(Enum): TH = auto() SMD = auto() - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - pin = L.if_list(8, Electrical) - shield = Electrical() - self.IFs = _IFs(self) + pin = L.if_list(8, F.Electrical) + shield: F.Electrical - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") - class _PARAMS(super().PARAMS()): - mounting = TBD[self.Mounting]() - self.PARAMs = _PARAMS(self) + mounting : F.TBD[self.Mounting] diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index 8174a622..ca9ca875 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -4,69 +4,53 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.I2C import I2C -from faebryk.library.MultiSPI import MultiSPI -from faebryk.library.SWD import SWD -from faebryk.library.UART_Base import UART_Base -from faebryk.library.USB2_0 import USB2_0 -from faebryk.libs.util import times + + + logger = logging.getLogger(__name__) class RP2040(Module): - def __init__(self) -> None: - super().__init__() - - class _NODEs(Module.NODES()): ... - - self.NODEs = _NODEs(self) - - class _IFs(Module.IFS()): - io_vdd = ElectricPower() - adc_vdd = ElectricPower() - core_vdd = ElectricPower() - vreg_in = ElectricPower() - vreg_out = ElectricPower() - power_vusb = ElectricPower() - gpio = L.if_list(30, Electrical) - run = ElectricLogic() + + + + + + io_vdd: F.ElectricPower + adc_vdd: F.ElectricPower + core_vdd: F.ElectricPower + vreg_in: F.ElectricPower + vreg_out: F.ElectricPower + power_vusb: F.ElectricPower + gpio = L.if_list(30, F.Electrical) + run: F.ElectricLogic usb = USB2_0() qspi = MultiSPI(data_lane_count=4) - xin = Electrical() - xout = Electrical() - test = Electrical() + xin: F.Electrical + xout: F.Electrical + test: F.Electrical swd = SWD() # TODO: these peripherals and more can be mapped to different pins i2c = I2C() uart = UART_Base() - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) # decouple power rails and connect GNDs toghether - gnd = self.IFs.io_vdd.IFs.lv + gnd = self.io_vdd.lv for pwrrail in [ - self.IFs.io_vdd, - self.IFs.adc_vdd, - self.IFs.core_vdd, - self.IFs.vreg_in, - self.IFs.vreg_out, - self.IFs.usb.IFs.usb_if.IFs.buspower, + self.io_vdd, + self.adc_vdd, + self.core_vdd, + self.vreg_in, + self.vreg_out, + self.usb.usb_if.buspower, ]: - pwrrail.IFs.lv.connect(gnd) + pwrrail.lv.connect(gnd) pwrrail.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( has_datasheet_defined( @@ -75,4 +59,4 @@ class _PARAMs(Module.PARAMS()): ... ) # set parameters - # self.IFs.io_vdd.PARAMs.voltage.merge(Range(1.8*P.V, 3.63*P.V)) + # self.io_vdd.voltage.merge(F.Range(1.8*P.V, 3.63*P.V)) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index 4a5b7a85..4dff2a77 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -4,18 +4,11 @@ import logging from faebryk.core.module import Module -from faebryk.library.Constant import Constant -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.LED import LED -from faebryk.library.PoweredLED import PoweredLED -from faebryk.library.Resistor import Resistor -from faebryk.library.RP2040 import RP2040 -from faebryk.library.SPIFlash import SPIFlash -from faebryk.library.USB2_0 import USB2_0 + + from faebryk.libs.brightness import TypicalLuminousIntensity from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) @@ -24,88 +17,77 @@ class RP2040_Reference_Design(Module): """Minimal required design for the Raspberry Pi RP2040 microcontroller. Based on the official Raspberry Pi RP2040 hardware design guidlines""" - def __init__(self) -> None: - super().__init__() + # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- - class _IFs(Module.IFS()): - power = ElectricPower() + + power: F.ElectricPower usb = USB2_0() - self.IFs = _IFs(self) - class _NODES(Module.NODES()): rp2040 = RP2040() flash = SPIFlash() led = PoweredLED() - usb_current_limmit_resistor = L.if_list(2, Resistor) + usb_current_limmit_resistor = L.if_list(2, F.Resistor) # TODO: add crystal oscillator # TODO: add voltage divider with switch # TODO: add boot button # TODO: add reset button # TODO: add optional LM4040 voltage reference or voltage divider - self.NODEs = _NODES(self) - - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) # ---------------------------------------- # aliasess # ---------------------------------------- - gnd = self.IFs.power.IFs.lv + gnd = self.power.lv # ---------------------------------------- # parametrization # ---------------------------------------- - self.IFs.power.PARAMs.voltage.merge(Constant(3.3 * P.V)) + self.power.voltage.merge(F.Constant(3.3 * P.V)) - self.NODEs.flash.PARAMs.memory_size.merge(Constant(16 * P.Mbit)) + self.flash.memory_size.merge(F.Constant(16 * P.Mbit)) - self.NODEs.led.NODEs.led.PARAMs.color.merge(LED.Color.GREEN) - self.NODEs.led.NODEs.led.PARAMs.brightness.merge( + self.led.led.color.merge(LED.Color.GREEN) + self.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) - self.NODEs.usb_current_limmit_resistor[0].PARAMs.resistance.merge( - Constant(27 * P.ohm) - ) - self.NODEs.usb_current_limmit_resistor[1].PARAMs.resistance.merge( - Constant(27 * P.ohm) - ) + self.usb_current_limmit_resistor[0].resistance.merge(F.Constant(27 * P.ohm)) + self.usb_current_limmit_resistor[1].resistance.merge(F.Constant(27 * P.ohm)) # ---------------------------------------- # connections # ---------------------------------------- # connect power rails - main_power_rail = self.IFs.power + main_power_rail = self.power for pwrrail in [ - self.NODEs.rp2040.IFs.io_vdd, - self.NODEs.rp2040.IFs.adc_vdd, - self.NODEs.rp2040.IFs.vreg_in, - self.NODEs.rp2040.IFs.usb.IFs.usb_if.IFs.buspower, + self.rp2040.io_vdd, + self.rp2040.adc_vdd, + self.rp2040.vreg_in, + self.rp2040.usb.usb_if.buspower, ]: pwrrail.connect(main_power_rail) - self.NODEs.rp2040.IFs.vreg_out.connect(self.NODEs.rp2040.IFs.core_vdd) + self.rp2040.vreg_out.connect(self.rp2040.core_vdd) # connect flash - self.NODEs.flash.IFs.spi.connect(self.NODEs.rp2040.IFs.qspi) - self.NODEs.flash.IFs.power.connect(main_power_rail) + self.flash.spi.connect(self.rp2040.qspi) + self.flash.power.connect(main_power_rail) # connect led - self.NODEs.rp2040.IFs.gpio[25].connect_via(self.NODEs.led, gnd) + self.rp2040.gpio[25].connect_via(self.led, gnd) # connect usb - self.IFs.usb.IFs.usb_if.IFs.d.IFs.p.connect_via( - self.NODEs.usb_current_limmit_resistor[0], - self.NODEs.rp2040.IFs.usb.IFs.usb_if.IFs.d.IFs.p, + self.usb.usb_if.d.p.connect_via( + self.usb_current_limmit_resistor[0], + self.rp2040.usb.usb_if.d.p, ) - self.IFs.usb.IFs.usb_if.IFs.d.IFs.n.connect_via( - self.NODEs.usb_current_limmit_resistor[1], - self.NODEs.rp2040.IFs.usb.IFs.usb_if.IFs.d.IFs.n, + self.usb.usb_if.d.n.connect_via( + self.usb_current_limmit_resistor[1], + self.rp2040.usb.usb_if.d.n, ) self.add_trait( diff --git a/src/faebryk/library/RS232.py b/src/faebryk/library/RS232.py index bc44b0cb..f7925a18 100644 --- a/src/faebryk/library/RS232.py +++ b/src/faebryk/library/RS232.py @@ -2,21 +2,16 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module, ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) + + class RS232(ModuleInterface): - def __init__(self) -> None: - super().__init__() - class IFS(Module.IFS()): - tx = ElectricLogic() - rx = ElectricLogic() - self.IFs = IFS(self) - ref = ElectricLogic.connect_all_module_references(self) + tx: F.ElectricLogic + rx: F.ElectricLogic + + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) diff --git a/src/faebryk/library/RS485.py b/src/faebryk/library/RS485.py index c7947ea1..d8c0f533 100644 --- a/src/faebryk/library/RS485.py +++ b/src/faebryk/library/RS485.py @@ -2,14 +2,7 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module, ModuleInterface -from faebryk.library.DifferentialPair import DifferentialPair class RS485(ModuleInterface): - def __init__(self) -> None: - super().__init__() - - class IFS(Module.IFS()): - diff_pair = DifferentialPair() - - self.IFs = IFS(self) + diff_pair = DifferentialPair() diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 8cba9573..94355029 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -7,22 +7,10 @@ from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Capacitor import Capacitor -from faebryk.library.Common_Mode_Filter import Common_Mode_Filter -from faebryk.library.Constant import Constant -from faebryk.library.Diode import Diode -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.GDT import GDT -from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.Range import Range -from faebryk.library.Resistor import Resistor -from faebryk.library.RS485 import RS485 -from faebryk.library.TVS import TVS + + from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) @@ -43,123 +31,99 @@ class RS485_Bus_Protection(Module): def __init__(self, termination: bool = True, polarization: bool = True) -> None: super().__init__() - class _NODEs(Module.NODES()): + gdt = GDT() tvs = TVS() - current_limmiter_resistors = L.if_list(2, Resistor) + current_limmiter_resistors = L.if_list(2, F.Resistor) common_mode_filter = Common_Mode_Filter() - gnd_couple_resistor = Resistor() - gnd_couple_capacitor = Capacitor() + gnd_couple_resistor : F.Resistor + gnd_couple_capacitor : F.Capacitor clamping_diodes = L.if_list(2, Diode) if termination: - termination_resistor = Resistor() + termination_resistor : F.Resistor if polarization: - polarization_resistors = L.if_list(2, Resistor) + polarization_resistors = L.if_list(2, F.Resistor) - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() + power: F.ElectricPower rs485_in = RS485() rs485_out = RS485() - earth = Electrical() + earth: F.Electrical - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): ... - - self.PARAMs = _PARAMs(self) if termination: - self.NODEs.termination_resistor.PARAMs.resistance.merge( - Constant(120 * P.ohm) - ) - self.IFs.rs485_out.IFs.diff_pair.IFs.p.connect_via( - self.NODEs.termination_resistor, self.IFs.rs485_out.IFs.diff_pair.IFs.n + self.termination_resistor.resistance.merge(F.Constant(120 * P.ohm)) + self.rs485_out.diff_pair.p.connect_via( + self.termination_resistor, self.rs485_out.diff_pair.n ) if polarization: - self.NODEs.polarization_resistors[0].PARAMs.resistance.merge( - Range(380 * P.ohm, 420 * P.ohm) + self.polarization_resistors[0].resistance.merge( + F.Range(380 * P.ohm, 420 * P.ohm) ) - self.NODEs.polarization_resistors[1].PARAMs.resistance.merge( - Range(380 * P.ohm, 420 * P.ohm) + self.polarization_resistors[1].resistance.merge( + F.Range(380 * P.ohm, 420 * P.ohm) ) - self.IFs.rs485_in.IFs.diff_pair.IFs.p.connect_via( - self.NODEs.polarization_resistors[0], self.IFs.power.IFs.hv + self.rs485_in.diff_pair.p.connect_via( + self.polarization_resistors[0], self.power.hv ) - self.IFs.rs485_in.IFs.diff_pair.IFs.n.connect_via( - self.NODEs.polarization_resistors[1], self.IFs.power.IFs.lv + self.rs485_in.diff_pair.n.connect_via( + self.polarization_resistors[1], self.power.lv ) - self.NODEs.current_limmiter_resistors[0].PARAMs.resistance.merge( - Constant(2.7 * P.ohm) - ) + self.current_limmiter_resistors[0].resistance.merge(F.Constant(2.7 * P.ohm)) # TODO: set power dissipation of resistor to 2W - self.NODEs.current_limmiter_resistors[1].PARAMs.resistance.merge( - Constant(2.7 * P.ohm) - ) + self.current_limmiter_resistors[1].resistance.merge(F.Constant(2.7 * P.ohm)) # TODO: set power dissipation of resistor to 2W - self.NODEs.gnd_couple_resistor.PARAMs.resistance.merge(Constant(1 * P.Mohm)) - self.NODEs.gnd_couple_capacitor.PARAMs.capacitance.merge(Constant(1 * P.uF)) - self.NODEs.gnd_couple_capacitor.PARAMs.rated_voltage.merge(Constant(2 * P.kV)) + self.gnd_couple_resistor.resistance.merge(F.Constant(1 * P.Mohm)) + self.gnd_couple_capacitor.capacitance.merge(F.Constant(1 * P.uF)) + self.gnd_couple_capacitor.rated_voltage.merge(F.Constant(2 * P.kV)) - self.NODEs.tvs.PARAMs.reverse_working_voltage.merge(Constant(8.5 * P.V)) - # self.NODEs.tvs.PARAMs.max_current.merge(Constant(41.7*P.A)) - # self.NODEs.tvs.PARAMs.forward_voltage.merge(Range(9.44*P.V, 10.40*P.V)) + self.tvs.reverse_working_voltage.merge(F.Constant(8.5 * P.V)) + # self.tvs.max_current.merge(F.Constant(41.7*P.A)) + # self.tvs.forward_voltage.merge(F.Range(9.44*P.V, 10.40*P.V)) - for diode in self.NODEs.clamping_diodes: - diode.PARAMs.forward_voltage.merge(Constant(1.1 * P.V)) - diode.PARAMs.max_current.merge(Constant(1 * P.A)) - diode.PARAMs.reverse_working_voltage.merge(Constant(1 * P.kV)) + for diode in self.clamping_diodes: + diode.forward_voltage.merge(F.Constant(1.1 * P.V)) + diode.max_current.merge(F.Constant(1 * P.A)) + diode.reverse_working_voltage.merge(F.Constant(1 * P.kV)) # connections # earth connections - self.IFs.power.IFs.lv.connect_via( - self.NODEs.gnd_couple_resistor, self.IFs.earth - ) - self.IFs.power.IFs.lv.connect_via( - self.NODEs.gnd_couple_capacitor, self.IFs.earth - ) - self.NODEs.gdt.IFs.common.connect(self.IFs.earth) + self.power.lv.connect_via(self.gnd_couple_resistor, self.earth) + self.power.lv.connect_via(self.gnd_couple_capacitor, self.earth) + self.gdt.common.connect(self.earth) # rs485_in connections - self.IFs.rs485_in.IFs.diff_pair.IFs.p.connect( - self.NODEs.common_mode_filter.IFs.c_a[0] - ) - self.IFs.rs485_in.IFs.diff_pair.IFs.n.connect( - self.NODEs.common_mode_filter.IFs.c_b[0] - ) + self.rs485_in.diff_pair.p.connect(self.common_mode_filter.c_a[0]) + self.rs485_in.diff_pair.n.connect(self.common_mode_filter.c_b[0]) # rs485_out connections - self.NODEs.common_mode_filter.IFs.c_a[1].connect_via( - self.NODEs.current_limmiter_resistors[0], - self.IFs.rs485_out.IFs.diff_pair.IFs.p, + self.common_mode_filter.c_a[1].connect_via( + self.current_limmiter_resistors[0], + self.rs485_out.diff_pair.p, ) - self.NODEs.common_mode_filter.IFs.c_b[1].connect_via( - self.NODEs.current_limmiter_resistors[1], - self.IFs.rs485_out.IFs.diff_pair.IFs.n, - ) - self.IFs.rs485_out.IFs.diff_pair.IFs.n.connect_via( - self.NODEs.gdt, self.IFs.rs485_out.IFs.diff_pair.IFs.p + self.common_mode_filter.c_b[1].connect_via( + self.current_limmiter_resistors[1], + self.rs485_out.diff_pair.n, ) + self.rs485_out.diff_pair.n.connect_via(self.gdt, self.rs485_out.diff_pair.p) # tvs connections # TODO: fix this, super ugly.... - diode_junction = self.NODEs.clamping_diodes[0].IFs.anode - diode_junction.connect(self.NODEs.clamping_diodes[1].IFs.cathode) - self.NODEs.common_mode_filter.IFs.c_a[1].connect_via( - self.NODEs.tvs, diode_junction - ) - self.NODEs.common_mode_filter.IFs.c_b[1].connect_via( - self.NODEs.clamping_diodes[0], diode_junction - ) - self.NODEs.common_mode_filter.IFs.c_b[1].connect( - self.NODEs.clamping_diodes[1].IFs.cathode + diode_junction = self.clamping_diodes[0].anode + diode_junction.connect(self.clamping_diodes[1].cathode) + self.common_mode_filter.c_a[1].connect_via(self.tvs, diode_junction) + self.common_mode_filter.c_b[1].connect_via( + self.clamping_diodes[0], diode_junction ) - self.NODEs.clamping_diodes[1].IFs.anode.connect(diode_junction) + self.common_mode_filter.c_b[1].connect(self.clamping_diodes[1].cathode) + self.clamping_diodes[1].anode.connect(diode_junction) - self.add_trait(can_bridge_defined(self.IFs.rs485_in, self.IFs.rs485_out)) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.rs485_in, self.rs485_out) # TODO: layout is only working when bbox is implemented or # when using specific components @@ -167,7 +131,7 @@ class _PARAMs(Module.PARAMS()): ... # PCB layout Point = has_pcb_position.Point L = has_pcb_position.layer_type - self.NODEs.gnd_couple_resistor.add_trait( + self.gnd_couple_resistor.add_trait( has_pcb_layout_defined( LayoutAbsolute( Point((-10, 0, 90, L.NONE)), @@ -205,14 +169,14 @@ class _PARAMs(Module.PARAMS()): ... ), ), LayoutTypeHierarchy.Level( - mod_type=Resistor, + mod_type=F.Resistor, layout=LayoutExtrude( base=Point((-2, 8, 90, L.NONE)), vector=(0, 4, 0), ), ), LayoutTypeHierarchy.Level( - mod_type=Capacitor, + mod_type=F.Capacitor, layout=LayoutAbsolute( Point((10, 0, 90, L.NONE)), ), diff --git a/src/faebryk/library/Relay.py b/src/faebryk/library/Relay.py index 22375d6e..2d35d70f 100644 --- a/src/faebryk/library/Relay.py +++ b/src/faebryk/library/Relay.py @@ -4,9 +4,8 @@ import logging from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) @@ -14,33 +13,26 @@ # TODO: make generic (use Switch module, different switch models, bistable, etc.) class Relay(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - switch_a_nc = Electrical() - switch_a_common = Electrical() - switch_a_no = Electrical() - switch_b_no = Electrical() - switch_b_common = Electrical() - switch_b_nc = Electrical() - coil_p = Electrical() - coil_n = Electrical() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): - coil_rated_voltage = TBD[Quantity]() - coil_rated_current = TBD[Quantity]() - coil_resistance = TBD[Quantity]() - contact_max_switching_voltage = TBD[Quantity]() - contact_rated_switching_current = TBD[Quantity]() - contact_max_switchng_current = TBD[Quantity]() + switch_a_nc: F.Electrical + switch_a_common: F.Electrical + switch_a_no: F.Electrical + switch_b_no: F.Electrical + switch_b_common: F.Electrical + switch_b_nc: F.Electrical + coil_p: F.Electrical + coil_n: F.Electrical + - self.PARAMs = _PARAMs(self) + coil_rated_voltage : F.TBD[Quantity] + coil_rated_current : F.TBD[Quantity] + coil_resistance : F.TBD[Quantity] + contact_max_switching_voltage : F.TBD[Quantity] + contact_rated_switching_current : F.TBD[Quantity] + contact_max_switchng_current : F.TBD[Quantity] - self.add_trait(has_designator_prefix_defined("RELAY")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("RELAY") diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index 2a17b478..c39b6cbd 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -8,45 +8,37 @@ as_unit, as_unit_with_tolerance, ) -from faebryk.library.can_attach_to_footprint_symmetrically import ( - can_attach_to_footprint_symmetrically, -) -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_multi_picker import has_multi_picker -from faebryk.library.has_simple_value_representation_based_on_params import ( - has_simple_value_representation_based_on_params, -) -from faebryk.library.TBD import TBD + + + + + from faebryk.libs.picker.picker import PickError, has_part_picked_remove from faebryk.libs.units import P, Quantity -from faebryk.libs.util import times + class Resistor(Module): - def __init__(self): - super().__init__() - class _IFs(super().IFS()): - unnamed = L.if_list(2, Electrical) - self.IFs = _IFs(self) - self.add_trait(can_bridge_defined(*self.IFs.unnamed)) + unnamed = L.if_list(2, F.Electrical) + + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(*self.unnamed) - class PARAMS(super().PARAMS()): - resistance = TBD[Quantity]() - rated_power = TBD[Quantity]() - rated_voltage = TBD[Quantity]() - self.PARAMs = PARAMS(self) + resistance : F.TBD[Quantity] + rated_power : F.TBD[Quantity] + rated_voltage : F.TBD[Quantity] self.add_trait(can_attach_to_footprint_symmetrically()) - self.add_trait( - has_simple_value_representation_based_on_params( + @L.rt_field + def simple_value_representation(self): + return F.has_simple_value_representation_based_on_params( ( - self.PARAMs.resistance, - self.PARAMs.rated_power, + self.resistance, + self.rated_power, ), lambda ps: " ".join( filter( @@ -56,7 +48,7 @@ class PARAMS(super().PARAMS()): ), ) ) - self.add_trait(has_designator_prefix_defined("R")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("R") def allow_removal_if_zero(self): import faebryk.library._F as F @@ -64,12 +56,12 @@ def allow_removal_if_zero(self): def replace_zero(m: Module): assert m is self - r = self.PARAMs.resistance.get_most_narrow() + r = self.resistance.get_most_narrow() if not F.Constant(0.0 * P.ohm).is_subset_of(r): raise PickError("", self) - self.PARAMs.resistance.override(F.Constant(0.0 * P.ohm)) - self.IFs.unnamed[0].connect(self.IFs.unnamed[1]) + self.resistance.override(F.Constant(0.0 * P.ohm)) + self.unnamed[0].connect(self.unnamed[1]) self.add_trait(has_part_picked_remove()) has_multi_picker.add_to_module( @@ -77,10 +69,10 @@ def replace_zero(m: Module): ) def get_voltage_drop_by_current_resistance(self, current_A: Parameter) -> Parameter: - return current_A * self.PARAMs.resistance + return current_A * self.resistance def get_voltage_drop_by_power_resistance(self, power_W: Parameter) -> Parameter: - return sqrt(power_W * self.PARAMs.resistance) + return sqrt(power_W * self.resistance) @staticmethod def set_voltage_drop_by_power_current( @@ -91,10 +83,10 @@ def set_voltage_drop_by_power_current( def get_current_flow_by_voltage_resistance( self, voltage_drop_V: Parameter ) -> Parameter: - return voltage_drop_V / self.PARAMs.resistance + return voltage_drop_V / self.resistance def get_current_flow_by_power_resistance(self, power_W: Parameter) -> Parameter: - return sqrt(power_W / self.PARAMs.resistance) + return sqrt(power_W / self.resistance) @staticmethod def get_current_flow_by_voltage_power( @@ -105,30 +97,30 @@ def get_current_flow_by_voltage_power( def set_resistance_by_voltage_current( self, voltage_drop_V: Parameter, current_A: Parameter ) -> Parameter: - self.PARAMs.resistance.merge(voltage_drop_V / current_A) - return self.PARAMs.resistance.get_most_narrow() + self.resistance.merge(voltage_drop_V / current_A) + return self.resistance.get_most_narrow() def set_resistance_by_voltage_power( self, voltage_drop_V: Parameter, power_W: Parameter ) -> Parameter: - self.PARAMs.resistance.merge(pow(voltage_drop_V, 2) / power_W) - return self.PARAMs.resistance.get_most_narrow() + self.resistance.merge(pow(voltage_drop_V, 2) / power_W) + return self.resistance.get_most_narrow() def set_resistance_by_power_current( self, current_A: Parameter, power_W: Parameter ) -> Parameter: - self.PARAMs.resistance.merge(power_W / pow(current_A, 2)) - return self.PARAMs.resistance.get_most_narrow() + self.resistance.merge(power_W / pow(current_A, 2)) + return self.resistance.get_most_narrow() def get_power_dissipation_by_voltage_resistance( self, voltage_drop_V: Parameter ) -> Parameter: - return pow(voltage_drop_V, 2) / self.PARAMs.resistance + return pow(voltage_drop_V, 2) / self.resistance def get_power_dissipation_by_current_resistance( self, current_A: Parameter ) -> Parameter: - return pow(current_A, 2) * self.PARAMs.resistance + return pow(current_A, 2) * self.resistance @staticmethod def get_power_dissipation_by_voltage_current( @@ -137,11 +129,11 @@ def get_power_dissipation_by_voltage_current( return voltage_drop_V * current_A def set_rated_power_by_voltage_resistance(self, voltage_drop_V: Parameter): - self.PARAMs.rated_power.merge( + self.rated_power.merge( self.get_power_dissipation_by_voltage_resistance(voltage_drop_V) ) def set_rated_power_by_current_resistance(self, current_A: Parameter): - self.PARAMs.rated_power.merge( + self.rated_power.merge( self.get_power_dissipation_by_current_resistance(current_A) ) diff --git a/src/faebryk/library/Resistor_Voltage_Divider.py b/src/faebryk/library/Resistor_Voltage_Divider.py index 5f83a3b6..69d50bc1 100644 --- a/src/faebryk/library/Resistor_Voltage_Divider.py +++ b/src/faebryk/library/Resistor_Voltage_Divider.py @@ -4,37 +4,30 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.Resistor import Resistor -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity -from faebryk.libs.util import times + logger = logging.getLogger(__name__) class Resistor_Voltage_Divider(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): - resistor = L.if_list(2, Resistor) - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - node = L.if_list(3, Electrical) + resistor = L.if_list(2, Resistor) + - self.IFs = _IFs(self) + node = L.if_list(3, F.Electrical) - class _PARAMs(Module.PARAMS()): - ratio = TBD[Quantity]() - max_current = TBD[Quantity]() - self.PARAMs = _PARAMs(self) + ratio : F.TBD[Quantity] + max_current : F.TBD[Quantity] - self.IFs.node[0].connect_via(self.NODEs.resistor[0], self.IFs.node[1]) - self.IFs.node[1].connect_via(self.NODEs.resistor[1], self.IFs.node[2]) + self.node[0].connect_via(self.resistor[0], self.node[1]) + self.node[1].connect_via(self.resistor[1], self.node[2]) - self.add_trait(can_bridge_defined(self.IFs.node[0], self.IFs.node[1])) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.node[0], self.node[1]) diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index 65406986..20545e66 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -4,18 +4,9 @@ from dataclasses import dataclass, field from faebryk.core.module import Module, Parameter -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Constant import Constant -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.I2C import I2C -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.TBD import TBD + + + from faebryk.libs.units import P @@ -26,20 +17,20 @@ class SCD40(Module): @dataclass class _scd4x_esphome_config(has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=TBD) + update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: super().__init__() def get_config(self) -> dict: assert isinstance( - self.update_interval_s, Constant + self.update_interval_s, F.Constant ), "No update interval set!" obj = self.get_obj() assert isinstance(obj, SCD40) - i2c = is_esphome_bus.find_connected_bus(obj.IFs.i2c) + i2c = is_esphome_bus.find_connected_bus(obj.i2c) return { "sensor": [ @@ -61,37 +52,34 @@ def get_config(self) -> dict: ] } - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - power = ElectricPower() - i2c = I2C() - self.IFs = _IFs(self) + power: F.ElectricPower + i2c = I2C() self.add_trait( can_attach_to_footprint_via_pinmap( { - "6": self.IFs.power.IFs.lv, - "20": self.IFs.power.IFs.lv, - "21": self.IFs.power.IFs.lv, - "7": self.IFs.power.IFs.hv, - "19": self.IFs.power.IFs.hv, - "9": self.IFs.i2c.IFs.scl.IFs.signal, - "10": self.IFs.i2c.IFs.sda.IFs.signal, + "6": self.power.lv, + "20": self.power.lv, + "21": self.power.lv, + "7": self.power.hv, + "19": self.power.hv, + "9": self.i2c.scl.signal, + "10": self.i2c.sda.signal, } ) ) - self.IFs.power.PARAMs.voltage.merge(Constant(3.3 * P.V)) + self.power.voltage.merge(F.Constant(3.3 * P.V)) - self.IFs.i2c.terminate() - self.IFs.power.get_trait(can_be_decoupled).decouple() + self.i2c.terminate() + self.power.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) - self.IFs.i2c.PARAMs.frequency.merge( + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + self.i2c.frequency.merge( I2C.define_max_frequency_capability(I2C.SpeedMode.fast_speed) ) self.add_trait( @@ -100,6 +88,6 @@ class _IFs(Module.IFS()): ) ) - self.IFs.i2c.add_trait(is_esphome_bus.impl()()) + self.i2c.add_trait(is_esphome_bus.impl()()) self.esphome = self._scd4x_esphome_config() self.add_trait(self.esphome) diff --git a/src/faebryk/library/SK9822_EC20.py b/src/faebryk/library/SK9822_EC20.py index 1202012d..e786238e 100644 --- a/src/faebryk/library/SK9822_EC20.py +++ b/src/faebryk/library/SK9822_EC20.py @@ -2,18 +2,11 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) + + + + + class SK9822_EC20(Module): @@ -22,7 +15,7 @@ class SK9822_EC20(Module): (RGB) driving intelligent control circuit and the light emitting circuit in one of the LED light source control. Products containing a signal - decoding module, data buffer, a built-in Constant + decoding module, data buffer, a built-in F.Constant current circuit and RC oscillator; CMOS, low voltage, low power consumption; 256 level grayscale PWM adjustment and 32 brightness adjustment; @@ -31,35 +24,32 @@ class SK9822_EC20(Module): output action synchronization. """ - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - power = ElectricPower() - sdo = ElectricLogic() - sdi = ElectricLogic() - cko = ElectricLogic() - ckl = ElectricLogic() - self.IFs = _IFs(self) + power: F.ElectricPower + sdo: F.ElectricLogic + sdi: F.ElectricLogic + cko: F.ElectricLogic + ckl: F.ElectricLogic - x = self.IFs + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": x.sdo.IFs.signal, - "2": x.power.IFs.lv, - "3": x.sdi.IFs.signal, - "4": x.ckl.IFs.signal, - "5": x.power.IFs.hv, - "6": x.cko.IFs.signal, + "1": x.sdo.signal, + "2": x.power.lv, + "3": x.sdi.signal, + "4": x.ckl.signal, + "5": x.power.hv, + "6": x.cko.signal, } ) ) # connect all logic references - ref = ElectricLogic.connect_all_module_references(self) + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) self.add_trait( @@ -68,4 +58,4 @@ class _IFs(Module.IFS()): ) ) - self.add_trait(has_designator_prefix_defined("LED")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("LED") diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index 8e43a554..84112431 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -3,14 +3,11 @@ from enum import Enum -from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -from faebryk.library.Footprint import Footprint -from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -from faebryk.library.Pad import Pad -from faebryk.libs.util import times -class SMDTwoPin(Footprint): + + +class SMDTwoPin(F.Footprint): class Type(Enum): _01005 = 0 _0201 = 1 @@ -26,10 +23,9 @@ class Type(Enum): def __init__(self, type: Type) -> None: super().__init__() - class _IFs(Footprint.IFS()): + pins = L.if_list(2, Pad) - self.IFs = _IFs(self) from faebryk.library.has_kicad_footprint_equal_ifs import ( has_kicad_footprint_equal_ifs, ) @@ -49,7 +45,7 @@ def get_kicad_footprint() -> str: self.Type._2010: "5025", self.Type._2512: "6332", } - return "Resistor_SMD:R_{imperial}_{metric}Metric".format( + return "F.Resistor_SMD:R_{imperial}_{metric}Metric".format( imperial=type.name[1:], metric=table[type] ) diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index 4a31b059..3924a5e0 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -4,7 +4,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.units import P -from faebryk.libs.util import times + class SNx4LVC541A(Module): @@ -14,26 +14,20 @@ class SNx4LVC541A(Module): octal buffer/driver is designed for 1.65-V to 3.6-V VCC operation. """ - def __init__(self): - super().__init__() # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) - class _IFs(Module.IFS()): + A = L.if_list(8, F.ElectricLogic) Y = L.if_list(8, F.ElectricLogic) - vcc = F.ElectricPower() + vcc: F.ElectricPower OE = L.if_list(2, F.ElectricLogic) - self.IFs = _IFs(self) - # ---------------------------------------- # traits # ---------------------------------------- @@ -47,7 +41,7 @@ class _IFs(Module.IFS()): # ---------------------------------------- # parameters # ---------------------------------------- - self.IFs.vcc.PARAMs.voltage.merge(F.Range.upper_bound(3.6 * P.V)) + self.vcc.voltage.merge(F.Range.upper_bound(3.6 * P.V)) # ---------------------------------------- # aliases @@ -56,10 +50,10 @@ class _IFs(Module.IFS()): # ---------------------------------------- # connections # ---------------------------------------- - self.IFs.vcc.get_trait(F.can_be_decoupled).decouple() + self.vcc.get_trait(F.can_be_decoupled).decouple() # set all electric logic references - for a, y, oe in zip(self.IFs.A, self.IFs.Y, self.IFs.OE): - a.connect_reference(self.IFs.vcc) - y.connect_reference(self.IFs.vcc) - oe.connect_reference(self.IFs.vcc) + for a, y, oe in zip(self.A, self.Y, self.OE): + a.connect_reference(self.vcc) + y.connect_reference(self.vcc) + oe.connect_reference(self.vcc) diff --git a/src/faebryk/library/SOIC.py b/src/faebryk/library/SOIC.py index 21e6086a..618ddeb9 100644 --- a/src/faebryk/library/SOIC.py +++ b/src/faebryk/library/SOIC.py @@ -1,15 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -from faebryk.library.Footprint import Footprint -from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -from faebryk.library.Pad import Pad + from faebryk.libs.units import P, Quantity -from faebryk.libs.util import times -class SOIC(Footprint): + +class SOIC(F.Footprint): def __init__( self, pin_cnt: int, @@ -18,10 +15,9 @@ def __init__( ) -> None: super().__init__() - class _IFs(Footprint.IFS()): + pins = L.if_list(pin_cnt, Pad) - self.IFs = _IFs(self) from faebryk.library.has_kicad_footprint_equal_ifs import ( has_kicad_footprint_equal_ifs, ) diff --git a/src/faebryk/library/SPI.py b/src/faebryk/library/SPI.py index 5401a186..7da5a4ec 100644 --- a/src/faebryk/library/SPI.py +++ b/src/faebryk/library/SPI.py @@ -2,17 +2,10 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Electrical import Electrical class SPI(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - - class IFS(ModuleInterface.IFS()): - sclk = Electrical() - miso = Electrical() - mosi = Electrical() - gnd = Electrical() - - self.IFs = IFS(self) + sclk: F.Electrical + miso: F.Electrical + mosi: F.Electrical + gnd: F.Electrical diff --git a/src/faebryk/library/SPIFlash.py b/src/faebryk/library/SPIFlash.py index 8603e3c8..ffb18d92 100644 --- a/src/faebryk/library/SPIFlash.py +++ b/src/faebryk/library/SPIFlash.py @@ -2,26 +2,19 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module, ModuleInterface -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.MultiSPI import MultiSPI -from faebryk.library.TBD import TBD + + from faebryk.libs.units import Quantity class SPIFlash(Module): - def __init__(self) -> None: - super().__init__() - class IFS(ModuleInterface.IFS()): - power = ElectricPower() - spi = MultiSPI() - self.IFs = IFS(self) - class PARAMS(ModuleInterface.PARAMS()): - memory_size = TBD[Quantity]() + power: F.ElectricPower + spi = MultiSPI() + - self.PARAMs = PARAMS(self) + memory_size: F.TBD[Quantity] - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/SWD.py b/src/faebryk/library/SWD.py index dfe34dd0..f6e6cf59 100644 --- a/src/faebryk/library/SWD.py +++ b/src/faebryk/library/SWD.py @@ -2,30 +2,23 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) + + class SWD(ModuleInterface): - def __init__(self) -> None: - super().__init__() - class IFS(ModuleInterface.IFS()): - clk = ElectricLogic() - dio = ElectricLogic() - swo = ElectricLogic() - reset = ElectricLogic() - self.IFs = IFS(self) - class PARAMS(ModuleInterface.PARAMS()): ... + clk: F.ElectricLogic + dio: F.ElectricLogic + swo: F.ElectricLogic + reset: F.ElectricLogic + - self.PARAMs = PARAMS(self) - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) diff --git a/src/faebryk/library/SWDConnector.py b/src/faebryk/library/SWDConnector.py index 0a1aeb88..e85640b2 100644 --- a/src/faebryk/library/SWDConnector.py +++ b/src/faebryk/library/SWDConnector.py @@ -2,34 +2,25 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module, ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.SWD import SWD + + + class SWDConnector(Module): - def __init__(self) -> None: - super().__init__() - class IFS(ModuleInterface.IFS()): - swd = SWD() - gnd_detect = ElectricLogic() - vcc = ElectricPower() - self.IFs = IFS(self) - class PARAMS(ModuleInterface.PARAMS()): ... + swd = SWD() + gnd_detect: F.ElectricLogic + vcc: F.ElectricPower + - self.PARAMs = PARAMS(self) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) diff --git a/src/faebryk/library/Sercom.py b/src/faebryk/library/Sercom.py index 3b8872f1..f69ee48d 100644 --- a/src/faebryk/library/Sercom.py +++ b/src/faebryk/library/Sercom.py @@ -2,21 +2,16 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module, ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.libs.util import times + + + class Sercom(ModuleInterface): - def __init__(self) -> None: - super().__init__() - class IFS(Module.IFS()): - unnamed = L.if_list(4, ElectricLogic) - self.IFs = IFS(self) - ref = ElectricLogic.connect_all_module_references(self) + unnamed = L.if_list(4, F.ElectricLogic) + + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) diff --git a/src/faebryk/library/Set.py b/src/faebryk/library/Set.py index 41ca9f41..3b9facc5 100644 --- a/src/faebryk/library/Set.py +++ b/src/faebryk/library/Set.py @@ -10,13 +10,11 @@ class Set[PV](Parameter[PV], Parameter[PV].SupportsSetOps): type LIT_OR_PARAM = Parameter[PV].LIT_OR_PARAM def __init__(self, params: Iterable[Parameter[LIT_OR_PARAM]]) -> None: - from faebryk.library.Constant import Constant - super().__init__() # make primitves to constants self._params = set( - p if isinstance(p, Parameter) else Constant(p) for p in params + p if isinstance(p, Parameter) else F.Constant(p) for p in params ) @staticmethod @@ -68,12 +66,10 @@ def copy(self) -> Self: @_resolved def __contains__(self, other: Parameter[PV]) -> bool: - from faebryk.library.Range import Range - def nested_in(p): if other == p: return True - if isinstance(p, Range): + if isinstance(p, F.Range): return other in p return False diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index ebc26df5..e8280ff9 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -5,14 +5,10 @@ from typing import Generic, TypeGuard, TypeVar from faebryk.core.module import Module, ModuleInterface -from faebryk.library.can_attach_to_footprint_symmetrically import ( - can_attach_to_footprint_symmetrically, -) -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.libs.util import times + + + + T = TypeVar("T", bound=ModuleInterface) @@ -33,14 +29,15 @@ class _Switch(_TSwitch[interface_type]): def __init__(self) -> None: super().__init__(interface_type) - self.add_trait(has_designator_prefix_defined("SW")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("SW") self.add_trait(can_attach_to_footprint_symmetrically()) - class _IFs(super().IFS()): + unnamed = L.if_list(2, interface_type) - self.IFs = _IFs(self) - self.add_trait(can_bridge_defined(*self.IFs.unnamed)) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(*self.unnamed) @staticmethod def is_instance(obj: Module) -> "TypeGuard[_Switch]": diff --git a/src/faebryk/library/TBD.py b/src/faebryk/library/TBD.py index 0b34cfc5..b5b89035 100644 --- a/src/faebryk/library/TBD.py +++ b/src/faebryk/library/TBD.py @@ -10,9 +10,6 @@ class TBD(Generic[PV], Parameter[PV]): - def __init__(self) -> None: - super().__init__() - def __eq__(self, __value: object) -> bool: if isinstance(__value, TBD): return True diff --git a/src/faebryk/library/TD541S485H.py b/src/faebryk/library/TD541S485H.py index 5777c5ea..b998058c 100644 --- a/src/faebryk/library/TD541S485H.py +++ b/src/faebryk/library/TD541S485H.py @@ -4,68 +4,54 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.RS485 import RS485 -from faebryk.library.UART_Base import UART_Base + + logger = logging.getLogger(__name__) class TD541S485H(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() - power_iso_in = ElectricPower() - power_iso_out = ElectricPower() + + + power: F.ElectricPower + power_iso_in: F.ElectricPower + power_iso_out: F.ElectricPower uart = UART_Base() rs485 = RS485() - read_enable = Electrical() - write_enable = Electrical() - - self.IFs = _IFs(self) + read_enable: F.Electrical + write_enable: F.Electrical - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) - self.IFs.power.get_trait(can_be_decoupled).decouple() - self.IFs.power_iso_in.get_trait(can_be_decoupled).decouple() - self.IFs.power_iso_out.get_trait(can_be_decoupled).decouple() + self.power.get_trait(can_be_decoupled).decouple() + self.power_iso_in.get_trait(can_be_decoupled).decouple() + self.power_iso_out.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.IFs.power_iso_in.IFs.lv.connect(self.IFs.power_iso_out.IFs.lv) + self.power_iso_in.lv.connect(self.power_iso_out.lv) - x = self.IFs + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": x.power.IFs.lv, - "2": x.power.IFs.hv, - "3": x.uart.IFs.rx.IFs.signal, + "1": x.power.lv, + "2": x.power.hv, + "3": x.uart.rx.signal, "4": x.read_enable, "5": x.write_enable, - "6": x.uart.IFs.tx.IFs.signal, - "7": x.power.IFs.hv, - "8": x.power.IFs.lv, - "9": x.power_iso_out.IFs.lv, - "10": x.power_iso_out.IFs.hv, - "13": x.rs485.IFs.diff_pair.IFs.n, - "14": x.rs485.IFs.diff_pair.IFs.p, - "15": x.power_iso_in.IFs.hv, - "16": x.power_iso_in.IFs.lv, + "6": x.uart.tx.signal, + "7": x.power.hv, + "8": x.power.lv, + "9": x.power_iso_out.lv, + "10": x.power_iso_out.hv, + "13": x.rs485.diff_pair.n, + "14": x.rs485.diff_pair.p, + "15": x.power_iso_in.hv, + "16": x.power_iso_in.lv, } ) ) diff --git a/src/faebryk/library/TI_CD4011BE.py b/src/faebryk/library/TI_CD4011BE.py index 24216257..12de1e62 100644 --- a/src/faebryk/library/TI_CD4011BE.py +++ b/src/faebryk/library/TI_CD4011BE.py @@ -1,45 +1,37 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.CD4011 import CD4011 -from faebryk.library.DIP import DIP -from faebryk.library.has_defined_descriptive_properties import ( - has_defined_descriptive_properties, -) -from faebryk.library.has_defined_footprint import has_defined_footprint + from faebryk.libs.picker.picker import DescriptiveProperties from faebryk.libs.units import P class TI_CD4011BE(CD4011): - def __init__(self): - super().__init__() - fp = DIP(pin_cnt=14, spacing=7.62 * P.mm, long_pads=False) - self.add_trait(has_defined_footprint(fp)) - fp.get_trait(can_attach_via_pinmap).attach( - { - "7": self.IFs.power.IFs.lv, - "14": self.IFs.power.IFs.hv, - "3": self.NODEs.gates[0].IFs.outputs[0].IFs.signal, - "4": self.NODEs.gates[1].IFs.outputs[0].IFs.signal, - "11": self.NODEs.gates[2].IFs.outputs[0].IFs.signal, - "10": self.NODEs.gates[3].IFs.outputs[0].IFs.signal, - "1": self.NODEs.gates[0].IFs.inputs[0].IFs.signal, - "2": self.NODEs.gates[0].IFs.inputs[1].IFs.signal, - "5": self.NODEs.gates[1].IFs.inputs[0].IFs.signal, - "6": self.NODEs.gates[1].IFs.inputs[1].IFs.signal, - "12": self.NODEs.gates[2].IFs.inputs[0].IFs.signal, - "13": self.NODEs.gates[2].IFs.inputs[1].IFs.signal, - "9": self.NODEs.gates[3].IFs.inputs[0].IFs.signal, - "8": self.NODEs.gates[3].IFs.inputs[1].IFs.signal, - } - ) + fp = DIP(pin_cnt=14, spacing=7.62 * P.mm, long_pads=False) + self.add_trait(has_defined_footprint(fp)) + fp.get_trait(can_attach_via_pinmap).attach( + { + "7": self.power.lv, + "14": self.power.hv, + "3": self.gates[0].outputs[0].signal, + "4": self.gates[1].outputs[0].signal, + "11": self.gates[2].outputs[0].signal, + "10": self.gates[3].outputs[0].signal, + "1": self.gates[0].inputs[0].signal, + "2": self.gates[0].inputs[1].signal, + "5": self.gates[1].inputs[0].signal, + "6": self.gates[1].inputs[1].signal, + "12": self.gates[2].inputs[0].signal, + "13": self.gates[2].inputs[1].signal, + "9": self.gates[3].inputs[0].signal, + "8": self.gates[3].inputs[1].signal, + } + ) - has_defined_descriptive_properties.add_properties_to( - self, - { - DescriptiveProperties.manufacturer: "Texas Instruments", - DescriptiveProperties.partno: "CD4011BE", - }, - ) + has_defined_descriptive_properties.add_properties_to( + self, + { + DescriptiveProperties.manufacturer: "Texas Instruments", + DescriptiveProperties.partno: "CD4011BE", + }, + ) diff --git a/src/faebryk/library/TVS.py b/src/faebryk/library/TVS.py index 4c29db42..8f2fd68c 100644 --- a/src/faebryk/library/TVS.py +++ b/src/faebryk/library/TVS.py @@ -3,18 +3,11 @@ import logging -from faebryk.library.Diode import Diode -from faebryk.library.TBD import TBD + from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) class TVS(Diode): - def __init__(self): - super().__init__() - - class _PARAMs(Diode.PARAMS()): - reverse_breakdown_voltage = TBD[Quantity]() - - self.PARAMs = _PARAMs(self) + reverse_breakdown_voltage: F.TBD[Quantity] diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index 3edb87c8..14c4f2e0 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -2,15 +2,10 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.libs.util import times + + + + class TXS0102DCUR(Module): @@ -24,57 +19,50 @@ def __init__(self) -> None: super().__init__() # interfaces - class _IFs(Module.IFS()): - io_a = ElectricLogic() - io_b = ElectricLogic() - self.IFs = _IFs(self) + io_a: F.ElectricLogic + io_b: F.ElectricLogic # TODO: bridge shallow - # self.add_trait(can_bridge_defined(self.IFs.io_a, self.IFs.io_b)) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.io_a, self.io_b) + - def __init__(self) -> None: - super().__init__() # interfaces - class _IFs(Module.IFS()): - voltage_a_power = ElectricPower() - voltage_b_power = ElectricPower() - n_oe = ElectricLogic() - self.IFs = _IFs(self) + voltage_a_power: F.ElectricPower + voltage_b_power: F.ElectricPower + n_oe: F.ElectricLogic - class _NODEs(Module.NODES()): - shifters = L.if_list(2, self._BidirectionalLevelShifter) - self.NODEs = _NODEs(self) + shifters = L.if_list(2, self._BidirectionalLevelShifter) - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) - gnd = self.IFs.voltage_a_power.IFs.lv - gnd.connect(self.IFs.voltage_b_power.IFs.lv) + gnd = self.voltage_a_power.lv + gnd.connect(self.voltage_b_power.lv) - self.IFs.voltage_a_power.get_trait(can_be_decoupled).decouple() - self.IFs.voltage_b_power.get_trait(can_be_decoupled).decouple() + self.voltage_a_power.get_trait(can_be_decoupled).decouple() + self.voltage_b_power.get_trait(can_be_decoupled).decouple() # eo is referenced to voltage_a_power (active high) - self.IFs.n_oe.connect_reference(self.IFs.voltage_a_power) + self.n_oe.connect_reference(self.voltage_a_power) - for shifter in self.NODEs.shifters: - side_a = shifter.IFs.io_a - # side_a.IFs.reference.connect(self.IFs.voltage_a_power) + for shifter in self.shifters: + side_a = shifter.io_a + # side_a.reference.connect(self.voltage_a_power) side_a.add_trait( - has_single_electric_reference_defined(self.IFs.voltage_a_power) + has_single_electric_reference_defined(self.voltage_a_power) ) - side_b = shifter.IFs.io_b - # side_b.IFs.reference.connect(self.IFs.voltage_b_power) + side_b = shifter.io_b + # side_b.reference.connect(self.voltage_b_power) side_b.add_trait( - has_single_electric_reference_defined(self.IFs.voltage_b_power) + has_single_electric_reference_defined(self.voltage_b_power) ) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( has_datasheet_defined( diff --git a/src/faebryk/library/TXS0102DCUR_UART.py b/src/faebryk/library/TXS0102DCUR_UART.py index f5f352af..d66b121c 100644 --- a/src/faebryk/library/TXS0102DCUR_UART.py +++ b/src/faebryk/library/TXS0102DCUR_UART.py @@ -2,9 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.TXS0102DCUR import TXS0102DCUR -from faebryk.library.UART_Base import UART_Base class TXS0102DCUR_UART(Module): @@ -13,43 +10,30 @@ class TXS0102DCUR_UART(Module): - Output enabled by default """ - def __init__(self) -> None: - super().__init__() - class _IFs(Module.IFS()): - voltage_a_power = ElectricPower() - voltage_b_power = ElectricPower() + + + voltage_a_power: F.ElectricPower + voltage_b_power: F.ElectricPower voltage_a_bus = UART_Base() voltage_b_bus = UART_Base() - self.IFs = _IFs(self) - class _NODEs(Module.NODES()): buffer = TXS0102DCUR() - self.NODEs = _NODEs(self) - - self.IFs.voltage_a_power.connect(self.NODEs.buffer.IFs.voltage_a_power) - self.IFs.voltage_b_power.connect(self.NODEs.buffer.IFs.voltage_b_power) + self.voltage_a_power.connect(self.buffer.voltage_a_power) + self.voltage_b_power.connect(self.buffer.voltage_b_power) # enable output by default - self.NODEs.buffer.IFs.n_oe.set(True) + self.buffer.n_oe.set(True) # connect UART interfaces to level shifter - self.IFs.voltage_a_bus.IFs.rx.connect( - self.NODEs.buffer.NODEs.shifters[0].IFs.io_a - ) - self.IFs.voltage_a_bus.IFs.tx.connect( - self.NODEs.buffer.NODEs.shifters[1].IFs.io_a - ) - self.IFs.voltage_b_bus.IFs.rx.connect( - self.NODEs.buffer.NODEs.shifters[0].IFs.io_b - ) - self.IFs.voltage_b_bus.IFs.tx.connect( - self.NODEs.buffer.NODEs.shifters[1].IFs.io_b - ) + self.voltage_a_bus.rx.connect(self.buffer.shifters[0].io_a) + self.voltage_a_bus.tx.connect(self.buffer.shifters[1].io_a) + self.voltage_b_bus.rx.connect(self.buffer.shifters[0].io_b) + self.voltage_b_bus.tx.connect(self.buffer.shifters[1].io_b) # TODO # self.add_trait( - # can_bridge_defined(self.IFs.voltage_a_bus, self.IFs.voltage_b_bus) + # can_bridge_defined(self.voltage_a_bus, self.voltage_b_bus) # ) diff --git a/src/faebryk/library/UART.py b/src/faebryk/library/UART.py index 8a4ff5b3..dc47b5ce 100644 --- a/src/faebryk/library/UART.py +++ b/src/faebryk/library/UART.py @@ -2,19 +2,11 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Electrical import Electrical -from faebryk.library.UART_Base import UART_Base class UART(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - - class IFS(super().IFS()): - base_uart = UART_Base() - rts = Electrical() - cts = Electrical() - dtr = Electrical() - dsr = Electrical() - - self.IFs = IFS(self) + base_uart = UART_Base() + rts: F.Electrical + cts: F.Electrical + dtr: F.Electrical + dsr: F.Electrical diff --git a/src/faebryk/library/UART_Base.py b/src/faebryk/library/UART_Base.py index f12f67be..e5d80733 100644 --- a/src/faebryk/library/UART_Base.py +++ b/src/faebryk/library/UART_Base.py @@ -2,33 +2,26 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.TBD import TBD + + + from faebryk.libs.units import Quantity class UART_Base(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - class IFS(ModuleInterface.IFS()): - rx = ElectricLogic() - tx = ElectricLogic() - self.IFs = IFS(self) - class PARAMS(ModuleInterface.PARAMS()): - baud = TBD[Quantity]() + rx: F.ElectricLogic + tx: F.ElectricLogic + - self.PARAMs = PARAMS(self) + baud: F.TBD[Quantity] - ref = ElectricLogic.connect_all_module_references(self) + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) def _on_connect(self, other: "UART_Base"): super()._on_connect(other) - self.PARAMs.baud.merge(other.PARAMs.baud) + self.baud.merge(other.baud) diff --git a/src/faebryk/library/UART_RS485.py b/src/faebryk/library/UART_RS485.py index ea651c2b..6ce66e88 100644 --- a/src/faebryk/library/UART_RS485.py +++ b/src/faebryk/library/UART_RS485.py @@ -4,44 +4,31 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.Range import Range -from faebryk.library.RS485 import RS485 -from faebryk.library.TBD import TBD -from faebryk.library.UART_Base import UART_Base + + from faebryk.libs.units import P, Quantity logger = logging.getLogger(__name__) class UART_RS485(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - power = ElectricPower() + + + power: F.ElectricPower uart = UART_Base() rs485 = RS485() - read_enable = Electrical() - write_enable = Electrical() - - self.IFs = _IFs(self) + read_enable: F.Electrical + write_enable: F.Electrical - class _PARAMs(Module.PARAMS()): - max_data_rate = TBD[Quantity]() - gpio_voltage = TBD[Quantity]() - self.PARAMs = _PARAMs(self) + max_data_rate : F.TBD[Quantity] + gpio_voltage : F.TBD[Quantity] - self.IFs.power.PARAMs.voltage.merge(Range(3.3 * P.V, 5.0 * P.V)) + self.power.voltage.merge(F.Range(3.3 * P.V, 5.0 * P.V)) - self.IFs.power.get_trait(can_be_decoupled).decouple() + self.power.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 902657dc..8cfec37b 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -5,16 +5,9 @@ from enum import Enum, auto from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.I2C import I2C -from faebryk.library.TBD import TBD -from faebryk.libs.util import times + + + logger = logging.getLogger(__name__) @@ -26,95 +19,79 @@ class InterfaceConfiguration(Enum): BUS_POWERED = auto() EEPROM = auto() - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - VDD33 = ElectricPower() - VDDA33 = ElectricPower() - PLLFILT = ElectricPower() - CRFILT = ElectricPower() - VBUS_DET = Electrical() + VDD33: F.ElectricPower + VDDA33: F.ElectricPower + + PLLFILT: F.ElectricPower + CRFILT: F.ElectricPower + + VBUS_DET: F.Electrical usb_downstream = L.if_list(4, DifferentialPair) usb_upstream = DifferentialPair() - XTALIN = Electrical() - XTALOUT = Electrical() + XTALIN: F.Electrical + XTALOUT: F.Electrical - TEST = Electrical() - SUSP_IND = ElectricLogic() - RESET_N = Electrical() - RBIAS = Electrical() - NON_REM = L.if_list(2, ElectricLogic) - LOCAL_PWR = Electrical() - CLKIN = Electrical() - CFG_SEL = L.if_list(2, ElectricLogic) + TEST: F.Electrical + SUSP_IND: F.ElectricLogic + RESET_N: F.Electrical + RBIAS: F.Electrical + NON_REM = L.if_list(2, F.ElectricLogic) + LOCAL_PWR: F.Electrical + CLKIN: F.Electrical + CFG_SEL = L.if_list(2, F.ElectricLogic) - HS_IND = ElectricLogic() + HS_IND: F.ElectricLogic - PRTPWR = L.if_list(4, ElectricLogic) - PRT_DIS_P = L.if_list(4, ElectricLogic) - PRT_DIS_M = L.if_list(4, ElectricLogic) - OCS_N = L.if_list(4, ElectricLogic) - BC_EN = L.if_list(4, ElectricLogic) + PRTPWR = L.if_list(4, F.ElectricLogic) + PRT_DIS_P = L.if_list(4, F.ElectricLogic) + PRT_DIS_M = L.if_list(4, F.ElectricLogic) + OCS_N = L.if_list(4, F.ElectricLogic) + BC_EN = L.if_list(4, F.ElectricLogic) i2c = I2C() - self.IFs = _IFs(self) - - class _PARAMs(Module.PARAMS()): - interface_configuration = TBD[USB2514B.InterfaceConfiguration]() - self.PARAMs = _PARAMs(self) + interface_configuration : F.TBD[USB2514B.InterfaceConfiguration] - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - if ( - self.PARAMs.interface_configuration - == USB2514B.InterfaceConfiguration.DEFAULT - ): - self.IFs.CFG_SEL[0].get_trait(ElectricLogic.can_be_pulled).pull(up=False) - self.IFs.CFG_SEL[1].get_trait(ElectricLogic.can_be_pulled).pull(up=False) - elif ( - self.PARAMs.interface_configuration == USB2514B.InterfaceConfiguration.SMBUS - ): - self.IFs.CFG_SEL[0].get_trait(ElectricLogic.can_be_pulled).pull(up=True) - self.IFs.CFG_SEL[1].get_trait(ElectricLogic.can_be_pulled).pull(up=False) - elif ( - self.PARAMs.interface_configuration - == USB2514B.InterfaceConfiguration.BUS_POWERED - ): - self.IFs.CFG_SEL[0].get_trait(ElectricLogic.can_be_pulled).pull(up=False) - self.IFs.CFG_SEL[1].get_trait(ElectricLogic.can_be_pulled).pull(up=True) + if self.interface_configuration == USB2514B.InterfaceConfiguration.DEFAULT: + self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + elif self.interface_configuration == USB2514B.InterfaceConfiguration.SMBUS: + self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) elif ( - self.PARAMs.interface_configuration - == USB2514B.InterfaceConfiguration.EEPROM + self.interface_configuration == USB2514B.InterfaceConfiguration.BUS_POWERED ): - self.IFs.CFG_SEL[0].get_trait(ElectricLogic.can_be_pulled).pull(up=True) - self.IFs.CFG_SEL[1].get_trait(ElectricLogic.can_be_pulled).pull(up=True) + self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + elif self.interface_configuration == USB2514B.InterfaceConfiguration.EEPROM: + self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) - gnd = Electrical() + gnd: F.Electrical # Add decoupling capacitors to power pins and connect all lv to gnd # TODO: decouple with 1.0uF and 0.1uF and maybe 4.7uF - for g in self.IFs.get_all(): - if isinstance(g, ElectricPower): + for g in self.get_all(): + if isinstance(g, F.ElectricPower): g.get_trait(can_be_decoupled).decouple() - g.IFs.lv.connect(gnd) + g.lv.connect(gnd) - x = self.IFs + x = self - x.CFG_SEL[0].connect(x.i2c.IFs.scl) + x.CFG_SEL[0].connect(x.i2c.scl) x.CFG_SEL[1].connect(x.HS_IND) x.NON_REM[0].connect(x.SUSP_IND) - x.NON_REM[1].connect(x.i2c.IFs.sda) + x.NON_REM[1].connect(x.i2c.sda) x.RESET_N.connect(gnd) diff --git a/src/faebryk/library/USB2_0.py b/src/faebryk/library/USB2_0.py index ae993f4d..8db61d36 100644 --- a/src/faebryk/library/USB2_0.py +++ b/src/faebryk/library/USB2_0.py @@ -1,18 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Range import Range -from faebryk.library.USB2_0_IF import USB2_0_IF class USB2_0(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) + usb_if: F.USB2_0_IF - class IFS(ModuleInterface.IFS()): - usb_if = USB2_0_IF() - - self.IFs = IFS(self) - - self.IFs.usb_if.IFs.buspower.PARAMs.voltage.merge(Range.from_center(5, 0.25)) + def __preinit__(self): + self.usb_if.buspower.voltage.merge(F.Range.from_center(5, 0.25)) diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index b2ab25e8..a3b4fb8f 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -4,52 +4,35 @@ import logging from faebryk.core.module import Module -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.Range import Range -from faebryk.library.TBD import TBD -from faebryk.library.USB2_0 import USB2_0 + + from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) class USB2_0_ESD_Protection(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - usb = L.if_list(2, USB2_0) - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): - vbus_esd_protection = TBD[bool]() - data_esd_protection = TBD[bool]() + usb = L.if_list(2, USB2_0) + - self.PARAMs = _PARAMs(self) + vbus_esd_protection : F.TBD[bool] + data_esd_protection : F.TBD[bool] - self.IFs.usb[0].IFs.usb_if.IFs.buspower.PARAMs.voltage.merge( - Range(4.75 * P.V, 5.25 * P.V) - ) + self.usb[0].usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.25 * P.V)) - self.add_trait( - can_bridge_defined( - self.IFs.usb[0].IFs.usb_if.IFs.d, self.IFs.usb[1].IFs.usb_if.IFs.d - ) - ) - self.IFs.usb[0].connect(self.IFs.usb[1]) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.usb[0].usb_if.d, self.usb[1].usb_if.d) + self.usb[0].connect(self.usb[1]) - self.IFs.usb[0].IFs.usb_if.IFs.buspower.connect( - self.IFs.usb[1].IFs.usb_if.IFs.buspower - ) + self.usb[0].usb_if.buspower.connect(self.usb[1].usb_if.buspower) - self.IFs.usb[0].IFs.usb_if.IFs.buspower.get_trait(can_be_decoupled).decouple() + self.usb[0].usb_if.buspower.get_trait(can_be_decoupled).decouple() - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/USB2_0_IF.py b/src/faebryk/library/USB2_0_IF.py index 14394c18..f5895481 100644 --- a/src/faebryk/library/USB2_0_IF.py +++ b/src/faebryk/library/USB2_0_IF.py @@ -1,17 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.ElectricPower import ElectricPower class USB2_0_IF(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - - class IFS(ModuleInterface.IFS()): - d = DifferentialPair() - buspower = ElectricPower() - - self.IFs = IFS(self) + d: F.DifferentialPair + buspower: F.ElectricPower diff --git a/src/faebryk/library/USB3.py b/src/faebryk/library/USB3.py index 805e742b..7ded685c 100644 --- a/src/faebryk/library/USB3.py +++ b/src/faebryk/library/USB3.py @@ -2,24 +2,17 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Range import Range -from faebryk.library.USB3_IF import USB3_IF + + from faebryk.libs.units import P class USB3(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - class IFS(ModuleInterface.IFS()): - usb3_if = USB3_IF() - self.IFs = IFS(self) - self.IFs.usb3_if.IFs.gnd_drain.connect( - self.IFs.usb3_if.IFs.usb_if.IFs.buspower.IFs.lv - ) + usb3_if = USB3_IF() + + self.usb3_if.gnd_drain.connect(self.usb3_if.usb_if.buspower.lv) - self.IFs.usb3_if.IFs.usb_if.IFs.buspower.PARAMs.voltage.merge( - Range(4.75 * P.V, 5.5 * P.V) - ) + self.usb3_if.usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.5 * P.V)) diff --git a/src/faebryk/library/USB3_IF.py b/src/faebryk/library/USB3_IF.py index b1bf46ed..dbe3684c 100644 --- a/src/faebryk/library/USB3_IF.py +++ b/src/faebryk/library/USB3_IF.py @@ -2,19 +2,10 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.Electrical import Electrical -from faebryk.library.USB2_0_IF import USB2_0_IF class USB3_IF(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - - class IFS(ModuleInterface.IFS()): - usb_if = USB2_0_IF() - rx = DifferentialPair() - tx = DifferentialPair() - gnd_drain = Electrical() - - self.IFs = IFS(self) + usb_if = USB2_0_IF() + rx = DifferentialPair() + tx = DifferentialPair() + gnd_drain: F.Electrical diff --git a/src/faebryk/library/USB3_connector.py b/src/faebryk/library/USB3_connector.py index cb006f75..a3260608 100644 --- a/src/faebryk/library/USB3_connector.py +++ b/src/faebryk/library/USB3_connector.py @@ -4,39 +4,26 @@ import logging from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.Range import Range -from faebryk.library.USB3 import USB3 + + from faebryk.libs.units import P logger = logging.getLogger(__name__) class USB3_connector(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): ... - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): - usb3 = USB3() - shield = Electrical() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): ... + usb3 = USB3() + shield: F.Electrical + - self.PARAMs = _PARAMs(self) - self.IFs.usb3.IFs.usb3_if.IFs.usb_if.IFs.buspower.PARAMs.voltage.merge( - Range(4.75 * P.V, 5.25 * P.V) - ) + self.usb3.usb3_if.usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.25 * P.V)) - self.IFs.usb3.IFs.usb3_if.IFs.usb_if.IFs.buspower.IFs.lv.connect( - self.IFs.usb3.IFs.usb3_if.IFs.gnd_drain - ) + self.usb3.usb3_if.usb_if.buspower.lv.connect(self.usb3.usb3_if.gnd_drain) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/USBLC6_2P6.py b/src/faebryk/library/USBLC6_2P6.py index f26d7056..ca7f5fac 100644 --- a/src/faebryk/library/USBLC6_2P6.py +++ b/src/faebryk/library/USBLC6_2P6.py @@ -2,12 +2,7 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.USB2_0 import USB2_0 + class USBLC6_2P6(Module): @@ -15,30 +10,27 @@ class USBLC6_2P6(Module): Low capacitance TVS diode array (for USB2.0) """ - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - usb = USB2_0() - self.IFs = _IFs(self) + usb = USB2_0() - x = self.IFs + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": x.usb.IFs.usb_if.IFs.d.IFs.p, - "2": x.usb.IFs.usb_if.IFs.buspower.IFs.lv, - "3": x.usb.IFs.usb_if.IFs.d.IFs.n, - "4": x.usb.IFs.usb_if.IFs.d.IFs.n, - "5": x.usb.IFs.usb_if.IFs.buspower.IFs.hv, - "6": x.usb.IFs.usb_if.IFs.d.IFs.p, + "1": x.usb.usb_if.d.p, + "2": x.usb.usb_if.buspower.lv, + "3": x.usb.usb_if.d.n, + "4": x.usb.usb_if.d.n, + "5": x.usb.usb_if.buspower.hv, + "6": x.usb.usb_if.d.p, } ) ) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.add_trait( has_datasheet_defined( diff --git a/src/faebryk/library/USB_C.py b/src/faebryk/library/USB_C.py index b0c0164f..8ad19ac2 100644 --- a/src/faebryk/library/USB_C.py +++ b/src/faebryk/library/USB_C.py @@ -2,32 +2,25 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.USB3 import USB3 + + + class USB_C(ModuleInterface): - def __init__(self, *args, **kwargs) -> None: - super().__init__(*args, **kwargs) - class IFS(ModuleInterface.IFS()): + + usb3 = USB3() - cc1 = Electrical() - cc2 = Electrical() - sbu1 = Electrical() - sbu2 = Electrical() + cc1: F.Electrical + cc2: F.Electrical + sbu1: F.Electrical + sbu2: F.Electrical rx = DifferentialPair() tx = DifferentialPair() - self.IFs = IFS(self) - - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index e53d39a2..7a1becfd 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -2,50 +2,38 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.Resistor import Resistor -from faebryk.library.USB_C import USB_C + + + + + from faebryk.libs.units import P -from faebryk.libs.util import times + class USB_C_5V_PSU(Module): - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - power_out = ElectricPower() - usb = USB_C() - self.IFs = _IFs(self) + power_out: F.ElectricPower + usb = USB_C() # components - class _NODEs(Module.NODES()): + configuration_resistors = L.if_list( 2, - lambda: Resistor().builder( - lambda r: r.PARAMs.resistance.merge(Constant(5.1 * P.kohm)) + lambda: F.Resistor().builder( + lambda r: r.resistance.merge(F.Constant(5.1 * P.kohm)) ), ) - self.NODEs = _NODEs(self) - - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) # configure as ufp with 5V@max3A - self.IFs.usb.IFs.cc1.connect_via( - self.NODEs.configuration_resistors[0], self.IFs.power_out.IFs.lv - ) - self.IFs.usb.IFs.cc2.connect_via( - self.NODEs.configuration_resistors[1], self.IFs.power_out.IFs.lv - ) + self.usb.cc1.connect_via(self.configuration_resistors[0], self.power_out.lv) + self.usb.cc2.connect_via(self.configuration_resistors[1], self.power_out.lv) diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index 86014e44..ae459827 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -3,80 +3,64 @@ from faebryk.core.module import Module from faebryk.core.util import connect_all_interfaces -from faebryk.library.Capacitor import Capacitor -from faebryk.library.Constant import Constant -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.Fuse import Fuse -from faebryk.library.Resistor import Resistor -from faebryk.library.USB2_0 import USB2_0 -from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection -from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import ( - USB_Type_C_Receptacle_14_pin_Vertical, -) + + + from faebryk.libs.units import P -from faebryk.libs.util import times + class USB_C_PSU_Vertical(Module): - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - power_out = ElectricPower() - usb = USB2_0() - self.IFs = _IFs(self) + power_out: F.ElectricPower + usb = USB2_0() # components - class _NODEs(Module.NODES()): + usb_connector = ( USB_Type_C_Receptacle_14_pin_Vertical() ) # TODO: make generic - configuration_resistors = L.if_list(2, Resistor) - gnd_resistor = Resistor() - gnd_capacitor = Capacitor() + configuration_resistors = L.if_list(2, F.Resistor) + gnd_resistor : F.Resistor + gnd_capacitor : F.Capacitor esd = USB2_0_ESD_Protection() fuse = Fuse() - self.NODEs = _NODEs(self) - - self.NODEs.gnd_capacitor.PARAMs.capacitance.merge(100 * P.nF) - self.NODEs.gnd_capacitor.PARAMs.rated_voltage.merge(16 * P.V) - self.NODEs.gnd_resistor.PARAMs.resistance.merge(1 * P.Mohm) - for res in self.NODEs.configuration_resistors: - res.PARAMs.resistance.merge(5.1 * P.kohm) - self.NODEs.fuse.PARAMs.fuse_type.merge(Fuse.FuseType.RESETTABLE) - self.NODEs.fuse.PARAMs.trip_current.merge(Constant(1 * P.A)) + self.gnd_capacitor.capacitance.merge(100 * P.nF) + self.gnd_capacitor.rated_voltage.merge(16 * P.V) + self.gnd_resistor.resistance.merge(1 * P.Mohm) + for res in self.configuration_resistors: + res.resistance.merge(5.1 * P.kohm) + self.fuse.fuse_type.merge(Fuse.FuseType.RESETTABLE) + self.fuse.trip_current.merge(F.Constant(1 * P.A)) # alliases - vcon = self.NODEs.usb_connector.IFs.vbus - vusb = self.IFs.usb.IFs.usb_if.IFs.buspower - v5 = self.IFs.power_out - gnd = v5.IFs.lv + vcon = self.usb_connector.vbus + vusb = self.usb.usb_if.buspower + v5 = self.power_out + gnd = v5.lv - vcon.IFs.hv.connect_via(self.NODEs.fuse, v5.IFs.hv) - vcon.IFs.lv.connect(gnd) - vusb.IFs.lv.connect(gnd) - v5.connect(self.NODEs.esd.IFs.usb[0].IFs.usb_if.IFs.buspower) + vcon.hv.connect_via(self.fuse, v5.hv) + vcon.lv.connect(gnd) + vusb.lv.connect(gnd) + v5.connect(self.esd.usb[0].usb_if.buspower) # connect usb data connect_all_interfaces( [ - self.NODEs.usb_connector.IFs.usb.IFs.usb_if.IFs.d, - self.IFs.usb.IFs.usb_if.IFs.d, - self.NODEs.esd.IFs.usb[0].IFs.usb_if.IFs.d, + self.usb_connector.usb.usb_if.d, + self.usb.usb_if.d, + self.esd.usb[0].usb_if.d, ] ) # configure as ufp with 5V@max3A - self.NODEs.usb_connector.IFs.cc1.connect_via( - self.NODEs.configuration_resistors[0], gnd - ) - self.NODEs.usb_connector.IFs.cc2.connect_via( - self.NODEs.configuration_resistors[1], gnd - ) + self.usb_connector.cc1.connect_via(self.configuration_resistors[0], gnd) + self.usb_connector.cc2.connect_via(self.configuration_resistors[1], gnd) # EMI shielding - self.NODEs.usb_connector.IFs.shield.connect_via(self.NODEs.gnd_resistor, gnd) - self.NODEs.usb_connector.IFs.shield.connect_via(self.NODEs.gnd_capacitor, gnd) + self.usb_connector.shield.connect_via(self.gnd_resistor, gnd) + self.usb_connector.shield.connect_via(self.gnd_capacitor, gnd) diff --git a/src/faebryk/library/USB_C_PowerOnly.py b/src/faebryk/library/USB_C_PowerOnly.py index 34219374..14bbf133 100644 --- a/src/faebryk/library/USB_C_PowerOnly.py +++ b/src/faebryk/library/USB_C_PowerOnly.py @@ -2,46 +2,37 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.can_be_surge_protected_defined import ( - can_be_surge_protected_defined, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.USB_C import USB_C + + + + class USB_C_PowerOnly(ModuleInterface): - def __init__(self) -> None: - super().__init__() - class IFS(ModuleInterface.IFS()): - power = ElectricPower() - cc1 = Electrical() - cc2 = Electrical() - self.IFs = IFS(self) + + power: F.ElectricPower + cc1: F.Electrical + cc2: F.Electrical self.add_trait( can_be_surge_protected_defined( - self.IFs.power.IFs.lv, - self.IFs.power.IFs.hv, - self.IFs.cc1, - self.IFs.cc2, + self.power.lv, + self.power.hv, + self.cc1, + self.cc2, ) ) - self.add_trait( - has_single_electric_reference_defined( - ElectricLogic.connect_all_module_references(self) - ) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) def connect_to_full_usb_c(self, usb_c: USB_C): - self.IFs.power.connect(usb_c.IFs.usb3.IFs.usb3_if.IFs.usb_if.IFs.buspower) - self.IFs.cc1.connect(usb_c.IFs.cc1) - self.IFs.cc2.connect(usb_c.IFs.cc2) + self.power.connect(usb_c.usb3.usb3_if.usb_if.buspower) + self.cc1.connect(usb_c.cc1) + self.cc2.connect(usb_c.cc2) return self diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index 353d3c0d..208c961a 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -4,77 +4,58 @@ import logging from faebryk.core.module import Module -from faebryk.library.CH340x import CH340x -from faebryk.library.Range import Range -from faebryk.library.Resistor import Resistor -from faebryk.library.RS485 import RS485 -from faebryk.library.UART_RS485 import UART_RS485 -from faebryk.library.USB2_0 import USB2_0 + + from faebryk.libs.units import P -from faebryk.libs.util import times + logger = logging.getLogger(__name__) class USB_RS485(Module): - def __init__(self) -> None: - super().__init__() - class _NODEs(Module.NODES()): + + usb_uart = CH340x() uart_rs485 = UART_RS485() - termination = Resistor() - polarization = L.if_list(2, Resistor) + termination : F.Resistor + polarization = L.if_list(2, F.Resistor) - self.NODEs = _NODEs(self) - class _IFs(Module.IFS()): usb = USB2_0() rs485 = RS485() - self.IFs = _IFs(self) - class _PARAMs(Module.PARAMS()): ... - self.PARAMs = _PARAMs(self) + self.usb.connect(self.usb_uart.usb) + self.usb_uart.uart.base_uart.connect(self.uart_rs485.uart) + self.rs485.connect(self.uart_rs485.rs485) - self.IFs.usb.connect(self.NODEs.usb_uart.IFs.usb) - self.NODEs.usb_uart.IFs.uart.IFs.base_uart.connect( - self.NODEs.uart_rs485.IFs.uart - ) - self.IFs.rs485.connect(self.NODEs.uart_rs485.IFs.rs485) + self.usb_uart.tnow.connect(self.uart_rs485.read_enable) + self.usb_uart.tnow.connect(self.uart_rs485.write_enable) - self.NODEs.usb_uart.IFs.tnow.connect(self.NODEs.uart_rs485.IFs.read_enable) - self.NODEs.usb_uart.IFs.tnow.connect(self.NODEs.uart_rs485.IFs.write_enable) - - self.NODEs.usb_uart.IFs.usb.IFs.usb_if.IFs.buspower.connect( - self.NODEs.uart_rs485.IFs.power - ) - self.IFs.usb.IFs.usb_if.IFs.buspower.connect( - self.NODEs.usb_uart.IFs.usb.IFs.usb_if.IFs.buspower - ) + self.usb_uart.usb.usb_if.buspower.connect(self.uart_rs485.power) + self.usb.usb_if.buspower.connect(self.usb_uart.usb.usb_if.buspower) # connect termination resistor between RS485 A and B - self.NODEs.uart_rs485.IFs.rs485.IFs.diff_pair.IFs.n.connect_via( - self.NODEs.termination, self.NODEs.uart_rs485.IFs.rs485.IFs.diff_pair.IFs.p + self.uart_rs485.rs485.diff_pair.n.connect_via( + self.termination, self.uart_rs485.rs485.diff_pair.p ) # connect polarization resistors to RS485 A and B - self.NODEs.uart_rs485.IFs.rs485.IFs.diff_pair.IFs.p.connect_via( - self.NODEs.polarization[0], - self.NODEs.uart_rs485.IFs.power.IFs.hv, + self.uart_rs485.rs485.diff_pair.p.connect_via( + self.polarization[0], + self.uart_rs485.power.hv, ) - self.NODEs.uart_rs485.IFs.rs485.IFs.diff_pair.IFs.n.connect_via( - self.NODEs.polarization[1], - self.NODEs.uart_rs485.IFs.power.IFs.lv, + self.uart_rs485.rs485.diff_pair.n.connect_via( + self.polarization[1], + self.uart_rs485.power.lv, ) - self.NODEs.termination.PARAMs.resistance.merge( - Range.from_center(150 * P.ohm, 1.5 * P.ohm) - ) - self.NODEs.polarization[0].PARAMs.resistance.merge( - Range.from_center(680 * P.ohm, 6.8 * P.ohm) + self.termination.resistance.merge(F.Range.from_center(150 * P.ohm, 1.5 * P.ohm)) + self.polarization[0].resistance.merge( + F.Range.from_center(680 * P.ohm, 6.8 * P.ohm) ) - self.NODEs.polarization[1].PARAMs.resistance.merge( - Range.from_center(680 * P.ohm, 6.8 * P.ohm) + self.polarization[1].resistance.merge( + F.Range.from_center(680 * P.ohm, 6.8 * P.ohm) ) diff --git a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py index 1dec95ae..4ff43cbc 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py @@ -2,15 +2,10 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.library.USB2_0 import USB2_0 + + + + class USB_Type_C_Receptacle_14_pin_Vertical(Module): @@ -19,42 +14,39 @@ class USB_Type_C_Receptacle_14_pin_Vertical(Module): 918-418K2022Y40000 """ - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): + # TODO make arrays? - cc1 = Electrical() - cc2 = Electrical() - shield = Electrical() + cc1: F.Electrical + cc2: F.Electrical + shield: F.Electrical # power - vbus = ElectricPower() + vbus: F.ElectricPower # diffpairs: p, n usb = USB2_0() - self.IFs = _IFs(self) - self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": self.IFs.vbus.IFs.lv, - "2": self.IFs.vbus.IFs.hv, - "3": self.IFs.usb.IFs.usb_if.IFs.d.IFs.n, - "4": self.IFs.usb.IFs.usb_if.IFs.d.IFs.p, - "5": self.IFs.cc2, - "6": self.IFs.vbus.IFs.hv, - "7": self.IFs.vbus.IFs.lv, - "8": self.IFs.vbus.IFs.lv, - "9": self.IFs.vbus.IFs.hv, - "10": self.IFs.usb.IFs.usb_if.IFs.d.IFs.n, - "11": self.IFs.usb.IFs.usb_if.IFs.d.IFs.p, - "12": self.IFs.cc1, - "13": self.IFs.vbus.IFs.hv, - "14": self.IFs.vbus.IFs.lv, - "0": self.IFs.shield, + "1": self.vbus.lv, + "2": self.vbus.hv, + "3": self.usb.usb_if.d.n, + "4": self.usb.usb_if.d.p, + "5": self.cc2, + "6": self.vbus.hv, + "7": self.vbus.lv, + "8": self.vbus.lv, + "9": self.vbus.hv, + "10": self.usb.usb_if.d.n, + "11": self.usb.usb_if.d.p, + "12": self.cc1, + "13": self.vbus.hv, + "14": self.vbus.lv, + "0": self.shield, } ) ) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py index 1f94cac2..794f44cb 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py @@ -3,62 +3,53 @@ from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined + class USB_Type_C_Receptacle_16_pin(Module): - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): + # TODO make arrays? - cc1 = Electrical() - cc2 = Electrical() - sbu1 = Electrical() - sbu2 = Electrical() - shield = Electrical() + cc1: F.Electrical + cc2: F.Electrical + sbu1: F.Electrical + sbu2: F.Electrical + shield: F.Electrical # power - power = ElectricPower() + power: F.ElectricPower # ds: p, n d = DifferentialPair() - self.IFs = _IFs(self) - - vbus = self.IFs.power.IFs.hv - gnd = self.IFs.power.IFs.lv + vbus = self.power.hv + gnd = self.power.lv self.add_trait( can_attach_to_footprint_via_pinmap( { "A1": gnd, "A4": vbus, - "A5": self.IFs.cc1, - "A6": self.IFs.d.IFs.p, - "A7": self.IFs.d.IFs.n, - "A8": self.IFs.sbu1, + "A5": self.cc1, + "A6": self.d.p, + "A7": self.d.n, + "A8": self.sbu1, "A9": vbus, "A12": gnd, "B1": gnd, "B4": vbus, - "B5": self.IFs.cc2, - "B6": self.IFs.d.IFs.p, - "B7": self.IFs.d.IFs.n, - "B8": self.IFs.sbu2, + "B5": self.cc2, + "B6": self.d.p, + "B7": self.d.n, + "B8": self.sbu2, "B9": vbus, "B12": gnd, - "0": self.IFs.shield, - "1": self.IFs.shield, - "2": self.IFs.shield, - "3": self.IFs.shield, + "0": self.shield, + "1": self.shield, + "2": self.shield, + "3": self.shield, } ) ) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py index 9d1ac9cf..6b816427 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py @@ -2,34 +2,27 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.DifferentialPair import ( - DifferentialPair, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.libs.util import times + + + + + class USB_Type_C_Receptacle_24_pin(Module): - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): + # TODO make arrays? - cc1 = Electrical() - cc2 = Electrical() - sbu1 = Electrical() - sbu2 = Electrical() - shield = Electrical() + cc1: F.Electrical + cc2: F.Electrical + sbu1: F.Electrical + sbu2: F.Electrical + shield: F.Electrical # power - gnd = L.if_list(4, Electrical) - vbus = L.if_list(4, Electrical) + gnd = L.if_list(4, F.Electrical) + vbus = L.if_list(4, F.Electrical) # diffpairs: p, n rx1 = DifferentialPair() rx2 = DifferentialPair() @@ -38,38 +31,36 @@ class _IFs(Module.IFS()): d1 = DifferentialPair() d2 = DifferentialPair() - self.IFs = _IFs(self) - self.add_trait( can_attach_to_footprint_via_pinmap( { - "A1": self.IFs.gnd[0], - "A2": self.IFs.tx1.IFs.p, - "A3": self.IFs.tx1.IFs.n, - "A4": self.IFs.vbus[0], - "A5": self.IFs.cc1, - "A6": self.IFs.d1.IFs.p, - "A7": self.IFs.d1.IFs.n, - "A8": self.IFs.sbu1, - "A9": self.IFs.vbus[1], - "A10": self.IFs.rx2.IFs.n, - "A11": self.IFs.rx2.IFs.p, - "A12": self.IFs.gnd[1], - "B1": self.IFs.gnd[2], - "B2": self.IFs.tx2.IFs.p, - "B3": self.IFs.tx2.IFs.n, - "B4": self.IFs.vbus[2], - "B5": self.IFs.cc2, - "B6": self.IFs.d2.IFs.p, - "B7": self.IFs.d2.IFs.n, - "B8": self.IFs.sbu2, - "B9": self.IFs.vbus[3], - "B10": self.IFs.rx1.IFs.n, - "B11": self.IFs.rx1.IFs.p, - "B12": self.IFs.gnd[3], - "0": self.IFs.shield, + "A1": self.gnd[0], + "A2": self.tx1.p, + "A3": self.tx1.n, + "A4": self.vbus[0], + "A5": self.cc1, + "A6": self.d1.p, + "A7": self.d1.n, + "A8": self.sbu1, + "A9": self.vbus[1], + "A10": self.rx2.n, + "A11": self.rx2.p, + "A12": self.gnd[1], + "B1": self.gnd[2], + "B2": self.tx2.p, + "B3": self.tx2.n, + "B4": self.vbus[2], + "B5": self.cc2, + "B6": self.d2.p, + "B7": self.d2.n, + "B8": self.sbu2, + "B9": self.vbus[3], + "B10": self.rx1.n, + "B11": self.rx1.p, + "B12": self.gnd[3], + "0": self.shield, } ) ) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index 27785937..c4bd5313 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -4,40 +4,25 @@ from dataclasses import dataclass, field from faebryk.core.module import Module, Parameter -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Constant import Constant -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.TBD import TBD class XL_3528RGBW_WS2812B(Module): @dataclass class _ws2812b_esphome_config(has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=TBD) + update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: super().__init__() def get_config(self) -> dict: assert isinstance( - self.update_interval_s, Constant + self.update_interval_s, F.Constant ), "No update interval set!" obj = self.get_obj() assert isinstance(obj, XL_3528RGBW_WS2812B), "This is not a WS2812B RGBW!" - data_pin = is_esphome_bus.find_connected_bus(obj.IFs.di.IFs.signal) + data_pin = is_esphome_bus.find_connected_bus(obj.di.signal) return { "light": [ @@ -54,33 +39,30 @@ def get_config(self) -> dict: ] } - def __init__(self) -> None: - super().__init__() + # interfaces - # interfaces - class _IFs(Module.IFS()): - power = ElectricPower() - do = ElectricLogic() - di = ElectricLogic() - - self.IFs = _IFs(self) + power: F.ElectricPower + do: F.ElectricLogic + di: F.ElectricLogic # connect all logic references - ref = ElectricLogic.connect_all_module_references(self) + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) - self.add_trait(has_designator_prefix_defined("LED")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("LED") - # Add bridge trait - self.add_trait(can_bridge_defined(self.IFs.di, self.IFs.do)) + # Add bridge trait + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.di, self.do) self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": self.IFs.power.IFs.lv, - "2": self.IFs.di.IFs.signal, - "3": self.IFs.power.IFs.hv, - "4": self.IFs.do.IFs.signal, + "1": self.power.lv, + "2": self.di.signal, + "3": self.power.hv, + "4": self.do.signal, } ) ) diff --git a/src/faebryk/library/can_attach_to_footprint.py b/src/faebryk/library/can_attach_to_footprint.py index a436d88e..bb645092 100644 --- a/src/faebryk/library/can_attach_to_footprint.py +++ b/src/faebryk/library/can_attach_to_footprint.py @@ -4,9 +4,8 @@ from abc import abstractmethod from faebryk.core.module import Module -from faebryk.library.Footprint import Footprint class can_attach_to_footprint(Module.TraitT): @abstractmethod - def attach(self, footprint: Footprint): ... + def attach(self, footprint: F.Footprint): ... diff --git a/src/faebryk/library/can_attach_to_footprint_symmetrically.py b/src/faebryk/library/can_attach_to_footprint_symmetrically.py index 2bb54dc1..7dc057a9 100644 --- a/src/faebryk/library/can_attach_to_footprint_symmetrically.py +++ b/src/faebryk/library/can_attach_to_footprint_symmetrically.py @@ -1,18 +1,16 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import Footprint -from faebryk.library.has_defined_footprint import has_defined_footprint -from faebryk.library.Pad import Pad +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.util import zip_children_by_name class can_attach_to_footprint_symmetrically(can_attach_to_footprint.impl()): - def attach(self, footprint: Footprint): + def attach(self, footprint: F.Footprint): self.get_obj().add_trait(has_defined_footprint(footprint)) - for i, j in zip(footprint.IFs.get_all(), self.get_obj().IFs.get_all()): + + for i, j in zip_children_by_name(footprint, self.get_obj(), ModuleInterface): assert isinstance(i, Pad) - assert isinstance(j, Electrical) - assert type(i.IFs.net) is type(j) + assert isinstance(j, F.Electrical) + assert type(i.net) is type(j) i.attach(j) diff --git a/src/faebryk/library/can_attach_to_footprint_via_pinmap.py b/src/faebryk/library/can_attach_to_footprint_via_pinmap.py index af6490ea..0ebdf341 100644 --- a/src/faebryk/library/can_attach_to_footprint_via_pinmap.py +++ b/src/faebryk/library/can_attach_to_footprint_via_pinmap.py @@ -1,18 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import Footprint -from faebryk.library.has_defined_footprint import has_defined_footprint - class can_attach_to_footprint_via_pinmap(can_attach_to_footprint.impl()): - def __init__(self, pinmap: dict[str, Electrical]) -> None: + def __init__(self, pinmap: dict[str, F.Electrical]) -> None: super().__init__() self.pinmap = pinmap - def attach(self, footprint: Footprint): + def attach(self, footprint: F.Footprint): self.get_obj().add_trait(has_defined_footprint(footprint)) footprint.get_trait(can_attach_via_pinmap).attach(self.pinmap) diff --git a/src/faebryk/library/can_attach_via_pinmap.py b/src/faebryk/library/can_attach_via_pinmap.py index e5a3496d..a1ec9b0e 100644 --- a/src/faebryk/library/can_attach_via_pinmap.py +++ b/src/faebryk/library/can_attach_via_pinmap.py @@ -3,10 +3,7 @@ from abc import abstractmethod -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import Footprint - -class can_attach_via_pinmap(Footprint.TraitT): +class can_attach_via_pinmap(F.Footprint.TraitT): @abstractmethod - def attach(self, pinmap: dict[str, Electrical]): ... + def attach(self, pinmap: dict[str, F.Electrical]): ... diff --git a/src/faebryk/library/can_attach_via_pinmap_equal.py b/src/faebryk/library/can_attach_via_pinmap_equal.py index 3bf75208..2763e19d 100644 --- a/src/faebryk/library/can_attach_via_pinmap_equal.py +++ b/src/faebryk/library/can_attach_via_pinmap_equal.py @@ -1,13 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.Electrical import Electrical -from faebryk.library.has_equal_pins import has_equal_pins - class can_attach_via_pinmap_equal(can_attach_via_pinmap.impl()): - def attach(self, pinmap: dict[str, Electrical]): + def attach(self, pinmap: dict[str, F.Electrical]): pin_list = { v: k for k, v in self.get_obj().get_trait(has_equal_pins).get_pin_map().items() diff --git a/src/faebryk/library/can_attach_via_pinmap_pinlist.py b/src/faebryk/library/can_attach_via_pinmap_pinlist.py index 804f041e..3f3b690a 100644 --- a/src/faebryk/library/can_attach_via_pinmap_pinlist.py +++ b/src/faebryk/library/can_attach_via_pinmap_pinlist.py @@ -1,17 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.Electrical import Electrical -from faebryk.library.Pad import Pad - class can_attach_via_pinmap_pinlist(can_attach_via_pinmap.impl()): def __init__(self, pin_list: dict[str, Pad]) -> None: super().__init__() self.pin_list = pin_list - def attach(self, pinmap: dict[str, Electrical]): + def attach(self, pinmap: dict[str, F.Electrical]): for no, intf in pinmap.items(): assert ( no in self.pin_list diff --git a/src/faebryk/library/can_be_decoupled.py b/src/faebryk/library/can_be_decoupled.py index 706f0f4d..84912ae4 100644 --- a/src/faebryk/library/can_be_decoupled.py +++ b/src/faebryk/library/can_be_decoupled.py @@ -5,7 +5,7 @@ from abc import abstractmethod from faebryk.core.trait import Trait -from faebryk.library.Capacitor import Capacitor + logger = logging.getLogger(__name__) @@ -13,4 +13,4 @@ # TODO better name class can_be_decoupled(Trait): @abstractmethod - def decouple(self) -> Capacitor: ... + def decouple(self) -> F.Capacitor: ... diff --git a/src/faebryk/library/can_be_decoupled_defined.py b/src/faebryk/library/can_be_decoupled_defined.py index 53ae3bdf..ed89daaa 100644 --- a/src/faebryk/library/can_be_decoupled_defined.py +++ b/src/faebryk/library/can_be_decoupled_defined.py @@ -3,17 +3,12 @@ import logging -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.Capacitor import Capacitor -from faebryk.library.Electrical import Electrical -from faebryk.library.is_decoupled import is_decoupled -from faebryk.library.is_decoupled_nodes import is_decoupled_nodes logger = logging.getLogger(__name__) class can_be_decoupled_defined(can_be_decoupled.impl()): - def __init__(self, hv: Electrical, lv: Electrical) -> None: + def __init__(self, hv: F.Electrical, lv: F.Electrical) -> None: super().__init__() self.hv = hv self.lv = lv @@ -21,8 +16,8 @@ def __init__(self, hv: Electrical, lv: Electrical) -> None: def decouple(self): obj = self.get_obj() - capacitor = Capacitor() - obj.NODEs.capacitor = capacitor + capacitor: F.Capacitor + obj.add(capacitor, "capacitor") self.hv.connect_via(capacitor, self.lv) obj.add_trait(is_decoupled_nodes()) diff --git a/src/faebryk/library/can_be_surge_protected.py b/src/faebryk/library/can_be_surge_protected.py index 86f41720..5514f551 100644 --- a/src/faebryk/library/can_be_surge_protected.py +++ b/src/faebryk/library/can_be_surge_protected.py @@ -6,7 +6,7 @@ from typing import Sequence from faebryk.core.trait import Trait -from faebryk.library.TVS import TVS + logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/can_be_surge_protected_defined.py b/src/faebryk/library/can_be_surge_protected_defined.py index 599e7a43..bd7bde1e 100644 --- a/src/faebryk/library/can_be_surge_protected_defined.py +++ b/src/faebryk/library/can_be_surge_protected_defined.py @@ -3,17 +3,12 @@ import logging -from faebryk.library.can_be_surge_protected import can_be_surge_protected -from faebryk.library.Electrical import Electrical -from faebryk.library.is_surge_protected import is_surge_protected -from faebryk.library.is_surge_protected_defined import is_surge_protected_defined -from faebryk.library.TVS import TVS logger = logging.getLogger(__name__) class can_be_surge_protected_defined(can_be_surge_protected.impl()): - def __init__(self, low_potential: Electrical, *protect_if: Electrical) -> None: + def __init__(self, low_potential: F.Electrical, *protect_if: F.Electrical) -> None: super().__init__() self.protect_if = protect_if self.low_potential = low_potential @@ -27,7 +22,7 @@ def protect(self): tvss.extend(protect_if.get_trait(can_be_surge_protected).protect()) else: tvs = TVS() - protect_if.NODEs.tvs = tvs + protect_if.add(tvs, "tvs") protect_if.connect_via(tvs, self.low_potential) tvss.append(tvs) diff --git a/src/faebryk/library/can_bridge_defined.py b/src/faebryk/library/can_bridge_defined.py index 3fb1a294..d2f9c0cb 100644 --- a/src/faebryk/library/can_bridge_defined.py +++ b/src/faebryk/library/can_bridge_defined.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.can_bridge import can_bridge class can_bridge_defined(can_bridge.impl()): diff --git a/src/faebryk/library/can_switch_power.py b/src/faebryk/library/can_switch_power.py index 7114d76c..cb328da6 100644 --- a/src/faebryk/library/can_switch_power.py +++ b/src/faebryk/library/can_switch_power.py @@ -3,10 +3,7 @@ from abc import abstractmethod -from faebryk.library.can_bridge import can_bridge -from faebryk.library.ElectricLogic import ElectricLogic - class can_switch_power(can_bridge): @abstractmethod - def get_logic_in(self) -> ElectricLogic: ... + def get_logic_in(self) -> F.ElectricLogic: ... diff --git a/src/faebryk/library/can_switch_power_defined.py b/src/faebryk/library/can_switch_power_defined.py index ed4a13b3..60223fa1 100644 --- a/src/faebryk/library/can_switch_power_defined.py +++ b/src/faebryk/library/can_switch_power_defined.py @@ -1,14 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.can_switch_power import can_switch_power -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower - class can_switch_power_defined(can_switch_power.impl()): def __init__( - self, in_power: ElectricPower, out_power: ElectricPower, in_logic: ElectricLogic + self, + in_power: F.ElectricPower, + out_power: F.ElectricPower, + in_logic: F.ElectricLogic, ) -> None: super().__init__() @@ -16,13 +15,13 @@ def __init__( self.out_power = out_power self.in_logic = in_logic - out_power.PARAMs.voltage.merge(in_power.PARAMs.voltage) + out_power.voltage.merge(in_power.voltage) - def get_logic_in(self) -> ElectricLogic: + def get_logic_in(self) -> F.ElectricLogic: return self.in_logic - def get_in(self) -> ElectricPower: + def get_in(self) -> F.ElectricPower: return self.in_power - def get_out(self) -> ElectricPower: + def get_out(self) -> F.ElectricPower: return self.out_power diff --git a/src/faebryk/library/has_datasheet_defined.py b/src/faebryk/library/has_datasheet_defined.py index 577d8b86..6b2e0884 100644 --- a/src/faebryk/library/has_datasheet_defined.py +++ b/src/faebryk/library/has_datasheet_defined.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_datasheet import has_datasheet - class has_datasheet_defined(has_datasheet.impl()): def __init__(self, datasheet: str) -> None: diff --git a/src/faebryk/library/has_defined_capacitance.py b/src/faebryk/library/has_defined_capacitance.py index d6dcc072..6d8e6f89 100644 --- a/src/faebryk/library/has_defined_capacitance.py +++ b/src/faebryk/library/has_defined_capacitance.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.core.parameter import Parameter -from faebryk.library.has_capacitance import has_capacitance class has_defined_capacitance(has_capacitance.impl()): diff --git a/src/faebryk/library/has_defined_descriptive_properties.py b/src/faebryk/library/has_defined_descriptive_properties.py index f1d818d0..4ab034bc 100644 --- a/src/faebryk/library/has_defined_descriptive_properties.py +++ b/src/faebryk/library/has_defined_descriptive_properties.py @@ -3,7 +3,6 @@ from faebryk.core.module import Module -from faebryk.library.has_descriptive_properties import has_descriptive_properties class has_defined_descriptive_properties(has_descriptive_properties.impl()): diff --git a/src/faebryk/library/has_defined_footprint.py b/src/faebryk/library/has_defined_footprint.py index 1f27f152..a2a14eda 100644 --- a/src/faebryk/library/has_defined_footprint.py +++ b/src/faebryk/library/has_defined_footprint.py @@ -1,12 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.Footprint import Footprint -from faebryk.library.has_footprint_impl import has_footprint_impl - class has_defined_footprint(has_footprint_impl): - def __init__(self, fp: Footprint) -> None: + def __init__(self, fp: F.Footprint) -> None: super().__init__() self.fp = fp diff --git a/src/faebryk/library/has_defined_kicad_ref.py b/src/faebryk/library/has_defined_kicad_ref.py index 99c30ace..cdc218ff 100644 --- a/src/faebryk/library/has_defined_kicad_ref.py +++ b/src/faebryk/library/has_defined_kicad_ref.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_kicad_ref import has_kicad_ref - class has_defined_kicad_ref(has_kicad_ref.impl()): def __init__(self, ref: str) -> None: diff --git a/src/faebryk/library/has_defined_resistance.py b/src/faebryk/library/has_defined_resistance.py index 54c086c9..6983a46c 100644 --- a/src/faebryk/library/has_defined_resistance.py +++ b/src/faebryk/library/has_defined_resistance.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.core.parameter import Parameter -from faebryk.library.has_resistance import has_resistance class has_defined_resistance(has_resistance.impl()): diff --git a/src/faebryk/library/has_designator_defined.py b/src/faebryk/library/has_designator_defined.py index 2a2a46a3..5cdb8ee0 100644 --- a/src/faebryk/library/has_designator_defined.py +++ b/src/faebryk/library/has_designator_defined.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_designator import has_designator - class has_designator_defined(has_designator.impl()): def __init__(self, value: str) -> None: diff --git a/src/faebryk/library/has_designator_prefix_defined.py b/src/faebryk/library/has_designator_prefix_defined.py index 40742fe9..1e1643e5 100644 --- a/src/faebryk/library/has_designator_prefix_defined.py +++ b/src/faebryk/library/has_designator_prefix_defined.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT # import faebryk.library._F as F -from faebryk.library.has_designator_prefix import has_designator_prefix class has_designator_prefix_defined(has_designator_prefix.impl()): diff --git a/src/faebryk/library/has_equal_pins.py b/src/faebryk/library/has_equal_pins.py index e2abf942..2fa0c05e 100644 --- a/src/faebryk/library/has_equal_pins.py +++ b/src/faebryk/library/has_equal_pins.py @@ -3,10 +3,7 @@ from abc import abstractmethod -from faebryk.library.Footprint import Footprint -from faebryk.library.Pad import Pad - -class has_equal_pins(Footprint.TraitT): +class has_equal_pins(F.Footprint.TraitT): @abstractmethod def get_pin_map(self) -> dict[Pad, str]: ... diff --git a/src/faebryk/library/has_equal_pins_in_ifs.py b/src/faebryk/library/has_equal_pins_in_ifs.py index 6d1101cd..fbefdfed 100644 --- a/src/faebryk/library/has_equal_pins_in_ifs.py +++ b/src/faebryk/library/has_equal_pins_in_ifs.py @@ -1,14 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_equal_pins import has_equal_pins -from faebryk.library.Pad import Pad - class has_equal_pins_in_ifs(has_equal_pins.impl()): def get_pin_map(self): return { p: str(i + 1) - for i, p in enumerate(self.get_obj().IFs.get_all()) + for i, p in enumerate(self.get_obj().get_all()) if isinstance(p, Pad) } diff --git a/src/faebryk/library/has_esphome_config_defined.py b/src/faebryk/library/has_esphome_config_defined.py index f4655af5..8b15b566 100644 --- a/src/faebryk/library/has_esphome_config_defined.py +++ b/src/faebryk/library/has_esphome_config_defined.py @@ -2,9 +2,6 @@ # SPDX-License-Identifier: MIT -from faebryk.library.has_esphome_config import has_esphome_config - - class has_esphome_config_defined(has_esphome_config.impl()): def __init__(self, config: dict): super().__init__() diff --git a/src/faebryk/library/has_footprint.py b/src/faebryk/library/has_footprint.py index 180ca786..aa687efe 100644 --- a/src/faebryk/library/has_footprint.py +++ b/src/faebryk/library/has_footprint.py @@ -4,9 +4,8 @@ from abc import abstractmethod from faebryk.core.module import Module -from faebryk.library.Footprint import Footprint class has_footprint(Module.TraitT): @abstractmethod - def get_footprint(self) -> Footprint: ... + def get_footprint(self) -> F.Footprint: ... diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index a272ca89..5b079a8e 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -4,20 +4,15 @@ from abc import abstractmethod from faebryk.core.link import LinkNamedParent -from faebryk.library.Footprint import Footprint -from faebryk.library.has_footprint import has_footprint class has_footprint_impl(has_footprint.impl()): @abstractmethod - def __init__(self) -> None: - super().__init__() - - def set_footprint(self, fp: Footprint): + def set_footprint(self, fp: F.Footprint): self.get_obj().children.connect(fp.parent, LinkNamedParent.curry("footprint")) - def get_footprint(self) -> Footprint: + def get_footprint(self) -> F.Footprint: children = self.get_obj().children.get_children() - fps = [c for _, c in children if isinstance(c, Footprint)] + fps = [c for _, c in children if isinstance(c, F.Footprint)] assert len(fps) == 1, f"candidates: {fps}" return fps[0] diff --git a/src/faebryk/library/has_footprint_requirement_defined.py b/src/faebryk/library/has_footprint_requirement_defined.py index f57e5189..37114d7b 100644 --- a/src/faebryk/library/has_footprint_requirement_defined.py +++ b/src/faebryk/library/has_footprint_requirement_defined.py @@ -4,7 +4,6 @@ import logging from typing import Sequence -from faebryk.library.has_footprint_requirement import has_footprint_requirement logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/has_kicad_footprint.py b/src/faebryk/library/has_kicad_footprint.py index 473b5abd..60e9d25c 100644 --- a/src/faebryk/library/has_kicad_footprint.py +++ b/src/faebryk/library/has_kicad_footprint.py @@ -3,11 +3,8 @@ from abc import abstractmethod -from faebryk.library.Footprint import Footprint -from faebryk.library.Pad import Pad - -class has_kicad_footprint(Footprint.TraitT): +class has_kicad_footprint(F.Footprint.TraitT): @abstractmethod def get_kicad_footprint(self) -> str: ... diff --git a/src/faebryk/library/has_kicad_footprint_equal_ifs.py b/src/faebryk/library/has_kicad_footprint_equal_ifs.py index 20b556f1..8d4e612b 100644 --- a/src/faebryk/library/has_kicad_footprint_equal_ifs.py +++ b/src/faebryk/library/has_kicad_footprint_equal_ifs.py @@ -1,11 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_kicad_footprint import has_kicad_footprint - class has_kicad_footprint_equal_ifs(has_kicad_footprint.impl()): def get_pin_names(self): - from faebryk.library.has_equal_pins import has_equal_pins - return self.get_obj().get_trait(has_equal_pins).get_pin_map() diff --git a/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py b/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py index e7ca9720..db40504d 100644 --- a/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py +++ b/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs - class has_kicad_footprint_equal_ifs_defined(has_kicad_footprint_equal_ifs): def __init__(self, str) -> None: diff --git a/src/faebryk/library/has_kicad_manual_footprint.py b/src/faebryk/library/has_kicad_manual_footprint.py index 6995278e..3bb96261 100644 --- a/src/faebryk/library/has_kicad_manual_footprint.py +++ b/src/faebryk/library/has_kicad_manual_footprint.py @@ -1,9 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_kicad_footprint import has_kicad_footprint -from faebryk.library.Pad import Pad - class has_kicad_manual_footprint(has_kicad_footprint.impl()): def __init__(self, str, pinmap: dict[Pad, str]) -> None: diff --git a/src/faebryk/library/has_linked_pad.py b/src/faebryk/library/has_linked_pad.py index 74fcb3a5..85eed56a 100644 --- a/src/faebryk/library/has_linked_pad.py +++ b/src/faebryk/library/has_linked_pad.py @@ -4,7 +4,6 @@ from abc import abstractmethod from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Pad import Pad class has_linked_pad(ModuleInterface.TraitT): diff --git a/src/faebryk/library/has_linked_pad_defined.py b/src/faebryk/library/has_linked_pad_defined.py index 7273c35b..e8da096f 100644 --- a/src/faebryk/library/has_linked_pad_defined.py +++ b/src/faebryk/library/has_linked_pad_defined.py @@ -2,10 +2,6 @@ # SPDX-License-Identifier: MIT -from faebryk.library.has_linked_pad import has_linked_pad -from faebryk.library.Pad import Pad - - class has_linked_pad_defined(has_linked_pad.impl()): def __init__(self, pad: Pad) -> None: super().__init__() diff --git a/src/faebryk/library/has_multi_picker.py b/src/faebryk/library/has_multi_picker.py index f9225e40..2b46316a 100644 --- a/src/faebryk/library/has_multi_picker.py +++ b/src/faebryk/library/has_multi_picker.py @@ -7,7 +7,7 @@ from typing import Callable, Mapping from faebryk.core.module import Module -from faebryk.library.has_picker import has_picker + from faebryk.libs.picker.picker import PickError logger = logging.getLogger(__name__) @@ -32,9 +32,6 @@ class Picker: @abstractmethod def pick(self, module: Module): ... - def __init__(self) -> None: - super().__init__() - self.pickers: list[tuple[int, has_multi_picker.Picker]] = [] def add_picker(self, prio: int, picker: Picker): diff --git a/src/faebryk/library/has_overriden_name_defined.py b/src/faebryk/library/has_overriden_name_defined.py index 9defd1e6..fed2e014 100644 --- a/src/faebryk/library/has_overriden_name_defined.py +++ b/src/faebryk/library/has_overriden_name_defined.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_overriden_name import has_overriden_name - class has_overriden_name_defined(has_overriden_name.impl()): def __init__(self, name: str) -> None: diff --git a/src/faebryk/library/has_pcb_layout_defined.py b/src/faebryk/library/has_pcb_layout_defined.py index e65a5e04..35ff78c7 100644 --- a/src/faebryk/library/has_pcb_layout_defined.py +++ b/src/faebryk/library/has_pcb_layout_defined.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT from faebryk.exporters.pcb.layout.layout import Layout -from faebryk.library.has_pcb_layout import has_pcb_layout class has_pcb_layout_defined(has_pcb_layout.impl()): diff --git a/src/faebryk/library/has_pcb_position_defined.py b/src/faebryk/library/has_pcb_position_defined.py index 8d8e9755..af57ee60 100644 --- a/src/faebryk/library/has_pcb_position_defined.py +++ b/src/faebryk/library/has_pcb_position_defined.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_pcb_position import has_pcb_position - class has_pcb_position_defined(has_pcb_position.impl()): def __init__(self, position: has_pcb_position.Point) -> None: diff --git a/src/faebryk/library/has_pcb_position_defined_relative.py b/src/faebryk/library/has_pcb_position_defined_relative.py index 59a6d825..33c2df21 100644 --- a/src/faebryk/library/has_pcb_position_defined_relative.py +++ b/src/faebryk/library/has_pcb_position_defined_relative.py @@ -3,7 +3,6 @@ from faebryk.core.module import Module -from faebryk.library.has_pcb_position import has_pcb_position class has_pcb_position_defined_relative(has_pcb_position.impl()): diff --git a/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py b/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py index d50051c5..944a6311 100644 --- a/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py +++ b/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py @@ -3,7 +3,6 @@ import logging -from faebryk.library.has_pcb_position import has_pcb_position logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/has_pcb_routing_strategy.py b/src/faebryk/library/has_pcb_routing_strategy.py index 873a7afd..ec8588c9 100644 --- a/src/faebryk/library/has_pcb_routing_strategy.py +++ b/src/faebryk/library/has_pcb_routing_strategy.py @@ -13,8 +13,7 @@ class has_pcb_routing_strategy(Trait): @abstractmethod def calculate(self, transformer: PCB_Transformer) -> list[Route]: ... - def __init__(self) -> None: - super().__init__() + self.priority = 0.0 def __repr__(self) -> str: diff --git a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py index fcd1aea5..d0f5423e 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py +++ b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py @@ -13,7 +13,7 @@ get_pads_pos_of_mifs, group_pads_that_are_connected_already, ) -from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy + from faebryk.libs.geometry.basic import Geometry logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/has_pcb_routing_strategy_manual.py b/src/faebryk/library/has_pcb_routing_strategy_manual.py index 1a2bd0e6..a022c9e9 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_manual.py +++ b/src/faebryk/library/has_pcb_routing_strategy_manual.py @@ -12,10 +12,7 @@ get_internal_nets_of_node, get_pads_pos_of_mifs, ) -from faebryk.library.Electrical import Electrical -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.Net import Net + logger = logging.getLogger(__name__) @@ -23,7 +20,7 @@ class has_pcb_routing_strategy_manual(has_pcb_routing_strategy.impl()): def __init__( self, - paths: list[tuple[Net | list[Electrical], Path]], + paths: list[tuple[Net | list[F.Electrical], Path]], relative_to: Node | None = None, absolute: bool = False, ): diff --git a/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py b/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py index f430619f..173041e1 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py +++ b/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py @@ -14,9 +14,8 @@ get_routes_of_pad, group_pads_that_are_connected_already, ) -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.Net import Net + + from faebryk.libs.geometry.basic import Geometry logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/has_pin_association_heuristic.py b/src/faebryk/library/has_pin_association_heuristic.py index 5943cc60..522382ea 100644 --- a/src/faebryk/library/has_pin_association_heuristic.py +++ b/src/faebryk/library/has_pin_association_heuristic.py @@ -4,7 +4,6 @@ from abc import abstractmethod from faebryk.core.module import Module -from faebryk.library.Electrical import Electrical class has_pin_association_heuristic(Module.TraitT): @@ -18,4 +17,4 @@ class PinMatchException(Exception): ... def get_pins( self, pins: list[tuple[str, str]], - ) -> dict[str, Electrical]: ... + ) -> dict[str, F.Electrical]: ... diff --git a/src/faebryk/library/has_pin_association_heuristic_lookup_table.py b/src/faebryk/library/has_pin_association_heuristic_lookup_table.py index 8de375c5..97ed2601 100644 --- a/src/faebryk/library/has_pin_association_heuristic_lookup_table.py +++ b/src/faebryk/library/has_pin_association_heuristic_lookup_table.py @@ -3,8 +3,6 @@ import logging -from faebryk.library.Electrical import Electrical -from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic logger = logging.getLogger(__name__) @@ -12,7 +10,7 @@ class has_pin_association_heuristic_lookup_table(has_pin_association_heuristic.impl()): def __init__( self, - mapping: dict[Electrical, list[str]], + mapping: dict[F.Electrical, list[str]], accept_prefix: bool, case_sensitive: bool, nc: list[str] | None = None, @@ -26,7 +24,7 @@ def __init__( def get_pins( self, pins: list[tuple[str, str]], - ) -> dict[str, Electrical]: + ) -> dict[str, F.Electrical]: """ Get the pinmapping for a list of pins based on a lookup table. diff --git a/src/faebryk/library/has_simple_value_representation_based_on_param.py b/src/faebryk/library/has_simple_value_representation_based_on_param.py index c43aa769..2613574f 100644 --- a/src/faebryk/library/has_simple_value_representation_based_on_param.py +++ b/src/faebryk/library/has_simple_value_representation_based_on_param.py @@ -4,17 +4,13 @@ from typing import Callable from faebryk.core.parameter import Parameter -from faebryk.library.Constant import Constant -from faebryk.library.has_simple_value_representation import ( - has_simple_value_representation, -) class has_simple_value_representation_based_on_param( has_simple_value_representation.impl() ): def __init__( - self, param: Parameter, transformer: Callable[[Constant], str] + self, param: Parameter, transformer: Callable[[F.Constant], str] ) -> None: super().__init__() self.param = param @@ -22,8 +18,8 @@ def __init__( def get_value(self) -> str: param_const = self.param.get_most_narrow() - assert isinstance(param_const, Constant) + assert isinstance(param_const, F.Constant) return self.transformer(param_const) def is_implemented(self): - return isinstance(self.param.get_most_narrow(), Constant) + return isinstance(self.param.get_most_narrow(), F.Constant) diff --git a/src/faebryk/library/has_simple_value_representation_based_on_params.py b/src/faebryk/library/has_simple_value_representation_based_on_params.py index 80ead29b..f7379a4f 100644 --- a/src/faebryk/library/has_simple_value_representation_based_on_params.py +++ b/src/faebryk/library/has_simple_value_representation_based_on_params.py @@ -4,9 +4,6 @@ from typing import Callable, Sequence from faebryk.core.parameter import Parameter -from faebryk.library.has_simple_value_representation import ( - has_simple_value_representation, -) class has_simple_value_representation_based_on_params( diff --git a/src/faebryk/library/has_simple_value_representation_defined.py b/src/faebryk/library/has_simple_value_representation_defined.py index cce81325..d12c9e8d 100644 --- a/src/faebryk/library/has_simple_value_representation_defined.py +++ b/src/faebryk/library/has_simple_value_representation_defined.py @@ -1,10 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_simple_value_representation import ( - has_simple_value_representation, -) - class has_simple_value_representation_defined(has_simple_value_representation.impl()): def __init__(self, value: str) -> None: diff --git a/src/faebryk/library/has_single_connection_impl.py b/src/faebryk/library/has_single_connection_impl.py index c926e636..f4107820 100644 --- a/src/faebryk/library/has_single_connection_impl.py +++ b/src/faebryk/library/has_single_connection_impl.py @@ -1,8 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.library.has_single_connection import has_single_connection - class has_single_connection_impl(has_single_connection.impl()): def get_connection(self): diff --git a/src/faebryk/library/has_single_electric_reference.py b/src/faebryk/library/has_single_electric_reference.py index 9fddcb64..fadfd310 100644 --- a/src/faebryk/library/has_single_electric_reference.py +++ b/src/faebryk/library/has_single_electric_reference.py @@ -5,9 +5,8 @@ from abc import abstractmethod from faebryk.core.core import Trait -from faebryk.library.ElectricPower import ElectricPower class has_single_electric_reference(Trait): @abstractmethod - def get_reference(self) -> ElectricPower: ... + def get_reference(self) -> F.ElectricPower: ... diff --git a/src/faebryk/library/has_single_electric_reference_defined.py b/src/faebryk/library/has_single_electric_reference_defined.py index 493d4676..df32335d 100644 --- a/src/faebryk/library/has_single_electric_reference_defined.py +++ b/src/faebryk/library/has_single_electric_reference_defined.py @@ -2,14 +2,10 @@ # SPDX-License-Identifier: MIT -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_single_electric_reference import has_single_electric_reference - - class has_single_electric_reference_defined(has_single_electric_reference.impl()): - def __init__(self, reference: ElectricPower) -> None: + def __init__(self, reference: F.ElectricPower) -> None: super().__init__() self.reference = reference - def get_reference(self) -> ElectricPower: + def get_reference(self) -> F.ElectricPower: return self.reference diff --git a/src/faebryk/library/is_decoupled.py b/src/faebryk/library/is_decoupled.py index 899fa7bb..f68add7c 100644 --- a/src/faebryk/library/is_decoupled.py +++ b/src/faebryk/library/is_decoupled.py @@ -5,11 +5,11 @@ from abc import abstractmethod from faebryk.core.trait import Trait -from faebryk.library.Capacitor import Capacitor + logger = logging.getLogger(__name__) class is_decoupled(Trait): @abstractmethod - def get_capacitor(self) -> Capacitor: ... + def get_capacitor(self) -> F.Capacitor: ... diff --git a/src/faebryk/library/is_decoupled_nodes.py b/src/faebryk/library/is_decoupled_nodes.py index 1eac341f..19f82f78 100644 --- a/src/faebryk/library/is_decoupled_nodes.py +++ b/src/faebryk/library/is_decoupled_nodes.py @@ -3,15 +3,13 @@ import logging -from faebryk.library.Capacitor import Capacitor -from faebryk.library.is_decoupled import is_decoupled logger = logging.getLogger(__name__) class is_decoupled_nodes(is_decoupled.impl()): def on_obj_set(self) -> None: - assert hasattr(self.get_obj().NODEs, "capacitor") + assert hasattr(self.get_obj(), "capacitor") - def get_capacitor(self) -> Capacitor: - return self.get_obj().NODEs.capacitor + def get_capacitor(self) -> F.Capacitor: + return self.get_obj().capacitor diff --git a/src/faebryk/library/is_esphome_bus_defined.py b/src/faebryk/library/is_esphome_bus_defined.py index 1aab4f93..e3437ef6 100644 --- a/src/faebryk/library/is_esphome_bus_defined.py +++ b/src/faebryk/library/is_esphome_bus_defined.py @@ -2,9 +2,6 @@ # SPDX-License-Identifier: MIT -from faebryk.library.is_esphome_bus import is_esphome_bus - - class is_esphome_bus_defined(is_esphome_bus.impl()): def __init__(self, bus_id: str): super().__init__() diff --git a/src/faebryk/library/is_representable_by_single_value_defined.py b/src/faebryk/library/is_representable_by_single_value_defined.py index 620a9b8c..5f77b099 100644 --- a/src/faebryk/library/is_representable_by_single_value_defined.py +++ b/src/faebryk/library/is_representable_by_single_value_defined.py @@ -3,10 +3,6 @@ import typing -from faebryk.library.is_representable_by_single_value import ( - is_representable_by_single_value, -) - class is_representable_by_single_value_defined(is_representable_by_single_value.impl()): def __init__(self, value: typing.Any) -> None: diff --git a/src/faebryk/library/is_surge_protected.py b/src/faebryk/library/is_surge_protected.py index 7b2d3d37..59358cf5 100644 --- a/src/faebryk/library/is_surge_protected.py +++ b/src/faebryk/library/is_surge_protected.py @@ -6,7 +6,7 @@ from typing import Sequence from faebryk.core.trait import Trait -from faebryk.library.TVS import TVS + logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/is_surge_protected_defined.py b/src/faebryk/library/is_surge_protected_defined.py index b05d8653..4269d531 100644 --- a/src/faebryk/library/is_surge_protected_defined.py +++ b/src/faebryk/library/is_surge_protected_defined.py @@ -4,8 +4,6 @@ import logging from typing import Sequence -from faebryk.library.is_surge_protected import is_surge_protected -from faebryk.library.TVS import TVS logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index c941f5e6..d55023f3 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -2,29 +2,22 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import ( - has_designator_prefix_defined, -) -from faebryk.libs.util import times + + + + + class pf_533984002(Module): - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - pin = L.if_list(2, Electrical) - mount = L.if_list(2, Electrical) - self.IFs = _IFs(self) + pin = L.if_list(2, F.Electrical) + mount = L.if_list(2, F.Electrical) - x = self.IFs + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { @@ -42,4 +35,4 @@ class _IFs(Module.IFS()): ) ) - self.add_trait(has_designator_prefix_defined("J")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/pf_74AHCT2G125.py b/src/faebryk/library/pf_74AHCT2G125.py index 86c4323e..80efaf6c 100644 --- a/src/faebryk/library/pf_74AHCT2G125.py +++ b/src/faebryk/library/pf_74AHCT2G125.py @@ -2,19 +2,11 @@ # SPDX-License-Identifier: MIT from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.Range import Range + + + + + from faebryk.libs.units import P @@ -27,42 +19,41 @@ class pf_74AHCT2G125(Module): output to assume a high-impedance OFF-state. """ - def __init__(self) -> None: - super().__init__() + # interfaces - class _IFs(Module.IFS()): - power = ElectricPower() - a = ElectricLogic() # IN - y = ElectricLogic() # OUT - oe = ElectricLogic() # enable, active low - self.IFs = _IFs(self) + power: F.ElectricPower + a: F.ElectricLogic # IN + y: F.ElectricLogic # OUT + oe: F.ElectricLogic # enable, active low - x = self.IFs + x = self self.add_trait( can_attach_to_footprint_via_pinmap( { - "1": x.oe.IFs.signal, - "2": x.a.IFs.signal, - "3": x.power.IFs.lv, - "4": x.y.IFs.signal, - "5": x.power.IFs.hv, + "1": x.oe.signal, + "2": x.a.signal, + "3": x.power.lv, + "4": x.y.signal, + "5": x.power.hv, } ) ) - self.IFs.power.PARAMs.voltage.merge(Range(4.5 * P.V, 5.5 * P.V)) + self.power.voltage.merge(F.Range(4.5 * P.V, 5.5 * P.V)) - self.IFs.power.get_trait(can_be_decoupled).decouple() + self.power.get_trait(can_be_decoupled).decouple() # connect all logic references - ref = ElectricLogic.connect_all_module_references(self) + ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) - self.add_trait(has_designator_prefix_defined("U")) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.add_trait(can_bridge_defined(self.IFs.a, self.IFs.y)) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.a, self.y) self.add_trait( has_datasheet_defined( diff --git a/src/faebryk/libs/library/L.py b/src/faebryk/libs/library/L.py index 261567ff..4cc902a5 100644 --- a/src/faebryk/libs/library/L.py +++ b/src/faebryk/libs/library/L.py @@ -6,4 +6,4 @@ logger = logging.getLogger(__name__) from faebryk.core.module import Module -from faebryk.core.node import d_field, if_list, rt_field, f_field +from faebryk.core.node import Node, d_field, f_field, if_list, rt_field From 806ce77b35de2a341167e24c2418c95f788337da Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Sat, 24 Aug 2024 01:50:38 +0200 Subject: [PATCH 12/63] more progress --- src/faebryk/library/BH1750FVI_TR.py | 13 +- src/faebryk/library/EEPROM.py | 2 +- src/faebryk/library/ESP32.py | 63 ++-- src/faebryk/library/ESP32_C3.py | 322 +++++++++--------- src/faebryk/library/ESP32_C3_MINI_1.py | 67 ++-- .../ESP32_C3_MINI_1_Reference_Design.py | 24 +- src/faebryk/library/HLK_LD2410B_P.py | 9 +- src/faebryk/library/I2C.py | 4 +- src/faebryk/library/LDO.py | 4 +- src/faebryk/library/M24C08_FMN6TP.py | 4 +- src/faebryk/library/MCP2221A.py | 10 +- src/faebryk/library/ME6211C33M5G_N.py | 11 +- src/faebryk/library/OLED_Module.py | 4 +- src/faebryk/library/PM1006.py | 9 +- src/faebryk/library/PowerSwitchMOSFET.py | 2 +- src/faebryk/library/QWIIC.py | 4 +- src/faebryk/library/QWIIC_Connector.py | 2 +- src/faebryk/library/RP2040.py | 15 +- .../library/RP2040_Reference_Design.py | 9 +- src/faebryk/library/SCD40.py | 12 +- src/faebryk/library/SK9822_EC20.py | 7 +- src/faebryk/library/TD541S485H.py | 8 +- src/faebryk/library/TXS0102DCUR.py | 11 +- src/faebryk/library/TXS0102DCUR_UART.py | 4 +- src/faebryk/library/UART.py | 2 +- src/faebryk/library/UART_Base.py | 4 +- src/faebryk/library/UART_RS485.py | 4 +- src/faebryk/library/USB2514B.py | 27 +- src/faebryk/library/USB2_0_ESD_Protection.py | 2 +- src/faebryk/library/USB3.py | 2 +- src/faebryk/library/USB3_IF.py | 2 +- src/faebryk/library/USB3_connector.py | 2 +- src/faebryk/library/USBLC6_2P6.py | 9 +- src/faebryk/library/USB_C.py | 2 +- src/faebryk/library/USB_C_5V_PSU.py | 2 +- src/faebryk/library/USB_C_PSU_Vertical.py | 4 +- src/faebryk/library/USB_RS485.py | 2 +- .../USB_Type_C_Receptacle_14_pin_Vertical.py | 2 +- src/faebryk/library/XL_3528RGBW_WS2812B.py | 7 +- src/faebryk/library/pf_533984002.py | 7 +- src/faebryk/library/pf_74AHCT2G125.py | 9 +- 41 files changed, 309 insertions(+), 400 deletions(-) diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 631ef0e4..aedcf811 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -62,7 +62,7 @@ def set_address(self, addr: int): addr: F.ElectricLogic dvi: F.ElectricLogic ep: F.ElectricLogic - i2c = I2C() + i2c = F.I2C() @@ -72,7 +72,7 @@ def set_address(self, addr: int): self.i2c.terminate() self.i2c.frequency.merge( - I2C.define_max_frequency_capability(I2C.SpeedMode.fast_speed) + F.I2C.define_max_frequency_capability(F.I2C.SpeedMode.fast_speed) ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") @@ -90,12 +90,7 @@ def set_address(self, addr: int): } ) ) - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/1811081611_ROHM-Semicon-BH1750FVI-TR_C78960.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/1811081611_ROHM-Semicon-BH1750FVI-TR_C78960.pdf") # set constraints self.power.voltage.merge(F.Range(2.4 * P.V, 3.6 * P.V)) @@ -105,7 +100,7 @@ def set_address(self, addr: int): self.add_trait(has_single_electric_reference_defined(ref)) ref.connect(self.power) - self.power.get_trait(can_be_decoupled).decouple().capacitance.merge(0.1 * P.uF) + self.power.decoupled.decouple().capacitance.merge(0.1 * P.uF) # TODO: self.dvi.low_pass(self.IF.dvi_capacitor, self.IF.dvi_resistor) # self.i2c.add_trait(is_esphome_bus.impl()()) diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index 534935fc..02890dd2 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -9,7 +9,7 @@ class EEPROM(Module): """ - Generic EEPROM module with I2C interface. + Generic EEPROM module with F.I2C interface. """ def set_address(self, addr: int): diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index b7d7cba3..1cc35235 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -4,8 +4,10 @@ import logging import typing from dataclasses import dataclass +import faebryk.library._F as F -from faebryk.core.module import Module, ModuleInterface +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface @@ -20,54 +22,55 @@ # TODO class _ESP_ADC(ModuleInterface): + CHANNELS = L.if_list(channel_count, F.Electrical) + def __init__(self, channel_count: int) -> None: super().__init__() - CHANNELS = L.if_list(channel_count, F.Electrical) class _ESP_SDIO(ModuleInterface): - DATA = L.if_list(4, F.Electrical) - CLK: F.Electrical - CMD: F.Electrical - GND: F.Electrical + DATA = L.if_list(4, F.Electrical) + CLK: F.Electrical + CMD: F.Electrical + GND: F.Electrical class _ESP32_EMAC(ModuleInterface): - TXD = L.if_list(4, F.Electrical) - RXD = L.if_list(4, F.Electrical) - TX_CLK: F.Electrical - RX_CLK: F.Electrical - TX_EN: F.Electrical - RX_ER: F.Electrical - RX_DV: F.Electrical - CLK_OUT: F.Electrical - CLK_OUT_180: F.Electrical - TX_ER: F.Electrical - MDC_out: F.Electrical - MDI_in: F.Electrical - MDO_out: F.Electrical - CRS_out: F.Electrical - COL_out: F.Electrical + TXD = L.if_list(4, F.Electrical) + RXD = L.if_list(4, F.Electrical) + TX_CLK: F.Electrical + RX_CLK: F.Electrical + TX_EN: F.Electrical + RX_ER: F.Electrical + RX_DV: F.Electrical + CLK_OUT: F.Electrical + CLK_OUT_180: F.Electrical + TX_ER: F.Electrical + MDC_out: F.Electrical + MDI_in: F.Electrical + MDO_out: F.Electrical + CRS_out: F.Electrical + COL_out: F.Electrical class _ESP32_SPI(ModuleInterface): - D: F.Electrical - Q: F.Electrical - WP: F.Electrical - HD: F.Electrical + D: F.Electrical + Q: F.Electrical + WP: F.Electrical + HD: F.Electrical - CS: F.Electrical + CS: F.Electrical - CLK: F.Electrical - GND: F.Electrical + CLK: F.Electrical + GND: F.Electrical class ESP32(Module): @@ -132,10 +135,10 @@ class ESP32(Module): GND: F.Electrical # High Level Functions - I2C = L.if_list(2, I2C) + F.I2C = L.if_list(2, F.I2C) SDIO_SLAVE = _ESP_SDIO() SDIO_HOST = L.if_list(2, _ESP_SDIO) - UART = UART_Base() + UART = F.UART_Base() JTAG = JTAG() TOUCH = L.if_list(10, F.Electrical) GPIO = L.if_list(40 - 6, F.Electrical) diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 75215d47..1274d2f3 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -3,40 +3,40 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import connect_to_all_interfaces - - +from faebryk.libs.library import L from faebryk.libs.units import P - logger = logging.getLogger(__name__) class ESP32_C3(Module): """ESP32-C3""" + vdd3p3_cpu: F.ElectricPower + vdd3p3_rtc: F.ElectricPower + vdd_spi: F.ElectricPower + vdd3p3: F.ElectricPower + vdda: F.ElectricPower + lna_in: F.Electrical + enable: F.ElectricLogic + xtal_p: F.Electrical + xtal_n: F.Electrical + gpio = L.if_list(22, F.ElectricLogic) + # TODO: map peripherals to GPIOs with pinmux + usb: F.USB2_0 + i2c = F.I2C() + uart = L.if_list(2, F.UART_Base) + # ... etc + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf" + ) - - - - vdd3p3_cpu: F.ElectricPower - vdd3p3_rtc: F.ElectricPower - vdd_spi: F.ElectricPower - vdd3p3: F.ElectricPower - vdda: F.ElectricPower - lna_in: F.Electrical - enable: F.ElectricLogic - xtal_p: F.Electrical - xtal_n: F.Electrical - gpio = L.if_list(22, F.ElectricLogic) - # TODO: map peripherals to GPIOs with pinmux - usb = USB2_0() - i2c = I2C() - uart = L.if_list(2, UART_Base) - # ... etc - + def __preinit__(self): x = self # https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#uart @@ -70,11 +70,11 @@ class ESP32_C3(Module): ) # connect decoupling caps to power domains - self.vdd3p3.get_trait(can_be_decoupled).decouple() - self.vdd3p3_cpu.get_trait(can_be_decoupled).decouple() - self.vdd3p3_rtc.get_trait(can_be_decoupled).decouple() - self.vdda.get_trait(can_be_decoupled).decouple() - self.vdd_spi.get_trait(can_be_decoupled).decouple() + self.vdd3p3.decoupled.decouple() + self.vdd3p3_cpu.decoupled.decouple() + self.vdd3p3_rtc.decoupled.decouple() + self.vdda.decoupled.decouple() + self.vdd_spi.decoupled.decouple() # rc delay circuit on enable pin for startup delay # https://www.espressif.com/sites/default/files/documentation/esp32-c3-mini-1_datasheet_en.pdf page 24 # noqa E501 @@ -82,150 +82,136 @@ class ESP32_C3(Module): # self.enable.signal.connect_via( # self.en_rc_capacitor, self.pwr3v3.lv # ) - self.enable.get_trait(F.ElectricLogic.can_be_pulled).pull( - up=True - ) # TODO: combine with lowpass filter + self.enable.pulled.pull(up=True) # TODO: combine with lowpass filter # set default boot mode to "SPI Boot mode" (gpio = N.C. or HIGH) # https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf page 25 # noqa E501 # TODO: make configurable - self.gpio[8].get_trait(F.ElectricLogic.can_be_pulled).pull( - up=True - ) # boot_resistors[0] - self.gpio[2].get_trait(F.ElectricLogic.can_be_pulled).pull( - up=True - ) # boot_resistors[1] + self.gpio[8].pulled.pull(up=True) # boot_resistors[0] + self.gpio[2].pulled.pull(up=True) # boot_resistors[1] # TODO: gpio[9] has an internal pull-up at boot = SPI-Boot - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.add_trait( - has_datasheet_defined( - "https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf" - ) - ) - - # TODO: Fix this - # # set mux states - # # UART 1 - # self.set_mux(x.gpio[20], self.serial[1].rx) - # self.set_mux(x.gpio[21], self.serial[1].tx) - # # UART 0 - # self.set_mux(x.gpio[0], self.serial[0].rx) - # self.set_mux(x.gpio[1], self.serial[0].tx) - - # # I2C - # self.set_mux(x.gpio[4], self.i2c.scl) - # self.set_mux(x.gpio[5], self.i2c.sda) - - # class _uart_esphome_config(has_esphome_config.impl()): - # def get_config(self_) -> dict: - # assert isinstance(self, ESP32_C3) - # obj = self_.get_obj() - # assert isinstance(obj, UART_Base) - # config = { - # "uart": [ - # { - # "id": obj.get_trait(is_esphome_bus).get_bus_id(), - # "baud_rate": get_parameter_max(obj.baud), - # } - # ] - # } - - # try: - # config["uart"][0]["rx_pin"] = self.get_mux_pin(obj.rx)[1] - # except IndexError: - # ... - - # try: - # config["uart"][0]["tx_pin"] = self.get_mux_pin(obj.tx)[1] - # except IndexError: - # ... - - # # if no rx/tx pin is set, then not in use - # if set(config["uart"][0].keys()).isdisjoint({"rx_pin", "tx_pin"}): - # return {} - - # return config - - # class _i2c_esphome_config(has_esphome_config.impl()): - # def get_config(self_) -> dict: - # assert isinstance(self, ESP32_C3) - # obj = self_.get_obj() - # assert isinstance(obj, I2C) - - # try: - # sda = self.get_mux_pin(obj.sda)[1] - # scl = self.get_mux_pin(obj.scl)[1] - # except IndexError: - # # Not in use if pinmux is not set - # return {} - - # config = { - # "i2c": [ - # { - # "id": obj.get_trait(is_esphome_bus).get_bus_id(), - # "frequency": int(get_parameter_max(obj.frequency)), # noqa: E501 - # "sda": sda, - # "scl": scl, - # } - # ] - # } - - # return config - - # for serial in self.serial: - # serial.add_trait( - # is_esphome_bus_defined(f"uart_{self.serial.index(serial)}") - # ) - # serial.add_trait(_uart_esphome_config()) - - # for i, gpio in enumerate(self.gpio): - # gpio.add_trait(is_esphome_bus_defined(f"GPIO{i}")) - - # self.i2c.add_trait(is_esphome_bus_defined("i2c_0")) - # self.i2c.add_trait(_i2c_esphome_config()) - # self.i2c.frequency.merge( - # Set( - # [ - # I2C.define_max_frequency_capability(speed) - # for speed in [ - # I2C.SpeedMode.low_speed, - # I2C.SpeedMode.standard_speed, - # ] - # ] - # + [ - # F.Range(10 * P.khertz, 800 * P.khertz) - # ], # TODO: should be range 200k-800k, but breaks parameter merge - # ) - # ) - - # self.add_trait( - # has_esphome_config_defined( - # { - # "esp32": { - # "board": "Espressif ESP32-C3-DevKitM-1", - # "variant": "esp32c3", - # "framework": { - # "type": "esp-idf", - # "version": "recommended", - # }, - # }, - # } - # ) - # ) - - # very simple mux that uses pinmap - # def set_mux(self, gpio: F.ElectricLogic, target: F.ElectricLogic): - # """Careful not checked""" - # pin, _ = self.get_mux_pin(gpio) - # self.pinmap[pin] = target.signal - - # def get_mux_pin(self, target: F.ElectricLogic) -> tuple[str, int]: - # """Returns pin & gpio number""" - # pin = [k for k, v in self.pinmap.items() if v == target.signal][0] - # gpio = self.pinmap_default[pin] - # gpio_index = [ - # i for i, g in enumerate(self.gpio) if g.signal == gpio - # ][0] - # return pin, gpio_index + # TODO: Fix this + # # set mux states + # # UART 1 + # self.set_mux(x.gpio[20], self.serial[1].rx) + # self.set_mux(x.gpio[21], self.serial[1].tx) + # # UART 0 + # self.set_mux(x.gpio[0], self.serial[0].rx) + # self.set_mux(x.gpio[1], self.serial[0].tx) + + # # F.I2C + # self.set_mux(x.gpio[4], self.i2c.scl) + # self.set_mux(x.gpio[5], self.i2c.sda) + + # class _uart_esphome_config(has_esphome_config.impl()): + # def get_config(self_) -> dict: + # assert isinstance(self, ESP32_C3) + # obj = self_.get_obj() + # assert isinstance(obj, F.UART_Base) + # config = { + # "uart": [ + # { + # "id": obj.get_trait(is_esphome_bus).get_bus_id(), + # "baud_rate": get_parameter_max(obj.baud), + # } + # ] + # } + + # try: + # config["uart"][0]["rx_pin"] = self.get_mux_pin(obj.rx)[1] + # except IndexError: + # ... + + # try: + # config["uart"][0]["tx_pin"] = self.get_mux_pin(obj.tx)[1] + # except IndexError: + # ... + + # # if no rx/tx pin is set, then not in use + # if set(config["uart"][0].keys()).isdisjoint({"rx_pin", "tx_pin"}): + # return {} + + # return config + + # class _i2c_esphome_config(has_esphome_config.impl()): + # def get_config(self_) -> dict: + # assert isinstance(self, ESP32_C3) + # obj = self_.get_obj() + # assert isinstance(obj, F.I2C) + + # try: + # sda = self.get_mux_pin(obj.sda)[1] + # scl = self.get_mux_pin(obj.scl)[1] + # except IndexError: + # # Not in use if pinmux is not set + # return {} + + # config = { + # "i2c": [ + # { + # "id": obj.get_trait(is_esphome_bus).get_bus_id(), + # "frequency": int(get_parameter_max(obj.frequency)), # noqa: E501 + # "sda": sda, + # "scl": scl, + # } + # ] + # } + + # return config + + # for serial in self.serial: + # serial.add_trait( + # is_esphome_bus_defined(f"uart_{self.serial.index(serial)}") + # ) + # serial.add_trait(_uart_esphome_config()) + + # for i, gpio in enumerate(self.gpio): + # gpio.add_trait(is_esphome_bus_defined(f"GPIO{i}")) + + # self.i2c.add_trait(is_esphome_bus_defined("i2c_0")) + # self.i2c.add_trait(_i2c_esphome_config()) + # self.i2c.frequency.merge( + # Set( + # [ + # F.I2C.define_max_frequency_capability(speed) + # for speed in [ + # F.I2C.SpeedMode.low_speed, + # F.I2C.SpeedMode.standard_speed, + # ] + # ] + # + [ + # F.Range(10 * P.khertz, 800 * P.khertz) + # ], # TODO: should be range 200k-800k, but breaks parameter merge + # ) + # ) + + # self.add_trait( + # has_esphome_config_defined( + # { + # "esp32": { + # "board": "Espressif ESP32-C3-DevKitM-1", + # "variant": "esp32c3", + # "framework": { + # "type": "esp-idf", + # "version": "recommended", + # }, + # }, + # } + # ) + # ) + + # very simple mux that uses pinmap + # def set_mux(self, gpio: F.ElectricLogic, target: F.ElectricLogic): + # """Careful not checked""" + # pin, _ = self.get_mux_pin(gpio) + # self.pinmap[pin] = target.signal + + # def get_mux_pin(self, target: F.ElectricLogic) -> tuple[str, int]: + # """Returns pin & gpio number""" + # pin = [k for k, v in self.pinmap.items() if v == target.signal][0] + # gpio = self.pinmap_default[pin] + # gpio_index = [ + # i for i, g in enumerate(self.gpio) if g.signal == gpio + # ][0] + # return pin, gpio_index diff --git a/src/faebryk/library/ESP32_C3_MINI_1.py b/src/faebryk/library/ESP32_C3_MINI_1.py index 554e4d79..f65d6b60 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1.py +++ b/src/faebryk/library/ESP32_C3_MINI_1.py @@ -3,13 +3,9 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - - - - - +from faebryk.libs.library import L logger = logging.getLogger(__name__) @@ -17,35 +13,38 @@ class ESP32_C3_MINI_1(Module): """ESP32-C3-MINI-1 module""" + esp32_c3: F.ESP32_C3 + # TODO: add components as described in the datasheet + rf_output: F.Electrical + chip_enable: F.ElectricLogic + gpio = L.if_list( + 22, F.ElectricLogic + ) # TODO: Only GPIO 0 to 10 and 18, 19 are exposed + uart: F.UART_Base + vdd3v3: F.ElectricPower + # TODO: connect all components (nodes) - esp32_c3 = ESP32_C3() - # TODO: add components as described in the datasheet - - - rf_output: F.Electrical - chip_enable: F.ElectricLogic - gpio = L.if_list( - 22, F.ElectricLogic - ) # TODO: Only GPIO 0 to 10 and 18, 19 are exposed - uart = UART_Base() - vdd3v3: F.ElectricPower - - # TODO: connect all components (nodes) - - # connect all logic references - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) + def __preinit__(self): # connect power decoupling caps - self.vdd3v3.get_trait(can_be_decoupled).decouple() + self.vdd3v3.decoupled.decouple() - for i, gpio in enumerate(self.gpio): - gpio.connect(self.esp32_c3.gpio[i]) + for lhs, rhs in zip(self.gpio, self.esp32_c3.gpio): + lhs.connect(rhs) - gnd = self.vdd3v3.lv + # TODO: set the following in the pinmux + # UART0 gpio 20/21 + @L.rt_field + def attach_to_footprint(self): + gnd = self.vdd3v3.lv self.pinmap_default = { "1": gnd, "2": gnd, @@ -111,15 +110,9 @@ class ESP32_C3_MINI_1(Module): } self.pinmap = dict(self.pinmap_default) - self.add_trait(can_attach_to_footprint_via_pinmap(self.pinmap)) - - # TODO: set the following in the pinmux - # UART0 gpio 20/21 + return F.can_attach_to_footprint_via_pinmap(self.pinmap) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.add_trait( - has_datasheet_defined( - "https://www.espressif.com/sites/default/files/russianDocumentation/esp32-c3-mini-1_datasheet_en.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)( + "https://www.espressif.com/sites/default/files/russianDocumentation/esp32-c3-mini-1_datasheet_en.pdf" + ) diff --git a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py index 0333f425..1e8fe8fd 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py +++ b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py @@ -6,28 +6,24 @@ import faebryk.library._F as F from faebryk.core.module import Module - logger = logging.getLogger(__name__) class ESP32_C3_MINI_1_Reference_Design(Module): """ESP32_C3_MINI_1 Module reference design""" + esp32_c3_mini_1: F.ESP32_C3_MINI_1 + # TODO make switch debounced + boot_switch: F.Button # TODO: this cannot be picked Switch(F.Electrical) + reset_switch: F.Button # TODO: this cannot be picked Switch(F.Electrical) + low_speed_crystal_clock = F.Crystal_Oscillator + vdd3v3: F.ElectricPower + uart: F.UART_Base + jtag: F.JTAG + usb: F.USB2_0 - - esp32_c3_mini_1 = ESP32_C3_MINI_1() - # TODO make switch debounced - boot_switch = Button() # TODO: this cannot be picked Switch(F.Electrical) - reset_switch = Button() # TODO: this cannot be picked Switch(F.Electrical) - low_speed_crystal_clock = Crystal_Oscillator() - - - vdd3v3: F.ElectricPower - uart = UART_Base() - jtag = JTAG() - usb = USB2_0() - + def __preinit__(self): gnd = self.vdd3v3.lv # connect power diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index d38fa668..da32db43 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -71,7 +71,7 @@ def get_config(self) -> dict: # interfaces power: F.ElectricPower - uart = UART_Base() + uart = F.UART_Base() out: F.ElectricLogic x = self @@ -95,11 +95,6 @@ def get_config(self) -> dict: self.esphome = self._ld2410b_esphome_config() self.add_trait(self.esphome) - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/2209271801_HI-LINK-HLK-LD2410B-P_C5183132.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2209271801_HI-LINK-HLK-LD2410B-P_C5183132.pdf") self.uart.baud.merge(F.Constant(256 * P.kbaud)) diff --git a/src/faebryk/library/I2C.py b/src/faebryk/library/I2C.py index d2e2428f..7db966d9 100644 --- a/src/faebryk/library/I2C.py +++ b/src/faebryk/library/I2C.py @@ -26,8 +26,8 @@ def single_electric_reference(self): def terminate(self): # TODO: https://www.ti.com/lit/an/slva689/slva689.pdf - self.sda.get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) - self.scl.get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.sda.pulled.pull(up=True) + self.scl.pulled.pull(up=True) def _on_connect(self, other: "I2C"): super()._on_connect(other) diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index 33d34686..fda7b516 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -43,8 +43,8 @@ class OutputPolarity(Enum): self.power_in.voltage.merge(self.max_input_voltage) self.power_out.voltage.merge(self.output_voltage) - self.power_in.get_trait(can_be_decoupled).decouple() - self.power_out.get_trait(can_be_decoupled).decouple() + self.power_in.decoupled.decouple() + self.power_out.decoupled.decouple() self.enable.reference.connect(self.power_in) if self.output_polarity == self.OutputPolarity.POSITIVE: diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index 2b4ddf41..8d6de4ab 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -23,7 +23,7 @@ class M24C08_FMN6TP(Module): power: F.ElectricPower - data = I2C() + data = F.I2C() nwc: F.ElectricLogic e = L.if_list(3, F.ElectricLogic) @@ -50,7 +50,7 @@ def single_electric_reference(self): ) self.data.terminate() - self.power.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 563a1619..828721ad 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -19,16 +19,16 @@ class MCP2221A(Module): power: F.ElectricPower power_vusb: F.ElectricPower - uart = UART_Base() - i2c = I2C() + uart = F.UART_Base() + i2c = F.I2C() gpio = L.if_list(4, F.Electrical) reset: F.ElectricLogic - usb = USB2_0() + usb : F.USB2_0 - self.power.get_trait(can_be_decoupled).decouple() - self.power_vusb.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() + self.power_vusb.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index 49a01340..649174ca 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -34,8 +34,8 @@ def __init__(self, default_enabled: bool = True) -> None: self.power_out.voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) # connect decouple capacitor - self.power_in.get_trait(can_be_decoupled).decouple() - self.power_out.get_trait(can_be_decoupled).decouple() + self.power_in.decoupled.decouple() + self.power_out.decoupled.decouple() # LDO in & out share gnd reference self.power_in.lv.connect(self.power_out.lv) @@ -51,12 +51,7 @@ def __init__(self, default_enabled: bool = True) -> None: } ) ) - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/1811131510_MICRONE-Nanjing-Micro-One-Elec-ME6211C33M5G-N_C82942.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/1811131510_MICRONE-Nanjing-Micro-One-Elec-ME6211C33M5G-N_C82942.pdf") if default_enabled: self.enable.connect(self.power_in.hv) diff --git a/src/faebryk/library/OLED_Module.py b/src/faebryk/library/OLED_Module.py index f07e76b2..c18a3a5e 100644 --- a/src/faebryk/library/OLED_Module.py +++ b/src/faebryk/library/OLED_Module.py @@ -29,7 +29,7 @@ class DisplayController(Enum): power: F.ElectricPower - i2c = I2C() + i2c = F.I2C() resolution : F.TBD[self.Resolution] @@ -37,6 +37,6 @@ class DisplayController(Enum): self.power.voltage.merge(F.Range(3.0 * P.V, 5 * P.V)) - self.power.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("OLED") diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index 20590ecd..6bb373b5 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -54,17 +54,12 @@ def get_config(self) -> dict: } power: F.ElectricPower - data = UART_Base() + data = F.UART_Base() # components # --------------------------------------------------------------------- - - self.add_trait( - has_datasheet_defined( - "http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_F.LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_F.LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf") self.esphome = self._pm1006_esphome_config() self.add_trait(self.esphome) diff --git a/src/faebryk/library/PowerSwitchMOSFET.py b/src/faebryk/library/PowerSwitchMOSFET.py index 3f76fda5..cb45f88c 100644 --- a/src/faebryk/library/PowerSwitchMOSFET.py +++ b/src/faebryk/library/PowerSwitchMOSFET.py @@ -35,7 +35,7 @@ def __init__(self, lowside: bool, normally_closed: bool) -> None: # True False False # False True False # False False True - self.logic_in.get_trait(F.ElectricLogic.can_be_pulled).pull( + self.logic_in.pulled.pull( lowside == normally_closed ) diff --git a/src/faebryk/library/QWIIC.py b/src/faebryk/library/QWIIC.py index 15da1e12..38f1381f 100644 --- a/src/faebryk/library/QWIIC.py +++ b/src/faebryk/library/QWIIC.py @@ -12,14 +12,14 @@ class QWIIC(Module): """ Sparkfun QWIIC connection spec. Also compatible with Adafruits STEMMA QT. - Delivers 3.3V power + I2C over JST SH 1mm pitch 4 pin connectors + Delivers 3.3V power + F.I2C over JST SH 1mm pitch 4 pin connectors """ # interfaces - i2c = I2C() + i2c = F.I2C() power: F.ElectricPower # set constraints diff --git a/src/faebryk/library/QWIIC_Connector.py b/src/faebryk/library/QWIIC_Connector.py index de73f6bc..f9141020 100644 --- a/src/faebryk/library/QWIIC_Connector.py +++ b/src/faebryk/library/QWIIC_Connector.py @@ -16,7 +16,7 @@ class QWIIC_Connector(Module): power: F.ElectricPower - i2c = I2C() + i2c = F.I2C() diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index ca9ca875..b201b8ca 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -25,15 +25,15 @@ class RP2040(Module): power_vusb: F.ElectricPower gpio = L.if_list(30, F.Electrical) run: F.ElectricLogic - usb = USB2_0() + usb : F.USB2_0 qspi = MultiSPI(data_lane_count=4) xin: F.Electrical xout: F.Electrical test: F.Electrical swd = SWD() # TODO: these peripherals and more can be mapped to different pins - i2c = I2C() - uart = UART_Base() + i2c = F.I2C() + uart = F.UART_Base() @@ -48,15 +48,10 @@ class RP2040(Module): self.usb.usb_if.buspower, ]: pwrrail.lv.connect(gnd) - pwrrail.get_trait(can_be_decoupled).decouple() + pwrrail.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.add_trait( - has_datasheet_defined( - "https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf") # set parameters # self.io_vdd.voltage.merge(F.Range(1.8*P.V, 3.63*P.V)) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index 4dff2a77..bd8c3bce 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -24,7 +24,7 @@ class RP2040_Reference_Design(Module): # ---------------------------------------- power: F.ElectricPower - usb = USB2_0() + usb : F.USB2_0 rp2040 = RP2040() @@ -89,9 +89,4 @@ class RP2040_Reference_Design(Module): self.usb_current_limmit_resistor[1], self.rp2040.usb.usb_if.d.n, ) - - self.add_trait( - has_datasheet_defined( - "https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040.pdf") diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index 20545e66..4939bba4 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -57,7 +57,7 @@ def get_config(self) -> dict: # interfaces power: F.ElectricPower - i2c = I2C() + i2c = F.I2C() self.add_trait( can_attach_to_footprint_via_pinmap( @@ -76,17 +76,13 @@ def get_config(self) -> dict: self.power.voltage.merge(F.Constant(3.3 * P.V)) self.i2c.terminate() - self.power.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.i2c.frequency.merge( - I2C.define_max_frequency_capability(I2C.SpeedMode.fast_speed) - ) - self.add_trait( - has_datasheet_defined( - "https://sensirion.com/media/documents/48C4B7FB/64C134E7/Sensirion_SCD4x_Datasheet.pdf" - ) + F.I2C.define_max_frequency_capability(F.I2C.SpeedMode.fast_speed) ) + datasheet = L.f_field(F.has_datasheet_defined)("https://sensirion.com/media/documents/48C4B7FB/64C134E7/Sensirion_SCD4x_Datasheet.pdf") self.i2c.add_trait(is_esphome_bus.impl()()) self.esphome = self._scd4x_esphome_config() diff --git a/src/faebryk/library/SK9822_EC20.py b/src/faebryk/library/SK9822_EC20.py index e786238e..316ce75f 100644 --- a/src/faebryk/library/SK9822_EC20.py +++ b/src/faebryk/library/SK9822_EC20.py @@ -51,11 +51,6 @@ class SK9822_EC20(Module): # connect all logic references ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/2110250930_OPSCO-Optoelectronics-SK9822-EC20_C2909059.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2110250930_OPSCO-Optoelectronics-SK9822-EC20_C2909059.pdf") designator_prefix = L.f_field(F.has_designator_prefix_defined)("LED") diff --git a/src/faebryk/library/TD541S485H.py b/src/faebryk/library/TD541S485H.py index b998058c..22e6b011 100644 --- a/src/faebryk/library/TD541S485H.py +++ b/src/faebryk/library/TD541S485H.py @@ -19,16 +19,16 @@ class TD541S485H(Module): power: F.ElectricPower power_iso_in: F.ElectricPower power_iso_out: F.ElectricPower - uart = UART_Base() + uart = F.UART_Base() rs485 = RS485() read_enable: F.Electrical write_enable: F.Electrical - self.power.get_trait(can_be_decoupled).decouple() - self.power_iso_in.get_trait(can_be_decoupled).decouple() - self.power_iso_out.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() + self.power_iso_in.decoupled.decouple() + self.power_iso_out.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index 14c4f2e0..4b0627da 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -44,8 +44,8 @@ def can_bridge(self): gnd = self.voltage_a_power.lv gnd.connect(self.voltage_b_power.lv) - self.voltage_a_power.get_trait(can_be_decoupled).decouple() - self.voltage_b_power.get_trait(can_be_decoupled).decouple() + self.voltage_a_power.decoupled.decouple() + self.voltage_b_power.decoupled.decouple() # eo is referenced to voltage_a_power (active high) self.n_oe.connect_reference(self.voltage_a_power) @@ -63,9 +63,4 @@ def can_bridge(self): ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/1810292010_Texas-Instruments-TXS0102DCUR_C53434.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/1810292010_Texas-Instruments-TXS0102DCUR_C53434.pdf") diff --git a/src/faebryk/library/TXS0102DCUR_UART.py b/src/faebryk/library/TXS0102DCUR_UART.py index d66b121c..df10edaa 100644 --- a/src/faebryk/library/TXS0102DCUR_UART.py +++ b/src/faebryk/library/TXS0102DCUR_UART.py @@ -15,8 +15,8 @@ class TXS0102DCUR_UART(Module): voltage_a_power: F.ElectricPower voltage_b_power: F.ElectricPower - voltage_a_bus = UART_Base() - voltage_b_bus = UART_Base() + voltage_a_bus = F.UART_Base() + voltage_b_bus = F.UART_Base() buffer = TXS0102DCUR() diff --git a/src/faebryk/library/UART.py b/src/faebryk/library/UART.py index dc47b5ce..d51f3260 100644 --- a/src/faebryk/library/UART.py +++ b/src/faebryk/library/UART.py @@ -5,7 +5,7 @@ class UART(ModuleInterface): - base_uart = UART_Base() + base_uart = F.UART_Base() rts: F.Electrical cts: F.Electrical dtr: F.Electrical diff --git a/src/faebryk/library/UART_Base.py b/src/faebryk/library/UART_Base.py index e5d80733..dbcbb17f 100644 --- a/src/faebryk/library/UART_Base.py +++ b/src/faebryk/library/UART_Base.py @@ -8,7 +8,7 @@ from faebryk.libs.units import Quantity -class UART_Base(ModuleInterface): +class F.UART_Base(ModuleInterface): @@ -21,7 +21,7 @@ class UART_Base(ModuleInterface): ref = F.ElectricLogic.connect_all_module_references(self) self.add_trait(has_single_electric_reference_defined(ref)) - def _on_connect(self, other: "UART_Base"): + def _on_connect(self, other: "F.UART_Base"): super()._on_connect(other) self.baud.merge(other.baud) diff --git a/src/faebryk/library/UART_RS485.py b/src/faebryk/library/UART_RS485.py index 6ce66e88..3d89233b 100644 --- a/src/faebryk/library/UART_RS485.py +++ b/src/faebryk/library/UART_RS485.py @@ -18,7 +18,7 @@ class UART_RS485(Module): power: F.ElectricPower - uart = UART_Base() + uart = F.UART_Base() rs485 = RS485() read_enable: F.Electrical write_enable: F.Electrical @@ -29,6 +29,6 @@ class UART_RS485(Module): self.power.voltage.merge(F.Range(3.3 * P.V, 5.0 * P.V)) - self.power.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 8cfec37b..617fb58f 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -55,7 +55,7 @@ class InterfaceConfiguration(Enum): OCS_N = L.if_list(4, F.ElectricLogic) BC_EN = L.if_list(4, F.ElectricLogic) - i2c = I2C() + i2c = F.I2C() interface_configuration : F.TBD[USB2514B.InterfaceConfiguration] @@ -63,19 +63,19 @@ class InterfaceConfiguration(Enum): designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") if self.interface_configuration == USB2514B.InterfaceConfiguration.DEFAULT: - self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) - self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + self.CFG_SEL[0].pulled.pull(up=False) + self.CFG_SEL[1].pulled.pull(up=False) elif self.interface_configuration == USB2514B.InterfaceConfiguration.SMBUS: - self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) - self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + self.CFG_SEL[0].pulled.pull(up=True) + self.CFG_SEL[1].pulled.pull(up=False) elif ( self.interface_configuration == USB2514B.InterfaceConfiguration.BUS_POWERED ): - self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) - self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.CFG_SEL[0].pulled.pull(up=False) + self.CFG_SEL[1].pulled.pull(up=True) elif self.interface_configuration == USB2514B.InterfaceConfiguration.EEPROM: - self.CFG_SEL[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) - self.CFG_SEL[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.CFG_SEL[0].pulled.pull(up=True) + self.CFG_SEL[1].pulled.pull(up=True) gnd: F.Electrical @@ -83,7 +83,7 @@ class InterfaceConfiguration(Enum): # TODO: decouple with 1.0uF and 0.1uF and maybe 4.7uF for g in self.get_all(): if isinstance(g, F.ElectricPower): - g.get_trait(can_be_decoupled).decouple() + g.decoupled.decouple() g.lv.connect(gnd) x = self @@ -94,9 +94,4 @@ class InterfaceConfiguration(Enum): x.NON_REM[1].connect(x.i2c.sda) x.RESET_N.connect(gnd) - - self.add_trait( - has_datasheet_defined( - "https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001692C.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001692C.pdf") diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index a3b4fb8f..f75e6b4e 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -33,6 +33,6 @@ def can_bridge(self): self.usb[0].usb_if.buspower.connect(self.usb[1].usb_if.buspower) - self.usb[0].usb_if.buspower.get_trait(can_be_decoupled).decouple() + self.usb[0].usb_if.buspower.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/USB3.py b/src/faebryk/library/USB3.py index 7ded685c..2dd45994 100644 --- a/src/faebryk/library/USB3.py +++ b/src/faebryk/library/USB3.py @@ -11,7 +11,7 @@ class USB3(ModuleInterface): - usb3_if = USB3_IF() + usb3_if : USB3_IF self.usb3_if.gnd_drain.connect(self.usb3_if.usb_if.buspower.lv) diff --git a/src/faebryk/library/USB3_IF.py b/src/faebryk/library/USB3_IF.py index dbe3684c..7c4161f7 100644 --- a/src/faebryk/library/USB3_IF.py +++ b/src/faebryk/library/USB3_IF.py @@ -5,7 +5,7 @@ class USB3_IF(ModuleInterface): - usb_if = USB2_0_IF() + usb_if: USB2_0_IF rx = DifferentialPair() tx = DifferentialPair() gnd_drain: F.Electrical diff --git a/src/faebryk/library/USB3_connector.py b/src/faebryk/library/USB3_connector.py index a3260608..819414f6 100644 --- a/src/faebryk/library/USB3_connector.py +++ b/src/faebryk/library/USB3_connector.py @@ -17,7 +17,7 @@ class USB3_connector(Module): - usb3 = USB3() + usb3 : USB3 shield: F.Electrical diff --git a/src/faebryk/library/USBLC6_2P6.py b/src/faebryk/library/USBLC6_2P6.py index ca7f5fac..7f902c46 100644 --- a/src/faebryk/library/USBLC6_2P6.py +++ b/src/faebryk/library/USBLC6_2P6.py @@ -14,7 +14,7 @@ class USBLC6_2P6(Module): # interfaces - usb = USB2_0() + usb : USB2_0 x = self self.add_trait( @@ -31,9 +31,4 @@ class USBLC6_2P6(Module): ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/2108132230_TECH-PUBLIC-USBLC6-2P6_C2827693.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2108132230_TECH-PUBLIC-USBLC6-2P6_C2827693.pdf") diff --git a/src/faebryk/library/USB_C.py b/src/faebryk/library/USB_C.py index 8ad19ac2..33315abf 100644 --- a/src/faebryk/library/USB_C.py +++ b/src/faebryk/library/USB_C.py @@ -11,7 +11,7 @@ class USB_C(ModuleInterface): - usb3 = USB3() + usb3 : USB3 cc1: F.Electrical cc2: F.Electrical sbu1: F.Electrical diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index 7a1becfd..506df679 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -17,7 +17,7 @@ class USB_C_5V_PSU(Module): # interfaces power_out: F.ElectricPower - usb = USB_C() + usb : USB_C # components diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index ae459827..d38dd957 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -16,7 +16,7 @@ class USB_C_PSU_Vertical(Module): # interfaces power_out: F.ElectricPower - usb = USB2_0() + usb : USB2_0 # components @@ -26,7 +26,7 @@ class USB_C_PSU_Vertical(Module): configuration_resistors = L.if_list(2, F.Resistor) gnd_resistor : F.Resistor gnd_capacitor : F.Capacitor - esd = USB2_0_ESD_Protection() + esd : USB2_0_ESD_Protection fuse = Fuse() self.gnd_capacitor.capacitance.merge(100 * P.nF) diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index 208c961a..0576f90b 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -22,7 +22,7 @@ class USB_RS485(Module): polarization = L.if_list(2, F.Resistor) - usb = USB2_0() + usb : USB2_0 rs485 = RS485() diff --git a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py index 4ff43cbc..7e454a78 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py @@ -25,7 +25,7 @@ class USB_Type_C_Receptacle_14_pin_Vertical(Module): # power vbus: F.ElectricPower # diffpairs: p, n - usb = USB2_0() + usb : USB2_0 self.add_trait( can_attach_to_footprint_via_pinmap( diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index c4bd5313..def7f937 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -66,12 +66,7 @@ def can_bridge(self): } ) ) - - self.add_trait( - has_datasheet_defined( - "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2402181504_XINGLIGHT-XL-3528RGBW-WS2812B_C2890364.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2402181504_XINGLIGHT-XL-3528RGBW-WS2812B_C2890364.pdf") self.esphome = self._ws2812b_esphome_config() self.add_trait(self.esphome) diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index d55023f3..df6854b0 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -28,11 +28,6 @@ class pf_533984002(Module): } ) ) - - self.add_trait( - has_datasheet_defined( - "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/1912111437_SHOU-HAN-1-25-2P_C393945.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/1912111437_SHOU-HAN-1-25-2P_C393945.pdf") designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/pf_74AHCT2G125.py b/src/faebryk/library/pf_74AHCT2G125.py index 80efaf6c..050d3bd0 100644 --- a/src/faebryk/library/pf_74AHCT2G125.py +++ b/src/faebryk/library/pf_74AHCT2G125.py @@ -43,7 +43,7 @@ class pf_74AHCT2G125(Module): self.power.voltage.merge(F.Range(4.5 * P.V, 5.5 * P.V)) - self.power.get_trait(can_be_decoupled).decouple() + self.power.decoupled.decouple() # connect all logic references ref = F.ElectricLogic.connect_all_module_references(self) @@ -54,9 +54,4 @@ class pf_74AHCT2G125(Module): @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.a, self.y) - - self.add_trait( - has_datasheet_defined( - "https://datasheet.lcsc.com/lcsc/2304140030_Nexperia-74AHCT1G125GV-125_C12494.pdf" - ) - ) + datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2304140030_Nexperia-74AHCT1G125GV-125_C12494.pdf") From f94f9d8508d224bc45306eee1b4c8d5859ce9724 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Mon, 26 Aug 2024 22:21:12 +0200 Subject: [PATCH 13/63] Refactored through to S --- src/faebryk/core/node.py | 18 +- src/faebryk/library/BH1750FVI_TR.py | 2 +- src/faebryk/library/DIP.py | 10 +- src/faebryk/library/ESP32.py | 255 +++++++++--------- src/faebryk/library/ESP32_C3.py | 2 +- src/faebryk/library/ElectricLogic.py | 2 +- src/faebryk/library/ElectricLogicGate.py | 16 +- src/faebryk/library/Ethernet.py | 7 +- src/faebryk/library/Fan.py | 1 + src/faebryk/library/Footprint.py | 3 +- src/faebryk/library/Fuse.py | 22 +- src/faebryk/library/GDT.py | 20 +- src/faebryk/library/GenericBusProtection.py | 46 ++-- src/faebryk/library/HLK_LD2410B_P.py | 74 +++-- src/faebryk/library/Header.py | 29 +- src/faebryk/library/JTAG.py | 33 ++- src/faebryk/library/KicadFootprint.py | 42 +-- src/faebryk/library/LDO.py | 103 ++++--- src/faebryk/library/LED.py | 14 +- src/faebryk/library/Logic.py | 6 +- src/faebryk/library/Logic74xx.py | 12 +- src/faebryk/library/LogicGate.py | 51 ++-- src/faebryk/library/LogicGates.py | 21 +- src/faebryk/library/LogicOps.py | 28 +- src/faebryk/library/M24C08_FMN6TP.py | 58 ++-- src/faebryk/library/MCP2221A.py | 32 +-- src/faebryk/library/ME6211C33M5G_N.py | 58 ++-- src/faebryk/library/MOSFET.py | 50 ++-- src/faebryk/library/Mounting_Hole.py | 24 +- src/faebryk/library/MultiSPI.py | 16 +- src/faebryk/library/Net.py | 22 +- src/faebryk/library/OLED_Module.py | 20 +- src/faebryk/library/OpAmp.py | 89 +++--- src/faebryk/library/PJ398SM.py | 13 +- src/faebryk/library/PM1006.py | 32 +-- src/faebryk/library/Pad.py | 20 +- src/faebryk/library/Potentiometer.py | 27 +- src/faebryk/library/PowerSwitch.py | 20 +- src/faebryk/library/PowerSwitchMOSFET.py | 27 +- src/faebryk/library/PowerSwitchStatic.py | 4 +- src/faebryk/library/PoweredLED.py | 16 +- src/faebryk/library/Powered_Relay.py | 47 ++-- src/faebryk/library/QFN.py | 46 ++-- src/faebryk/library/QWIIC.py | 18 +- src/faebryk/library/QWIIC_Connector.py | 14 +- src/faebryk/library/RJ45_Receptacle.py | 17 +- src/faebryk/library/RP2040.py | 57 ++-- .../library/RP2040_Reference_Design.py | 54 ++-- src/faebryk/library/RS232.py | 22 +- src/faebryk/library/RS485.py | 5 +- src/faebryk/library/RS485_Bus_Protection.py | 87 +++--- src/faebryk/library/Range.py | 2 + src/faebryk/library/Relay.py | 40 ++- src/faebryk/library/Resistor.py | 50 ++-- .../library/Resistor_Voltage_Divider.py | 20 +- src/faebryk/library/SCD40.py | 66 +++-- src/faebryk/library/SK9822_EC20.py | 57 ++-- src/faebryk/library/SMDTwoPin.py | 61 ++--- src/faebryk/library/SNx4LVC541A.py | 51 ++-- src/faebryk/library/SOIC.py | 47 ++-- src/faebryk/library/SPI.py | 2 + src/faebryk/library/SPIFlash.py | 17 +- src/faebryk/library/SWD.py | 17 +- src/faebryk/library/SWDConnector.py | 18 +- src/faebryk/library/Sercom.py | 19 +- src/faebryk/library/Set.py | 1 + src/faebryk/library/Switch.py | 30 +-- src/faebryk/library/TI_CD4011BE.py | 2 +- src/faebryk/library/UART_Base.py | 2 +- src/faebryk/library/XL_3528RGBW_WS2812B.py | 2 +- src/faebryk/library/_F.py | 2 +- .../can_attach_to_footprint_symmetrically.py | 4 +- .../can_attach_to_footprint_via_pinmap.py | 2 +- .../library/can_attach_via_pinmap_equal.py | 2 +- .../library/can_attach_via_pinmap_pinlist.py | 2 +- src/faebryk/library/has_capacitance.py | 3 +- src/faebryk/library/has_datasheet_defined.py | 4 +- .../library/has_defined_capacitance.py | 3 +- .../has_defined_descriptive_properties.py | 7 +- src/faebryk/library/has_defined_kicad_ref.py | 4 +- src/faebryk/library/has_defined_resistance.py | 3 +- src/faebryk/library/has_designator_defined.py | 4 +- .../library/has_designator_prefix_defined.py | 4 +- src/faebryk/library/has_equal_pins.py | 4 +- src/faebryk/library/has_equal_pins_in_ifs.py | 6 +- src/faebryk/library/has_esphome_config.py | 2 +- .../library/has_esphome_config_defined.py | 4 +- src/faebryk/library/has_footprint.py | 1 + ..._footprint.py => has_footprint_defined.py} | 4 +- src/faebryk/library/has_footprint_impl.py | 3 +- .../has_footprint_requirement_defined.py | 3 +- src/faebryk/library/has_kicad_footprint.py | 4 +- .../library/has_kicad_footprint_equal_ifs.py | 6 +- .../has_kicad_footprint_equal_ifs_defined.py | 4 +- .../library/has_kicad_manual_footprint.py | 6 +- src/faebryk/library/has_kicad_ref.py | 2 +- src/faebryk/library/has_linked_pad.py | 3 +- src/faebryk/library/has_linked_pad_defined.py | 9 +- src/faebryk/library/has_multi_picker.py | 10 +- .../library/has_overriden_name_defined.py | 4 +- src/faebryk/library/has_pcb_layout_defined.py | 4 +- .../library/has_pcb_position_defined.py | 8 +- .../has_pcb_position_defined_relative.py | 9 +- ...pcb_position_defined_relative_to_parent.py | 11 +- .../library/has_pcb_routing_strategy.py | 4 +- ...pcb_routing_strategy_greedy_direct_line.py | 4 +- .../has_pcb_routing_strategy_manual.py | 16 +- .../has_pcb_routing_strategy_via_to_layer.py | 9 +- .../library/has_pin_association_heuristic.py | 1 + ..._pin_association_heuristic_lookup_table.py | 7 +- src/faebryk/library/has_resistance.py | 3 +- ...ple_value_representation_based_on_param.py | 3 +- ...le_value_representation_based_on_params.py | 3 +- ...has_simple_value_representation_defined.py | 4 +- src/faebryk/library/has_single_connection.py | 5 +- .../library/has_single_connection_impl.py | 4 +- .../library/has_single_electric_reference.py | 3 +- .../has_single_electric_reference_defined.py | 4 +- src/faebryk/library/is_decoupled.py | 2 +- src/faebryk/library/is_decoupled_nodes.py | 3 +- src/faebryk/library/is_esphome_bus_defined.py | 4 +- ...s_representable_by_single_value_defined.py | 6 +- src/faebryk/library/is_surge_protected.py | 4 +- .../library/is_surge_protected_defined.py | 5 +- src/faebryk/library/pf_533984002.py | 39 ++- src/faebryk/library/pf_74AHCT2G125.py | 54 ++-- 126 files changed, 1263 insertions(+), 1291 deletions(-) rename src/faebryk/library/{has_defined_footprint.py => has_footprint_defined.py} (73%) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 5eccc6dd..dc2ef56a 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -100,12 +100,12 @@ def __hash__(self) -> int: # TODO proper hash return hash(id(self)) - def add( + def add[T: Node]( self, - obj: "Node", + obj: T, name: str | None = None, container: list | dict[str, Any] | None = None, - ): + ) -> T: if container is None: container = self.runtime_anon if name: @@ -129,12 +129,18 @@ def add( name = f"{container_name}[{len(container) - 1}]" self._handle_add_node(name, obj) + return obj def add_to_container[T: Node]( - self, n: int, factory: Callable[[], T], container: list[T] + self, n: int, factory: Callable[[], T], container: list[T] | None = None ): - for _ in range(n): - self.add(factory(), container=container) + if container is None: + container = self.runtime_anon + + constr = [factory() for _ in range(n)] + for obj in constr: + self.add(obj, container=container) + return constr def __init_subclass__(cls, *, init: bool = True) -> None: super().__init_subclass__() diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index aedcf811..27a60c6b 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -97,7 +97,7 @@ def set_address(self, addr: int): # internal connections ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + self.add_trait(F.has_single_electric_reference_defined(ref)) ref.connect(self.power) self.power.decoupled.decouple().capacitance.merge(0.1 * P.uF) diff --git a/src/faebryk/library/DIP.py b/src/faebryk/library/DIP.py index 0fb97f9d..cfc5f392 100644 --- a/src/faebryk/library/DIP.py +++ b/src/faebryk/library/DIP.py @@ -5,18 +5,20 @@ import faebryk.library._F as F from faebryk.libs.library import L from faebryk.libs.units import P, Quantity +from faebryk.libs.util import times class DIP(F.Footprint): - pins = L.if_list(0, F.Pad) - def __init__(self, pin_cnt: int, spacing: Quantity, long_pads: bool) -> None: super().__init__() - self.add_to_container(pin_cnt, F.Pad, self.pins) - self.spacing = spacing self.long_pads = long_pads + self.pin_cnt = pin_cnt + + @L.rt_field + def pins(self): + return times(self.pin_cnt, F.Pad) @L.rt_field def kicad_footprint(self): diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index 1cc35235..924edf20 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -4,35 +4,29 @@ import logging import typing from dataclasses import dataclass -import faebryk.library._F as F +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface - - - - - - +from faebryk.libs.library import L from faebryk.libs.units import P - +from faebryk.libs.util import times logger = logging.getLogger(__name__) # TODO class _ESP_ADC(ModuleInterface): - CHANNELS = L.if_list(channel_count, F.Electrical) - def __init__(self, channel_count: int) -> None: super().__init__() + self.channel_count = channel_count - + @L.rt_field + def CHANNELS(self): + return times(self.channel_count, F.Electrical) class _ESP_SDIO(ModuleInterface): - - DATA = L.if_list(4, F.Electrical) CLK: F.Electrical CMD: F.Electrical @@ -40,8 +34,6 @@ class _ESP_SDIO(ModuleInterface): class _ESP32_EMAC(ModuleInterface): - - TXD = L.if_list(4, F.Electrical) RXD = L.if_list(4, F.Electrical) TX_CLK: F.Electrical @@ -60,103 +52,103 @@ class _ESP32_EMAC(ModuleInterface): class _ESP32_SPI(ModuleInterface): - - D: F.Electrical Q: F.Electrical WP: F.Electrical HD: F.Electrical - CS: F.Electrical - CLK: F.Electrical GND: F.Electrical class ESP32(Module): - - self.add_trait(has_simple_value_representation_defined("ESP32")) + simple_value_representation = L.f_field(F.has_simple_value_representation_defined)( + "ESP32" + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + # Analog + VDDA0: F.Electrical + LNA_IN: F.Electrical + VDD3P30: F.Electrical + VDD3P31: F.Electrical + SENSOR_VP: F.Electrical + # VDD3P3_RTC + SENSOR_CAPP: F.Electrical + SENSOR_CAPN: F.Electrical + SENSOR_VN: F.Electrical + CHIP_PU: F.Electrical + VDET_1: F.Electrical + VDET_2: F.Electrical + _32K_XP: F.Electrical + _32K_XN: F.Electrical + GPIO25: F.Electrical + GPIO26: F.Electrical + GPIO27: F.Electrical + MTMS: F.Electrical + MTDI: F.Electrical + VDD3P3_RTC: F.Electrical + MTCK: F.Electrical + MTDO: F.Electrical + GPIO2: F.Electrical + GPIO0: F.Electrical + GPIO4: F.Electrical + # VDD_SDIO + GPIO16: F.Electrical + VDD_SDIO: F.Electrical + GPIO17: F.Electrical + SD_DATA_2: F.Electrical + SD_DATA_3: F.Electrical + SD_CMD: F.Electrical + SD_CLK: F.Electrical + SD_DATA_0: F.Electrical + SD_DATA_1: F.Electrical + # VDD3P3_CPU + GPIO5: F.Electrical + GPIO18: F.Electrical + GPIO23: F.Electrical + VDD3P3_CPU: F.Electrical + GPIO19: F.Electrical + GPIO22: F.Electrical + U0RXD: F.Electrical + U0TXD: F.Electrical + GPIO21: F.Electrical + # Analog + VDDA1: F.Electrical + XTAL_N: F.Electrical + XTAL_P: F.Electrical + VDDA2: F.Electrical + CAP2: F.Electrical + CAP1: F.Electrical + GND: F.Electrical - # Analog - VDDA0: F.Electrical - LNA_IN: F.Electrical - VDD3P30: F.Electrical - VDD3P31: F.Electrical - SENSOR_VP: F.Electrical - # VDD3P3_RTC - SENSOR_CAPP: F.Electrical - SENSOR_CAPN: F.Electrical - SENSOR_VN: F.Electrical - CHIP_PU: F.Electrical - VDET_1: F.Electrical - VDET_2: F.Electrical - _32K_XP: F.Electrical - _32K_XN: F.Electrical - GPIO25: F.Electrical - GPIO26: F.Electrical - GPIO27: F.Electrical - MTMS: F.Electrical - MTDI: F.Electrical - VDD3P3_RTC: F.Electrical - MTCK: F.Electrical - MTDO: F.Electrical - GPIO2: F.Electrical - GPIO0: F.Electrical - GPIO4: F.Electrical - # VDD_SDIO - GPIO16: F.Electrical - VDD_SDIO: F.Electrical - GPIO17: F.Electrical - SD_DATA_2: F.Electrical - SD_DATA_3: F.Electrical - SD_CMD: F.Electrical - SD_CLK: F.Electrical - SD_DATA_0: F.Electrical - SD_DATA_1: F.Electrical - # VDD3P3_CPU - GPIO5: F.Electrical - GPIO18: F.Electrical - GPIO23: F.Electrical - VDD3P3_CPU: F.Electrical - GPIO19: F.Electrical - GPIO22: F.Electrical - U0RXD: F.Electrical - U0TXD: F.Electrical - GPIO21: F.Electrical - # Analog - VDDA1: F.Electrical - XTAL_N: F.Electrical - XTAL_P: F.Electrical - VDDA2: F.Electrical - CAP2: F.Electrical - CAP1: F.Electrical - GND: F.Electrical - - # High Level Functions - F.I2C = L.if_list(2, F.I2C) - SDIO_SLAVE = _ESP_SDIO() - SDIO_HOST = L.if_list(2, _ESP_SDIO) - UART = F.UART_Base() - JTAG = JTAG() - TOUCH = L.if_list(10, F.Electrical) - GPIO = L.if_list(40 - 6, F.Electrical) - RTC_GPIO = L.if_list(18, F.Electrical) - ADC = [ - None, - _ESP_ADC(channel_count=8), - _ESP_ADC(channel_count=10), - ] - SPI = L.if_list(4, _ESP32_SPI) - EMAC = _ESP32_EMAC() - - # Power - POWER_RTC: F.ElectricPower - POWER_CPU: F.ElectricPower - POWER_SDIO: F.ElectricPower - POWER_ANALOG: F.ElectricPower - + # High Level Functions + F.I2C = L.if_list(2, F.I2C) + SDIO_SLAVE: _ESP_SDIO + SDIO_HOST = L.if_list(2, _ESP_SDIO) + UART: F.UART_Base + JTAG: F.JTAG + TOUCH = L.if_list(10, F.Electrical) + GPIO = L.if_list(40 - 6, F.Electrical) + RTC_GPIO = L.if_list(18, F.Electrical) + ADC = L.d_field( + lambda: ( + None, + _ESP_ADC(channel_count=8), + _ESP_ADC(channel_count=10), + ) + ) + SPI = L.if_list(4, _ESP32_SPI) + EMAC: _ESP32_EMAC + + # Power + POWER_RTC: F.ElectricPower + POWER_CPU: F.ElectricPower + POWER_SDIO: F.ElectricPower + POWER_ANALOG: F.ElectricPower + + @L.rt_field + def attach_to_footprint(self): x = self self.pinmap = { # Analog @@ -214,7 +206,10 @@ class ESP32(Module): "48": x.GND, } - self.add_trait(can_attach_to_footprint_via_pinmap(self.pinmap)) + return F.can_attach_to_footprint_via_pinmap(self.pinmap) + + def __preinit__(self): + x = self # SPI0 is connected to SPI1 (Arbiter) x.SPI[0].Q.connect(x.SPI[1].Q) @@ -222,7 +217,7 @@ class ESP32(Module): x.SPI[0].HD.connect(x.SPI[1].HD) x.SPI[0].WP.connect(x.SPI[1].WP) x.SPI[0].CLK.connect(x.SPI[1].CLK) - x.SPI[0].CS.connect(x.SPI[1].NODES.CS) + x.SPI[0].CS.connect(x.SPI[1].CS) x.POWER_RTC.hv.connect(x.VDD3P3_RTC) x.POWER_RTC.lv.connect(x.GND) @@ -245,19 +240,16 @@ def get_gpio(self, idx: int): class _ESP32_D0WD(ESP32): - - self.add_trait( - has_defined_footprint( - QFN( - pin_cnt=48, - size_xy=(5 * P.mm, 5 * P.mm), - pitch=0.350 * P.mm, - exposed_thermal_pad_cnt=1, - exposed_thermal_pad_dimensions=(3.700 * P.mm, 3.700 * P.mm), - has_thermal_vias=True, - ) - ) + footprint: F.Footprint = L.f_field(F.has_footprint_defined)( + F.QFN( + pin_cnt=48, + size_xy=(5 * P.mm, 5 * P.mm), + pitch=0.350 * P.mm, + exposed_thermal_pad_cnt=1, + exposed_thermal_pad_dimensions=(3.700 * P.mm, 3.700 * P.mm), + has_thermal_vias=True, ) + ) class _ESP32_D0WD_V3(_ESP32_D0WD): @@ -294,15 +286,20 @@ class _Pad: class _Mux(Module): - def __init__(self, input: F.Electrical, *outputs: F.Electrical) -> None: - super().__init__() + IN: F.Electrical + @L.rt_field + def OUT(self): + return times(len(self.outputs), F.Electrical) - IN: F.Electrical - OUT = L.if_list(len(outputs), F.Electrical) + def __init__(self, input: F.Electrical, *outputs: F.Electrical) -> None: + super().__init__() + self.input = input + self.outputs = outputs - input.connect(self.IN) - self.map = dict(zip(outputs, self.OUT)) + def __preinit__(self): + self.input.connect(self.IN) + self.map = dict(zip(self.outputs, self.OUT)) for o1, o2 in self.map.items(): o1.connect(o2) @@ -356,18 +353,20 @@ def _matrix(esp32: ESP32): class _ESP32_Pinmux(Module): + @L.rt_field + def MUXES(self): + return [ + _Mux( + self.esp32.pinmap[str(pad.interface)], + *[f.interface for f in pad.functions.values()], + ) + for pad in self.matrix + ] + def __init__(self, esp32: ESP32) -> None: default_function = 5 self.matrix = _matrix(esp32) - - - MUXES = [ - _Mux( - esp32.pinmap[str(pad.interface)], - *[f.interface for f in pad.functions.values()], - ) - for pad in self.matrix - ] + self.esp32 = esp32 for pad in self.matrix: if len(pad.functions.items()) == 0: diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 1274d2f3..58dbd789 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -46,7 +46,7 @@ def __preinit__(self): # connect all logic references # TODO: set correctly for each power domain # ref = F.ElectricLogic.connect_all_module_references(self) - # self.add_trait(has_single_electric_reference_defined(ref)) + # self.add_trait(F.has_single_electric_reference_defined(ref)) # set power domain constraints to recommended operating conditions for power_domain in [self.vdd3p3_rtc, self.vdd3p3, self.vdda]: diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 318a92b2..d979ba9e 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -18,7 +18,7 @@ class has_pulls(F.Logic.TraitT): @abstractmethod def get_pulls(self) -> tuple[F.Resistor | None, F.Resistor | None]: ... - class has_pulls_defined(has_pulls.impl()): + class has_pulls_defined(F.has_pulls.impl()): def __init__(self, up: F.Resistor | None, down: F.Resistor | None) -> None: super().__init__() self.up = up diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index c4d0098c..49acdb34 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -7,14 +7,12 @@ from faebryk.core.trait import TraitImpl from faebryk.core.util import specialize_interface from faebryk.libs.library import L +from faebryk.libs.util import times T = TypeVar("T", bound=F.Logic) class ElectricLogicGate(F.LogicGate): - inputs = L.if_list(0, F.ElectricLogic) - outputs = L.if_list(0, F.ElectricLogic) - def __init__( self, input_cnt: F.Constant[int], @@ -23,8 +21,8 @@ def __init__( ) -> None: super().__init__(input_cnt, output_cnt, *functions) - self.add_to_container(int(input_cnt), F.ElectricLogic, self.inputs) - self.add_to_container(int(output_cnt), F.ElectricLogic, self.outputs) + self.input_cnt = input_cnt + self.output_cnt = output_cnt self_logic = self @@ -33,6 +31,14 @@ def __init__( for out_if_l, out_if_el in zip(self_logic.outputs, self.outputs): specialize_interface(out_if_l, out_if_el) + @L.rt_field + def inputs(self): + return times(self.input_cnt, F.ElectricLogic) + + @L.rt_field + def outputs(self): + return times(self.output_cnt, F.ElectricLogic) + @L.rt_field def single_electric_reference(self): return F.has_single_electric_reference_defined( diff --git a/src/faebryk/library/Ethernet.py b/src/faebryk/library/Ethernet.py index a57740ac..165d9a6e 100644 --- a/src/faebryk/library/Ethernet.py +++ b/src/faebryk/library/Ethernet.py @@ -1,9 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface +import faebryk.library._F as F +from faebryk.core.moduleinterface import ModuleInterface class Ethernet(ModuleInterface): - tx = DifferentialPair() - rx = DifferentialPair() + tx: F.DifferentialPair + rx: F.DifferentialPair diff --git a/src/faebryk/library/Fan.py b/src/faebryk/library/Fan.py index 6914422b..9fdf6c01 100644 --- a/src/faebryk/library/Fan.py +++ b/src/faebryk/library/Fan.py @@ -1,6 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index 63380e3b..f53ba3f5 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node @@ -17,5 +18,5 @@ def get_footprint_of_parent( ) -> "tuple[Node, Footprint]": from faebryk.core.util import get_parent_with_trait - parent, trait = get_parent_with_trait(intf, has_footprint) + parent, trait = get_parent_with_trait(intf, F.has_footprint) return parent, trait.get_footprint() diff --git a/src/faebryk/library/Fuse.py b/src/faebryk/library/Fuse.py index 1e34d039..c24203ed 100644 --- a/src/faebryk/library/Fuse.py +++ b/src/faebryk/library/Fuse.py @@ -4,15 +4,11 @@ import logging from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module - - - - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity - logger = logging.getLogger(__name__) @@ -25,17 +21,15 @@ class ResponseType(Enum): SLOW = auto() FAST = auto() + unnamed = L.if_list(2, F.Electrical) + fuse_type: F.TBD[FuseType] + response_type: F.TBD[ResponseType] + trip_current: F.TBD[Quantity] + attach_to_footprint: F.can_attach_to_footprint_symmetrically - unnamed = L.if_list(2, F.Electrical) - - - fuse_type : F.TBD[Fuse.FuseType] - response_type : F.TBD[Fuse.ResponseType] - trip_current : F.TBD[Quantity] - - self.add_trait(can_attach_to_footprint_symmetrically()) @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.unnamed[0], self.unnamed[1]) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("F") diff --git a/src/faebryk/library/GDT.py b/src/faebryk/library/GDT.py index 628b6730..249be751 100644 --- a/src/faebryk/library/GDT.py +++ b/src/faebryk/library/GDT.py @@ -3,27 +3,21 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) class GDT(Module): + common: F.Electrical + tube_1: F.Electrical + tube_2: F.Electrical - - - - - common: F.Electrical - tube_1: F.Electrical - tube_2: F.Electrical - - - dc_breakdown_voltage : F.TBD[Quantity] - impulse_discharge_current : F.TBD[Quantity] + dc_breakdown_voltage: F.TBD[Quantity] + impulse_discharge_current: F.TBD[Quantity] @L.rt_field def can_bridge(self): diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index 69cd9ce4..1bdf1cd2 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -1,31 +1,31 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from typing import Callable, Generic, TypeVar +from typing import Callable -from faebryk.core.core import ( - Module, - ModuleInterface, -) +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.util import get_children +from faebryk.libs.library import L +class GenericBusProtection[T: ModuleInterface](Module): + @L.rt_field + def bus_unprotected(self): + return self.bus_factory() + @L.rt_field + def bus_protected(self): + return self.bus_factory() -T = TypeVar("T", bound=ModuleInterface) - - -class GenericBusProtection(Generic[T], Module): def __init__(self, bus_factory: Callable[[], T]) -> None: super().__init__() + self.bus_factory = bus_factory - - bus_unprotected = bus_factory() - bus_protected = bus_factory() - - U = TypeVar("U", bound=ModuleInterface) - - def get_mifs(bus: T, mif_type: type[U]) -> list[U]: - return [i for i in bus.get_all() if isinstance(i, mif_type)] + def __preinit__(self): + def get_mifs[U: ModuleInterface](bus: T, mif_type: type[U]) -> set[U]: + return get_children(bus, direct_only=True, types=mif_type) raw = list( zip( @@ -46,8 +46,7 @@ def get_mifs(bus: T, mif_type: type[U]) -> list[U]: ) ) - - fuse = L.if_list(len(power), Fuse) + fuse = L.if_list(len(power), F.Fuse) # Pass through except hv for power_unprotected, power_protected in power: @@ -58,19 +57,20 @@ def get_mifs(bus: T, mif_type: type[U]) -> list[U]: raw_unprotected.connect(raw_protected) # Fuse - for (power_unprotected, power_protected), fuse in zip(power, self.fuse): + for (power_unprotected, power_protected), fuse in zip(power, fuse): power_unprotected.hv.connect_via(fuse, power_protected.hv) # TODO maybe shallow connect? power_protected.voltage.merge(power_unprotected.voltage) # TVS - if self.bus_protected.has_trait(can_be_surge_protected): - self.bus_protected.get_trait(can_be_surge_protected).protect() + if self.bus_protected.has_trait(F.can_be_surge_protected): + self.bus_protected.get_trait(F.can_be_surge_protected).protect() else: for line_unprotected, line_protected in signals + power + raw: - line_protected.get_trait(can_be_surge_protected).protect() + line_protected.get_trait(F.can_be_surge_protected).protect() # TODO add shallow connect + @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.bus_unprotected, self.bus_protected) diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index da32db43..ee743c1a 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -3,26 +3,18 @@ from dataclasses import dataclass, field -from faebryk.core.module import Module, Parameter - - - - - - - - +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.libs.library import L from faebryk.libs.units import P class HLK_LD2410B_P(Module): @dataclass - class _ld2410b_esphome_config(has_esphome_config.impl()): + class _ld2410b_esphome_config(F.has_esphome_config.impl()): throttle_ms: Parameter = field(default_factory=F.TBD) - def __post_init__(self) -> None: - super().__init__() - def get_config(self) -> dict: assert isinstance(self.throttle_ms, F.Constant), "No update interval set!" @@ -32,12 +24,13 @@ def get_config(self) -> dict: uart_candidates = { mif for mif in obj.uart.get_direct_connections() - if mif.has_trait(is_esphome_bus) and mif.has_trait(has_esphome_config) + if mif.has_trait(F.is_esphome_bus) + and mif.has_trait(F.has_esphome_config) } assert len(uart_candidates) == 1, f"Expected 1 UART, got {uart_candidates}" uart = uart_candidates.pop() - uart_cfg = uart.get_trait(has_esphome_config).get_config()["uart"][0] + uart_cfg = uart.get_trait(F.has_esphome_config).get_config()["uart"][0] assert ( uart_cfg["baud_rate"] == 256000 ), f"Baudrate not 256000 but {uart_cfg['baud_rate']}" @@ -66,35 +59,38 @@ def get_config(self) -> dict: ], } + # interfaces + power: F.ElectricPower + uart = F.UART_Base() + out: F.ElectricLogic + esphome_config: _ld2410b_esphome_config - # interfaces - - power: F.ElectricPower - uart = F.UART_Base() - out: F.ElectricLogic - + @L.rt_field + def attach_to_footprint(self): x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "5": x.power.hv, - "4": x.power.lv, - "3": x.uart.rx.signal, - "2": x.uart.tx.signal, - "1": x.out.signal, - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "5": x.power.hv, + "4": x.power.lv, + "3": x.uart.rx.signal, + "2": x.uart.tx.signal, + "1": x.out.signal, + } ) - # connect all logic references - ref = F.ElectricLogic.connect_all_module_references(self, gnd_only=True) - self.add_trait(has_single_electric_reference_defined(ref)) + def __preinit__(self): + self.uart.baud.merge(F.Constant(256 * P.kbaud)) + + # connect all logic references + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self, gnd_only=True) + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.esphome = self._ld2410b_esphome_config() - self.add_trait(self.esphome) - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2209271801_HI-LINK-HLK-LD2410B-P_C5183132.pdf") - - self.uart.baud.merge(F.Constant(256 * P.kbaud)) + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/2209271801_HI-LINK-HLK-LD2410B-P_C5183132.pdf" + ) diff --git a/src/faebryk/library/Header.py b/src/faebryk/library/Header.py index 53772d98..12e4f4ce 100644 --- a/src/faebryk/library/Header.py +++ b/src/faebryk/library/Header.py @@ -3,11 +3,11 @@ from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity - +from faebryk.libs.util import times class Header(Module): @@ -30,18 +30,23 @@ def __init__( vertical_pin_count: int, ) -> None: super().__init__() + self.horizontal_pin_count = horizonal_pin_count + self.vertical_pin_count = vertical_pin_count + def __preinit__(self): + self.pin_count_horizonal.merge(self.horizontal_pin_count) + self.pin_count_vertical.merge(self.vertical_pin_count) + pin_pitch: F.TBD[Quantity] + pin_type: F.TBD[PinType] + pad_type: F.TBD[PadType] + angle: F.TBD[Angle] + pin_count_horizonal: F.TBD[int] + pin_count_vertical: F.TBD[int] - unnamed = L.if_list(horizonal_pin_count * vertical_pin_count, F.Electrical) - - - pin_pitch : F.TBD[Quantity] - pin_type : F.TBD[self.PinType] - pad_type : F.TBD[self.PadType] - angle : F.TBD[self.Angle] - pin_count_horizonal = F.Constant(horizonal_pin_count) - pin_count_vertical = F.Constant(vertical_pin_count) + @L.rt_field + def unnamed(self): + return times(self.horizonal_pin_count * self.vertical_pin_count, F.Electrical) designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/JTAG.py b/src/faebryk/library/JTAG.py index 9dc0b835..566f74c4 100644 --- a/src/faebryk/library/JTAG.py +++ b/src/faebryk/library/JTAG.py @@ -1,24 +1,23 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - - +from faebryk.libs.library import L class JTAG(ModuleInterface): - - - - dbgrq: F.ElectricLogic - tdo: F.ElectricLogic - tdi: F.ElectricLogic - tms: F.ElectricLogic - tck: F.ElectricLogic - n_trst: F.ElectricLogic - n_reset: F.ElectricLogic - vtref: F.Electrical - - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + dbgrq: F.ElectricLogic + tdo: F.ElectricLogic + tdi: F.ElectricLogic + tms: F.ElectricLogic + tck: F.ElectricLogic + n_trst: F.ElectricLogic + n_reset: F.ElectricLogic + vtref: F.Electrical + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/KicadFootprint.py b/src/faebryk/library/KicadFootprint.py index 04a5ad28..a9c91080 100644 --- a/src/faebryk/library/KicadFootprint.py +++ b/src/faebryk/library/KicadFootprint.py @@ -1,33 +1,37 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F +from faebryk.library.Footprint import Footprint +from faebryk.libs.library import L +from faebryk.libs.util import times - - -class KicadF.Footprint(Footprint): +class KicadFootprint(Footprint): def __init__(self, kicad_identifier: str, pin_names: list[str]) -> None: super().__init__() unique_pin_names = sorted(set(pin_names)) + self.pin_names_sorted = list(enumerate(unique_pin_names)) + self.kicad_identifier = kicad_identifier + @classmethod + def with_simple_names(cls, kicad_identifier: str, pin_cnt: int): + return cls(kicad_identifier, [str(i + 1) for i in range(pin_cnt)]) - pins = L.if_list(len(unique_pin_names), Pad) - - pin_names_sorted = list(enumerate(unique_pin_names)) + @L.rt_field + def pins(self): + return times(len(self.pin_names_sorted), F.Pad) - self.add_trait( - can_attach_via_pinmap_pinlist( - {pin_name: self.pins[i] for i, pin_name in pin_names_sorted} - ) - ) - self.add_trait( - has_kicad_manual_footprint( - kicad_identifier, - {self.pins[i]: pin_name for i, pin_name in pin_names_sorted}, - ) + @L.rt_field + def attach_via_pinmap(self): + return F.can_attach_via_pinmap_pinlist( + {pin_name: self.pins[i] for i, pin_name in self.pin_names_sorted} ) - @classmethod - def with_simple_names(cls, kicad_identifier: str, pin_cnt: int): - return cls(kicad_identifier, [str(i + 1) for i in range(pin_cnt)]) + @L.rt_field + def kicad_footprint(self): + return F.has_kicad_manual_footprint( + self.kicad_identifier, + {self.pins[i]: pin_name for i, pin_name in self.pin_names_sorted}, + ) diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index fda7b516..18e5ec6e 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -3,13 +3,10 @@ from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import as_unit, as_unit_with_tolerance - - - - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -22,24 +19,20 @@ class OutputPolarity(Enum): POSITIVE = auto() NEGATIVE = auto() + max_input_voltage: F.TBD[Quantity] + output_voltage: F.TBD[Quantity] + output_polarity: F.TBD[OutputPolarity] + output_type: F.TBD[OutputType] + output_current: F.TBD[Quantity] + psrr: F.TBD[Quantity] + dropout_voltage: F.TBD[Quantity] + quiescent_current: F.TBD[Quantity] - max_input_voltage : F.TBD[Quantity] - output_voltage : F.TBD[Quantity] - output_polarity : F.TBD[LDO.OutputPolarity] - output_type : F.TBD[LDO.OutputType] - output_current : F.TBD[Quantity] - psrr : F.TBD[Quantity] - dropout_voltage : F.TBD[Quantity] - quiescent_current : F.TBD[Quantity] - - - - - - enable: F.ElectricLogic - power_in: F.ElectricPower - power_out: F.ElectricPower + enable: F.ElectricLogic + power_in: F.ElectricPower + power_out: F.ElectricPower + def __preinit__(self): self.power_in.voltage.merge(self.max_input_voltage) self.power_out.voltage.merge(self.output_voltage) @@ -55,42 +48,44 @@ class OutputPolarity(Enum): @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.power_in, self.power_out) + @L.rt_field def simple_value_representation(self): return F.has_simple_value_representation_based_on_params( - ( - self.output_polarity, - self.output_type, - self.output_voltage, - self.output_current, - self.psrr, - self.dropout_voltage, - self.max_input_voltage, - self.quiescent_current, - ), - lambda ps: "LDO " - + " ".join( - [ - as_unit_with_tolerance(ps[2], "V"), - as_unit(ps[3], "A"), - as_unit(ps[4], "dB"), - as_unit(ps[5], "V"), - f"Vin max {as_unit(ps[6], 'V')}", - f"Iq {as_unit(ps[7], 'A')}", - ] - ), - ) + ( + self.output_polarity, + self.output_type, + self.output_voltage, + self.output_current, + self.psrr, + self.dropout_voltage, + self.max_input_voltage, + self.quiescent_current, + ), + lambda ps: "LDO " + + " ".join( + [ + as_unit_with_tolerance(ps[2], "V"), + as_unit(ps[3], "A"), + as_unit(ps[4], "dB"), + as_unit(ps[5], "V"), + f"Vin max {as_unit(ps[6], 'V')}", + f"Iq {as_unit(ps[7], 'A')}", + ] + ), ) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.add_trait( - has_pin_association_heuristic_lookup_table( - mapping={ - self.power_in.hv: ["Vin", "Vi", "in"], - self.power_out.hv: ["Vout", "Vo", "out"], - self.power_in.lv: ["GND", "V-"], - self.enable.signal: ["EN", "Enable"], - }, - accept_prefix=False, - case_sensitive=False, - ) + + @L.rt_field + def pin_association_heuristic(self): + return F.has_pin_association_heuristic_lookup_table( + mapping={ + self.power_in.hv: ["Vin", "Vi", "in"], + self.power_out.hv: ["Vout", "Vo", "out"], + self.power_in.lv: ["GND", "V-"], + self.enable.signal: ["EN", "Enable"], + }, + accept_prefix=False, + case_sensitive=False, ) diff --git a/src/faebryk/library/LED.py b/src/faebryk/library/LED.py index 7a1f480b..2d9c0749 100644 --- a/src/faebryk/library/LED.py +++ b/src/faebryk/library/LED.py @@ -4,13 +4,12 @@ from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.parameter import Parameter - - from faebryk.libs.units import Quantity -class LED(Diode): +class LED(F.Diode): class Color(Enum): RED = auto() EMERALD = auto() @@ -19,14 +18,13 @@ class Color(Enum): YELLOW = auto() WHITE = auto() - brightness: F.TBD[Quantity] - max_brightness: F.TBD[Quantity] - color: F.TBD[cls.Color] + brightness: F.TBD[Quantity] + max_brightness: F.TBD[Quantity] + color: F.TBD[Color] + def __preinit__(self): self.current.merge(self.brightness / self.max_brightness * self.max_current) - self.inherit() - # self.brightness.merge( # F.Range(0 * P.millicandela, self.max_brightness) # ) diff --git a/src/faebryk/library/Logic.py b/src/faebryk/library/Logic.py index 77604ced..67c3a2fc 100644 --- a/src/faebryk/library/Logic.py +++ b/src/faebryk/library/Logic.py @@ -1,13 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L class Logic(ModuleInterface): - @staticmethod - def PARAMS(): - state = F.Range(False, True) + state = L.f_field(F.Range)(False, True) def set(self, on: bool): self.state.merge(on) diff --git a/src/faebryk/library/Logic74xx.py b/src/faebryk/library/Logic74xx.py index 4308d965..7dcb0e52 100644 --- a/src/faebryk/library/Logic74xx.py +++ b/src/faebryk/library/Logic74xx.py @@ -51,13 +51,14 @@ class Family(Enum): power: F.ElectricPower logic_family: F.TBD[Family] - gates = L.if_list(0, F.ElectricLogicGate) designator = L.f_field(F.has_designator_prefix_defined)("U") @L.rt_field def single_electric_reference(self): - return F.has_single_electric_reference_defined(self) + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) def __init__( self, @@ -65,5 +66,8 @@ def __init__( ) -> None: super().__init__() - for g in gates_factory: - self.add(g(), container=self.gates) + self.gates_factory = gates_factory + + @L.rt_field + def gates(self): + return [g() for g in self.gates_factory] diff --git a/src/faebryk/library/LogicGate.py b/src/faebryk/library/LogicGate.py index 80f50cfe..eb60f01c 100644 --- a/src/faebryk/library/LogicGate.py +++ b/src/faebryk/library/LogicGate.py @@ -1,49 +1,48 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from typing import Sequence, TypeVar +from typing import Sequence -from faebryk.core.module import Module, TraitImpl - - - - -T = TypeVar("T", bound=Logic) +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.trait import TraitImpl +from faebryk.libs.library import L +from faebryk.libs.util import times class LogicGate(Module): - class can_logic_or_gate(LogicOps.can_logic_or.impl()): + class can_logic_or_gate(F.LogicOps.can_logic_or.impl()): def on_obj_set(self) -> None: assert isinstance(self.get_obj(), LogicGate) - def or_(self, *ins: Logic): + def or_(self, *ins: F.Logic): obj = self.get_obj() assert isinstance(obj, LogicGate) return obj.op(*ins)[0] - class can_logic_nor_gate(LogicOps.can_logic_nor.impl()): + class can_logic_nor_gate(F.LogicOps.can_logic_nor.impl()): def on_obj_set(self) -> None: assert isinstance(self.get_obj(), LogicGate) - def nor(self, *ins: Logic): + def nor(self, *ins: F.Logic): obj = self.get_obj() assert isinstance(obj, LogicGate) return obj.op(*ins)[0] - class can_logic_nand_gate(LogicOps.can_logic_nand.impl()): + class can_logic_nand_gate(F.LogicOps.can_logic_nand.impl()): def on_obj_set(self) -> None: assert isinstance(self.get_obj(), LogicGate) - def nand(self, *ins: Logic): + def nand(self, *ins: F.Logic): obj = self.get_obj() assert isinstance(obj, LogicGate) return obj.op(*ins)[0] - class can_logic_xor_gate(LogicOps.can_logic_xor.impl()): + class can_logic_xor_gate(F.LogicOps.can_logic_xor.impl()): def on_obj_set(self) -> None: assert isinstance(self.get_obj(), LogicGate) - def xor(self, *ins: Logic): + def xor(self, *ins: F.Logic): obj = self.get_obj() assert isinstance(obj, LogicGate) return obj.op(*ins)[0] @@ -55,22 +54,30 @@ def __init__( *functions: TraitImpl, ) -> None: super().__init__() + self._input_cnt = input_cnt + self._output_cnt = output_cnt + self._functions = functions + @L.rt_field + def functions(self): + return self._functions - inputs = L.if_list(input_cnt, Logic) - outputs = L.if_list(output_cnt, Logic) + @L.rt_field + def inputs(self): + return times(self._input_cnt, F.Logic) - for f in functions: - self.add_trait(f) + @L.rt_field + def outputs(self): + return times(self._output_cnt, F.Logic) @staticmethod - def op_( - ins1: Sequence[Logic], ins2: Sequence[Logic], out: Sequence[T] + def op_[T: F.Logic]( + ins1: Sequence[F.Logic], ins2: Sequence[F.Logic], out: Sequence[T] ) -> Sequence[T]: assert len(ins1) == len(ins2) for in_if_mod, in_if in zip(ins1, ins2): in_if_mod.connect(in_if) return out - def op(self, *ins: Logic): + def op(self, *ins: F.Logic): return self.op_(ins, self.inputs, self.outputs) diff --git a/src/faebryk/library/LogicGates.py b/src/faebryk/library/LogicGates.py index bfb986b3..309de0fc 100644 --- a/src/faebryk/library/LogicGates.py +++ b/src/faebryk/library/LogicGates.py @@ -3,23 +3,26 @@ from typing import TypeVar +import faebryk.library._F as F -T = TypeVar("T", bound=Logic) +T = TypeVar("T", bound=F.Logic) class LogicGates: - class OR(LogicGate): + class OR(F.LogicGate): def __init__(self, input_cnt: F.Constant[int]): - super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_or_gate()) + super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_or_gate()) - class NOR(LogicGate): + class NOR(F.LogicGate): def __init__(self, input_cnt: F.Constant[int]): - super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_nor_gate()) + super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_nor_gate()) - class NAND(LogicGate): + class NAND(F.LogicGate): def __init__(self, input_cnt: F.Constant[int]): - super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_nand_gate()) + super().__init__( + input_cnt, F.Constant(1), F.LogicGate.can_logic_nand_gate() + ) - class XOR(LogicGate): + class XOR(F.LogicGate): def __init__(self, input_cnt: F.Constant[int]): - super().__init__(input_cnt, F.Constant(1), LogicGate.can_logic_xor_gate()) + super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_xor_gate()) diff --git a/src/faebryk/library/LogicOps.py b/src/faebryk/library/LogicOps.py index 02ae0b95..6617264e 100644 --- a/src/faebryk/library/LogicOps.py +++ b/src/faebryk/library/LogicOps.py @@ -4,48 +4,48 @@ from abc import abstractmethod from typing import TypeVar -from faebryk.core.core import Trait +import faebryk.library._F as F +from faebryk.core.trait import Trait - -T = TypeVar("T", bound=Logic) +T = TypeVar("T", bound=F.Logic) class LogicOps: class can_logic(Trait): @abstractmethod - def op(self, *ins: Logic) -> Logic: ... + def op(self, *ins: F.Logic) -> F.Logic: ... class can_logic_or(can_logic): @abstractmethod - def or_(self, *ins: Logic) -> Logic: ... + def or_(self, *ins: F.Logic) -> F.Logic: ... - def op(self, *ins: Logic) -> Logic: + def op(self, *ins: F.Logic) -> F.Logic: return self.or_(*ins) class can_logic_and(can_logic): @abstractmethod - def and_(self, *ins: Logic) -> Logic: ... + def and_(self, *ins: F.Logic) -> F.Logic: ... - def op(self, *ins: Logic) -> Logic: + def op(self, *ins: F.Logic) -> F.Logic: return self.and_(*ins) class can_logic_nor(can_logic): @abstractmethod - def nor(self, *ins: Logic) -> Logic: ... + def nor(self, *ins: F.Logic) -> F.Logic: ... - def op(self, *ins: Logic) -> Logic: + def op(self, *ins: F.Logic) -> F.Logic: return self.nor(*ins) class can_logic_nand(can_logic): @abstractmethod - def nand(self, *ins: Logic) -> Logic: ... + def nand(self, *ins: F.Logic) -> F.Logic: ... - def op(self, *ins: Logic) -> Logic: + def op(self, *ins: F.Logic) -> F.Logic: return self.nand(*ins) class can_logic_xor(can_logic): @abstractmethod - def xor(self, *ins: Logic) -> Logic: ... + def xor(self, *ins: F.Logic) -> F.Logic: ... - def op(self, *ins: Logic) -> Logic: + def op(self, *ins: F.Logic) -> F.Logic: return self.xor(*ins) diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index 8d6de4ab..5751c6af 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -3,45 +3,44 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - - - - - - +from faebryk.libs.library import L from faebryk.libs.units import P - logger = logging.getLogger(__name__) # TODO remove generic stuff into EEPROM/i2c device etc class M24C08_FMN6TP(Module): + power: F.ElectricPower + data: F.I2C + nwc: F.ElectricLogic + e = L.if_list(3, F.ElectricLogic) + @L.rt_field + def attach_to_footprint(self): + x = self + return F.can_attach_to_footprint_via_pinmap( + { + "1": x.e[0].signal, + "2": x.e[1].signal, + "3": x.e[2].signal, + "4": x.power.lv, + "5": x.data.sda.signal, + "6": x.data.scl.signal, + "7": x.nwc.signal, + "8": x.power.hv, + } + ) + def __preinit__(self): + self.attach_to_footprint.attach( + F.SOIC(8, size_xy=(3.9 * P.mm, 4.9 * P.mm), pitch=1.27 * P.mm) + ) - power: F.ElectricPower - data = F.I2C() - nwc: F.ElectricLogic - e = L.if_list(3, F.ElectricLogic) - - x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.e[0].signal, - "2": x.e[1].signal, - "3": x.e[2].signal, - "4": x.power.lv, - "5": x.data.sda.signal, - "6": x.data.scl.signal, - "7": x.nwc.signal, - "8": x.power.hv, - } - ) - ).attach(SOIC(8, size_xy=(3.9 * P.mm, 4.9 * P.mm), pitch=1.27 * P.mm)) + self.data.terminate() + self.power.decoupled.decouple() @L.rt_field def single_electric_reference(self): @@ -49,9 +48,6 @@ def single_electric_reference(self): F.ElectricLogic.connect_all_module_references(self) ) - self.data.terminate() - self.power.decoupled.decouple() - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") def set_address(self, addr: int): diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 828721ad..20751227 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -3,33 +3,25 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - - +from faebryk.libs.library import L logger = logging.getLogger(__name__) class MCP2221A(Module): - - - - - - power: F.ElectricPower - power_vusb: F.ElectricPower - uart = F.UART_Base() - i2c = F.I2C() - gpio = L.if_list(4, F.Electrical) - reset: F.ElectricLogic - usb : F.USB2_0 - - - + power: F.ElectricPower + power_vusb: F.ElectricPower + uart: F.UART_Base + i2c: F.I2C + gpio = L.if_list(4, F.Electrical) + reset: F.ElectricLogic + usb: F.USB2_0 + + def __preinit__(self): self.power.decoupled.decouple() self.power_vusb.decoupled.decouple() + self.power.lv.connect(self.power_vusb.lv) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.power.lv.connect(self.power_vusb.lv) diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index 649174ca..d7a802c5 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -1,13 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import connect_to_all_interfaces - - - - - +from faebryk.libs.library import L from faebryk.libs.units import P @@ -16,20 +13,19 @@ class ME6211C33M5G_N(Module): 3.3V 600mA LDO """ - def __init__(self, default_enabled: bool = True) -> None: - super().__init__() - - # interfaces - - power_in: F.ElectricPower - power_out: F.ElectricPower - enable: F.Electrical - - # components + # interfaces + power_in: F.ElectricPower + power_out: F.ElectricPower + enable: F.Electrical + # components + def __init__(self, default_enabled: bool = True) -> None: + super().__init__() + self._default_enabled = default_enabled + def __preinit__(self): # set constraints self.power_out.voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) @@ -40,20 +36,24 @@ def __init__(self, default_enabled: bool = True) -> None: # LDO in & out share gnd reference self.power_in.lv.connect(self.power_out.lv) - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": self.power_in.hv, - "2": self.power_in.lv, - "3": self.enable, - "5": self.power_out.hv, - } - ) - ) - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/1811131510_MICRONE-Nanjing-Micro-One-Elec-ME6211C33M5G-N_C82942.pdf") - - if default_enabled: + if self._default_enabled: self.enable.connect(self.power_in.hv) connect_to_all_interfaces(self.power_in.lv, [self.power_out.lv]) + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "1": self.power_in.hv, + "2": self.power_in.lv, + "3": self.enable, + "5": self.power_out.hv, + } + ) + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/1811131510_MICRONE-Nanjing-Micro-One-Elec-ME6211C33M5G-N_C82942.pdf" + ) diff --git a/src/faebryk/library/MOSFET.py b/src/faebryk/library/MOSFET.py index 1ffd7f45..48e293ac 100644 --- a/src/faebryk/library/MOSFET.py +++ b/src/faebryk/library/MOSFET.py @@ -3,11 +3,9 @@ from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module - - - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -20,34 +18,32 @@ class SaturationType(Enum): ENHANCEMENT = auto() DEPLETION = auto() + channel_type: F.TBD[ChannelType] + saturation_type: F.TBD[SaturationType] + gate_source_threshold_voltage: F.TBD[Quantity] + max_drain_source_voltage: F.TBD[Quantity] + max_continuous_drain_current: F.TBD[Quantity] + on_resistance: F.TBD[Quantity] - - channel_type : F.TBD[MOSFET.ChannelType] - saturation_type : F.TBD[MOSFET.SaturationType] - gate_source_threshold_voltage : F.TBD[Quantity] - max_drain_source_voltage : F.TBD[Quantity] - max_continuous_drain_current : F.TBD[Quantity] - on_resistance : F.TBD[Quantity] - - - source: F.Electrical - gate: F.Electrical - drain: F.Electrical + source: F.Electrical + gate: F.Electrical + drain: F.Electrical designator_prefix = L.f_field(F.has_designator_prefix_defined)("Q") - # TODO pretty confusing + + # TODO pretty confusing @L.rt_field def can_bridge(self): return F.can_bridge_defined(in_if=self.source, out_if=self.drain) - self.add_trait( - has_pin_association_heuristic_lookup_table( - mapping={ - self.source: ["S", "Source"], - self.gate: ["G", "Gate"], - self.drain: ["D", "Drain"], - }, - accept_prefix=False, - case_sensitive=False, - ) + @L.rt_field + def pin_association_heuristic(self): + return F.has_pin_association_heuristic_lookup_table( + mapping={ + self.source: ["S", "Source"], + self.gate: ["G", "Gate"], + self.drain: ["D", "Drain"], + }, + accept_prefix=False, + case_sensitive=False, ) diff --git a/src/faebryk/library/Mounting_Hole.py b/src/faebryk/library/Mounting_Hole.py index 6801e0c9..87c7e8c1 100644 --- a/src/faebryk/library/Mounting_Hole.py +++ b/src/faebryk/library/Mounting_Hole.py @@ -3,32 +3,24 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - - - - - +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity logger = logging.getLogger(__name__) class Mounting_Hole(Module): + diameter: F.TBD[Quantity] - - - diameter : F.TBD[Quantity] - - self.add_trait(can_attach_to_footprint_symmetrically()) + attach_to_footprint: F.can_attach_to_footprint_symmetrically designator_prefix = L.f_field(F.has_designator_prefix_defined)("H") + def __preinit__(self): # Only 3.2mm supported for now self.diameter.merge(F.Constant(3.2 * P.mm)) - self.add_trait( - has_defined_footprint( - KicadF.Footprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) - ) - ) + footprint = L.f_field(F.has_footprint_defined)( + F.KicadFootprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) + ) diff --git a/src/faebryk/library/MultiSPI.py b/src/faebryk/library/MultiSPI.py index 83698953..b7b3c34a 100644 --- a/src/faebryk/library/MultiSPI.py +++ b/src/faebryk/library/MultiSPI.py @@ -1,18 +1,20 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - +from faebryk.libs.library import L +from faebryk.libs.util import times class MultiSPI(ModuleInterface): def __init__(self, data_lane_count: int) -> None: super().__init__() + self._data_lane_count = data_lane_count + clk: F.ElectricLogic + cs: F.ElectricLogic - clk: F.ElectricLogic - data = L.if_list(data_lane_count, F.ElectricLogic) - cs: F.ElectricLogic - - + @L.rt_field + def data(self): + return times(self._data_lane_count, F.ElectricLogic) diff --git a/src/faebryk/library/Net.py b/src/faebryk/library/Net.py index 9ea63b20..baae172b 100644 --- a/src/faebryk/library/Net.py +++ b/src/faebryk/library/Net.py @@ -3,20 +3,20 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import get_connected_mifs, get_parent_of_type - +from faebryk.libs.library import L logger = logging.getLogger(__name__) class Net(Module): + part_of: F.Electrical - - - part_of: F.Electrical - - class _(has_overriden_name.impl()): + @L.rt_field + def overriden_name(self): + class _(F.has_overriden_name.impl()): def get_name(_self): from faebryk.exporters.netlist.graph import ( can_represent_kicad_footprint, @@ -40,14 +40,14 @@ def get_name(_self): return name - self.add_trait(_()) + return _() def get_fps(self): return { pad: fp for mif in self.get_connected_interfaces() if (fp := get_parent_of_type(mif, F.Footprint)) is not None - and (pad := get_parent_of_type(mif, Pad)) is not None + and (pad := get_parent_of_type(mif, F.Pad)) is not None } # TODO should this be here? @@ -60,13 +60,13 @@ def get_connected_interfaces(self): def __repr__(self) -> str: up = super().__repr__() - if self.has_trait(has_overriden_name): - return f"{up}'{self.get_trait(has_overriden_name).get_name()}'" + if self.has_trait(F.has_overriden_name): + return f"{up}'{self.get_trait(F.has_overriden_name).get_name()}'" else: return up @classmethod def with_name(cls, name: str) -> "Net": n = cls() - n.add_trait(has_overriden_name_defined(name)) + n.add_trait(F.has_overriden_name_defined(name)) return n diff --git a/src/faebryk/library/OLED_Module.py b/src/faebryk/library/OLED_Module.py index c18a3a5e..53ffe0f4 100644 --- a/src/faebryk/library/OLED_Module.py +++ b/src/faebryk/library/OLED_Module.py @@ -4,9 +4,9 @@ import logging from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -23,20 +23,14 @@ class DisplayController(Enum): SSD1315 = auto() SSD1306 = auto() + power: F.ElectricPower + i2c: F.I2C + resolution: F.TBD[Resolution] + display_controller: F.TBD[DisplayController] - - - - power: F.ElectricPower - i2c = F.I2C() - - - resolution : F.TBD[self.Resolution] - display_controller : F.TBD[self.DisplayController] - + def __preinit__(self): self.power.voltage.merge(F.Range(3.0 * P.V, 5 * P.V)) - self.power.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("OLED") diff --git a/src/faebryk/library/OpAmp.py b/src/faebryk/library/OpAmp.py index e2012775..e33d0ea2 100644 --- a/src/faebryk/library/OpAmp.py +++ b/src/faebryk/library/OpAmp.py @@ -1,63 +1,58 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import as_unit - - - - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity class OpAmp(Module): - - - bandwidth : F.TBD[Quantity] - common_mode_rejection_ratio : F.TBD[Quantity] - input_bias_current : F.TBD[Quantity] - input_offset_voltage : F.TBD[Quantity] - gain_bandwidth_product : F.TBD[Quantity] - output_current : F.TBD[Quantity] - slew_rate : F.TBD[Quantity] - - - power: F.ElectricPower - inverting_input: F.Electrical - non_inverting_input: F.Electrical - output: F.Electrical + bandwidth: F.TBD[Quantity] + common_mode_rejection_ratio: F.TBD[Quantity] + input_bias_current: F.TBD[Quantity] + input_offset_voltage: F.TBD[Quantity] + gain_bandwidth_product: F.TBD[Quantity] + output_current: F.TBD[Quantity] + slew_rate: F.TBD[Quantity] + + power: F.ElectricPower + inverting_input: F.Electrical + non_inverting_input: F.Electrical + output: F.Electrical @L.rt_field def simple_value_representation(self): return F.has_simple_value_representation_based_on_params( - [ - self.bandwidth, - self.common_mode_rejection_ratio, - self.input_bias_current, - self.input_offset_voltage, - self.gain_bandwidth_product, - self.output_current, - self.slew_rate, - ], - lambda p: ( - f"{as_unit(p[0], 'Hz')} BW, {p[1]} CMRR, {as_unit(p[2], 'A')} Ib, " - f"{as_unit(p[3], 'V')} Vos, {as_unit(p[4], 'Hz')} GBW, " - f"{as_unit(p[5], 'A')} Iout, {as_unit(p[6], 'V/s')} SR" - ), - ) + [ + self.bandwidth, + self.common_mode_rejection_ratio, + self.input_bias_current, + self.input_offset_voltage, + self.gain_bandwidth_product, + self.output_current, + self.slew_rate, + ], + lambda p: ( + f"{as_unit(p[0], 'Hz')} BW, {p[1]} CMRR, {as_unit(p[2], 'A')} Ib, " + f"{as_unit(p[3], 'V')} Vos, {as_unit(p[4], 'Hz')} GBW, " + f"{as_unit(p[5], 'A')} Iout, {as_unit(p[6], 'V/s')} SR" + ), ) - self.add_trait( - has_pin_association_heuristic_lookup_table( - mapping={ - self.power.hv: ["V+", "Vcc", "Vdd"], - self.power.lv: ["V-", "Vee", "Vss", "GND"], - self.inverting_input: ["-", "IN-"], - self.non_inverting_input: ["+", "IN+"], - self.output: ["OUT"], - }, - accept_prefix=False, - case_sensitive=False, - ) + + @L.rt_field + def pin_association_heuristic(self): + return F.has_pin_association_heuristic_lookup_table( + mapping={ + self.power.hv: ["V+", "Vcc", "Vdd"], + self.power.lv: ["V-", "Vee", "Vss", "GND"], + self.inverting_input: ["-", "IN-"], + self.non_inverting_input: ["+", "IN+"], + self.output: ["OUT"], + }, + accept_prefix=False, + case_sensitive=False, ) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/PJ398SM.py b/src/faebryk/library/PJ398SM.py index fe635c96..e1e80c93 100644 --- a/src/faebryk/library/PJ398SM.py +++ b/src/faebryk/library/PJ398SM.py @@ -1,17 +1,14 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L class PJ398SM(Module): - - - - tip: F.Electrical - sleeve: F.Electrical - switch: F.Electrical + tip: F.Electrical + sleeve: F.Electrical + switch: F.Electrical designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index 6bb373b5..a994c010 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -3,9 +3,10 @@ from dataclasses import dataclass, field -from faebryk.core.module import Module, Parameter - - +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.libs.library import L from faebryk.libs.units import P @@ -27,7 +28,7 @@ class PM1006(Module): """ @dataclass - class _pm1006_esphome_config(has_esphome_config.impl()): + class _pm1006_esphome_config(F.has_esphome_config.impl()): update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: @@ -41,30 +42,31 @@ def get_config(self) -> dict: obj = self.get_obj() assert isinstance(obj, PM1006), "This is not an PM1006!" - uart = is_esphome_bus.find_connected_bus(obj.data) + uart = F.is_esphome_bus.find_connected_bus(obj.data) return { "sensor": [ { "platform": "pm1006", "update_interval": f"{self.update_interval_s.value}s", - "uart_id": uart.get_trait(is_esphome_bus).get_bus_id(), + "uart_id": uart.get_trait(F.is_esphome_bus).get_bus_id(), } ] } - power: F.ElectricPower - data = F.UART_Base() + esphome_config: _pm1006_esphome_config - # components + power: F.ElectricPower + data: F.UART_Base - # --------------------------------------------------------------------- - datasheet = L.f_field(F.has_datasheet_defined)("http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_F.LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf") + # components - self.esphome = self._pm1006_esphome_config() - self.add_trait(self.esphome) - # --------------------------------------------------------------------- + # --------------------------------------------------------------------- + datasheet = L.f_field(F.has_datasheet_defined)( + "http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_F.LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf" + ) + # --------------------------------------------------------------------- + def __preinit__(self): self.power.voltage.merge(F.Range.from_center(5, 0.2)) - self.data.baud.merge(F.Constant(9600 * P.baud)) diff --git a/src/faebryk/library/Pad.py b/src/faebryk/library/Pad.py index a82b0677..465f11d1 100644 --- a/src/faebryk/library/Pad.py +++ b/src/faebryk/library/Pad.py @@ -2,20 +2,18 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.core.util import get_parent_of_type +from faebryk.core.util import get_children, get_parent_of_type class Pad(ModuleInterface): - - - - net: F.Electrical - pcb = ModuleInterface() + net: F.Electrical + pcb: ModuleInterface def attach(self, intf: F.Electrical): self.net.connect(intf) - intf.add_trait(has_linked_pad_defined(self)) + intf.add_trait(F.has_linked_pad_defined(self)) @staticmethod def find_pad_for_intf_with_parent_that_has_footprint_unique( @@ -32,15 +30,15 @@ def find_pad_for_intf_with_parent_that_has_footprint( ) -> list["Pad"]: # This only finds directly attached pads # -> misses from parents / children nodes - if intf.has_trait(has_linked_pad): - return [intf.get_trait(has_linked_pad).get_pad()] + if intf.has_trait(F.has_linked_pad): + return [intf.get_trait(F.has_linked_pad).get_pad()] # This is a bit slower, but finds them all _, footprint = F.Footprint.get_footprint_of_parent(intf) pads = [ pad - for pad in footprint.get_all() - if isinstance(pad, Pad) and pad.net.is_connected_to(intf) is not None + for pad in get_children(footprint, direct_only=True, types=Pad) + if pad.net.is_connected_to(intf) is not None ] return pads diff --git a/src/faebryk/library/Potentiometer.py b/src/faebryk/library/Potentiometer.py index 06527b50..568775e4 100644 --- a/src/faebryk/library/Potentiometer.py +++ b/src/faebryk/library/Potentiometer.py @@ -1,28 +1,21 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity - class Potentiometer(Module): + resistors_ifs = L.if_list(2, F.Electrical) + wiper: F.Electrical + total_resistance: F.TBD[Quantity] + resistors = L.if_list(2, F.Resistor) - - - resistors = L.if_list(2, F.Electrical) - wiper: F.Electrical - - - total_resistance : F.TBD[Quantity] - - - resistors = L.if_list(2, F.Resistor) - + def __preinit__(self): for i, resistor in enumerate(self.resistors): - self.resistors[i].connect_via(resistor, self.wiper) + self.resistors_ifs[i].connect_via(resistor, self.wiper) # TODO use range(0, total_resistance) resistor.resistance.merge(self.total_resistance) @@ -30,6 +23,6 @@ class Potentiometer(Module): def connect_as_voltage_divider( self, high: F.Electrical, low: F.Electrical, out: F.Electrical ): - self.resistors[0].connect(high) - self.resistors[1].connect(low) + self.resistors_ifs[0].connect(high) + self.resistors_ifs[1].connect(low) self.wiper.connect(out) diff --git a/src/faebryk/library/PowerSwitch.py b/src/faebryk/library/PowerSwitch.py index 57a901c2..f264e8b2 100644 --- a/src/faebryk/library/PowerSwitch.py +++ b/src/faebryk/library/PowerSwitch.py @@ -1,7 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.libs.library import L class PowerSwitch(Module): @@ -15,17 +17,17 @@ class PowerSwitch(Module): def __init__(self, normally_closed: bool) -> None: super().__init__() - self.normally_closed = normally_closed + self._normally_closed = normally_closed + logic_in: F.ElectricLogic + power_in: F.ElectricPower + switched_power_out: F.ElectricPower - logic_in: F.ElectricLogic - power_in: F.ElectricPower - switched_power_out: F.ElectricPower - - self.add_trait( - can_switch_power_defined( - self.power_in, self.switched_power_out, self.logic_in - ) + @L.rt_field + def switch_power(self): + return F.can_switch_power_defined( + self.power_in, self.switched_power_out, self.logic_in ) + def __preinit__(self): self.switched_power_out.voltage.merge(self.power_in.voltage) diff --git a/src/faebryk/library/PowerSwitchMOSFET.py b/src/faebryk/library/PowerSwitchMOSFET.py index cb45f88c..2dc452ce 100644 --- a/src/faebryk/library/PowerSwitchMOSFET.py +++ b/src/faebryk/library/PowerSwitchMOSFET.py @@ -1,10 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module +import faebryk.library._F as F -class PowerSwitchMOSFET(PowerSwitch): +class PowerSwitchMOSFET(F.PowerSwitch): """ Power switch using a MOSFET @@ -14,20 +14,23 @@ class PowerSwitchMOSFET(PowerSwitch): def __init__(self, lowside: bool, normally_closed: bool) -> None: super().__init__(normally_closed=normally_closed) - self.lowside = lowside + self._lowside = lowside - # components + # components - mosfet = MOSFET() + mosfet: F.MOSFET + def __preinit__(self): self.mosfet.channel_type.merge( F.Constant( - MOSFET.ChannelType.N_CHANNEL - if lowside - else MOSFET.ChannelType.P_CHANNEL + F.MOSFET.ChannelType.N_CHANNEL + if self._lowside + else F.MOSFET.ChannelType.P_CHANNEL ) ) - self.mosfet.saturation_type.merge(F.Constant(MOSFET.SaturationType.ENHANCEMENT)) + self.mosfet.saturation_type.merge( + F.Constant(F.MOSFET.SaturationType.ENHANCEMENT) + ) # pull gate # lowside normally_closed pull up @@ -35,15 +38,13 @@ def __init__(self, lowside: bool, normally_closed: bool) -> None: # True False False # False True False # False False True - self.logic_in.pulled.pull( - lowside == normally_closed - ) + self.logic_in.pulled.pull(self._lowside == self._normally_closed) # connect gate to logic self.logic_in.signal.connect(self.mosfet.gate) # passthrough non-switched side, bridge switched side - if lowside: + if self._lowside: self.power_in.hv.connect(self.switched_power_out.hv) self.power_in.lv.connect_via(self.mosfet, self.switched_power_out.lv) else: diff --git a/src/faebryk/library/PowerSwitchStatic.py b/src/faebryk/library/PowerSwitchStatic.py index b00c183f..20ea6c98 100644 --- a/src/faebryk/library/PowerSwitchStatic.py +++ b/src/faebryk/library/PowerSwitchStatic.py @@ -1,8 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class PowerSwitchStatic(PowerSwitch): +class PowerSwitchStatic(F.PowerSwitch): """ A power switch that bridges power through statically @@ -12,6 +13,7 @@ class PowerSwitchStatic(PowerSwitch): def __init__(self) -> None: super().__init__(normally_closed=False) + def __preinit__(self): self.power_in.connect(self.switched_power_out) self.logic_in.connect_reference(self.power_in) self.logic_in.set(True) diff --git a/src/faebryk/library/PoweredLED.py b/src/faebryk/library/PoweredLED.py index eb52005b..95db8264 100644 --- a/src/faebryk/library/PoweredLED.py +++ b/src/faebryk/library/PoweredLED.py @@ -1,27 +1,25 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.libs.library import L class PoweredLED(Module): + power: F.ElectricPower + current_limiting_resistor: F.Resistor + led: F.LED - - - power: F.ElectricPower - - - current_limiting_resistor : F.Resistor - led = LED() - + def __preinit__(self): self.power.hv.connect(self.led.anode) self.led.connect_via_current_limiting_resistor_to_power( self.current_limiting_resistor, self.power, low_side=True, ) + self.current_limiting_resistor.allow_removal_if_zero() @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.power.hv, self.power.lv) - self.current_limiting_resistor.allow_removal_if_zero() diff --git a/src/faebryk/library/Powered_Relay.py b/src/faebryk/library/Powered_Relay.py index a0922a26..28d0b124 100644 --- a/src/faebryk/library/Powered_Relay.py +++ b/src/faebryk/library/Powered_Relay.py @@ -3,39 +3,31 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - +from faebryk.core.util import connect_module_mifs_by_name +from faebryk.libs.library import L logger = logging.getLogger(__name__) class Powered_Relay(Module): - - - - relay = Relay() - indicator = PoweredLED() - flyback_diode = Diode() - relay_driver = PowerSwitchMOSFET(lowside=True, normally_closed=False) - - - switch_a_nc: F.Electrical - switch_a_common: F.Electrical - switch_a_no: F.Electrical - switch_b_no: F.Electrical - switch_b_common: F.Electrical - switch_b_nc: F.Electrical - enable: F.ElectricLogic - power: F.ElectricPower - - - - self.relay.switch_a_common.connect(self.switch_a_common) - self.relay.switch_a_nc.connect(self.switch_a_nc) - self.relay.switch_a_no.connect(self.switch_a_no) - self.relay.switch_b_common.connect(self.switch_b_common) - self.relay.switch_b_nc.connect(self.switch_b_nc) - self.relay.switch_b_no.connect(self.switch_b_no) + relay: F.Relay + indicator: F.PoweredLED + flyback_diode: F.Diode + relay_driver = L.f_field(F.PowerSwitchMOSFET)(lowside=True, normally_closed=False) + + switch_a_nc: F.Electrical + switch_a_common: F.Electrical + switch_a_no: F.Electrical + switch_b_no: F.Electrical + switch_b_common: F.Electrical + switch_b_nc: F.Electrical + enable: F.ElectricLogic + power: F.ElectricPower + + def __preinit__(self): + connect_module_mifs_by_name(self, self.relay) self.relay_driver.power_in.connect(self.power) self.relay_driver.logic_in.connect(self.enable) @@ -43,5 +35,4 @@ class Powered_Relay(Module): self.relay_driver.switched_power_out.hv.connect(self.relay.coil_p) self.relay.coil_n.connect_via(self.flyback_diode, self.relay.coil_p) - self.indicator.power.connect(self.relay_driver.switched_power_out) diff --git a/src/faebryk/library/QFN.py b/src/faebryk/library/QFN.py index 23e021f0..b0a22d18 100644 --- a/src/faebryk/library/QFN.py +++ b/src/faebryk/library/QFN.py @@ -2,8 +2,10 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity - +from faebryk.libs.util import times class QFN(F.Footprint): @@ -18,32 +20,40 @@ def __init__( ) -> None: super().__init__() - - pins = L.if_list(pin_cnt, Pad) + self._pin_cnt = pin_cnt + self._exposed_thermal_pad_cnt = exposed_thermal_pad_cnt + self._size_xy = size_xy + self._pitch = pitch + self._exposed_thermal_pad_dimensions = exposed_thermal_pad_dimensions + self._has_thermal_vias = has_thermal_vias assert exposed_thermal_pad_cnt > 0 or not has_thermal_vias assert ( exposed_thermal_pad_dimensions[0] < size_xy[0] and exposed_thermal_pad_dimensions[1] < size_xy[1] ) - from faebryk.library.has_kicad_footprint_equal_ifs import ( - has_kicad_footprint_equal_ifs, - ) - class _has_kicad_footprint(has_kicad_footprint_equal_ifs): + @L.rt_field + def pins(self): + return times(self._pin_cnt, F.Pad) + + equal_pins: F.has_equal_pins_in_ifs + attach_via_pinmap: F.can_attach_via_pinmap_equal + + @L.rt_field + def kicad_footprint(self): + class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): @staticmethod def get_kicad_footprint() -> str: return "Package_DFN_QFN:QFN-{leads}-{ep}EP_{size_x}x{size_y}mm_P{pitch}mm_EP{ep_x}x{ep_y}mm{vias}".format( # noqa: E501 - leads=pin_cnt, - ep=exposed_thermal_pad_cnt, - size_x=size_xy[0].to(P.mm).m, - size_y=size_xy[1].to(P.mm).m, - pitch=pitch.to(P.mm).m, - ep_x=exposed_thermal_pad_dimensions[0].to(P.mm).m, - ep_y=exposed_thermal_pad_dimensions[1].to(P.mm).m, - vias="_ThermalVias" if has_thermal_vias else "", + leads=self._pin_cnt, + ep=self._exposed_thermal_pad_cnt, + size_x=self._size_xy[0].to(P.mm).m, + size_y=self._size_xy[1].to(P.mm).m, + pitch=self._pitch.to(P.mm).m, + ep_x=self._exposed_thermal_pad_dimensions[0].to(P.mm).m, + ep_y=self._exposed_thermal_pad_dimensions[1].to(P.mm).m, + vias="_ThermalVias" if self._has_thermal_vias else "", ) - self.add_trait(_has_kicad_footprint()) - self.add_trait(has_equal_pins_in_ifs()) - self.add_trait(can_attach_via_pinmap_equal()) + return _has_kicad_footprint() diff --git a/src/faebryk/library/QWIIC.py b/src/faebryk/library/QWIIC.py index 38f1381f..a2ae539c 100644 --- a/src/faebryk/library/QWIIC.py +++ b/src/faebryk/library/QWIIC.py @@ -1,11 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - +from faebryk.libs.library import L from faebryk.libs.units import P @@ -15,17 +13,15 @@ class QWIIC(Module): Delivers 3.3V power + F.I2C over JST SH 1mm pitch 4 pin connectors """ + # interfaces + i2c: F.I2C + power: F.ElectricPower - - # interfaces - - i2c = F.I2C() - power: F.ElectricPower - + def __preinit__(self): # set constraints self.power.voltage.merge(F.Constant(3.3 * P.V)) # TODO: self.power.source_current.merge(F.Constant(226 * P.mA)) designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") - self.add_trait(has_datasheet_defined("https://www.sparkfun.com/qwiic")) + datasheet = L.f_field(F.has_datasheet_defined)("https://www.sparkfun.com/qwiic") diff --git a/src/faebryk/library/QWIIC_Connector.py b/src/faebryk/library/QWIIC_Connector.py index f9141020..644de83f 100644 --- a/src/faebryk/library/QWIIC_Connector.py +++ b/src/faebryk/library/QWIIC_Connector.py @@ -3,21 +3,15 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - +from faebryk.libs.library import L logger = logging.getLogger(__name__) class QWIIC_Connector(Module): - - - - - - power: F.ElectricPower - i2c = F.I2C() - - + power: F.ElectricPower + i2c: F.I2C designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/RJ45_Receptacle.py b/src/faebryk/library/RJ45_Receptacle.py index 8cc46063..47a619e5 100644 --- a/src/faebryk/library/RJ45_Receptacle.py +++ b/src/faebryk/library/RJ45_Receptacle.py @@ -3,10 +3,9 @@ from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module - - - +from faebryk.libs.library import L class RJ45_Receptacle(Module): @@ -14,14 +13,10 @@ class Mounting(Enum): TH = auto() SMD = auto() + # interfaces - - # interfaces - - pin = L.if_list(8, F.Electrical) - shield: F.Electrical + pin = L.if_list(8, F.Electrical) + shield: F.Electrical designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") - - - mounting : F.TBD[self.Mounting] + mounting: F.TBD[Mounting] diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index b201b8ca..08574d76 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -3,40 +3,33 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - - +from faebryk.libs.library import L logger = logging.getLogger(__name__) class RP2040(Module): - - - - - - io_vdd: F.ElectricPower - adc_vdd: F.ElectricPower - core_vdd: F.ElectricPower - vreg_in: F.ElectricPower - vreg_out: F.ElectricPower - power_vusb: F.ElectricPower - gpio = L.if_list(30, F.Electrical) - run: F.ElectricLogic - usb : F.USB2_0 - qspi = MultiSPI(data_lane_count=4) - xin: F.Electrical - xout: F.Electrical - test: F.Electrical - swd = SWD() - # TODO: these peripherals and more can be mapped to different pins - i2c = F.I2C() - uart = F.UART_Base() - - - + io_vdd: F.ElectricPower + adc_vdd: F.ElectricPower + core_vdd: F.ElectricPower + vreg_in: F.ElectricPower + vreg_out: F.ElectricPower + power_vusb: F.ElectricPower + gpio = L.if_list(30, F.Electrical) + run: F.ElectricLogic + usb: F.USB2_0 + qspi = L.f_field(F.MultiSPI)(data_lane_count=4) + xin: F.Electrical + xout: F.Electrical + test: F.Electrical + swd: F.SWD + # TODO: these peripherals and more can be mapped to different pins + i2c: F.I2C + uart: F.UART_Base + + def __preinit__(self): # decouple power rails and connect GNDs toghether gnd = self.io_vdd.lv for pwrrail in [ @@ -50,8 +43,10 @@ class RP2040(Module): pwrrail.lv.connect(gnd) pwrrail.decoupled.decouple() - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf") - # set parameters # self.io_vdd.voltage.merge(F.Range(1.8*P.V, 3.63*P.V)) + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf" + ) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index bd8c3bce..ec027400 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -3,13 +3,12 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - from faebryk.libs.brightness import TypicalLuminousIntensity +from faebryk.libs.library import L from faebryk.libs.units import P - logger = logging.getLogger(__name__) @@ -17,28 +16,24 @@ class RP2040_Reference_Design(Module): """Minimal required design for the Raspberry Pi RP2040 microcontroller. Based on the official Raspberry Pi RP2040 hardware design guidlines""" + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + power: F.ElectricPower + usb: F.USB2_0 - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - - power: F.ElectricPower - usb : F.USB2_0 - - - rp2040 = RP2040() - flash = SPIFlash() - led = PoweredLED() - usb_current_limmit_resistor = L.if_list(2, F.Resistor) - # TODO: add crystal oscillator - # TODO: add voltage divider with switch - # TODO: add boot button - # TODO: add reset button - # TODO: add optional LM4040 voltage reference or voltage divider - - + rp2040: F.RP2040 + flash: F.SPIFlash + led: F.PoweredLED + usb_current_limit_resistor = L.if_list(2, F.Resistor) + # TODO: add crystal oscillator + # TODO: add voltage divider with switch + # TODO: add boot button + # TODO: add reset button + # TODO: add optional LM4040 voltage reference or voltage divider + def __preinit__(self): # ---------------------------------------- # aliasess # ---------------------------------------- @@ -50,13 +45,13 @@ class RP2040_Reference_Design(Module): self.flash.memory_size.merge(F.Constant(16 * P.Mbit)) - self.led.led.color.merge(LED.Color.GREEN) + self.led.led.color.merge(F.LED.Color.GREEN) self.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) - self.usb_current_limmit_resistor[0].resistance.merge(F.Constant(27 * P.ohm)) - self.usb_current_limmit_resistor[1].resistance.merge(F.Constant(27 * P.ohm)) + self.usb_current_limit_resistor[0].resistance.merge(F.Constant(27 * P.ohm)) + self.usb_current_limit_resistor[1].resistance.merge(F.Constant(27 * P.ohm)) # ---------------------------------------- # connections @@ -82,11 +77,14 @@ class RP2040_Reference_Design(Module): # connect usb self.usb.usb_if.d.p.connect_via( - self.usb_current_limmit_resistor[0], + self.usb_current_limit_resistor[0], self.rp2040.usb.usb_if.d.p, ) self.usb.usb_if.d.n.connect_via( - self.usb_current_limmit_resistor[1], + self.usb_current_limit_resistor[1], self.rp2040.usb.usb_if.d.n, ) - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040.pdf") + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040.pdf" + ) diff --git a/src/faebryk/library/RS232.py b/src/faebryk/library/RS232.py index f7925a18..33fad49f 100644 --- a/src/faebryk/library/RS232.py +++ b/src/faebryk/library/RS232.py @@ -1,17 +1,17 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface - - +import faebryk.library._F as F +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L class RS232(ModuleInterface): - - - - tx: F.ElectricLogic - rx: F.ElectricLogic - - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + tx: F.ElectricLogic + rx: F.ElectricLogic + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/RS485.py b/src/faebryk/library/RS485.py index d8c0f533..270b6a41 100644 --- a/src/faebryk/library/RS485.py +++ b/src/faebryk/library/RS485.py @@ -1,8 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface +import faebryk.library._F as F +from faebryk.core.moduleinterface import ModuleInterface class RS485(ModuleInterface): - diff_pair = DifferentialPair() + diff_pair: F.DifferentialPair diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 94355029..87730197 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -3,14 +3,14 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy - - +from faebryk.libs.library import L from faebryk.libs.units import P - +from faebryk.libs.util import times logger = logging.getLogger(__name__) @@ -30,45 +30,42 @@ class RS485_Bus_Protection(Module): def __init__(self, termination: bool = True, polarization: bool = True) -> None: super().__init__() - - - gdt = GDT() - tvs = TVS() - current_limmiter_resistors = L.if_list(2, F.Resistor) - common_mode_filter = Common_Mode_Filter() - gnd_couple_resistor : F.Resistor - gnd_couple_capacitor : F.Capacitor - clamping_diodes = L.if_list(2, Diode) - if termination: - termination_resistor : F.Resistor - if polarization: - polarization_resistors = L.if_list(2, F.Resistor) - - - power: F.ElectricPower - rs485_in = RS485() - rs485_out = RS485() - earth: F.Electrical - - - - if termination: - self.termination_resistor.resistance.merge(F.Constant(120 * P.ohm)) + self._termination = termination + self._polarization = polarization + + gdt: F.GDT + tvs: F.TVS + current_limmiter_resistors = L.if_list(2, F.Resistor) + common_mode_filter: F.Common_Mode_Filter + gnd_couple_resistor: F.Resistor + gnd_couple_capacitor: F.Capacitor + clamping_diodes = L.if_list(2, F.Diode) + power: F.ElectricPower + rs485_in: F.RS485 + rs485_out: F.RS485 + earth: F.Electrical + + def __preinit__(self): + if self._termination: + termination_resistor = self.add(F.Resistor(), name="termination_resistor") + termination_resistor.resistance.merge(F.Constant(120 * P.ohm)) self.rs485_out.diff_pair.p.connect_via( - self.termination_resistor, self.rs485_out.diff_pair.n + termination_resistor, self.rs485_out.diff_pair.n ) - if polarization: - self.polarization_resistors[0].resistance.merge( + if self._polarization: + polarization_resistors = self.add_to_container(2, F.Resistor) + + polarization_resistors[0].resistance.merge( F.Range(380 * P.ohm, 420 * P.ohm) ) - self.polarization_resistors[1].resistance.merge( + polarization_resistors[1].resistance.merge( F.Range(380 * P.ohm, 420 * P.ohm) ) self.rs485_in.diff_pair.p.connect_via( - self.polarization_resistors[0], self.power.hv + polarization_resistors[0], self.power.hv ) self.rs485_in.diff_pair.n.connect_via( - self.polarization_resistors[1], self.power.lv + polarization_resistors[1], self.power.lv ) self.current_limmiter_resistors[0].resistance.merge(F.Constant(2.7 * P.ohm)) @@ -121,48 +118,44 @@ def __init__(self, termination: bool = True, polarization: bool = True) -> None: self.common_mode_filter.c_b[1].connect(self.clamping_diodes[1].cathode) self.clamping_diodes[1].anode.connect(diode_junction) - @L.rt_field - def can_bridge(self): - return F.can_bridge_defined(self.rs485_in, self.rs485_out) - # TODO: layout is only working when bbox is implemented or # when using specific components # PCB layout - Point = has_pcb_position.Point - L = has_pcb_position.layer_type + Point = F.has_pcb_position.Point + L = F.has_pcb_position.layer_type self.gnd_couple_resistor.add_trait( - has_pcb_layout_defined( + F.has_pcb_layout_defined( LayoutAbsolute( Point((-10, 0, 90, L.NONE)), ) ) ) self.add_trait( - has_pcb_layout_defined( + F.has_pcb_layout_defined( LayoutTypeHierarchy( layouts=[ LayoutTypeHierarchy.Level( - mod_type=GDT, + mod_type=F.GDT, layout=LayoutAbsolute( Point((0, 0, 0, L.NONE)), ), ), # TODO: fix # LayoutTypeHierarchy.Level( - # mod_type=TVS, + # mod_type=F.TVS, # layout=LayoutAbsolute( # Point((0, 11, 0, L.NONE)), # ), # ), LayoutTypeHierarchy.Level( - mod_type=Common_Mode_Filter, + mod_type=F.Common_Mode_Filter, layout=LayoutAbsolute( Point((0, 25.5, 90, L.NONE)), ), ), LayoutTypeHierarchy.Level( - mod_type=Diode, + mod_type=F.Diode, layout=LayoutExtrude( base=Point((0, 14.5, 0, L.NONE)), vector=(0, 3.5, 0), @@ -185,3 +178,7 @@ def can_bridge(self): ), ) ) + + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.rs485_in, self.rs485_out) diff --git a/src/faebryk/library/Range.py b/src/faebryk/library/Range.py index 37928733..76ec57cc 100644 --- a/src/faebryk/library/Range.py +++ b/src/faebryk/library/Range.py @@ -4,7 +4,9 @@ from math import inf from typing import Any, Protocol, Self +import faebryk.library._F as F from faebryk.core.parameter import Parameter +from faebryk.libs.library import L class _SupportsRangeOps(Protocol): diff --git a/src/faebryk/library/Relay.py b/src/faebryk/library/Relay.py index 2d35d70f..6661a18e 100644 --- a/src/faebryk/library/Relay.py +++ b/src/faebryk/library/Relay.py @@ -3,9 +3,9 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) @@ -13,26 +13,20 @@ # TODO: make generic (use Switch module, different switch models, bistable, etc.) class Relay(Module): - - - - - - switch_a_nc: F.Electrical - switch_a_common: F.Electrical - switch_a_no: F.Electrical - switch_b_no: F.Electrical - switch_b_common: F.Electrical - switch_b_nc: F.Electrical - coil_p: F.Electrical - coil_n: F.Electrical - - - coil_rated_voltage : F.TBD[Quantity] - coil_rated_current : F.TBD[Quantity] - coil_resistance : F.TBD[Quantity] - contact_max_switching_voltage : F.TBD[Quantity] - contact_rated_switching_current : F.TBD[Quantity] - contact_max_switchng_current : F.TBD[Quantity] + switch_a_nc: F.Electrical + switch_a_common: F.Electrical + switch_a_no: F.Electrical + switch_b_no: F.Electrical + switch_b_common: F.Electrical + switch_b_nc: F.Electrical + coil_p: F.Electrical + coil_n: F.Electrical + + coil_rated_voltage: F.TBD[Quantity] + coil_rated_current: F.TBD[Quantity] + coil_resistance: F.TBD[Quantity] + contact_max_switching_voltage: F.TBD[Quantity] + contact_rated_switching_current: F.TBD[Quantity] + contact_max_switchng_current: F.TBD[Quantity] designator_prefix = L.f_field(F.has_designator_prefix_defined)("RELAY") diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index c39b6cbd..99d5d7ae 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -3,52 +3,46 @@ from math import sqrt -from faebryk.core.module import Module, Parameter +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter from faebryk.core.util import ( as_unit, as_unit_with_tolerance, ) - - - - - +from faebryk.libs.library import L from faebryk.libs.picker.picker import PickError, has_part_picked_remove from faebryk.libs.units import P, Quantity - class Resistor(Module): + unnamed = L.if_list(2, F.Electrical) + resistance: F.TBD[Quantity] + rated_power: F.TBD[Quantity] + rated_voltage: F.TBD[Quantity] - unnamed = L.if_list(2, F.Electrical) + attach_to_footprint: F.can_attach_to_footprint_symmetrically + designator_prefix = L.f_field(F.has_designator_prefix_defined)("R") @L.rt_field def can_bridge(self): return F.can_bridge_defined(*self.unnamed) - - resistance : F.TBD[Quantity] - rated_power : F.TBD[Quantity] - rated_voltage : F.TBD[Quantity] - - self.add_trait(can_attach_to_footprint_symmetrically()) @L.rt_field def simple_value_representation(self): return F.has_simple_value_representation_based_on_params( - ( - self.resistance, - self.rated_power, - ), - lambda ps: " ".join( - filter( - None, - [as_unit_with_tolerance(ps[0], "Ω"), as_unit(ps[1], "W")], - ) - ), - ) + ( + self.resistance, + self.rated_power, + ), + lambda ps: " ".join( + filter( + None, + [as_unit_with_tolerance(ps[0], "Ω"), as_unit(ps[1], "W")], + ) + ), ) - designator_prefix = L.f_field(F.has_designator_prefix_defined)("R") def allow_removal_if_zero(self): import faebryk.library._F as F @@ -64,8 +58,8 @@ def replace_zero(m: Module): self.unnamed[0].connect(self.unnamed[1]) self.add_trait(has_part_picked_remove()) - has_multi_picker.add_to_module( - self, -100, has_multi_picker.FunctionPicker(replace_zero) + F.has_multi_picker.add_to_module( + self, -100, F.has_multi_picker.FunctionPicker(replace_zero) ) def get_voltage_drop_by_current_resistance(self, current_A: Parameter) -> Parameter: diff --git a/src/faebryk/library/Resistor_Voltage_Divider.py b/src/faebryk/library/Resistor_Voltage_Divider.py index 69d50bc1..0d589288 100644 --- a/src/faebryk/library/Resistor_Voltage_Divider.py +++ b/src/faebryk/library/Resistor_Voltage_Divider.py @@ -3,28 +3,22 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity - logger = logging.getLogger(__name__) class Resistor_Voltage_Divider(Module): + resistor = L.if_list(2, F.Resistor) + node = L.if_list(3, F.Electrical) + ratio: F.TBD[Quantity] + max_current: F.TBD[Quantity] - - resistor = L.if_list(2, Resistor) - - - node = L.if_list(3, F.Electrical) - - - ratio : F.TBD[Quantity] - max_current : F.TBD[Quantity] - + def __preinit__(self): self.node[0].connect_via(self.resistor[0], self.node[1]) self.node[1].connect_via(self.resistor[1], self.node[2]) diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index 4939bba4..b4c048d8 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -3,10 +3,10 @@ from dataclasses import dataclass, field -from faebryk.core.module import Module, Parameter - - - +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.libs.library import L from faebryk.libs.units import P @@ -16,12 +16,9 @@ class SCD40(Module): """ @dataclass - class _scd4x_esphome_config(has_esphome_config.impl()): + class _scd4x_esphome_config(F.has_esphome_config.impl()): update_interval_s: Parameter = field(default_factory=F.TBD) - def __post_init__(self) -> None: - super().__init__() - def get_config(self) -> dict: assert isinstance( self.update_interval_s, F.Constant @@ -30,7 +27,7 @@ def get_config(self) -> dict: obj = self.get_obj() assert isinstance(obj, SCD40) - i2c = is_esphome_bus.find_connected_bus(obj.i2c) + i2c = F.is_esphome_bus.find_connected_bus(obj.i2c) return { "sensor": [ @@ -46,44 +43,41 @@ def get_config(self) -> dict: "name": "Humidity", }, "address": 0x62, - "i2c_id": i2c.get_trait(is_esphome_bus).get_bus_id(), + "i2c_id": i2c.get_trait(F.is_esphome_bus).get_bus_id(), "update_interval": f"{self.update_interval_s.value}s", } ] } - - - # interfaces - - power: F.ElectricPower - i2c = F.I2C() - - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "6": self.power.lv, - "20": self.power.lv, - "21": self.power.lv, - "7": self.power.hv, - "19": self.power.hv, - "9": self.i2c.scl.signal, - "10": self.i2c.sda.signal, - } - ) + esphome_config: _scd4x_esphome_config + + # interfaces + power: F.ElectricPower + i2c: F.I2C + + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "6": self.power.lv, + "20": self.power.lv, + "21": self.power.lv, + "7": self.power.hv, + "19": self.power.hv, + "9": self.i2c.scl.signal, + "10": self.i2c.sda.signal, + } ) + def __preinit__(self): self.power.voltage.merge(F.Constant(3.3 * P.V)) - self.i2c.terminate() self.power.decoupled.decouple() - - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") self.i2c.frequency.merge( F.I2C.define_max_frequency_capability(F.I2C.SpeedMode.fast_speed) ) - datasheet = L.f_field(F.has_datasheet_defined)("https://sensirion.com/media/documents/48C4B7FB/64C134E7/Sensirion_SCD4x_Datasheet.pdf") - self.i2c.add_trait(is_esphome_bus.impl()()) - self.esphome = self._scd4x_esphome_config() - self.add_trait(self.esphome) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://sensirion.com/media/documents/48C4B7FB/64C134E7/Sensirion_SCD4x_Datasheet.pdf" + ) diff --git a/src/faebryk/library/SK9822_EC20.py b/src/faebryk/library/SK9822_EC20.py index 316ce75f..964b2ba8 100644 --- a/src/faebryk/library/SK9822_EC20.py +++ b/src/faebryk/library/SK9822_EC20.py @@ -1,12 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - - +from faebryk.libs.library import L class SK9822_EC20(Module): @@ -24,33 +21,35 @@ class SK9822_EC20(Module): output action synchronization. """ + # interfaces + power: F.ElectricPower + sdo: F.ElectricLogic + sdi: F.ElectricLogic + cko: F.ElectricLogic + ckl: F.ElectricLogic - - # interfaces - - power: F.ElectricPower - sdo: F.ElectricLogic - sdi: F.ElectricLogic - cko: F.ElectricLogic - ckl: F.ElectricLogic - + @L.rt_field + def attach_to_footprint(self): x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.sdo.signal, - "2": x.power.lv, - "3": x.sdi.signal, - "4": x.ckl.signal, - "5": x.power.hv, - "6": x.cko.signal, - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "1": x.sdo.signal, + "2": x.power.lv, + "3": x.sdi.signal, + "4": x.ckl.signal, + "5": x.power.hv, + "6": x.cko.signal, + } + ) + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) ) - # connect all logic references - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2110250930_OPSCO-Optoelectronics-SK9822-EC20_C2909059.pdf") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/2110250930_OPSCO-Optoelectronics-SK9822-EC20_C2909059.pdf" + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("LED") diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index 84112431..5551481a 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -3,8 +3,8 @@ from enum import Enum - - +import faebryk.library._F as F +from faebryk.libs.library import L class SMDTwoPin(F.Footprint): @@ -22,33 +22,30 @@ class Type(Enum): def __init__(self, type: Type) -> None: super().__init__() - - - pins = L.if_list(2, Pad) - - from faebryk.library.has_kicad_footprint_equal_ifs import ( - has_kicad_footprint_equal_ifs, - ) - - class _has_kicad_footprint(has_kicad_footprint_equal_ifs): - @staticmethod - def get_kicad_footprint() -> str: - table = { - self.Type._01005: "0402", - self.Type._0201: "0603", - self.Type._0402: "1005", - self.Type._0603: "1608", - self.Type._0805: "2012", - self.Type._1206: "3216", - self.Type._1210: "3225", - self.Type._1218: "3246", - self.Type._2010: "5025", - self.Type._2512: "6332", - } - return "F.Resistor_SMD:R_{imperial}_{metric}Metric".format( - imperial=type.name[1:], metric=table[type] - ) - - self.add_trait(_has_kicad_footprint()) - self.add_trait(has_equal_pins_in_ifs()) - self.add_trait(can_attach_via_pinmap_equal()) + self._type = type + + pins = L.if_list(2, F.Pad) + + class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): + def get_kicad_footprint(self) -> str: + obj = self.get_obj() + assert isinstance(obj, SMDTwoPin) + table = { + SMDTwoPin.Type._01005: "0402", + SMDTwoPin.Type._0201: "0603", + SMDTwoPin.Type._0402: "1005", + SMDTwoPin.Type._0603: "1608", + SMDTwoPin.Type._0805: "2012", + SMDTwoPin.Type._1206: "3216", + SMDTwoPin.Type._1210: "3225", + SMDTwoPin.Type._1218: "3246", + SMDTwoPin.Type._2010: "5025", + SMDTwoPin.Type._2512: "6332", + } + return "F.Resistor_SMD:R_{imperial}_{metric}Metric".format( + imperial=obj._type.name[1:], metric=table[obj._type] + ) + + kicad_footprint: _has_kicad_footprint + equal_pins: F.has_equal_pins_in_ifs + attach_via_pinmap: F.can_attach_via_pinmap_equal diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index 3924a5e0..b6869fd4 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -3,10 +3,10 @@ import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.libs.library import L from faebryk.libs.units import P - class SNx4LVC541A(Module): """ The SN54LVC541A octal buffer/driver is designed for @@ -14,34 +14,29 @@ class SNx4LVC541A(Module): octal buffer/driver is designed for 1.65-V to 3.6-V VCC operation. """ + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + A = L.if_list(8, F.ElectricLogic) + Y = L.if_list(8, F.ElectricLogic) - # ---------------------------------------- - # modules, interfaces, parameters - # ---------------------------------------- - - - - A = L.if_list(8, F.ElectricLogic) - Y = L.if_list(8, F.ElectricLogic) + power: F.ElectricPower - vcc: F.ElectricPower + OE = L.if_list(2, F.ElectricLogic) - OE = L.if_list(2, F.ElectricLogic) - - # ---------------------------------------- - # traits - # ---------------------------------------- - self.add_trait(F.has_designator_prefix_defined("U")) - self.add_trait( - F.has_datasheet_defined( - "https://www.ti.com/lit/ds/symlink/sn74lvc541a.pdf?ts=1718881644774&ref_url=https%253A%252F%252Fwww.mouser.ie%252F" - ) - ) + # ---------------------------------------- + # traits + # ---------------------------------------- + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://www.ti.com/lit/ds/symlink/sn74lvc541a.pdf?ts=1718881644774&ref_url=https%253A%252F%252Fwww.mouser.ie%252F" + ) + def __preinit__(self): # ---------------------------------------- # parameters # ---------------------------------------- - self.vcc.voltage.merge(F.Range.upper_bound(3.6 * P.V)) + self.power.voltage.merge(F.Range.upper_bound(3.6 * P.V)) # ---------------------------------------- # aliases @@ -50,10 +45,10 @@ class SNx4LVC541A(Module): # ---------------------------------------- # connections # ---------------------------------------- - self.vcc.get_trait(F.can_be_decoupled).decouple() + self.power.get_trait(F.can_be_decoupled).decouple() - # set all electric logic references - for a, y, oe in zip(self.A, self.Y, self.OE): - a.connect_reference(self.vcc) - y.connect_reference(self.vcc) - oe.connect_reference(self.vcc) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/SOIC.py b/src/faebryk/library/SOIC.py index 618ddeb9..4829975d 100644 --- a/src/faebryk/library/SOIC.py +++ b/src/faebryk/library/SOIC.py @@ -2,8 +2,10 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity - +from faebryk.libs.util import times class SOIC(F.Footprint): @@ -14,24 +16,25 @@ def __init__( pitch: Quantity, ) -> None: super().__init__() - - - pins = L.if_list(pin_cnt, Pad) - - from faebryk.library.has_kicad_footprint_equal_ifs import ( - has_kicad_footprint_equal_ifs, - ) - - class _has_kicad_footprint(has_kicad_footprint_equal_ifs): - @staticmethod - def get_kicad_footprint() -> str: - return "Package_SO:SOIC-{leads}_{size_x:.1f}x{size_y:.1f}mm_P{pitch:.2f}mm".format( # noqa: E501 - leads=pin_cnt, - size_x=size_xy[0].to(P.mm).m, - size_y=size_xy[1].to(P.mm).m, - pitch=pitch.to(P.mm).m, - ) - - self.add_trait(_has_kicad_footprint()) - self.add_trait(has_equal_pins_in_ifs()) - self.add_trait(can_attach_via_pinmap_equal()) + self._pin_cnt = pin_cnt + self._size_xy = size_xy + self._pitch = pitch + + @L.rt_field + def pins(self): + return times(self._pin_cnt, F.Pad) + + class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): + def get_kicad_footprint(self) -> str: + obj = self.get_obj() + assert isinstance(obj, SOIC) + return "Package_SO:SOIC-{leads}_{size_x:.1f}x{size_y:.1f}mm_P{pitch:.2f}mm".format( # noqa: E501 + leads=obj._pin_cnt, + size_x=obj._size_xy[0].to(P.mm).m, + size_y=obj._size_xy[1].to(P.mm).m, + pitch=obj._pitch.to(P.mm).m, + ) + + kicad_footprint: _has_kicad_footprint + attach_via_pinmap: F.can_attach_via_pinmap_equal + equal_pins: F.has_equal_pins_in_ifs diff --git a/src/faebryk/library/SPI.py b/src/faebryk/library/SPI.py index 7da5a4ec..b786ef3e 100644 --- a/src/faebryk/library/SPI.py +++ b/src/faebryk/library/SPI.py @@ -1,7 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L class SPI(ModuleInterface): diff --git a/src/faebryk/library/SPIFlash.py b/src/faebryk/library/SPIFlash.py index ffb18d92..88491710 100644 --- a/src/faebryk/library/SPIFlash.py +++ b/src/faebryk/library/SPIFlash.py @@ -1,20 +1,15 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface - - +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.libs.library import L from faebryk.libs.units import Quantity class SPIFlash(Module): + power: F.ElectricPower + spi: F.MultiSPI - - - power: F.ElectricPower - spi = MultiSPI() - - - memory_size: F.TBD[Quantity] - + memory_size: F.TBD[Quantity] designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/SWD.py b/src/faebryk/library/SWD.py index f6e6cf59..cf5c2d0e 100644 --- a/src/faebryk/library/SWD.py +++ b/src/faebryk/library/SWD.py @@ -1,21 +1,16 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - +from faebryk.libs.library import L class SWD(ModuleInterface): - - - - clk: F.ElectricLogic - dio: F.ElectricLogic - swo: F.ElectricLogic - reset: F.ElectricLogic - - + clk: F.ElectricLogic + dio: F.ElectricLogic + swo: F.ElectricLogic + reset: F.ElectricLogic @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/SWDConnector.py b/src/faebryk/library/SWDConnector.py index e85640b2..8b51791e 100644 --- a/src/faebryk/library/SWDConnector.py +++ b/src/faebryk/library/SWDConnector.py @@ -1,21 +1,15 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface - - - +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.libs.library import L class SWDConnector(Module): - - - - swd = SWD() - gnd_detect: F.ElectricLogic - vcc: F.ElectricPower - - + swd: F.SWD + gnd_detect: F.ElectricLogic + vcc: F.ElectricPower designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/Sercom.py b/src/faebryk/library/Sercom.py index f69ee48d..11d8f1ca 100644 --- a/src/faebryk/library/Sercom.py +++ b/src/faebryk/library/Sercom.py @@ -1,17 +1,16 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.module import Module, ModuleInterface - - - +import faebryk.library._F as F +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L class Sercom(ModuleInterface): + unnamed = L.if_list(4, F.ElectricLogic) - - - unnamed = L.if_list(4, F.ElectricLogic) - - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/Set.py b/src/faebryk/library/Set.py index 3b9facc5..48b44966 100644 --- a/src/faebryk/library/Set.py +++ b/src/faebryk/library/Set.py @@ -3,6 +3,7 @@ from typing import Iterable, Self +import faebryk.library._F as F from faebryk.core.parameter import Parameter, _resolved diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index e8280ff9..c3f8cb28 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -2,18 +2,15 @@ # SPDX-License-Identifier: MIT from functools import cache -from typing import Generic, TypeGuard, TypeVar +from typing import TypeGuard -from faebryk.core.module import Module, ModuleInterface +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L - - - -T = TypeVar("T", bound=ModuleInterface) - - -class _TSwitch(Generic[T], Module): +class _TSwitch[T: ModuleInterface](Module): def __init__(self, t: type[T]): super().__init__() self.t = t @@ -24,20 +21,19 @@ def is_instance(obj: Module, t: type[T]) -> bool: @cache # This means we can use a normal "isinstance" to test for them -def Switch(interface_type: type[T]): +def Switch[T: ModuleInterface](interface_type: type[T]): class _Switch(_TSwitch[interface_type]): def __init__(self) -> None: super().__init__(interface_type) - designator_prefix = L.f_field(F.has_designator_prefix_defined)("SW") - self.add_trait(can_attach_to_footprint_symmetrically()) - + designator_prefix = L.f_field(F.has_designator_prefix_defined)("SW") + attach_to_footprint: F.can_attach_to_footprint_symmetrically - unnamed = L.if_list(2, interface_type) + unnamed = L.if_list(2, interface_type) - @L.rt_field - def can_bridge(self): - return F.can_bridge_defined(*self.unnamed) + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(*self.unnamed) @staticmethod def is_instance(obj: Module) -> "TypeGuard[_Switch]": diff --git a/src/faebryk/library/TI_CD4011BE.py b/src/faebryk/library/TI_CD4011BE.py index 12de1e62..142f9d3f 100644 --- a/src/faebryk/library/TI_CD4011BE.py +++ b/src/faebryk/library/TI_CD4011BE.py @@ -8,7 +8,7 @@ class TI_CD4011BE(CD4011): fp = DIP(pin_cnt=14, spacing=7.62 * P.mm, long_pads=False) - self.add_trait(has_defined_footprint(fp)) + self.add_trait(F.has_defined_footprint(fp)) fp.get_trait(can_attach_via_pinmap).attach( { "7": self.power.lv, diff --git a/src/faebryk/library/UART_Base.py b/src/faebryk/library/UART_Base.py index dbcbb17f..6e889da6 100644 --- a/src/faebryk/library/UART_Base.py +++ b/src/faebryk/library/UART_Base.py @@ -19,7 +19,7 @@ class F.UART_Base(ModuleInterface): baud: F.TBD[Quantity] ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + self.add_trait(F.has_single_electric_reference_defined(ref)) def _on_connect(self, other: "F.UART_Base"): super()._on_connect(other) diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index def7f937..b4bc8282 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -47,7 +47,7 @@ def get_config(self) -> dict: # connect all logic references ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + self.add_trait(F.has_single_electric_reference_defined(ref)) designator_prefix = L.f_field(F.has_designator_prefix_defined)("LED") diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index b7a6aa12..7f0238a4 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -156,7 +156,7 @@ from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_defined_capacitance import has_defined_capacitance from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties -from faebryk.library.has_defined_footprint import has_defined_footprint +from faebryk.library.has_footprint_defined import has_footprint_defined from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref from faebryk.library.has_defined_resistance import has_defined_resistance from faebryk.library.has_descriptive_properties import has_descriptive_properties diff --git a/src/faebryk/library/can_attach_to_footprint_symmetrically.py b/src/faebryk/library/can_attach_to_footprint_symmetrically.py index 7dc057a9..70ff1f97 100644 --- a/src/faebryk/library/can_attach_to_footprint_symmetrically.py +++ b/src/faebryk/library/can_attach_to_footprint_symmetrically.py @@ -7,10 +7,10 @@ class can_attach_to_footprint_symmetrically(can_attach_to_footprint.impl()): def attach(self, footprint: F.Footprint): - self.get_obj().add_trait(has_defined_footprint(footprint)) + self.get_obj().add_trait(F.has_defined_footprint(footprint)) for i, j in zip_children_by_name(footprint, self.get_obj(), ModuleInterface): - assert isinstance(i, Pad) + assert isinstance(i, F.Pad) assert isinstance(j, F.Electrical) assert type(i.net) is type(j) i.attach(j) diff --git a/src/faebryk/library/can_attach_to_footprint_via_pinmap.py b/src/faebryk/library/can_attach_to_footprint_via_pinmap.py index 0ebdf341..36dc149b 100644 --- a/src/faebryk/library/can_attach_to_footprint_via_pinmap.py +++ b/src/faebryk/library/can_attach_to_footprint_via_pinmap.py @@ -8,5 +8,5 @@ def __init__(self, pinmap: dict[str, F.Electrical]) -> None: self.pinmap = pinmap def attach(self, footprint: F.Footprint): - self.get_obj().add_trait(has_defined_footprint(footprint)) + self.get_obj().add_trait(F.has_defined_footprint(footprint)) footprint.get_trait(can_attach_via_pinmap).attach(self.pinmap) diff --git a/src/faebryk/library/can_attach_via_pinmap_equal.py b/src/faebryk/library/can_attach_via_pinmap_equal.py index 2763e19d..d6224692 100644 --- a/src/faebryk/library/can_attach_via_pinmap_equal.py +++ b/src/faebryk/library/can_attach_via_pinmap_equal.py @@ -6,7 +6,7 @@ class can_attach_via_pinmap_equal(can_attach_via_pinmap.impl()): def attach(self, pinmap: dict[str, F.Electrical]): pin_list = { v: k - for k, v in self.get_obj().get_trait(has_equal_pins).get_pin_map().items() + for k, v in self.get_obj().get_trait(F.has_equal_pins).get_pin_map().items() } for no, intf in pinmap.items(): pin_list[no].attach(intf) diff --git a/src/faebryk/library/can_attach_via_pinmap_pinlist.py b/src/faebryk/library/can_attach_via_pinmap_pinlist.py index 3f3b690a..af51b059 100644 --- a/src/faebryk/library/can_attach_via_pinmap_pinlist.py +++ b/src/faebryk/library/can_attach_via_pinmap_pinlist.py @@ -3,7 +3,7 @@ class can_attach_via_pinmap_pinlist(can_attach_via_pinmap.impl()): - def __init__(self, pin_list: dict[str, Pad]) -> None: + def __init__(self, pin_list: dict[str, F.Pad]) -> None: super().__init__() self.pin_list = pin_list diff --git a/src/faebryk/library/has_capacitance.py b/src/faebryk/library/has_capacitance.py index 126991ce..c034c9fb 100644 --- a/src/faebryk/library/has_capacitance.py +++ b/src/faebryk/library/has_capacitance.py @@ -3,7 +3,8 @@ from abc import abstractmethod -from faebryk.core.module import Module, Parameter +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter class has_capacitance(Module.TraitT): diff --git a/src/faebryk/library/has_datasheet_defined.py b/src/faebryk/library/has_datasheet_defined.py index 6b2e0884..c385db8b 100644 --- a/src/faebryk/library/has_datasheet_defined.py +++ b/src/faebryk/library/has_datasheet_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_datasheet_defined(has_datasheet.impl()): + +class has_datasheet_defined(F.has_datasheet.impl()): def __init__(self, datasheet: str) -> None: super().__init__() self.datasheet = datasheet diff --git a/src/faebryk/library/has_defined_capacitance.py b/src/faebryk/library/has_defined_capacitance.py index 6d8e6f89..9114638f 100644 --- a/src/faebryk/library/has_defined_capacitance.py +++ b/src/faebryk/library/has_defined_capacitance.py @@ -1,10 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.parameter import Parameter -class has_defined_capacitance(has_capacitance.impl()): +class has_defined_capacitance(F.has_capacitance.impl()): def __init__(self, capacitance: Parameter) -> None: super().__init__() self.component_capacitance = capacitance diff --git a/src/faebryk/library/has_defined_descriptive_properties.py b/src/faebryk/library/has_defined_descriptive_properties.py index 4ab034bc..70dac756 100644 --- a/src/faebryk/library/has_defined_descriptive_properties.py +++ b/src/faebryk/library/has_defined_descriptive_properties.py @@ -2,10 +2,11 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module -class has_defined_descriptive_properties(has_descriptive_properties.impl()): +class has_defined_descriptive_properties(F.has_descriptive_properties.impl()): def __init__(self, properties: dict[str, str]) -> None: super().__init__() self.properties = properties @@ -18,7 +19,7 @@ def get_properties(self) -> dict[str, str]: @classmethod def add_properties_to(cls, module: Module, properties: dict[str, str]): - if not module.has_trait(has_descriptive_properties): + if not module.has_trait(F.has_descriptive_properties): module.add_trait(cls(properties)) else: - module.get_trait(has_descriptive_properties).add_properties(properties) + module.get_trait(F.has_descriptive_properties).add_properties(properties) diff --git a/src/faebryk/library/has_defined_kicad_ref.py b/src/faebryk/library/has_defined_kicad_ref.py index cdc218ff..58450289 100644 --- a/src/faebryk/library/has_defined_kicad_ref.py +++ b/src/faebryk/library/has_defined_kicad_ref.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_defined_kicad_ref(has_kicad_ref.impl()): + +class has_defined_kicad_ref(F.has_kicad_ref.impl()): def __init__(self, ref: str) -> None: super().__init__() self.ref = ref diff --git a/src/faebryk/library/has_defined_resistance.py b/src/faebryk/library/has_defined_resistance.py index 6983a46c..6f3bfb99 100644 --- a/src/faebryk/library/has_defined_resistance.py +++ b/src/faebryk/library/has_defined_resistance.py @@ -1,10 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.parameter import Parameter -class has_defined_resistance(has_resistance.impl()): +class has_defined_resistance(F.has_resistance.impl()): def __init__(self, resistance: Parameter) -> None: super().__init__() self.component_resistance = resistance diff --git a/src/faebryk/library/has_designator_defined.py b/src/faebryk/library/has_designator_defined.py index 5cdb8ee0..1665338d 100644 --- a/src/faebryk/library/has_designator_defined.py +++ b/src/faebryk/library/has_designator_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_designator_defined(has_designator.impl()): + +class has_designator_defined(F.has_designator.impl()): def __init__(self, value: str) -> None: super().__init__() self.value = value diff --git a/src/faebryk/library/has_designator_prefix_defined.py b/src/faebryk/library/has_designator_prefix_defined.py index 1e1643e5..ed174514 100644 --- a/src/faebryk/library/has_designator_prefix_defined.py +++ b/src/faebryk/library/has_designator_prefix_defined.py @@ -1,10 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -# import faebryk.library._F as F +import faebryk.library._F as F -class has_designator_prefix_defined(has_designator_prefix.impl()): +class has_designator_prefix_defined(F.has_designator_prefix.impl()): def __init__(self, prefix: str) -> None: super().__init__() self.prefix = prefix diff --git a/src/faebryk/library/has_equal_pins.py b/src/faebryk/library/has_equal_pins.py index 2fa0c05e..d78f0aaa 100644 --- a/src/faebryk/library/has_equal_pins.py +++ b/src/faebryk/library/has_equal_pins.py @@ -3,7 +3,9 @@ from abc import abstractmethod +import faebryk.library._F as F + class has_equal_pins(F.Footprint.TraitT): @abstractmethod - def get_pin_map(self) -> dict[Pad, str]: ... + def get_pin_map(self) -> dict[F.Pad, str]: ... diff --git a/src/faebryk/library/has_equal_pins_in_ifs.py b/src/faebryk/library/has_equal_pins_in_ifs.py index fbefdfed..08710bde 100644 --- a/src/faebryk/library/has_equal_pins_in_ifs.py +++ b/src/faebryk/library/has_equal_pins_in_ifs.py @@ -1,11 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_equal_pins_in_ifs(has_equal_pins.impl()): + +class has_equal_pins_in_ifs(F.has_equal_pins.impl()): def get_pin_map(self): return { p: str(i + 1) for i, p in enumerate(self.get_obj().get_all()) - if isinstance(p, Pad) + if isinstance(p, F.Pad) } diff --git a/src/faebryk/library/has_esphome_config.py b/src/faebryk/library/has_esphome_config.py index 3a2a6f6e..e1d75c0e 100644 --- a/src/faebryk/library/has_esphome_config.py +++ b/src/faebryk/library/has_esphome_config.py @@ -3,7 +3,7 @@ from abc import abstractmethod -from faebryk.core.core import Trait +from faebryk.core.trait import Trait class has_esphome_config(Trait): diff --git a/src/faebryk/library/has_esphome_config_defined.py b/src/faebryk/library/has_esphome_config_defined.py index 8b15b566..216e9daa 100644 --- a/src/faebryk/library/has_esphome_config_defined.py +++ b/src/faebryk/library/has_esphome_config_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_esphome_config_defined(has_esphome_config.impl()): + +class has_esphome_config_defined(F.has_esphome_config.impl()): def __init__(self, config: dict): super().__init__() self._config = config diff --git a/src/faebryk/library/has_footprint.py b/src/faebryk/library/has_footprint.py index aa687efe..58f15694 100644 --- a/src/faebryk/library/has_footprint.py +++ b/src/faebryk/library/has_footprint.py @@ -3,6 +3,7 @@ from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.module import Module diff --git a/src/faebryk/library/has_defined_footprint.py b/src/faebryk/library/has_footprint_defined.py similarity index 73% rename from src/faebryk/library/has_defined_footprint.py rename to src/faebryk/library/has_footprint_defined.py index a2a14eda..71940e62 100644 --- a/src/faebryk/library/has_defined_footprint.py +++ b/src/faebryk/library/has_footprint_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_defined_footprint(has_footprint_impl): + +class has_footprint_defined(F.has_footprint_impl): def __init__(self, fp: F.Footprint) -> None: super().__init__() self.fp = fp diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index 5b079a8e..c950d598 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -3,10 +3,11 @@ from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.link import LinkNamedParent -class has_footprint_impl(has_footprint.impl()): +class has_footprint_impl(F.has_footprint.impl()): @abstractmethod def set_footprint(self, fp: F.Footprint): self.get_obj().children.connect(fp.parent, LinkNamedParent.curry("footprint")) diff --git a/src/faebryk/library/has_footprint_requirement_defined.py b/src/faebryk/library/has_footprint_requirement_defined.py index 37114d7b..ec2a4ced 100644 --- a/src/faebryk/library/has_footprint_requirement_defined.py +++ b/src/faebryk/library/has_footprint_requirement_defined.py @@ -4,11 +4,12 @@ import logging from typing import Sequence +import faebryk.library._F as F logger = logging.getLogger(__name__) -class has_footprint_requirement_defined(has_footprint_requirement.impl()): +class has_footprint_requirement_defined(F.has_footprint_requirement.impl()): def __init__(self, req: Sequence[tuple[str, int]]) -> None: super().__init__() self.req = req diff --git a/src/faebryk/library/has_kicad_footprint.py b/src/faebryk/library/has_kicad_footprint.py index 60e9d25c..71ef6688 100644 --- a/src/faebryk/library/has_kicad_footprint.py +++ b/src/faebryk/library/has_kicad_footprint.py @@ -3,13 +3,15 @@ from abc import abstractmethod +import faebryk.library._F as F + class has_kicad_footprint(F.Footprint.TraitT): @abstractmethod def get_kicad_footprint(self) -> str: ... @abstractmethod - def get_pin_names(self) -> dict[Pad, str]: ... + def get_pin_names(self) -> dict[F.Pad, str]: ... def get_kicad_footprint_name(self) -> str: return self.get_kicad_footprint().split(":")[-1] diff --git a/src/faebryk/library/has_kicad_footprint_equal_ifs.py b/src/faebryk/library/has_kicad_footprint_equal_ifs.py index 8d4e612b..57d57be1 100644 --- a/src/faebryk/library/has_kicad_footprint_equal_ifs.py +++ b/src/faebryk/library/has_kicad_footprint_equal_ifs.py @@ -1,7 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_kicad_footprint_equal_ifs(has_kicad_footprint.impl()): + +class has_kicad_footprint_equal_ifs(F.has_kicad_footprint.impl()): def get_pin_names(self): - return self.get_obj().get_trait(has_equal_pins).get_pin_map() + return self.get_obj().get_trait(F.has_equal_pins).get_pin_map() diff --git a/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py b/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py index db40504d..bce6b7c0 100644 --- a/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py +++ b/src/faebryk/library/has_kicad_footprint_equal_ifs_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_kicad_footprint_equal_ifs_defined(has_kicad_footprint_equal_ifs): + +class has_kicad_footprint_equal_ifs_defined(F.has_kicad_footprint_equal_ifs): def __init__(self, str) -> None: super().__init__() self.str = str diff --git a/src/faebryk/library/has_kicad_manual_footprint.py b/src/faebryk/library/has_kicad_manual_footprint.py index 3bb96261..9fce01bc 100644 --- a/src/faebryk/library/has_kicad_manual_footprint.py +++ b/src/faebryk/library/has_kicad_manual_footprint.py @@ -1,9 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_kicad_manual_footprint(has_kicad_footprint.impl()): - def __init__(self, str, pinmap: dict[Pad, str]) -> None: + +class has_kicad_manual_footprint(F.has_kicad_footprint.impl()): + def __init__(self, str, pinmap: dict[F.Pad, str]) -> None: super().__init__() self.str = str self.pinmap = pinmap diff --git a/src/faebryk/library/has_kicad_ref.py b/src/faebryk/library/has_kicad_ref.py index 0a2e475c..7e63b6b3 100644 --- a/src/faebryk/library/has_kicad_ref.py +++ b/src/faebryk/library/has_kicad_ref.py @@ -1,7 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from faebryk.core.core import Trait +from faebryk.core.trait import Trait class has_kicad_ref(Trait): diff --git a/src/faebryk/library/has_linked_pad.py b/src/faebryk/library/has_linked_pad.py index 85eed56a..0a169157 100644 --- a/src/faebryk/library/has_linked_pad.py +++ b/src/faebryk/library/has_linked_pad.py @@ -3,9 +3,10 @@ from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface class has_linked_pad(ModuleInterface.TraitT): @abstractmethod - def get_pad(self) -> Pad: ... + def get_pad(self) -> F.Pad: ... diff --git a/src/faebryk/library/has_linked_pad_defined.py b/src/faebryk/library/has_linked_pad_defined.py index e8da096f..5eee8bfa 100644 --- a/src/faebryk/library/has_linked_pad_defined.py +++ b/src/faebryk/library/has_linked_pad_defined.py @@ -2,10 +2,13 @@ # SPDX-License-Identifier: MIT -class has_linked_pad_defined(has_linked_pad.impl()): - def __init__(self, pad: Pad) -> None: +import faebryk.library._F as F + + +class has_linked_pad_defined(F.has_linked_pad.impl()): + def __init__(self, pad: F.Pad) -> None: super().__init__() self.pad = pad - def get_pad(self) -> Pad: + def get_pad(self) -> F.Pad: return self.pad diff --git a/src/faebryk/library/has_multi_picker.py b/src/faebryk/library/has_multi_picker.py index 2b46316a..1af34502 100644 --- a/src/faebryk/library/has_multi_picker.py +++ b/src/faebryk/library/has_multi_picker.py @@ -6,16 +6,17 @@ from abc import abstractmethod from typing import Callable, Mapping +import faebryk.library._F as F from faebryk.core.module import Module - from faebryk.libs.picker.picker import PickError logger = logging.getLogger(__name__) -class has_multi_picker(has_picker.impl()): +class has_multi_picker(F.has_picker.impl()): def pick(self): module = self.get_obj() + assert isinstance(module, Module) es = [] for _, picker in self.pickers: logger.debug(f"Trying picker for {module}: {picker}") @@ -32,6 +33,7 @@ class Picker: @abstractmethod def pick(self, module: Module): ... + def __preinit__(self): self.pickers: list[tuple[int, has_multi_picker.Picker]] = [] def add_picker(self, prio: int, picker: Picker): @@ -40,10 +42,10 @@ def add_picker(self, prio: int, picker: Picker): @classmethod def add_to_module(cls, module: Module, prio: int, picker: Picker): - if not module.has_trait(has_picker): + if not module.has_trait(F.has_picker): module.add_trait(cls()) - t = module.get_trait(has_picker) + t = module.get_trait(F.has_picker) assert isinstance(t, has_multi_picker) t.add_picker(prio, picker) diff --git a/src/faebryk/library/has_overriden_name_defined.py b/src/faebryk/library/has_overriden_name_defined.py index fed2e014..6180e3bd 100644 --- a/src/faebryk/library/has_overriden_name_defined.py +++ b/src/faebryk/library/has_overriden_name_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_overriden_name_defined(has_overriden_name.impl()): + +class has_overriden_name_defined(F.has_overriden_name.impl()): def __init__(self, name: str) -> None: super().__init__() self.component_name = name diff --git a/src/faebryk/library/has_pcb_layout_defined.py b/src/faebryk/library/has_pcb_layout_defined.py index 35ff78c7..8cfea49d 100644 --- a/src/faebryk/library/has_pcb_layout_defined.py +++ b/src/faebryk/library/has_pcb_layout_defined.py @@ -1,10 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT + +import faebryk.library._F as F from faebryk.exporters.pcb.layout.layout import Layout -class has_pcb_layout_defined(has_pcb_layout.impl()): +class has_pcb_layout_defined(F.has_pcb_layout.impl()): def __init__(self, layout: Layout) -> None: super().__init__() self.layout = layout diff --git a/src/faebryk/library/has_pcb_position_defined.py b/src/faebryk/library/has_pcb_position_defined.py index af57ee60..4b3f478b 100644 --- a/src/faebryk/library/has_pcb_position_defined.py +++ b/src/faebryk/library/has_pcb_position_defined.py @@ -1,11 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_pcb_position_defined(has_pcb_position.impl()): - def __init__(self, position: has_pcb_position.Point) -> None: + +class has_pcb_position_defined(F.has_pcb_position.impl()): + def __init__(self, position: F.has_pcb_position.Point) -> None: super().__init__() self.position = position - def get_position(self) -> has_pcb_position.Point: + def get_position(self) -> F.has_pcb_position.Point: return self.position diff --git a/src/faebryk/library/has_pcb_position_defined_relative.py b/src/faebryk/library/has_pcb_position_defined_relative.py index 33c2df21..6b3ee11d 100644 --- a/src/faebryk/library/has_pcb_position_defined_relative.py +++ b/src/faebryk/library/has_pcb_position_defined_relative.py @@ -2,18 +2,19 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module -class has_pcb_position_defined_relative(has_pcb_position.impl()): - def __init__(self, position_relative: has_pcb_position.Point, to: Module) -> None: +class has_pcb_position_defined_relative(F.has_pcb_position.impl()): + def __init__(self, position_relative: F.has_pcb_position.Point, to: Module) -> None: super().__init__() self.position_relative = position_relative self.to = to - def get_position(self) -> has_pcb_position.Point: + def get_position(self) -> F.has_pcb_position.Point: from faebryk.libs.geometry.basic import Geometry return Geometry.abs_pos( - self.to.get_trait(has_pcb_position).get_position(), self.position_relative + self.to.get_trait(F.has_pcb_position).get_position(), self.position_relative ) diff --git a/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py b/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py index 944a6311..14d77b16 100644 --- a/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py +++ b/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py @@ -3,21 +3,22 @@ import logging +import faebryk.library._F as F logger = logging.getLogger(__name__) -class has_pcb_position_defined_relative_to_parent(has_pcb_position.impl()): - def __init__(self, position_relative: has_pcb_position.Point): +class has_pcb_position_defined_relative_to_parent(F.has_pcb_position.impl()): + def __init__(self, position_relative: F.has_pcb_position.Point): super().__init__() self.position_relative = position_relative - def get_position(self) -> has_pcb_position.Point: + def get_position(self) -> F.has_pcb_position.Point: from faebryk.libs.geometry.basic import Geometry for parent, _ in reversed(self.get_obj().get_hierarchy()[:-1]): - if parent.has_trait(has_pcb_position): - pos = parent.get_trait(has_pcb_position).get_position() + if parent.has_trait(F.has_pcb_position): + pos = parent.get_trait(F.has_pcb_position).get_position() logger.debug( f"Found parent position for: {self.get_obj().get_full_name()}:" f"{pos} [{parent.get_full_name()}]" diff --git a/src/faebryk/library/has_pcb_routing_strategy.py b/src/faebryk/library/has_pcb_routing_strategy.py index ec8588c9..64a8af60 100644 --- a/src/faebryk/library/has_pcb_routing_strategy.py +++ b/src/faebryk/library/has_pcb_routing_strategy.py @@ -3,7 +3,7 @@ from abc import abstractmethod -from faebryk.core.core import Trait +from faebryk.core.trait import Trait from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import Route @@ -13,7 +13,7 @@ class has_pcb_routing_strategy(Trait): @abstractmethod def calculate(self, transformer: PCB_Transformer) -> list[Route]: ... - + def __preinit__(self): self.priority = 0.0 def __repr__(self) -> str: diff --git a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py index d0f5423e..6bc697a8 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py +++ b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py @@ -4,6 +4,7 @@ import logging from enum import Enum, auto +import faebryk.library._F as F from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import ( DEFAULT_TRACE_WIDTH, @@ -13,13 +14,12 @@ get_pads_pos_of_mifs, group_pads_that_are_connected_already, ) - from faebryk.libs.geometry.basic import Geometry logger = logging.getLogger(__name__) -class has_pcb_routing_strategy_greedy_direct_line(has_pcb_routing_strategy.impl()): +class has_pcb_routing_strategy_greedy_direct_line(F.has_pcb_routing_strategy.impl()): class Topology(Enum): STAR = auto() DIRECT = auto() diff --git a/src/faebryk/library/has_pcb_routing_strategy_manual.py b/src/faebryk/library/has_pcb_routing_strategy_manual.py index a022c9e9..b5b092c1 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_manual.py +++ b/src/faebryk/library/has_pcb_routing_strategy_manual.py @@ -3,7 +3,8 @@ import logging -from faebryk.core.core import Node +import faebryk.library._F as F +from faebryk.core.node import Node from faebryk.core.util import get_parent_with_trait from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import ( @@ -13,14 +14,13 @@ get_pads_pos_of_mifs, ) - logger = logging.getLogger(__name__) -class has_pcb_routing_strategy_manual(has_pcb_routing_strategy.impl()): +class has_pcb_routing_strategy_manual(F.has_pcb_routing_strategy.impl()): def __init__( self, - paths: list[tuple[Net | list[F.Electrical], Path]], + paths: list[tuple[F.Net | list[F.Electrical], Path]], relative_to: Node | None = None, absolute: bool = False, ): @@ -39,7 +39,9 @@ def calculate(self, transformer: PCB_Transformer): ) if relative_to: - pos = get_parent_with_trait(relative_to, has_pcb_position)[1].get_position() + pos = get_parent_with_trait(relative_to, F.has_pcb_position)[ + 1 + ].get_position() for _, path in self.paths_rel: path.abs_pos(pos) @@ -56,7 +58,9 @@ def get_route_for_mifs_in_net(mifs, path): for net_or_mifs, path in self.paths_rel if ( route := get_route_for_mifs_in_net( - nets[net_or_mifs] if isinstance(net_or_mifs, Net) else net_or_mifs, + nets[net_or_mifs] + if isinstance(net_or_mifs, F.Net) + else net_or_mifs, path, ) ) diff --git a/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py b/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py index 173041e1..6d2a1088 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py +++ b/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py @@ -3,6 +3,7 @@ import logging +import faebryk.library._F as F from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import ( DEFAULT_TRACE_WIDTH, @@ -14,14 +15,12 @@ get_routes_of_pad, group_pads_that_are_connected_already, ) - - from faebryk.libs.geometry.basic import Geometry logger = logging.getLogger(__name__) -class has_pcb_routing_strategy_via_to_layer(has_pcb_routing_strategy.impl()): +class has_pcb_routing_strategy_via_to_layer(F.has_pcb_routing_strategy.impl()): def __init__(self, layer: str, vec: Geometry.Point2D): super().__init__() self.vec = vec @@ -35,8 +34,8 @@ def calculate(self, transformer: PCB_Transformer): logger.debug(f"Routing {node} {'-'*40}") - def get_route_for_net(net: Net, mifs) -> Route | None: - net_name = net.get_trait(has_overriden_name).get_name() + def get_route_for_net(net: F.Net, mifs) -> Route | None: + net_name = net.get_trait(F.has_overriden_name).get_name() pads = get_pads_pos_of_mifs(mifs) pad_groups = group_pads_that_are_connected_already(pads) diff --git a/src/faebryk/library/has_pin_association_heuristic.py b/src/faebryk/library/has_pin_association_heuristic.py index 522382ea..57cff597 100644 --- a/src/faebryk/library/has_pin_association_heuristic.py +++ b/src/faebryk/library/has_pin_association_heuristic.py @@ -3,6 +3,7 @@ from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.module import Module diff --git a/src/faebryk/library/has_pin_association_heuristic_lookup_table.py b/src/faebryk/library/has_pin_association_heuristic_lookup_table.py index 97ed2601..69027322 100644 --- a/src/faebryk/library/has_pin_association_heuristic_lookup_table.py +++ b/src/faebryk/library/has_pin_association_heuristic_lookup_table.py @@ -3,11 +3,14 @@ import logging +import faebryk.library._F as F logger = logging.getLogger(__name__) -class has_pin_association_heuristic_lookup_table(has_pin_association_heuristic.impl()): +class has_pin_association_heuristic_lookup_table( + F.has_pin_association_heuristic.impl() +): def __init__( self, mapping: dict[F.Electrical, list[str]], @@ -49,7 +52,7 @@ def get_pins( match = (mif, alt_name) break if not match: - raise has_pin_association_heuristic.PinMatchException( + raise F.has_pin_association_heuristic.PinMatchException( f"Could not find a match for pin {number} with name {name}" f" in the mapping {self.mapping}" ) diff --git a/src/faebryk/library/has_resistance.py b/src/faebryk/library/has_resistance.py index 69f70443..35da9994 100644 --- a/src/faebryk/library/has_resistance.py +++ b/src/faebryk/library/has_resistance.py @@ -3,7 +3,8 @@ from abc import abstractmethod -from faebryk.core.module import Module, Parameter +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter class has_resistance(Module.TraitT): diff --git a/src/faebryk/library/has_simple_value_representation_based_on_param.py b/src/faebryk/library/has_simple_value_representation_based_on_param.py index 2613574f..ffcb1829 100644 --- a/src/faebryk/library/has_simple_value_representation_based_on_param.py +++ b/src/faebryk/library/has_simple_value_representation_based_on_param.py @@ -3,11 +3,12 @@ from typing import Callable +import faebryk.library._F as F from faebryk.core.parameter import Parameter class has_simple_value_representation_based_on_param( - has_simple_value_representation.impl() + F.has_simple_value_representation.impl() ): def __init__( self, param: Parameter, transformer: Callable[[F.Constant], str] diff --git a/src/faebryk/library/has_simple_value_representation_based_on_params.py b/src/faebryk/library/has_simple_value_representation_based_on_params.py index f7379a4f..70fa30ab 100644 --- a/src/faebryk/library/has_simple_value_representation_based_on_params.py +++ b/src/faebryk/library/has_simple_value_representation_based_on_params.py @@ -3,11 +3,12 @@ from typing import Callable, Sequence +import faebryk.library._F as F from faebryk.core.parameter import Parameter class has_simple_value_representation_based_on_params( - has_simple_value_representation.impl() + F.has_simple_value_representation.impl() ): def __init__( self, diff --git a/src/faebryk/library/has_simple_value_representation_defined.py b/src/faebryk/library/has_simple_value_representation_defined.py index d12c9e8d..572d28be 100644 --- a/src/faebryk/library/has_simple_value_representation_defined.py +++ b/src/faebryk/library/has_simple_value_representation_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_simple_value_representation_defined(has_simple_value_representation.impl()): + +class has_simple_value_representation_defined(F.has_simple_value_representation.impl()): def __init__(self, value: str) -> None: super().__init__() self.value = value diff --git a/src/faebryk/library/has_single_connection.py b/src/faebryk/library/has_single_connection.py index 75b5df96..6800871d 100644 --- a/src/faebryk/library/has_single_connection.py +++ b/src/faebryk/library/has_single_connection.py @@ -3,9 +3,10 @@ from abc import abstractmethod -from faebryk.core.core import InterfaceTrait, Link +from faebryk.core.link import Link +from faebryk.core.moduleinterface import ModuleInterface -class has_single_connection(InterfaceTrait): +class has_single_connection(ModuleInterface.TraitT): @abstractmethod def get_connection(self) -> Link: ... diff --git a/src/faebryk/library/has_single_connection_impl.py b/src/faebryk/library/has_single_connection_impl.py index f4107820..3a802bac 100644 --- a/src/faebryk/library/has_single_connection_impl.py +++ b/src/faebryk/library/has_single_connection_impl.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_single_connection_impl(has_single_connection.impl()): + +class has_single_connection_impl(F.has_single_connection.impl()): def get_connection(self): conns = self.get_obj().connections assert len(conns) == 1 diff --git a/src/faebryk/library/has_single_electric_reference.py b/src/faebryk/library/has_single_electric_reference.py index fadfd310..f9d23a87 100644 --- a/src/faebryk/library/has_single_electric_reference.py +++ b/src/faebryk/library/has_single_electric_reference.py @@ -4,7 +4,8 @@ from abc import abstractmethod -from faebryk.core.core import Trait +import faebryk.library._F as F +from faebryk.core.trait import Trait class has_single_electric_reference(Trait): diff --git a/src/faebryk/library/has_single_electric_reference_defined.py b/src/faebryk/library/has_single_electric_reference_defined.py index df32335d..dd957dc3 100644 --- a/src/faebryk/library/has_single_electric_reference_defined.py +++ b/src/faebryk/library/has_single_electric_reference_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class has_single_electric_reference_defined(has_single_electric_reference.impl()): + +class has_single_electric_reference_defined(F.has_single_electric_reference.impl()): def __init__(self, reference: F.ElectricPower) -> None: super().__init__() self.reference = reference diff --git a/src/faebryk/library/is_decoupled.py b/src/faebryk/library/is_decoupled.py index f68add7c..4c4dec6a 100644 --- a/src/faebryk/library/is_decoupled.py +++ b/src/faebryk/library/is_decoupled.py @@ -4,9 +4,9 @@ import logging from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.trait import Trait - logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/is_decoupled_nodes.py b/src/faebryk/library/is_decoupled_nodes.py index 19f82f78..0dee2e05 100644 --- a/src/faebryk/library/is_decoupled_nodes.py +++ b/src/faebryk/library/is_decoupled_nodes.py @@ -3,11 +3,12 @@ import logging +import faebryk.library._F as F logger = logging.getLogger(__name__) -class is_decoupled_nodes(is_decoupled.impl()): +class is_decoupled_nodes(F.is_decoupled.impl()): def on_obj_set(self) -> None: assert hasattr(self.get_obj(), "capacitor") diff --git a/src/faebryk/library/is_esphome_bus_defined.py b/src/faebryk/library/is_esphome_bus_defined.py index e3437ef6..1c6b2ed9 100644 --- a/src/faebryk/library/is_esphome_bus_defined.py +++ b/src/faebryk/library/is_esphome_bus_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class is_esphome_bus_defined(is_esphome_bus.impl()): + +class is_esphome_bus_defined(F.is_esphome_bus.impl()): def __init__(self, bus_id: str): super().__init__() self._bus_id = bus_id diff --git a/src/faebryk/library/is_representable_by_single_value_defined.py b/src/faebryk/library/is_representable_by_single_value_defined.py index 5f77b099..3d3410d1 100644 --- a/src/faebryk/library/is_representable_by_single_value_defined.py +++ b/src/faebryk/library/is_representable_by_single_value_defined.py @@ -3,8 +3,12 @@ import typing +import faebryk.library._F as F -class is_representable_by_single_value_defined(is_representable_by_single_value.impl()): + +class is_representable_by_single_value_defined( + F.is_representable_by_single_value.impl() +): def __init__(self, value: typing.Any) -> None: super().__init__() self.value = value diff --git a/src/faebryk/library/is_surge_protected.py b/src/faebryk/library/is_surge_protected.py index 59358cf5..a4a42964 100644 --- a/src/faebryk/library/is_surge_protected.py +++ b/src/faebryk/library/is_surge_protected.py @@ -5,12 +5,12 @@ from abc import abstractmethod from typing import Sequence +import faebryk.library._F as F from faebryk.core.trait import Trait - logger = logging.getLogger(__name__) class is_surge_protected(Trait): @abstractmethod - def get_tvs(self) -> Sequence[TVS]: ... + def get_tvs(self) -> Sequence[F.TVS]: ... diff --git a/src/faebryk/library/is_surge_protected_defined.py b/src/faebryk/library/is_surge_protected_defined.py index 4269d531..1d5129f6 100644 --- a/src/faebryk/library/is_surge_protected_defined.py +++ b/src/faebryk/library/is_surge_protected_defined.py @@ -4,12 +4,13 @@ import logging from typing import Sequence +import faebryk.library._F as F logger = logging.getLogger(__name__) -class is_surge_protected_defined(is_surge_protected.impl()): - def __init__(self, tvss: Sequence[TVS]) -> None: +class is_surge_protected_defined(F.is_surge_protected.impl()): + def __init__(self, tvss: Sequence[F.TVS]) -> None: super().__init__() self.tvss = tvss diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index df6854b0..627af979 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -1,33 +1,30 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - - +from faebryk.libs.library import L class pf_533984002(Module): + # interfaces + pin = L.if_list(2, F.Electrical) + mount = L.if_list(2, F.Electrical) - - # interfaces - - pin = L.if_list(2, F.Electrical) - mount = L.if_list(2, F.Electrical) - + @L.rt_field + def attach_to_footprint(self): x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.pin[0], - "2": x.pin[1], - "3": x.mount[0], - "4": x.mount[1], - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "1": x.pin[0], + "2": x.pin[1], + "3": x.mount[0], + "4": x.mount[1], + } ) - datasheet = L.f_field(F.has_datasheet_defined)("https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/1912111437_SHOU-HAN-1-25-2P_C393945.pdf") + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/1912111437_SHOU-HAN-1-25-2P_C393945.pdf" + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/pf_74AHCT2G125.py b/src/faebryk/library/pf_74AHCT2G125.py index 050d3bd0..8307e8f8 100644 --- a/src/faebryk/library/pf_74AHCT2G125.py +++ b/src/faebryk/library/pf_74AHCT2G125.py @@ -1,12 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - - +from faebryk.libs.library import L from faebryk.libs.units import P @@ -19,39 +16,42 @@ class pf_74AHCT2G125(Module): output to assume a high-impedance OFF-state. """ + # interfaces + power: F.ElectricPower + a: F.ElectricLogic # IN + y: F.ElectricLogic # OUT + oe: F.ElectricLogic # enable, active low - # interfaces - - power: F.ElectricPower - a: F.ElectricLogic # IN - y: F.ElectricLogic # OUT - oe: F.ElectricLogic # enable, active low - + @L.rt_field + def attach_to_footprint(self): x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.oe.signal, - "2": x.a.signal, - "3": x.power.lv, - "4": x.y.signal, - "5": x.power.hv, - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "1": x.oe.signal, + "2": x.a.signal, + "3": x.power.lv, + "4": x.y.signal, + "5": x.power.hv, + } ) + def __preinit__(self): self.power.voltage.merge(F.Range(4.5 * P.V, 5.5 * P.V)) - self.power.decoupled.decouple() - # connect all logic references - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.a, self.y) - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2304140030_Nexperia-74AHCT1G125GV-125_C12494.pdf") + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/2304140030_Nexperia-74AHCT1G125GV-125_C12494.pdf" + ) From 516f846e93e6030f2b93d38ef8464144bc806ea0 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Mon, 26 Aug 2024 22:44:26 +0200 Subject: [PATCH 14/63] Done first pass library --- src/faebryk/core/node.py | 2 +- src/faebryk/library/TD541S485H.py | 66 +++++------ src/faebryk/library/TI_CD4011BE.py | 59 +++++----- src/faebryk/library/TVS.py | 4 +- src/faebryk/library/TXS0102DCUR.py | 45 ++++---- src/faebryk/library/TXS0102DCUR_UART.py | 17 ++- src/faebryk/library/UART.py | 3 +- src/faebryk/library/UART_Base.py | 24 ++-- src/faebryk/library/UART_RS485.py | 26 ++--- src/faebryk/library/USB2514B.py | 81 +++++++------ src/faebryk/library/USB2_0_ESD_Protection.py | 26 ++--- src/faebryk/library/USB3.py | 11 +- src/faebryk/library/USB3_IF.py | 7 +- src/faebryk/library/USB3_connector.py | 16 +-- src/faebryk/library/USBLC6_2P6.py | 36 +++--- src/faebryk/library/USB_C.py | 22 ++-- src/faebryk/library/USB_C_5V_PSU.py | 35 +++--- src/faebryk/library/USB_C_PSU_Vertical.py | 34 +++--- src/faebryk/library/USB_C_PowerOnly.py | 31 +++-- src/faebryk/library/USB_RS485.py | 27 ++--- .../USB_Type_C_Receptacle_14_pin_Vertical.py | 70 ++++++------ .../library/USB_Type_C_Receptacle_16_pin.py | 81 +++++++------ .../library/USB_Type_C_Receptacle_24_pin.py | 107 +++++++++--------- src/faebryk/library/XL_3528RGBW_WS2812B.py | 53 +++++---- 24 files changed, 407 insertions(+), 476 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index dc2ef56a..d830ffb3 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -33,7 +33,7 @@ class FieldContainerError(FieldError): pass -def if_list[T](n: int, if_type: type[T]) -> list[T]: +def if_list[T](n: int, if_type: Callable[[], T]) -> list[T]: return d_field(lambda: times(n, if_type)) diff --git a/src/faebryk/library/TD541S485H.py b/src/faebryk/library/TD541S485H.py index 22e6b011..c4a6cc72 100644 --- a/src/faebryk/library/TD541S485H.py +++ b/src/faebryk/library/TD541S485H.py @@ -3,55 +3,49 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L logger = logging.getLogger(__name__) class TD541S485H(Module): + power: F.ElectricPower + power_iso_in: F.ElectricPower + power_iso_out: F.ElectricPower + uart: F.UART_Base + rs485: F.RS485 + read_enable: F.Electrical + write_enable: F.Electrical + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - - - power: F.ElectricPower - power_iso_in: F.ElectricPower - power_iso_out: F.ElectricPower - uart = F.UART_Base() - rs485 = RS485() - read_enable: F.Electrical - write_enable: F.Electrical - - - + def __preinit__(self): self.power.decoupled.decouple() self.power_iso_in.decoupled.decouple() self.power_iso_out.decoupled.decouple() - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - self.power_iso_in.lv.connect(self.power_iso_out.lv) + @L.rt_field + def attach_to_footprint(self): x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.power.lv, - "2": x.power.hv, - "3": x.uart.rx.signal, - "4": x.read_enable, - "5": x.write_enable, - "6": x.uart.tx.signal, - "7": x.power.hv, - "8": x.power.lv, - "9": x.power_iso_out.lv, - "10": x.power_iso_out.hv, - "13": x.rs485.diff_pair.n, - "14": x.rs485.diff_pair.p, - "15": x.power_iso_in.hv, - "16": x.power_iso_in.lv, - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "1": x.power.lv, + "2": x.power.hv, + "3": x.uart.rx.signal, + "4": x.read_enable, + "5": x.write_enable, + "6": x.uart.tx.signal, + "7": x.power.hv, + "8": x.power.lv, + "9": x.power_iso_out.lv, + "10": x.power_iso_out.hv, + "13": x.rs485.diff_pair.n, + "14": x.rs485.diff_pair.p, + "15": x.power_iso_in.hv, + "16": x.power_iso_in.lv, + } ) diff --git a/src/faebryk/library/TI_CD4011BE.py b/src/faebryk/library/TI_CD4011BE.py index 142f9d3f..9e5d7371 100644 --- a/src/faebryk/library/TI_CD4011BE.py +++ b/src/faebryk/library/TI_CD4011BE.py @@ -2,36 +2,41 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F +from faebryk.libs.library import L from faebryk.libs.picker.picker import DescriptiveProperties from faebryk.libs.units import P -class TI_CD4011BE(CD4011): - fp = DIP(pin_cnt=14, spacing=7.62 * P.mm, long_pads=False) - self.add_trait(F.has_defined_footprint(fp)) - fp.get_trait(can_attach_via_pinmap).attach( - { - "7": self.power.lv, - "14": self.power.hv, - "3": self.gates[0].outputs[0].signal, - "4": self.gates[1].outputs[0].signal, - "11": self.gates[2].outputs[0].signal, - "10": self.gates[3].outputs[0].signal, - "1": self.gates[0].inputs[0].signal, - "2": self.gates[0].inputs[1].signal, - "5": self.gates[1].inputs[0].signal, - "6": self.gates[1].inputs[1].signal, - "12": self.gates[2].inputs[0].signal, - "13": self.gates[2].inputs[1].signal, - "9": self.gates[3].inputs[0].signal, - "8": self.gates[3].inputs[1].signal, - } +class TI_CD4011BE(F.CD4011): + footprint = L.f_field(F.has_footprint_defined)( + F.DIP(pin_cnt=14, spacing=7.62 * P.mm, long_pads=False) ) - has_defined_descriptive_properties.add_properties_to( - self, - { - DescriptiveProperties.manufacturer: "Texas Instruments", - DescriptiveProperties.partno: "CD4011BE", - }, - ) + def __preinit__(self): + self.footprint.get_footprint().get_trait(F.can_attach_via_pinmap).attach( + { + "7": self.power.lv, + "14": self.power.hv, + "3": self.gates[0].outputs[0].signal, + "4": self.gates[1].outputs[0].signal, + "11": self.gates[2].outputs[0].signal, + "10": self.gates[3].outputs[0].signal, + "1": self.gates[0].inputs[0].signal, + "2": self.gates[0].inputs[1].signal, + "5": self.gates[1].inputs[0].signal, + "6": self.gates[1].inputs[1].signal, + "12": self.gates[2].inputs[0].signal, + "13": self.gates[2].inputs[1].signal, + "9": self.gates[3].inputs[0].signal, + "8": self.gates[3].inputs[1].signal, + } + ) + + F.has_defined_descriptive_properties.add_properties_to( + self, + { + DescriptiveProperties.manufacturer: "Texas Instruments", + DescriptiveProperties.partno: "CD4011BE", + }, + ) diff --git a/src/faebryk/library/TVS.py b/src/faebryk/library/TVS.py index 8f2fd68c..205643a5 100644 --- a/src/faebryk/library/TVS.py +++ b/src/faebryk/library/TVS.py @@ -3,11 +3,11 @@ import logging - +import faebryk.library._F as F from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) -class TVS(Diode): +class TVS(F.Diode): reverse_breakdown_voltage: F.TBD[Quantity] diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index 4b0627da..f0789fdf 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -1,11 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - +from faebryk.libs.library import L class TXS0102DCUR(Module): @@ -15,32 +13,25 @@ class TXS0102DCUR(Module): """ class _BidirectionalLevelShifter(Module): - def __init__(self) -> None: - super().__init__() - - # interfaces - - io_a: F.ElectricLogic - io_b: F.ElectricLogic - - # TODO: bridge shallow - @L.rt_field - def can_bridge(self): - return F.can_bridge_defined(self.io_a, self.io_b) - - - # interfaces + io_a: F.ElectricLogic + io_b: F.ElectricLogic - voltage_a_power: F.ElectricPower - voltage_b_power: F.ElectricPower - n_oe: F.ElectricLogic + # TODO: bridge shallow + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.io_a, self.io_b) - shifters = L.if_list(2, self._BidirectionalLevelShifter) + # interfaces + voltage_a_power: F.ElectricPower + voltage_b_power: F.ElectricPower + n_oe: F.ElectricLogic + shifters = L.if_list(2, _BidirectionalLevelShifter) + def __preinit__(self): gnd = self.voltage_a_power.lv gnd.connect(self.voltage_b_power.lv) @@ -54,13 +45,15 @@ def can_bridge(self): side_a = shifter.io_a # side_a.reference.connect(self.voltage_a_power) side_a.add_trait( - has_single_electric_reference_defined(self.voltage_a_power) + F.has_single_electric_reference_defined(self.voltage_a_power) ) side_b = shifter.io_b # side_b.reference.connect(self.voltage_b_power) side_b.add_trait( - has_single_electric_reference_defined(self.voltage_b_power) + F.has_single_electric_reference_defined(self.voltage_b_power) ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/1810292010_Texas-Instruments-TXS0102DCUR_C53434.pdf") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/1810292010_Texas-Instruments-TXS0102DCUR_C53434.pdf" + ) diff --git a/src/faebryk/library/TXS0102DCUR_UART.py b/src/faebryk/library/TXS0102DCUR_UART.py index df10edaa..35541ac3 100644 --- a/src/faebryk/library/TXS0102DCUR_UART.py +++ b/src/faebryk/library/TXS0102DCUR_UART.py @@ -1,7 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.libs.library import L class TXS0102DCUR_UART(Module): @@ -10,17 +12,14 @@ class TXS0102DCUR_UART(Module): - Output enabled by default """ + voltage_a_power: F.ElectricPower + voltage_b_power: F.ElectricPower + voltage_a_bus: F.UART_Base + voltage_b_bus: F.UART_Base + buffer: F.TXS0102DCUR - - voltage_a_power: F.ElectricPower - voltage_b_power: F.ElectricPower - voltage_a_bus = F.UART_Base() - voltage_b_bus = F.UART_Base() - - - buffer = TXS0102DCUR() - + def __preinit__(self): self.voltage_a_power.connect(self.buffer.voltage_a_power) self.voltage_b_power.connect(self.buffer.voltage_b_power) diff --git a/src/faebryk/library/UART.py b/src/faebryk/library/UART.py index d51f3260..e8013ff4 100644 --- a/src/faebryk/library/UART.py +++ b/src/faebryk/library/UART.py @@ -1,11 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface class UART(ModuleInterface): - base_uart = F.UART_Base() + base_uart: F.UART_Base rts: F.Electrical cts: F.Electrical dtr: F.Electrical diff --git a/src/faebryk/library/UART_Base.py b/src/faebryk/library/UART_Base.py index 6e889da6..ecf7a297 100644 --- a/src/faebryk/library/UART_Base.py +++ b/src/faebryk/library/UART_Base.py @@ -1,25 +1,23 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity -class F.UART_Base(ModuleInterface): - - - - rx: F.ElectricLogic - tx: F.ElectricLogic - +class UART_Base(ModuleInterface): + rx: F.ElectricLogic + tx: F.ElectricLogic - baud: F.TBD[Quantity] + baud: F.TBD[Quantity] - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(F.has_single_electric_reference_defined(ref)) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) def _on_connect(self, other: "F.UART_Base"): super()._on_connect(other) diff --git a/src/faebryk/library/UART_RS485.py b/src/faebryk/library/UART_RS485.py index 3d89233b..af6da5ea 100644 --- a/src/faebryk/library/UART_RS485.py +++ b/src/faebryk/library/UART_RS485.py @@ -3,32 +3,26 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import P, Quantity logger = logging.getLogger(__name__) class UART_RS485(Module): + power: F.ElectricPower + uart: F.UART_Base + rs485: F.RS485 + read_enable: F.Electrical + write_enable: F.Electrical + max_data_rate: F.TBD[Quantity] + gpio_voltage: F.TBD[Quantity] - - - - power: F.ElectricPower - uart = F.UART_Base() - rs485 = RS485() - read_enable: F.Electrical - write_enable: F.Electrical - - - max_data_rate : F.TBD[Quantity] - gpio_voltage : F.TBD[Quantity] - + def __preinit__(self): self.power.voltage.merge(F.Range(3.3 * P.V, 5.0 * P.V)) - self.power.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 617fb58f..8c92cdd4 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -4,10 +4,10 @@ import logging from enum import Enum, auto +import faebryk.library._F as F from faebryk.core.module import Module - - - +from faebryk.core.util import get_children +from faebryk.libs.library import L logger = logging.getLogger(__name__) @@ -19,49 +19,44 @@ class InterfaceConfiguration(Enum): BUS_POWERED = auto() EEPROM = auto() + VDD33: F.ElectricPower + VDDA33: F.ElectricPower + PLLFILT: F.ElectricPower + CRFILT: F.ElectricPower + VBUS_DET: F.Electrical + usb_downstream = L.if_list(4, F.DifferentialPair) + usb_upstream = F.DifferentialPair + XTALIN: F.Electrical + XTALOUT: F.Electrical - VDD33: F.ElectricPower - VDDA33: F.ElectricPower - - PLLFILT: F.ElectricPower - CRFILT: F.ElectricPower - - VBUS_DET: F.Electrical - - usb_downstream = L.if_list(4, DifferentialPair) - usb_upstream = DifferentialPair() + TEST: F.Electrical + SUSP_IND: F.ElectricLogic + RESET_N: F.Electrical + RBIAS: F.Electrical + NON_REM = L.if_list(2, F.ElectricLogic) + LOCAL_PWR: F.Electrical + CLKIN: F.Electrical + CFG_SEL = L.if_list(2, F.ElectricLogic) - XTALIN: F.Electrical - XTALOUT: F.Electrical + HS_IND: F.ElectricLogic - TEST: F.Electrical - SUSP_IND: F.ElectricLogic - RESET_N: F.Electrical - RBIAS: F.Electrical - NON_REM = L.if_list(2, F.ElectricLogic) - LOCAL_PWR: F.Electrical - CLKIN: F.Electrical - CFG_SEL = L.if_list(2, F.ElectricLogic) + PRTPWR = L.if_list(4, F.ElectricLogic) + PRT_DIS_P = L.if_list(4, F.ElectricLogic) + PRT_DIS_M = L.if_list(4, F.ElectricLogic) + OCS_N = L.if_list(4, F.ElectricLogic) + BC_EN = L.if_list(4, F.ElectricLogic) - HS_IND: F.ElectricLogic - - PRTPWR = L.if_list(4, F.ElectricLogic) - PRT_DIS_P = L.if_list(4, F.ElectricLogic) - PRT_DIS_M = L.if_list(4, F.ElectricLogic) - OCS_N = L.if_list(4, F.ElectricLogic) - BC_EN = L.if_list(4, F.ElectricLogic) - - i2c = F.I2C() - - - interface_configuration : F.TBD[USB2514B.InterfaceConfiguration] + i2c: F.I2C + gnd: F.Electrical + interface_configuration: F.TBD[F.USB2514B.InterfaceConfiguration] designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + def __preinit__(self): if self.interface_configuration == USB2514B.InterfaceConfiguration.DEFAULT: self.CFG_SEL[0].pulled.pull(up=False) self.CFG_SEL[1].pulled.pull(up=False) @@ -77,14 +72,11 @@ class InterfaceConfiguration(Enum): self.CFG_SEL[0].pulled.pull(up=True) self.CFG_SEL[1].pulled.pull(up=True) - gnd: F.Electrical - # Add decoupling capacitors to power pins and connect all lv to gnd # TODO: decouple with 1.0uF and 0.1uF and maybe 4.7uF - for g in self.get_all(): - if isinstance(g, F.ElectricPower): - g.decoupled.decouple() - g.lv.connect(gnd) + for g in get_children(self, direct_only=True, types=F.ElectricPower): + g.decoupled.decouple() + g.lv.connect(self.gnd) x = self @@ -93,5 +85,8 @@ class InterfaceConfiguration(Enum): x.NON_REM[0].connect(x.SUSP_IND) x.NON_REM[1].connect(x.i2c.sda) - x.RESET_N.connect(gnd) - datasheet = L.f_field(F.has_datasheet_defined)("https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001692C.pdf") + x.RESET_N.connect(self.gnd) + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001692C.pdf" + ) diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index f75e6b4e..d6c58f7d 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -3,36 +3,28 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import P - logger = logging.getLogger(__name__) class USB2_0_ESD_Protection(Module): + usb = L.if_list(2, F.USB2_0) + vbus_esd_protection: F.TBD[bool] + data_esd_protection: F.TBD[bool] - - - - usb = L.if_list(2, USB2_0) - - - vbus_esd_protection : F.TBD[bool] - data_esd_protection : F.TBD[bool] - + def __preinit__(self): self.usb[0].usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.25 * P.V)) + self.usb[0].connect(self.usb[1]) + self.usb[0].usb_if.buspower.connect(self.usb[1].usb_if.buspower) + self.usb[0].usb_if.buspower.decoupled.decouple() @L.rt_field def can_bridge(self): return F.can_bridge_defined(self.usb[0].usb_if.d, self.usb[1].usb_if.d) - self.usb[0].connect(self.usb[1]) - - self.usb[0].usb_if.buspower.connect(self.usb[1].usb_if.buspower) - - self.usb[0].usb_if.buspower.decoupled.decouple() designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/USB3.py b/src/faebryk/library/USB3.py index 2dd45994..c23910e7 100644 --- a/src/faebryk/library/USB3.py +++ b/src/faebryk/library/USB3.py @@ -1,18 +1,15 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - +from faebryk.libs.library import L from faebryk.libs.units import P class USB3(ModuleInterface): + usb3_if: F.USB3_IF - - - usb3_if : USB3_IF - + def __preinit__(self): self.usb3_if.gnd_drain.connect(self.usb3_if.usb_if.buspower.lv) - self.usb3_if.usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.5 * P.V)) diff --git a/src/faebryk/library/USB3_IF.py b/src/faebryk/library/USB3_IF.py index 7c4161f7..ef2c7e20 100644 --- a/src/faebryk/library/USB3_IF.py +++ b/src/faebryk/library/USB3_IF.py @@ -1,11 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface class USB3_IF(ModuleInterface): - usb_if: USB2_0_IF - rx = DifferentialPair() - tx = DifferentialPair() + usb_if: F.USB2_0_IF + rx: F.DifferentialPair + tx: F.DifferentialPair gnd_drain: F.Electrical diff --git a/src/faebryk/library/USB3_connector.py b/src/faebryk/library/USB3_connector.py index 819414f6..13f6c416 100644 --- a/src/faebryk/library/USB3_connector.py +++ b/src/faebryk/library/USB3_connector.py @@ -3,25 +3,19 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import P logger = logging.getLogger(__name__) class USB3_connector(Module): + usb3: F.USB3 + shield: F.Electrical - - - - - usb3 : USB3 - shield: F.Electrical - - - + def __preinit__(self): self.usb3.usb3_if.usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.25 * P.V)) self.usb3.usb3_if.usb_if.buspower.lv.connect(self.usb3.usb3_if.gnd_drain) diff --git a/src/faebryk/library/USBLC6_2P6.py b/src/faebryk/library/USBLC6_2P6.py index 7f902c46..86484a52 100644 --- a/src/faebryk/library/USBLC6_2P6.py +++ b/src/faebryk/library/USBLC6_2P6.py @@ -1,8 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - +from faebryk.libs.library import L class USBLC6_2P6(Module): @@ -10,25 +11,24 @@ class USBLC6_2P6(Module): Low capacitance TVS diode array (for USB2.0) """ + # interfaces + usb: F.USB2_0 - - # interfaces - - usb : USB2_0 - + @L.rt_field + def attach_to_footprint(self): x = self - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": x.usb.usb_if.d.p, - "2": x.usb.usb_if.buspower.lv, - "3": x.usb.usb_if.d.n, - "4": x.usb.usb_if.d.n, - "5": x.usb.usb_if.buspower.hv, - "6": x.usb.usb_if.d.p, - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "1": x.usb.usb_if.d.p, + "2": x.usb.usb_if.buspower.lv, + "3": x.usb.usb_if.d.n, + "4": x.usb.usb_if.d.n, + "5": x.usb.usb_if.buspower.hv, + "6": x.usb.usb_if.d.p, + } ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/2108132230_TECH-PUBLIC-USBLC6-2P6_C2827693.pdf") + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/2108132230_TECH-PUBLIC-USBLC6-2P6_C2827693.pdf" + ) diff --git a/src/faebryk/library/USB_C.py b/src/faebryk/library/USB_C.py index 33315abf..5fa63fee 100644 --- a/src/faebryk/library/USB_C.py +++ b/src/faebryk/library/USB_C.py @@ -1,23 +1,19 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - - +from faebryk.libs.library import L class USB_C(ModuleInterface): - - - - usb3 : USB3 - cc1: F.Electrical - cc2: F.Electrical - sbu1: F.Electrical - sbu2: F.Electrical - rx = DifferentialPair() - tx = DifferentialPair() + usb3: F.USB3 + cc1: F.Electrical + cc2: F.Electrical + sbu1: F.Electrical + sbu2: F.Electrical + rx: F.DifferentialPair + tx: F.DifferentialPair @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index 506df679..2f0950b9 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -1,32 +1,24 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - - +from faebryk.libs.library import L from faebryk.libs.units import P - class USB_C_5V_PSU(Module): - - - # interfaces - - power_out: F.ElectricPower - usb : USB_C - - # components - - configuration_resistors = L.if_list( - 2, - lambda: F.Resistor().builder( - lambda r: r.resistance.merge(F.Constant(5.1 * P.kohm)) - ), - ) + # interfaces + power_out: F.ElectricPower + usb: F.USB_C + + # components + configuration_resistors = L.if_list( + 2, + lambda: F.Resistor().builder( + lambda r: r.resistance.merge(F.Constant(5.1 * P.kohm)) + ), + ) @L.rt_field def single_electric_reference(self): @@ -34,6 +26,7 @@ def single_electric_reference(self): F.ElectricLogic.connect_all_module_references(self) ) + def __preinit__(self): # configure as ufp with 5V@max3A self.usb.cc1.connect_via(self.configuration_resistors[0], self.power_out.lv) self.usb.cc2.connect_via(self.configuration_resistors[1], self.power_out.lv) diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index d38dd957..92ee353b 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -1,40 +1,34 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import connect_all_interfaces - - - +from faebryk.libs.library import L from faebryk.libs.units import P - class USB_C_PSU_Vertical(Module): + # interfaces + power_out: F.ElectricPower + usb: F.USB2_0 + # components - # interfaces - - power_out: F.ElectricPower - usb : USB2_0 - - # components - - usb_connector = ( - USB_Type_C_Receptacle_14_pin_Vertical() - ) # TODO: make generic - configuration_resistors = L.if_list(2, F.Resistor) - gnd_resistor : F.Resistor - gnd_capacitor : F.Capacitor - esd : USB2_0_ESD_Protection - fuse = Fuse() + usb_connector: F.USB_Type_C_Receptacle_14_pin_Vertical # TODO: make generic + configuration_resistors = L.if_list(2, F.Resistor) + gnd_resistor: F.Resistor + gnd_capacitor: F.Capacitor + esd: F.USB2_0_ESD_Protection + fuse: F.Fuse + def __preinit__(self): self.gnd_capacitor.capacitance.merge(100 * P.nF) self.gnd_capacitor.rated_voltage.merge(16 * P.V) self.gnd_resistor.resistance.merge(1 * P.Mohm) for res in self.configuration_resistors: res.resistance.merge(5.1 * P.kohm) - self.fuse.fuse_type.merge(Fuse.FuseType.RESETTABLE) + self.fuse.fuse_type.merge(F.Fuse.FuseType.RESETTABLE) self.fuse.trip_current.merge(F.Constant(1 * P.A)) # alliases diff --git a/src/faebryk/library/USB_C_PowerOnly.py b/src/faebryk/library/USB_C_PowerOnly.py index 14bbf133..02f5f1f6 100644 --- a/src/faebryk/library/USB_C_PowerOnly.py +++ b/src/faebryk/library/USB_C_PowerOnly.py @@ -1,28 +1,23 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface - - - - +from faebryk.libs.library import L class USB_C_PowerOnly(ModuleInterface): + power: F.ElectricPower + cc1: F.Electrical + cc2: F.Electrical - - - power: F.ElectricPower - cc1: F.Electrical - cc2: F.Electrical - - self.add_trait( - can_be_surge_protected_defined( - self.power.lv, - self.power.hv, - self.cc1, - self.cc2, - ) + @L.rt_field + def surge_protected(self): + return F.can_be_surge_protected_defined( + self.power.lv, + self.power.hv, + self.cc1, + self.cc2, ) @L.rt_field @@ -31,7 +26,7 @@ def single_electric_reference(self): F.ElectricLogic.connect_all_module_references(self) ) - def connect_to_full_usb_c(self, usb_c: USB_C): + def connect_to_full_usb_c(self, usb_c: F.USB_C): self.power.connect(usb_c.usb3.usb3_if.usb_if.buspower) self.cc1.connect(usb_c.cc1) self.cc2.connect(usb_c.cc2) diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index 0576f90b..5d37a8e6 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -3,30 +3,23 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module - - +from faebryk.libs.library import L from faebryk.libs.units import P - logger = logging.getLogger(__name__) class USB_RS485(Module): - - - - usb_uart = CH340x() - uart_rs485 = UART_RS485() - termination : F.Resistor - polarization = L.if_list(2, F.Resistor) - - - usb : USB2_0 - rs485 = RS485() - - - + usb_uart: F.CH340x + uart_rs485: F.UART_RS485 + termination: F.Resistor + polarization = L.if_list(2, F.Resistor) + usb: F.USB2_0 + rs485: F.RS485 + + def __preinit__(self): self.usb.connect(self.usb_uart.usb) self.usb_uart.uart.base_uart.connect(self.uart_rs485.uart) self.rs485.connect(self.uart_rs485.rs485) diff --git a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py index 7e454a78..6bc59937 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_14_pin_Vertical.py @@ -1,11 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - +from faebryk.libs.library import L class USB_Type_C_Receptacle_14_pin_Vertical(Module): @@ -14,39 +12,37 @@ class USB_Type_C_Receptacle_14_pin_Vertical(Module): 918-418K2022Y40000 """ - - - # interfaces - - # TODO make arrays? - cc1: F.Electrical - cc2: F.Electrical - shield: F.Electrical - # power - vbus: F.ElectricPower - # diffpairs: p, n - usb : USB2_0 - - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": self.vbus.lv, - "2": self.vbus.hv, - "3": self.usb.usb_if.d.n, - "4": self.usb.usb_if.d.p, - "5": self.cc2, - "6": self.vbus.hv, - "7": self.vbus.lv, - "8": self.vbus.lv, - "9": self.vbus.hv, - "10": self.usb.usb_if.d.n, - "11": self.usb.usb_if.d.p, - "12": self.cc1, - "13": self.vbus.hv, - "14": self.vbus.lv, - "0": self.shield, - } - ) + # interfaces + + # TODO make arrays? + cc1: F.Electrical + cc2: F.Electrical + shield: F.Electrical + # power + vbus: F.ElectricPower + # diffpairs: p, n + usb: F.USB2_0 + + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "1": self.vbus.lv, + "2": self.vbus.hv, + "3": self.usb.usb_if.d.n, + "4": self.usb.usb_if.d.p, + "5": self.cc2, + "6": self.vbus.hv, + "7": self.vbus.lv, + "8": self.vbus.lv, + "9": self.vbus.hv, + "10": self.usb.usb_if.d.n, + "11": self.usb.usb_if.d.p, + "12": self.cc1, + "13": self.vbus.hv, + "14": self.vbus.lv, + "0": self.shield, + } ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py index 794f44cb..5eb5a6dc 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_16_pin.py @@ -2,54 +2,53 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - +from faebryk.libs.library import L class USB_Type_C_Receptacle_16_pin(Module): - - - # interfaces - - # TODO make arrays? - cc1: F.Electrical - cc2: F.Electrical - sbu1: F.Electrical - sbu2: F.Electrical - shield: F.Electrical - # power - power: F.ElectricPower - # ds: p, n - d = DifferentialPair() - + # interfaces + + # TODO make arrays? + cc1: F.Electrical + cc2: F.Electrical + sbu1: F.Electrical + sbu2: F.Electrical + shield: F.Electrical + # power + power: F.ElectricPower + # ds: p, n + d: F.DifferentialPair + + @L.rt_field + def attach_to_footprint(self): vbus = self.power.hv gnd = self.power.lv - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "A1": gnd, - "A4": vbus, - "A5": self.cc1, - "A6": self.d.p, - "A7": self.d.n, - "A8": self.sbu1, - "A9": vbus, - "A12": gnd, - "B1": gnd, - "B4": vbus, - "B5": self.cc2, - "B6": self.d.p, - "B7": self.d.n, - "B8": self.sbu2, - "B9": vbus, - "B12": gnd, - "0": self.shield, - "1": self.shield, - "2": self.shield, - "3": self.shield, - } - ) + return F.can_attach_to_footprint_via_pinmap( + { + "A1": gnd, + "A4": vbus, + "A5": self.cc1, + "A6": self.d.p, + "A7": self.d.n, + "A8": self.sbu1, + "A9": vbus, + "A12": gnd, + "B1": gnd, + "B4": vbus, + "B5": self.cc2, + "B6": self.d.p, + "B7": self.d.n, + "B8": self.sbu2, + "B9": vbus, + "B12": gnd, + "0": self.shield, + "1": self.shield, + "2": self.shield, + "3": self.shield, + } ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py index 6b816427..418f0c4d 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py @@ -1,66 +1,61 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module - - - - - +from faebryk.libs.library import L class USB_Type_C_Receptacle_24_pin(Module): - - - # interfaces - - # TODO make arrays? - cc1: F.Electrical - cc2: F.Electrical - sbu1: F.Electrical - sbu2: F.Electrical - shield: F.Electrical - # power - gnd = L.if_list(4, F.Electrical) - vbus = L.if_list(4, F.Electrical) - # diffpairs: p, n - rx1 = DifferentialPair() - rx2 = DifferentialPair() - tx1 = DifferentialPair() - tx2 = DifferentialPair() - d1 = DifferentialPair() - d2 = DifferentialPair() - - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "A1": self.gnd[0], - "A2": self.tx1.p, - "A3": self.tx1.n, - "A4": self.vbus[0], - "A5": self.cc1, - "A6": self.d1.p, - "A7": self.d1.n, - "A8": self.sbu1, - "A9": self.vbus[1], - "A10": self.rx2.n, - "A11": self.rx2.p, - "A12": self.gnd[1], - "B1": self.gnd[2], - "B2": self.tx2.p, - "B3": self.tx2.n, - "B4": self.vbus[2], - "B5": self.cc2, - "B6": self.d2.p, - "B7": self.d2.n, - "B8": self.sbu2, - "B9": self.vbus[3], - "B10": self.rx1.n, - "B11": self.rx1.p, - "B12": self.gnd[3], - "0": self.shield, - } - ) + # interfaces + + # TODO make arrays? + cc1: F.Electrical + cc2: F.Electrical + sbu1: F.Electrical + sbu2: F.Electrical + shield: F.Electrical + # power + gnd = L.if_list(4, F.Electrical) + vbus = L.if_list(4, F.Electrical) + # diffpairs: p, n + rx1: F.DifferentialPair + rx2: F.DifferentialPair + tx1: F.DifferentialPair + tx2: F.DifferentialPair + d1: F.DifferentialPair + d2: F.DifferentialPair + + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "A1": self.gnd[0], + "A2": self.tx1.p, + "A3": self.tx1.n, + "A4": self.vbus[0], + "A5": self.cc1, + "A6": self.d1.p, + "A7": self.d1.n, + "A8": self.sbu1, + "A9": self.vbus[1], + "A10": self.rx2.n, + "A11": self.rx2.p, + "A12": self.gnd[1], + "B1": self.gnd[2], + "B2": self.tx2.p, + "B3": self.tx2.n, + "B4": self.vbus[2], + "B5": self.cc2, + "B6": self.d2.p, + "B7": self.d2.n, + "B8": self.sbu2, + "B9": self.vbus[3], + "B10": self.rx1.n, + "B11": self.rx1.p, + "B12": self.gnd[3], + "0": self.shield, + } ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index b4bc8282..b0a537b4 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -3,12 +3,15 @@ from dataclasses import dataclass, field -from faebryk.core.module import Module, Parameter +import faebryk.library._F as F +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.libs.library import L class XL_3528RGBW_WS2812B(Module): @dataclass - class _ws2812b_esphome_config(has_esphome_config.impl()): + class _ws2812b_esphome_config(F.has_esphome_config.impl()): update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: @@ -22,7 +25,7 @@ def get_config(self) -> dict: obj = self.get_obj() assert isinstance(obj, XL_3528RGBW_WS2812B), "This is not a WS2812B RGBW!" - data_pin = is_esphome_bus.find_connected_bus(obj.di.signal) + data_pin = F.is_esphome_bus.find_connected_bus(obj.di.signal) return { "light": [ @@ -34,20 +37,22 @@ def get_config(self) -> dict: "chipset": "WS2812", "rgb_order": "RGB", "is_rgbw": "true", - "pin": data_pin.get_trait(is_esphome_bus).get_bus_id(), + "pin": data_pin.get_trait(F.is_esphome_bus).get_bus_id(), } ] } - # interfaces + # interfaces - power: F.ElectricPower - do: F.ElectricLogic - di: F.ElectricLogic + power: F.ElectricPower + do: F.ElectricLogic + di: F.ElectricLogic - # connect all logic references - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(F.has_single_electric_reference_defined(ref)) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("LED") @@ -56,17 +61,19 @@ def get_config(self) -> dict: def can_bridge(self): return F.can_bridge_defined(self.di, self.do) - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": self.power.lv, - "2": self.di.signal, - "3": self.power.hv, - "4": self.do.signal, - } - ) + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "1": self.power.lv, + "2": self.di.signal, + "3": self.power.hv, + "4": self.do.signal, + } ) - datasheet = L.f_field(F.has_datasheet_defined)("https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2402181504_XINGLIGHT-XL-3528RGBW-WS2812B_C2890364.pdf") - self.esphome = self._ws2812b_esphome_config() - self.add_trait(self.esphome) + datasheet = L.f_field(F.has_datasheet_defined)( + "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2402181504_XINGLIGHT-XL-3528RGBW-WS2812B_C2890364.pdf" + ) + + esphome_config: _ws2812b_esphome_config From b6efe01ca6e28708855a8c6a98d239d34923f44c Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Mon, 26 Aug 2024 23:49:04 +0200 Subject: [PATCH 15/63] 2nd pass --- src/faebryk/core/trait.py | 8 +- src/faebryk/library/BH1750FVI_TR.py | 87 +++++++++---------- src/faebryk/library/ESP32.py | 2 +- src/faebryk/library/ESP32_C3.py | 6 +- src/faebryk/library/ElectricLogic.py | 6 +- src/faebryk/library/ElectricPower.py | 16 ++-- src/faebryk/library/HLK_LD2410B_P.py | 2 +- src/faebryk/library/LEDIndicator.py | 19 ++-- src/faebryk/library/LogicGate.py | 16 ++-- src/faebryk/library/PM1006.py | 2 +- src/faebryk/library/SCD40.py | 2 +- src/faebryk/library/SMDTwoPin.py | 2 +- src/faebryk/library/SOIC.py | 2 +- src/faebryk/library/XL_3528RGBW_WS2812B.py | 2 +- .../library/can_attach_to_footprint.py | 1 + .../can_attach_to_footprint_symmetrically.py | 7 +- .../can_attach_to_footprint_via_pinmap.py | 8 +- src/faebryk/library/can_attach_via_pinmap.py | 2 + .../library/can_attach_via_pinmap_equal.py | 7 +- .../library/can_attach_via_pinmap_pinlist.py | 4 +- src/faebryk/library/can_be_decoupled.py | 2 +- .../library/can_be_decoupled_defined.py | 12 +-- src/faebryk/library/can_be_surge_protected.py | 4 +- .../library/can_be_surge_protected_defined.py | 16 ++-- src/faebryk/library/can_bridge_defined.py | 3 +- src/faebryk/library/can_switch_power.py | 4 +- .../library/can_switch_power_defined.py | 4 +- src/faebryk/library/has_equal_pins_in_ifs.py | 4 +- src/faebryk/library/has_footprint_impl.py | 7 +- .../library/has_kicad_footprint_equal_ifs.py | 2 +- src/faebryk/library/has_multi_picker.py | 3 +- src/faebryk/library/has_pcb_layout_defined.py | 2 +- ...pcb_position_defined_relative_to_parent.py | 6 +- ...pcb_routing_strategy_greedy_direct_line.py | 2 +- .../has_pcb_routing_strategy_manual.py | 6 +- .../has_pcb_routing_strategy_via_to_layer.py | 2 +- .../library/has_single_connection_impl.py | 2 +- src/faebryk/library/is_decoupled_nodes.py | 5 +- 38 files changed, 148 insertions(+), 139 deletions(-) diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index 13eb91fa..f6c05bf4 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -3,9 +3,8 @@ import logging from abc import ABC -from deprecated import deprecated - from faebryk.core.node import Node +from faebryk.libs.util import cast_assert logger = logging.getLogger(__name__) @@ -57,9 +56,8 @@ def obj(self) -> Node: raise Exception("trait is not linked to node") return p[0] - @deprecated("Use obj property") - def get_obj(self) -> Node: - return self.obj + def get_obj[T: Node](self, type: type[T]) -> T: + return cast_assert(type, self.obj) def cmp(self, other: "TraitImpl") -> tuple[bool, "TraitImpl"]: assert type(other), TraitImpl diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 27a60c6b..4f13f1b9 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -5,7 +5,9 @@ from dataclasses import dataclass, field import faebryk.library._F as F -from faebryk.core.module import Module, Parameter +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.libs.library import L from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -13,7 +15,7 @@ class BH1750FVI_TR(Module): @dataclass - class _bh1750_esphome_config(has_esphome_config.impl()): + class _bh1750_esphome_config(F.has_esphome_config.impl()): update_interval_s: Parameter = field(default_factory=F.TBD) def __post_init__(self) -> None: @@ -24,10 +26,10 @@ def get_config(self) -> dict: self.update_interval_s, F.Constant ), "No update interval set!" - obj = self.get_obj() + obj = self.obj assert isinstance(obj, BH1750FVI_TR) - i2c = is_esphome_bus.find_connected_bus(obj.i2c) + i2c = F.is_esphome_bus.find_connected_bus(obj.i2c) return { "sensor": [ @@ -35,12 +37,21 @@ def get_config(self) -> dict: "platform": "bh1750", "name": "BH1750 Illuminance", "address": "0x23", - "i2c_id": i2c.get_trait(is_esphome_bus).get_bus_id(), + "i2c_id": i2c.get_trait(F.is_esphome_bus).get_bus_id(), "update_interval": f"{self.update_interval_s.value}s", } ] } + dvi_capacitor: F.Capacitor + dvi_resistor: F.Resistor + + power: F.ElectricPower + addr: F.ElectricLogic + dvi: F.ElectricLogic + ep: F.ElectricLogic + i2c: F.I2C + def set_address(self, addr: int): raise NotImplementedError() # ADDR = ‘H’ ( ADDR ≧ 0.7VCC ) “1011100“ @@ -51,21 +62,9 @@ def set_address(self, addr: int): # for i, e in enumerate(self.e): # e.set(addr & (1 << i) != 0) + esphome_config: _bh1750_esphome_config - - - dvi_capacitor : F.Capacitor - dvi_resistor : F.Resistor - - - power: F.ElectricPower - addr: F.ElectricLogic - dvi: F.ElectricLogic - ep: F.ElectricLogic - i2c = F.I2C() - - - + def __preinit__(self): self.dvi_capacitor.capacitance.merge(1 * P.uF) self.dvi_resistor.resistance.merge(1 * P.kohm) @@ -75,34 +74,34 @@ def set_address(self, addr: int): F.I2C.define_max_frequency_capability(F.I2C.SpeedMode.fast_speed) ) - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - self.add_trait( - can_attach_to_footprint_via_pinmap( - { - "1": self.power.hv, - "2": self.addr.signal, - "3": self.power.lv, - "4": self.i2c.sda.signal, - "5": self.dvi.signal, - "6": self.i2c.scl.signal, - "7": self.ep.signal, - } - ) - ) - datasheet = L.f_field(F.has_datasheet_defined)("https://datasheet.lcsc.com/lcsc/1811081611_ROHM-Semicon-BH1750FVI-TR_C78960.pdf") - # set constraints self.power.voltage.merge(F.Range(2.4 * P.V, 3.6 * P.V)) - # internal connections - ref = F.ElectricLogic.connect_all_module_references(self) - self.add_trait(F.has_single_electric_reference_defined(ref)) - ref.connect(self.power) - self.power.decoupled.decouple().capacitance.merge(0.1 * P.uF) # TODO: self.dvi.low_pass(self.IF.dvi_capacitor, self.IF.dvi_resistor) - # self.i2c.add_trait(is_esphome_bus.impl()()) - self.esphome = self._bh1750_esphome_config() - self.add_trait(self.esphome) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) + + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") + + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "1": self.power.hv, + "2": self.addr.signal, + "3": self.power.lv, + "4": self.i2c.sda.signal, + "5": self.dvi.signal, + "6": self.i2c.scl.signal, + "7": self.ep.signal, + } + ) + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://datasheet.lcsc.com/lcsc/1811081611_ROHM-Semicon-BH1750FVI-TR_C78960.pdf" + ) diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index 924edf20..4b684736 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -240,7 +240,7 @@ def get_gpio(self, idx: int): class _ESP32_D0WD(ESP32): - footprint: F.Footprint = L.f_field(F.has_footprint_defined)( + footprint = L.f_field(F.has_footprint_defined)( F.QFN( pin_cnt=48, size_xy=(5 * P.mm, 5 * P.mm), diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 58dbd789..c91a4c62 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -41,7 +41,7 @@ def __preinit__(self): # https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#uart for ser in x.uart: - ser.baud.merge(F.Range(0, 5000000)) + ser.baud.merge(F.Range(0 * P.baud, 5000000 * P.baud)) # connect all logic references # TODO: set correctly for each power domain @@ -107,7 +107,7 @@ def __preinit__(self): # class _uart_esphome_config(has_esphome_config.impl()): # def get_config(self_) -> dict: # assert isinstance(self, ESP32_C3) - # obj = self_.get_obj() + # obj = self_.obj # assert isinstance(obj, F.UART_Base) # config = { # "uart": [ @@ -137,7 +137,7 @@ def __preinit__(self): # class _i2c_esphome_config(has_esphome_config.impl()): # def get_config(self_) -> dict: # assert isinstance(self, ESP32_C3) - # obj = self_.get_obj() + # obj = self_.obj # assert isinstance(obj, F.I2C) # try: diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index d979ba9e..9d198ada 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -18,7 +18,7 @@ class has_pulls(F.Logic.TraitT): @abstractmethod def get_pulls(self) -> tuple[F.Resistor | None, F.Resistor | None]: ... - class has_pulls_defined(F.has_pulls.impl()): + class has_pulls_defined(has_pulls.impl()): def __init__(self, up: F.Resistor | None, down: F.Resistor | None) -> None: super().__init__() self.up = up @@ -38,7 +38,7 @@ def __init__(self, signal: F.Electrical, ref: F.ElectricPower) -> None: self.signal = signal def pull(self, up: bool): - obj = self.get_obj() + obj = self.obj up_r, down_r = None, None if obj.has_trait(F.ElectricLogic.has_pulls): @@ -74,7 +74,7 @@ def pull(self, up: bool): # self.signal = signal # # def buffer(self): - # obj = self.get_obj() + # obj = self.obj # # if hasattr(obj, "buffer"): # return cast_assert(SignalBuffer, getattr(obj, "buffer")) diff --git a/src/faebryk/library/ElectricPower.py b/src/faebryk/library/ElectricPower.py index 9fd43830..665009fa 100644 --- a/src/faebryk/library/ElectricPower.py +++ b/src/faebryk/library/ElectricPower.py @@ -13,16 +13,16 @@ class can_be_decoupled_power(F.can_be_decoupled_defined): def __init__(self) -> None: ... def on_obj_set(self): - super().__init__(hv=self.get_obj().hv, lv=self.get_obj().lv) + obj = self.get_obj(ElectricPower) + super().__init__(hv=obj.hv, lv=obj.lv) def decouple(self): + obj = self.get_obj(ElectricPower) return ( super() .decouple() .builder( - lambda c: c.rated_voltage.merge( - F.Range(0 * P.V, self.get_obj().voltage * 2.0) - ) + lambda c: c.rated_voltage.merge(F.Range(0 * P.V, obj.voltage * 2.0)) ) ) @@ -30,13 +30,13 @@ class can_be_surge_protected_power(F.can_be_surge_protected_defined): def __init__(self) -> None: ... def on_obj_set(self): - super().__init__(self.get_obj().lv, self.get_obj().hv) + obj = self.get_obj(ElectricPower) + super().__init__(obj.lv, obj.hv) def protect(self): + obj = self.get_obj(ElectricPower) return [ - tvs.builder( - lambda t: t.reverse_working_voltage.merge(self.get_obj().voltage) - ) + tvs.builder(lambda t: t.reverse_working_voltage.merge(obj.voltage)) for tvs in super().protect() ] diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index ee743c1a..1aaac33d 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -18,7 +18,7 @@ class _ld2410b_esphome_config(F.has_esphome_config.impl()): def get_config(self) -> dict: assert isinstance(self.throttle_ms, F.Constant), "No update interval set!" - obj = self.get_obj() + obj = self.obj assert isinstance(obj, HLK_LD2410B_P), "This is not an HLK_LD2410B_P!" uart_candidates = { diff --git a/src/faebryk/library/LEDIndicator.py b/src/faebryk/library/LEDIndicator.py index ea8c420c..fa1f66bb 100644 --- a/src/faebryk/library/LEDIndicator.py +++ b/src/faebryk/library/LEDIndicator.py @@ -1,21 +1,24 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT + +import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.libs.library import L class LEDIndicator(Module): + # interfaces + logic_in: F.ElectricLogic + power_in: F.ElectricPower - # interfaces - - logic_in: F.ElectricLogic - power_in: F.ElectricPower + # components - # components + led: F.PoweredLED - led = PoweredLED() - # TODO make generic - power_switch = PowerSwitchMOSFET(lowside=True, normally_closed=False) + # TODO make generic + power_switch = L.f_field(F.PowerSwitchMOSFET)(lowside=True, normally_closed=False) + def __preinit__(self): self.power_in.connect_via(self.power_switch, self.led.power) self.power_switch.logic_in.connect(self.logic_in) diff --git a/src/faebryk/library/LogicGate.py b/src/faebryk/library/LogicGate.py index eb60f01c..731741ee 100644 --- a/src/faebryk/library/LogicGate.py +++ b/src/faebryk/library/LogicGate.py @@ -13,37 +13,37 @@ class LogicGate(Module): class can_logic_or_gate(F.LogicOps.can_logic_or.impl()): def on_obj_set(self) -> None: - assert isinstance(self.get_obj(), LogicGate) + assert isinstance(self.obj, LogicGate) def or_(self, *ins: F.Logic): - obj = self.get_obj() + obj = self.obj assert isinstance(obj, LogicGate) return obj.op(*ins)[0] class can_logic_nor_gate(F.LogicOps.can_logic_nor.impl()): def on_obj_set(self) -> None: - assert isinstance(self.get_obj(), LogicGate) + assert isinstance(self.obj, LogicGate) def nor(self, *ins: F.Logic): - obj = self.get_obj() + obj = self.obj assert isinstance(obj, LogicGate) return obj.op(*ins)[0] class can_logic_nand_gate(F.LogicOps.can_logic_nand.impl()): def on_obj_set(self) -> None: - assert isinstance(self.get_obj(), LogicGate) + assert isinstance(self.obj, LogicGate) def nand(self, *ins: F.Logic): - obj = self.get_obj() + obj = self.obj assert isinstance(obj, LogicGate) return obj.op(*ins)[0] class can_logic_xor_gate(F.LogicOps.can_logic_xor.impl()): def on_obj_set(self) -> None: - assert isinstance(self.get_obj(), LogicGate) + assert isinstance(self.obj, LogicGate) def xor(self, *ins: F.Logic): - obj = self.get_obj() + obj = self.obj assert isinstance(obj, LogicGate) return obj.op(*ins)[0] diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index a994c010..8734f1ae 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -39,7 +39,7 @@ def get_config(self) -> dict: self.update_interval_s, F.Constant ), "No update interval set!" - obj = self.get_obj() + obj = self.obj assert isinstance(obj, PM1006), "This is not an PM1006!" uart = F.is_esphome_bus.find_connected_bus(obj.data) diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index b4c048d8..dc261384 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -24,7 +24,7 @@ def get_config(self) -> dict: self.update_interval_s, F.Constant ), "No update interval set!" - obj = self.get_obj() + obj = self.obj assert isinstance(obj, SCD40) i2c = F.is_esphome_bus.find_connected_bus(obj.i2c) diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index 5551481a..15a160a7 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -28,7 +28,7 @@ def __init__(self, type: Type) -> None: class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): def get_kicad_footprint(self) -> str: - obj = self.get_obj() + obj = self.obj assert isinstance(obj, SMDTwoPin) table = { SMDTwoPin.Type._01005: "0402", diff --git a/src/faebryk/library/SOIC.py b/src/faebryk/library/SOIC.py index 4829975d..81254336 100644 --- a/src/faebryk/library/SOIC.py +++ b/src/faebryk/library/SOIC.py @@ -26,7 +26,7 @@ def pins(self): class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): def get_kicad_footprint(self) -> str: - obj = self.get_obj() + obj = self.obj assert isinstance(obj, SOIC) return "Package_SO:SOIC-{leads}_{size_x:.1f}x{size_y:.1f}mm_P{pitch:.2f}mm".format( # noqa: E501 leads=obj._pin_cnt, diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index b0a537b4..615b16b2 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -22,7 +22,7 @@ def get_config(self) -> dict: self.update_interval_s, F.Constant ), "No update interval set!" - obj = self.get_obj() + obj = self.obj assert isinstance(obj, XL_3528RGBW_WS2812B), "This is not a WS2812B RGBW!" data_pin = F.is_esphome_bus.find_connected_bus(obj.di.signal) diff --git a/src/faebryk/library/can_attach_to_footprint.py b/src/faebryk/library/can_attach_to_footprint.py index bb645092..2c118c24 100644 --- a/src/faebryk/library/can_attach_to_footprint.py +++ b/src/faebryk/library/can_attach_to_footprint.py @@ -3,6 +3,7 @@ from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.module import Module diff --git a/src/faebryk/library/can_attach_to_footprint_symmetrically.py b/src/faebryk/library/can_attach_to_footprint_symmetrically.py index 70ff1f97..a6ebf7e9 100644 --- a/src/faebryk/library/can_attach_to_footprint_symmetrically.py +++ b/src/faebryk/library/can_attach_to_footprint_symmetrically.py @@ -1,15 +1,16 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.util import zip_children_by_name -class can_attach_to_footprint_symmetrically(can_attach_to_footprint.impl()): +class can_attach_to_footprint_symmetrically(F.can_attach_to_footprint.impl()): def attach(self, footprint: F.Footprint): - self.get_obj().add_trait(F.has_defined_footprint(footprint)) + self.obj.add_trait(F.has_footprint_defined(footprint)) - for i, j in zip_children_by_name(footprint, self.get_obj(), ModuleInterface): + for i, j in zip_children_by_name(footprint, self.obj, ModuleInterface): assert isinstance(i, F.Pad) assert isinstance(j, F.Electrical) assert type(i.net) is type(j) diff --git a/src/faebryk/library/can_attach_to_footprint_via_pinmap.py b/src/faebryk/library/can_attach_to_footprint_via_pinmap.py index 36dc149b..3e9b022e 100644 --- a/src/faebryk/library/can_attach_to_footprint_via_pinmap.py +++ b/src/faebryk/library/can_attach_to_footprint_via_pinmap.py @@ -1,12 +1,14 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class can_attach_to_footprint_via_pinmap(can_attach_to_footprint.impl()): + +class can_attach_to_footprint_via_pinmap(F.can_attach_to_footprint.impl()): def __init__(self, pinmap: dict[str, F.Electrical]) -> None: super().__init__() self.pinmap = pinmap def attach(self, footprint: F.Footprint): - self.get_obj().add_trait(F.has_defined_footprint(footprint)) - footprint.get_trait(can_attach_via_pinmap).attach(self.pinmap) + self.obj.add_trait(F.has_footprint_defined(footprint)) + footprint.get_trait(F.can_attach_via_pinmap).attach(self.pinmap) diff --git a/src/faebryk/library/can_attach_via_pinmap.py b/src/faebryk/library/can_attach_via_pinmap.py index a1ec9b0e..bc1b9334 100644 --- a/src/faebryk/library/can_attach_via_pinmap.py +++ b/src/faebryk/library/can_attach_via_pinmap.py @@ -3,6 +3,8 @@ from abc import abstractmethod +import faebryk.library._F as F + class can_attach_via_pinmap(F.Footprint.TraitT): @abstractmethod diff --git a/src/faebryk/library/can_attach_via_pinmap_equal.py b/src/faebryk/library/can_attach_via_pinmap_equal.py index d6224692..5ec3d392 100644 --- a/src/faebryk/library/can_attach_via_pinmap_equal.py +++ b/src/faebryk/library/can_attach_via_pinmap_equal.py @@ -1,12 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class can_attach_via_pinmap_equal(can_attach_via_pinmap.impl()): + +class can_attach_via_pinmap_equal(F.can_attach_via_pinmap.impl()): def attach(self, pinmap: dict[str, F.Electrical]): pin_list = { - v: k - for k, v in self.get_obj().get_trait(F.has_equal_pins).get_pin_map().items() + v: k for k, v in self.obj.get_trait(F.has_equal_pins).get_pin_map().items() } for no, intf in pinmap.items(): pin_list[no].attach(intf) diff --git a/src/faebryk/library/can_attach_via_pinmap_pinlist.py b/src/faebryk/library/can_attach_via_pinmap_pinlist.py index af51b059..5fad9689 100644 --- a/src/faebryk/library/can_attach_via_pinmap_pinlist.py +++ b/src/faebryk/library/can_attach_via_pinmap_pinlist.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class can_attach_via_pinmap_pinlist(can_attach_via_pinmap.impl()): + +class can_attach_via_pinmap_pinlist(F.can_attach_via_pinmap.impl()): def __init__(self, pin_list: dict[str, F.Pad]) -> None: super().__init__() self.pin_list = pin_list diff --git a/src/faebryk/library/can_be_decoupled.py b/src/faebryk/library/can_be_decoupled.py index 84912ae4..703cd8aa 100644 --- a/src/faebryk/library/can_be_decoupled.py +++ b/src/faebryk/library/can_be_decoupled.py @@ -4,9 +4,9 @@ import logging from abc import abstractmethod +import faebryk.library._F as F from faebryk.core.trait import Trait - logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/can_be_decoupled_defined.py b/src/faebryk/library/can_be_decoupled_defined.py index ed89daaa..228d292c 100644 --- a/src/faebryk/library/can_be_decoupled_defined.py +++ b/src/faebryk/library/can_be_decoupled_defined.py @@ -3,25 +3,25 @@ import logging +import faebryk.library._F as F logger = logging.getLogger(__name__) -class can_be_decoupled_defined(can_be_decoupled.impl()): +class can_be_decoupled_defined(F.can_be_decoupled.impl()): def __init__(self, hv: F.Electrical, lv: F.Electrical) -> None: super().__init__() self.hv = hv self.lv = lv def decouple(self): - obj = self.get_obj() + obj = self.obj - capacitor: F.Capacitor - obj.add(capacitor, "capacitor") + capacitor = obj.add(F.Capacitor(), "capacitor") self.hv.connect_via(capacitor, self.lv) - obj.add_trait(is_decoupled_nodes()) + obj.add_trait(F.is_decoupled_nodes()) return capacitor def is_implemented(self): - return not self.get_obj().has_trait(is_decoupled) + return not self.obj.has_trait(F.is_decoupled) diff --git a/src/faebryk/library/can_be_surge_protected.py b/src/faebryk/library/can_be_surge_protected.py index 5514f551..db161dae 100644 --- a/src/faebryk/library/can_be_surge_protected.py +++ b/src/faebryk/library/can_be_surge_protected.py @@ -5,12 +5,12 @@ from abc import abstractmethod from typing import Sequence +import faebryk.library._F as F from faebryk.core.trait import Trait - logger = logging.getLogger(__name__) class can_be_surge_protected(Trait): @abstractmethod - def protect(self) -> Sequence[TVS]: ... + def protect(self) -> Sequence[F.TVS]: ... diff --git a/src/faebryk/library/can_be_surge_protected_defined.py b/src/faebryk/library/can_be_surge_protected_defined.py index bd7bde1e..77ba53e8 100644 --- a/src/faebryk/library/can_be_surge_protected_defined.py +++ b/src/faebryk/library/can_be_surge_protected_defined.py @@ -3,31 +3,31 @@ import logging +import faebryk.library._F as F logger = logging.getLogger(__name__) -class can_be_surge_protected_defined(can_be_surge_protected.impl()): +class can_be_surge_protected_defined(F.can_be_surge_protected.impl()): def __init__(self, low_potential: F.Electrical, *protect_if: F.Electrical) -> None: super().__init__() self.protect_if = protect_if self.low_potential = low_potential def protect(self): - obj = self.get_obj() + obj = self.obj tvss = [] for protect_if in self.protect_if: - if protect_if.has_trait(can_be_surge_protected): - tvss.extend(protect_if.get_trait(can_be_surge_protected).protect()) + if protect_if.has_trait(F.can_be_surge_protected): + tvss.extend(protect_if.get_trait(F.can_be_surge_protected).protect()) else: - tvs = TVS() - protect_if.add(tvs, "tvs") + tvs = protect_if.add(F.TVS(), "tvs") protect_if.connect_via(tvs, self.low_potential) tvss.append(tvs) - obj.add_trait(is_surge_protected_defined(tvss)) + obj.add_trait(F.is_surge_protected_defined(tvss)) return tvss def is_implemented(self): - return not self.get_obj().has_trait(is_surge_protected) + return not self.obj.has_trait(F.is_surge_protected) diff --git a/src/faebryk/library/can_bridge_defined.py b/src/faebryk/library/can_bridge_defined.py index d2f9c0cb..3104c5b5 100644 --- a/src/faebryk/library/can_bridge_defined.py +++ b/src/faebryk/library/can_bridge_defined.py @@ -1,10 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -class can_bridge_defined(can_bridge.impl()): +class can_bridge_defined(F.can_bridge.impl()): def __init__(self, in_if: ModuleInterface, out_if: ModuleInterface) -> None: super().__init__() self.get_in = lambda: in_if diff --git a/src/faebryk/library/can_switch_power.py b/src/faebryk/library/can_switch_power.py index cb328da6..86893f74 100644 --- a/src/faebryk/library/can_switch_power.py +++ b/src/faebryk/library/can_switch_power.py @@ -3,7 +3,9 @@ from abc import abstractmethod +import faebryk.library._F as F -class can_switch_power(can_bridge): + +class can_switch_power(F.can_bridge): @abstractmethod def get_logic_in(self) -> F.ElectricLogic: ... diff --git a/src/faebryk/library/can_switch_power_defined.py b/src/faebryk/library/can_switch_power_defined.py index 60223fa1..5feffed5 100644 --- a/src/faebryk/library/can_switch_power_defined.py +++ b/src/faebryk/library/can_switch_power_defined.py @@ -1,8 +1,10 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +import faebryk.library._F as F -class can_switch_power_defined(can_switch_power.impl()): + +class can_switch_power_defined(F.can_switch_power.impl()): def __init__( self, in_power: F.ElectricPower, diff --git a/src/faebryk/library/has_equal_pins_in_ifs.py b/src/faebryk/library/has_equal_pins_in_ifs.py index 08710bde..08c0d671 100644 --- a/src/faebryk/library/has_equal_pins_in_ifs.py +++ b/src/faebryk/library/has_equal_pins_in_ifs.py @@ -2,12 +2,12 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F +from faebryk.core.util import get_children class has_equal_pins_in_ifs(F.has_equal_pins.impl()): def get_pin_map(self): return { p: str(i + 1) - for i, p in enumerate(self.get_obj().get_all()) - if isinstance(p, F.Pad) + for i, p in enumerate(get_children(self.obj, direct_only=True, types=F.Pad)) } diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index c950d598..e3ae8b5c 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -1,19 +1,16 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from abc import abstractmethod - import faebryk.library._F as F from faebryk.core.link import LinkNamedParent class has_footprint_impl(F.has_footprint.impl()): - @abstractmethod def set_footprint(self, fp: F.Footprint): - self.get_obj().children.connect(fp.parent, LinkNamedParent.curry("footprint")) + self.obj.children.connect(fp.parent, LinkNamedParent.curry("footprint")) def get_footprint(self) -> F.Footprint: - children = self.get_obj().children.get_children() + children = self.obj.children.get_children() fps = [c for _, c in children if isinstance(c, F.Footprint)] assert len(fps) == 1, f"candidates: {fps}" return fps[0] diff --git a/src/faebryk/library/has_kicad_footprint_equal_ifs.py b/src/faebryk/library/has_kicad_footprint_equal_ifs.py index 57d57be1..900bcd5f 100644 --- a/src/faebryk/library/has_kicad_footprint_equal_ifs.py +++ b/src/faebryk/library/has_kicad_footprint_equal_ifs.py @@ -6,4 +6,4 @@ class has_kicad_footprint_equal_ifs(F.has_kicad_footprint.impl()): def get_pin_names(self): - return self.get_obj().get_trait(F.has_equal_pins).get_pin_map() + return self.obj.get_trait(F.has_equal_pins).get_pin_map() diff --git a/src/faebryk/library/has_multi_picker.py b/src/faebryk/library/has_multi_picker.py index 1af34502..c8c759a6 100644 --- a/src/faebryk/library/has_multi_picker.py +++ b/src/faebryk/library/has_multi_picker.py @@ -15,8 +15,7 @@ class has_multi_picker(F.has_picker.impl()): def pick(self): - module = self.get_obj() - assert isinstance(module, Module) + module = self.get_obj(Module) es = [] for _, picker in self.pickers: logger.debug(f"Trying picker for {module}: {picker}") diff --git a/src/faebryk/library/has_pcb_layout_defined.py b/src/faebryk/library/has_pcb_layout_defined.py index 8cfea49d..44b7b1b6 100644 --- a/src/faebryk/library/has_pcb_layout_defined.py +++ b/src/faebryk/library/has_pcb_layout_defined.py @@ -12,5 +12,5 @@ def __init__(self, layout: Layout) -> None: self.layout = layout def apply(self): - node = self.get_obj() + node = self.obj return self.layout.apply(node) diff --git a/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py b/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py index 14d77b16..72a6b029 100644 --- a/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py +++ b/src/faebryk/library/has_pcb_position_defined_relative_to_parent.py @@ -16,11 +16,11 @@ def __init__(self, position_relative: F.has_pcb_position.Point): def get_position(self) -> F.has_pcb_position.Point: from faebryk.libs.geometry.basic import Geometry - for parent, _ in reversed(self.get_obj().get_hierarchy()[:-1]): + for parent, _ in reversed(self.obj.get_hierarchy()[:-1]): if parent.has_trait(F.has_pcb_position): pos = parent.get_trait(F.has_pcb_position).get_position() logger.debug( - f"Found parent position for: {self.get_obj().get_full_name()}:" + f"Found parent position for: {self.obj.get_full_name()}:" f"{pos} [{parent.get_full_name()}]" ) return Geometry.abs_pos( @@ -28,6 +28,6 @@ def get_position(self) -> F.has_pcb_position.Point: self.position_relative, ) raise Exception( - f"Component of type {type(self.get_obj())} with relative to parent position" + f"Component of type {type(self.obj)} with relative to parent position" " has no (valid) parent" ) diff --git a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py index 6bc697a8..8e3286ae 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py +++ b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py @@ -30,7 +30,7 @@ def __init__(self, topology: Topology = Topology.DIRECT, priority: float = 0.0): self.topology = topology def calculate(self, transformer: PCB_Transformer): - node = self.get_obj() + node = self.obj nets = get_internal_nets_of_node(node) logger.debug(f"Routing {node} {'-'*40}") diff --git a/src/faebryk/library/has_pcb_routing_strategy_manual.py b/src/faebryk/library/has_pcb_routing_strategy_manual.py index b5b092c1..c2307395 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_manual.py +++ b/src/faebryk/library/has_pcb_routing_strategy_manual.py @@ -31,12 +31,10 @@ def __init__( self.absolute = absolute def calculate(self, transformer: PCB_Transformer): - node = self.get_obj() + node = self.obj nets = get_internal_nets_of_node(node) - relative_to = ( - (self.relative_to or self.get_obj()) if not self.absolute else None - ) + relative_to = (self.relative_to or self.obj) if not self.absolute else None if relative_to: pos = get_parent_with_trait(relative_to, F.has_pcb_position)[ diff --git a/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py b/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py index 6d2a1088..559079f9 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py +++ b/src/faebryk/library/has_pcb_routing_strategy_via_to_layer.py @@ -29,7 +29,7 @@ def __init__(self, layer: str, vec: Geometry.Point2D): def calculate(self, transformer: PCB_Transformer): layer = transformer.get_layer_id(self.layer) - node = self.get_obj() + node = self.obj nets = get_internal_nets_of_node(node) logger.debug(f"Routing {node} {'-'*40}") diff --git a/src/faebryk/library/has_single_connection_impl.py b/src/faebryk/library/has_single_connection_impl.py index 3a802bac..833e3ae4 100644 --- a/src/faebryk/library/has_single_connection_impl.py +++ b/src/faebryk/library/has_single_connection_impl.py @@ -6,6 +6,6 @@ class has_single_connection_impl(F.has_single_connection.impl()): def get_connection(self): - conns = self.get_obj().connections + conns = self.obj.connections assert len(conns) == 1 return conns[0] diff --git a/src/faebryk/library/is_decoupled_nodes.py b/src/faebryk/library/is_decoupled_nodes.py index 0dee2e05..5fae541a 100644 --- a/src/faebryk/library/is_decoupled_nodes.py +++ b/src/faebryk/library/is_decoupled_nodes.py @@ -4,13 +4,14 @@ import logging import faebryk.library._F as F +from faebryk.libs.util import cast_assert logger = logging.getLogger(__name__) class is_decoupled_nodes(F.is_decoupled.impl()): def on_obj_set(self) -> None: - assert hasattr(self.get_obj(), "capacitor") + assert "capacitor" in self.obj.runtime def get_capacitor(self) -> F.Capacitor: - return self.get_obj().capacitor + return cast_assert(F.Capacitor, self.obj.runtime["capacitor"]) From ee99e9a408cf8d7cadce81897c5a984de43a0e4e Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Mon, 26 Aug 2024 23:53:53 +0200 Subject: [PATCH 16/63] ruff --- src/faebryk/library/Battery.py | 1 - src/faebryk/library/Inductor.py | 62 +++++++++------------ src/faebryk/library/RS485_Bus_Protection.py | 1 - src/faebryk/library/Range.py | 2 - src/faebryk/library/SPI.py | 1 - src/faebryk/library/TXS0102DCUR_UART.py | 1 - src/faebryk/library/USB3.py | 1 - src/faebryk/libs/library/L.py | 12 +++- 8 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/faebryk/library/Battery.py b/src/faebryk/library/Battery.py index 688f3dd6..21c1f2d0 100644 --- a/src/faebryk/library/Battery.py +++ b/src/faebryk/library/Battery.py @@ -3,7 +3,6 @@ import faebryk.library._F as F -import faebryk.libs.library.L as L from faebryk.core.module import Module from faebryk.libs.units import Quantity diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index 0f27f7e6..6a58f5d9 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -2,60 +2,50 @@ # SPDX-License-Identifier: MIT +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import ( as_unit, as_unit_with_tolerance, ) - - - - - +from faebryk.libs.library import L from faebryk.libs.units import Quantity - class Inductor(Module): - def __init__( - self, - ): - super().__init__() - + unnamed = L.if_list(2, F.Electrical) - unnamed = L.if_list(2, F.Electrical) + inductance: F.TBD[Quantity] + self_resonant_frequency: F.TBD[Quantity] + rated_current: F.TBD[Quantity] + dc_resistance: F.TBD[Quantity] @L.rt_field def can_bridge(self): return F.can_bridge_defined(*self.unnamed) + attach_to_footprint: F.can_attach_to_footprint_symmetrically - inductance : F.TBD[Quantity] - self_resonant_frequency : F.TBD[Quantity] - rated_current : F.TBD[Quantity] - dc_resistance : F.TBD[Quantity] - - self.add_trait(can_attach_to_footprint_symmetrically()) @L.rt_field def simple_value_representation(self): return F.has_simple_value_representation_based_on_params( - ( - self.inductance, - self.self_resonant_frequency, - self.rated_current, - self.dc_resistance, - ), - lambda ps: " ".join( - filter( - None, - [ - as_unit_with_tolerance(ps[0], "H"), - as_unit(ps[1], "Hz"), - as_unit(ps[2], "A"), - as_unit(ps[3], "Ω"), - ], - ) - ), - ) + ( + self.inductance, + self.self_resonant_frequency, + self.rated_current, + self.dc_resistance, + ), + lambda ps: " ".join( + filter( + None, + [ + as_unit_with_tolerance(ps[0], "H"), + as_unit(ps[1], "Hz"), + as_unit(ps[2], "A"), + as_unit(ps[3], "Ω"), + ], + ) + ), ) + designator_prefix = L.f_field(F.has_designator_prefix_defined)("L") diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 87730197..7744ebb6 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -10,7 +10,6 @@ from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy from faebryk.libs.library import L from faebryk.libs.units import P -from faebryk.libs.util import times logger = logging.getLogger(__name__) diff --git a/src/faebryk/library/Range.py b/src/faebryk/library/Range.py index 76ec57cc..37928733 100644 --- a/src/faebryk/library/Range.py +++ b/src/faebryk/library/Range.py @@ -4,9 +4,7 @@ from math import inf from typing import Any, Protocol, Self -import faebryk.library._F as F from faebryk.core.parameter import Parameter -from faebryk.libs.library import L class _SupportsRangeOps(Protocol): diff --git a/src/faebryk/library/SPI.py b/src/faebryk/library/SPI.py index b786ef3e..c7c2307b 100644 --- a/src/faebryk/library/SPI.py +++ b/src/faebryk/library/SPI.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.libs.library import L class SPI(ModuleInterface): diff --git a/src/faebryk/library/TXS0102DCUR_UART.py b/src/faebryk/library/TXS0102DCUR_UART.py index 35541ac3..b9eec658 100644 --- a/src/faebryk/library/TXS0102DCUR_UART.py +++ b/src/faebryk/library/TXS0102DCUR_UART.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.libs.library import L class TXS0102DCUR_UART(Module): diff --git a/src/faebryk/library/USB3.py b/src/faebryk/library/USB3.py index c23910e7..09be9d81 100644 --- a/src/faebryk/library/USB3.py +++ b/src/faebryk/library/USB3.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.libs.library import L from faebryk.libs.units import P diff --git a/src/faebryk/libs/library/L.py b/src/faebryk/libs/library/L.py index 4cc902a5..16f40cf9 100644 --- a/src/faebryk/libs/library/L.py +++ b/src/faebryk/libs/library/L.py @@ -3,7 +3,13 @@ import logging -logger = logging.getLogger(__name__) +from faebryk.core.module import Module # noqa: F401 +from faebryk.core.node import ( # noqa: F401 + Node, + d_field, + f_field, + if_list, + rt_field, +) -from faebryk.core.module import Module -from faebryk.core.node import Node, d_field, f_field, if_list, rt_field +logger = logging.getLogger(__name__) From 0e415f87315cdaa0b96b569bef4d9afb14453ac7 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Mon, 26 Aug 2024 23:59:34 +0200 Subject: [PATCH 17/63] gen_F try --- src/faebryk/library/_F.py | 796 ++++++++++++++++++++++++++++---------- tools/library/gen_F.py | 7 +- 2 files changed, 603 insertions(+), 200 deletions(-) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 7f0238a4..44f8cf87 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,202 +15,600 @@ # flake8: noqa: I001 # flake8: noqa: E501 -from faebryk.library.ANY import ANY -from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF -from faebryk.library.BH1750FVI_TR import BH1750FVI_TR -from faebryk.library.BJT import BJT -from faebryk.library.Battery import Battery -from faebryk.library.Button import Button -from faebryk.library.ButtonCell import ButtonCell -from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG -from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design -from faebryk.library.CD4011 import CD4011 -from faebryk.library.CH340x import CH340x -from faebryk.library.Capacitor import Capacitor -from faebryk.library.Common_Mode_Filter import Common_Mode_Filter -from faebryk.library.Comparator import Comparator -from faebryk.library.Constant import Constant -from faebryk.library.Crystal import Crystal -from faebryk.library.Crystal_Oscillator import Crystal_Oscillator -from faebryk.library.DIP import DIP -from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.Diode import Diode -from faebryk.library.EEPROM import EEPROM -from faebryk.library.ESP32 import ESP32 -from faebryk.library.ESP32_C3 import ESP32_C3 -from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 -from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.ElectricLogicGate import ElectricLogicGate -from faebryk.library.ElectricLogicGates import ElectricLogicGates -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.Electrical import Electrical -from faebryk.library.Ethernet import Ethernet -from faebryk.library.Fan import Fan -from faebryk.library.Footprint import Footprint -from faebryk.library.Fuse import Fuse -from faebryk.library.GDT import GDT -from faebryk.library.GenericBusProtection import GenericBusProtection -from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P -from faebryk.library.Header import Header -from faebryk.library.I2C import I2C -from faebryk.library.Inductor import Inductor -from faebryk.library.JTAG import JTAG -from faebryk.library.KicadFootprint import KicadFootprint -from faebryk.library.LDO import LDO -from faebryk.library.LED import LED -from faebryk.library.LEDIndicator import LEDIndicator -from faebryk.library.Logic import Logic -from faebryk.library.Logic74xx import Logic74xx -from faebryk.library.LogicGate import LogicGate -from faebryk.library.LogicGates import LogicGates -from faebryk.library.LogicOps import LogicOps -from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP -from faebryk.library.MCP2221A import MCP2221A -from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N -from faebryk.library.MOSFET import MOSFET -from faebryk.library.Mechanical import Mechanical -from faebryk.library.Mounting_Hole import Mounting_Hole -from faebryk.library.MultiSPI import MultiSPI -from faebryk.library.Net import Net -from faebryk.library.OLED_Module import OLED_Module -from faebryk.library.OpAmp import OpAmp -from faebryk.library.Operation import Operation -from faebryk.library.PJ398SM import PJ398SM -from faebryk.library.PM1006 import PM1006 -from faebryk.library.Pad import Pad -from faebryk.library.Potentiometer import Potentiometer -from faebryk.library.Power import Power -from faebryk.library.PowerSwitch import PowerSwitch -from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET -from faebryk.library.PowerSwitchStatic import PowerSwitchStatic -from faebryk.library.PoweredLED import PoweredLED -from faebryk.library.Powered_Relay import Powered_Relay -from faebryk.library.QFN import QFN -from faebryk.library.QWIIC import QWIIC -from faebryk.library.QWIIC_Connector import QWIIC_Connector -from faebryk.library.RJ45_Receptacle import RJ45_Receptacle -from faebryk.library.RP2040 import RP2040 -from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design -from faebryk.library.RS232 import RS232 -from faebryk.library.RS485 import RS485 -from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection -from faebryk.library.Range import Range -from faebryk.library.Relay import Relay -from faebryk.library.Resistor import Resistor -from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider -from faebryk.library.SCD40 import SCD40 -from faebryk.library.SK9822_EC20 import SK9822_EC20 -from faebryk.library.SMDTwoPin import SMDTwoPin -from faebryk.library.SNx4LVC541A import SNx4LVC541A -from faebryk.library.SOIC import SOIC -from faebryk.library.SPI import SPI -from faebryk.library.SPIFlash import SPIFlash -from faebryk.library.SWD import SWD -from faebryk.library.SWDConnector import SWDConnector -from faebryk.library.Sercom import Sercom -from faebryk.library.Set import Set -from faebryk.library.Switch import Switch -from faebryk.library.TBD import TBD -from faebryk.library.TD541S485H import TD541S485H -from faebryk.library.TI_CD4011BE import TI_CD4011BE -from faebryk.library.TVS import TVS -from faebryk.library.TXS0102DCUR import TXS0102DCUR -from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART -from faebryk.library.UART import UART -from faebryk.library.UART_Base import UART_Base -from faebryk.library.UART_RS485 import UART_RS485 -from faebryk.library.USB2514B import USB2514B -from faebryk.library.USB2_0 import USB2_0 -from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection -from faebryk.library.USB2_0_IF import USB2_0_IF -from faebryk.library.USB3 import USB3 -from faebryk.library.USB3_IF import USB3_IF -from faebryk.library.USB3_connector import USB3_connector -from faebryk.library.USBLC6_2P6 import USBLC6_2P6 -from faebryk.library.USB_C import USB_C -from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU -from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical -from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly -from faebryk.library.USB_RS485 import USB_RS485 -from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical -from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin -from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin -from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically -from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap -from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined -from faebryk.library.can_be_surge_protected import can_be_surge_protected -from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined -from faebryk.library.can_bridge import can_bridge -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.can_switch_power import can_switch_power -from faebryk.library.can_switch_power_defined import can_switch_power_defined -from faebryk.library.has_capacitance import has_capacitance -from faebryk.library.has_datasheet import has_datasheet -from faebryk.library.has_datasheet_defined import has_datasheet_defined -from faebryk.library.has_defined_capacitance import has_defined_capacitance -from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties -from faebryk.library.has_footprint_defined import has_footprint_defined -from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref -from faebryk.library.has_defined_resistance import has_defined_resistance -from faebryk.library.has_descriptive_properties import has_descriptive_properties -from faebryk.library.has_designator import has_designator -from faebryk.library.has_designator_defined import has_designator_defined -from faebryk.library.has_designator_prefix import has_designator_prefix -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_equal_pins import has_equal_pins -from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_footprint_impl import has_footprint_impl -from faebryk.library.has_footprint_requirement import has_footprint_requirement -from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined -from faebryk.library.has_kicad_footprint import has_kicad_footprint -from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs -from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined -from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint -from faebryk.library.has_kicad_ref import has_kicad_ref -from faebryk.library.has_linked_pad import has_linked_pad -from faebryk.library.has_linked_pad_defined import has_linked_pad_defined -from faebryk.library.has_multi_picker import has_multi_picker -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.has_pcb_layout import has_pcb_layout -from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative -from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent -from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual -from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer -from faebryk.library.has_picker import has_picker -from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic -from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table -from faebryk.library.has_resistance import has_resistance -from faebryk.library.has_simple_value_representation import has_simple_value_representation -from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params -from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined -from faebryk.library.has_single_connection import has_single_connection -from faebryk.library.has_single_connection_impl import has_single_connection_impl -from faebryk.library.has_single_electric_reference import has_single_electric_reference -from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined -from faebryk.library.is_decoupled import is_decoupled -from faebryk.library.is_decoupled_nodes import is_decoupled_nodes -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -from faebryk.library.is_representable_by_single_value import is_representable_by_single_value -from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined -from faebryk.library.is_surge_protected import is_surge_protected -from faebryk.library.is_surge_protected_defined import is_surge_protected_defined -from faebryk.library.pf_533984002 import pf_533984002 -from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 +try: + from faebryk.library.ANY import ANY +except AttributeError: ... +try: + from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF +except AttributeError: ... +try: + from faebryk.library.BH1750FVI_TR import BH1750FVI_TR +except AttributeError: ... +try: + from faebryk.library.BJT import BJT +except AttributeError: ... +try: + from faebryk.library.Battery import Battery +except AttributeError: ... +try: + from faebryk.library.Button import Button +except AttributeError: ... +try: + from faebryk.library.ButtonCell import ButtonCell +except AttributeError: ... +try: + from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG +except AttributeError: ... +try: + from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design +except AttributeError: ... +try: + from faebryk.library.CD4011 import CD4011 +except AttributeError: ... +try: + from faebryk.library.CH340x import CH340x +except AttributeError: ... +try: + from faebryk.library.Capacitor import Capacitor +except AttributeError: ... +try: + from faebryk.library.Common_Mode_Filter import Common_Mode_Filter +except AttributeError: ... +try: + from faebryk.library.Comparator import Comparator +except AttributeError: ... +try: + from faebryk.library.Constant import Constant +except AttributeError: ... +try: + from faebryk.library.Crystal import Crystal +except AttributeError: ... +try: + from faebryk.library.Crystal_Oscillator import Crystal_Oscillator +except AttributeError: ... +try: + from faebryk.library.DIP import DIP +except AttributeError: ... +try: + from faebryk.library.DifferentialPair import DifferentialPair +except AttributeError: ... +try: + from faebryk.library.Diode import Diode +except AttributeError: ... +try: + from faebryk.library.EEPROM import EEPROM +except AttributeError: ... +try: + from faebryk.library.ESP32 import ESP32 +except AttributeError: ... +try: + from faebryk.library.ESP32_C3 import ESP32_C3 +except AttributeError: ... +try: + from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 +except AttributeError: ... +try: + from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design +except AttributeError: ... +try: + from faebryk.library.ElectricLogic import ElectricLogic +except AttributeError: ... +try: + from faebryk.library.ElectricLogicGate import ElectricLogicGate +except AttributeError: ... +try: + from faebryk.library.ElectricLogicGates import ElectricLogicGates +except AttributeError: ... +try: + from faebryk.library.ElectricPower import ElectricPower +except AttributeError: ... +try: + from faebryk.library.Electrical import Electrical +except AttributeError: ... +try: + from faebryk.library.Ethernet import Ethernet +except AttributeError: ... +try: + from faebryk.library.Fan import Fan +except AttributeError: ... +try: + from faebryk.library.Footprint import Footprint +except AttributeError: ... +try: + from faebryk.library.Fuse import Fuse +except AttributeError: ... +try: + from faebryk.library.GDT import GDT +except AttributeError: ... +try: + from faebryk.library.GenericBusProtection import GenericBusProtection +except AttributeError: ... +try: + from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P +except AttributeError: ... +try: + from faebryk.library.Header import Header +except AttributeError: ... +try: + from faebryk.library.I2C import I2C +except AttributeError: ... +try: + from faebryk.library.Inductor import Inductor +except AttributeError: ... +try: + from faebryk.library.JTAG import JTAG +except AttributeError: ... +try: + from faebryk.library.KicadFootprint import KicadFootprint +except AttributeError: ... +try: + from faebryk.library.LDO import LDO +except AttributeError: ... +try: + from faebryk.library.LED import LED +except AttributeError: ... +try: + from faebryk.library.LEDIndicator import LEDIndicator +except AttributeError: ... +try: + from faebryk.library.Logic import Logic +except AttributeError: ... +try: + from faebryk.library.Logic74xx import Logic74xx +except AttributeError: ... +try: + from faebryk.library.LogicGate import LogicGate +except AttributeError: ... +try: + from faebryk.library.LogicGates import LogicGates +except AttributeError: ... +try: + from faebryk.library.LogicOps import LogicOps +except AttributeError: ... +try: + from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP +except AttributeError: ... +try: + from faebryk.library.MCP2221A import MCP2221A +except AttributeError: ... +try: + from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N +except AttributeError: ... +try: + from faebryk.library.MOSFET import MOSFET +except AttributeError: ... +try: + from faebryk.library.Mechanical import Mechanical +except AttributeError: ... +try: + from faebryk.library.Mounting_Hole import Mounting_Hole +except AttributeError: ... +try: + from faebryk.library.MultiSPI import MultiSPI +except AttributeError: ... +try: + from faebryk.library.Net import Net +except AttributeError: ... +try: + from faebryk.library.OLED_Module import OLED_Module +except AttributeError: ... +try: + from faebryk.library.OpAmp import OpAmp +except AttributeError: ... +try: + from faebryk.library.Operation import Operation +except AttributeError: ... +try: + from faebryk.library.PJ398SM import PJ398SM +except AttributeError: ... +try: + from faebryk.library.PM1006 import PM1006 +except AttributeError: ... +try: + from faebryk.library.Pad import Pad +except AttributeError: ... +try: + from faebryk.library.Potentiometer import Potentiometer +except AttributeError: ... +try: + from faebryk.library.Power import Power +except AttributeError: ... +try: + from faebryk.library.PowerSwitch import PowerSwitch +except AttributeError: ... +try: + from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET +except AttributeError: ... +try: + from faebryk.library.PowerSwitchStatic import PowerSwitchStatic +except AttributeError: ... +try: + from faebryk.library.PoweredLED import PoweredLED +except AttributeError: ... +try: + from faebryk.library.Powered_Relay import Powered_Relay +except AttributeError: ... +try: + from faebryk.library.QFN import QFN +except AttributeError: ... +try: + from faebryk.library.QWIIC import QWIIC +except AttributeError: ... +try: + from faebryk.library.QWIIC_Connector import QWIIC_Connector +except AttributeError: ... +try: + from faebryk.library.RJ45_Receptacle import RJ45_Receptacle +except AttributeError: ... +try: + from faebryk.library.RP2040 import RP2040 +except AttributeError: ... +try: + from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design +except AttributeError: ... +try: + from faebryk.library.RS232 import RS232 +except AttributeError: ... +try: + from faebryk.library.RS485 import RS485 +except AttributeError: ... +try: + from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection +except AttributeError: ... +try: + from faebryk.library.Range import Range +except AttributeError: ... +try: + from faebryk.library.Relay import Relay +except AttributeError: ... +try: + from faebryk.library.Resistor import Resistor +except AttributeError: ... +try: + from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider +except AttributeError: ... +try: + from faebryk.library.SCD40 import SCD40 +except AttributeError: ... +try: + from faebryk.library.SK9822_EC20 import SK9822_EC20 +except AttributeError: ... +try: + from faebryk.library.SMDTwoPin import SMDTwoPin +except AttributeError: ... +try: + from faebryk.library.SNx4LVC541A import SNx4LVC541A +except AttributeError: ... +try: + from faebryk.library.SOIC import SOIC +except AttributeError: ... +try: + from faebryk.library.SPI import SPI +except AttributeError: ... +try: + from faebryk.library.SPIFlash import SPIFlash +except AttributeError: ... +try: + from faebryk.library.SWD import SWD +except AttributeError: ... +try: + from faebryk.library.SWDConnector import SWDConnector +except AttributeError: ... +try: + from faebryk.library.Sercom import Sercom +except AttributeError: ... +try: + from faebryk.library.Set import Set +except AttributeError: ... +try: + from faebryk.library.Switch import Switch +except AttributeError: ... +try: + from faebryk.library.TBD import TBD +except AttributeError: ... +try: + from faebryk.library.TD541S485H import TD541S485H +except AttributeError: ... +try: + from faebryk.library.TI_CD4011BE import TI_CD4011BE +except AttributeError: ... +try: + from faebryk.library.TVS import TVS +except AttributeError: ... +try: + from faebryk.library.TXS0102DCUR import TXS0102DCUR +except AttributeError: ... +try: + from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART +except AttributeError: ... +try: + from faebryk.library.UART import UART +except AttributeError: ... +try: + from faebryk.library.UART_Base import UART_Base +except AttributeError: ... +try: + from faebryk.library.UART_RS485 import UART_RS485 +except AttributeError: ... +try: + from faebryk.library.USB2514B import USB2514B +except AttributeError: ... +try: + from faebryk.library.USB2_0 import USB2_0 +except AttributeError: ... +try: + from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection +except AttributeError: ... +try: + from faebryk.library.USB2_0_IF import USB2_0_IF +except AttributeError: ... +try: + from faebryk.library.USB3 import USB3 +except AttributeError: ... +try: + from faebryk.library.USB3_IF import USB3_IF +except AttributeError: ... +try: + from faebryk.library.USB3_connector import USB3_connector +except AttributeError: ... +try: + from faebryk.library.USBLC6_2P6 import USBLC6_2P6 +except AttributeError: ... +try: + from faebryk.library.USB_C import USB_C +except AttributeError: ... +try: + from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU +except AttributeError: ... +try: + from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical +except AttributeError: ... +try: + from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly +except AttributeError: ... +try: + from faebryk.library.USB_RS485 import USB_RS485 +except AttributeError: ... +try: + from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical +except AttributeError: ... +try: + from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin +except AttributeError: ... +try: + from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin +except AttributeError: ... +try: + from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B +except AttributeError: ... +try: + from faebryk.library.can_attach_to_footprint import can_attach_to_footprint +except AttributeError: ... +try: + from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically +except AttributeError: ... +try: + from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap +except AttributeError: ... +try: + from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap +except AttributeError: ... +try: + from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal +except AttributeError: ... +try: + from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist +except AttributeError: ... +try: + from faebryk.library.can_be_decoupled import can_be_decoupled +except AttributeError: ... +try: + from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined +except AttributeError: ... +try: + from faebryk.library.can_be_surge_protected import can_be_surge_protected +except AttributeError: ... +try: + from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined +except AttributeError: ... +try: + from faebryk.library.can_bridge import can_bridge +except AttributeError: ... +try: + from faebryk.library.can_bridge_defined import can_bridge_defined +except AttributeError: ... +try: + from faebryk.library.can_switch_power import can_switch_power +except AttributeError: ... +try: + from faebryk.library.can_switch_power_defined import can_switch_power_defined +except AttributeError: ... +try: + from faebryk.library.has_capacitance import has_capacitance +except AttributeError: ... +try: + from faebryk.library.has_datasheet import has_datasheet +except AttributeError: ... +try: + from faebryk.library.has_datasheet_defined import has_datasheet_defined +except AttributeError: ... +try: + from faebryk.library.has_defined_capacitance import has_defined_capacitance +except AttributeError: ... +try: + from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties +except AttributeError: ... +try: + from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref +except AttributeError: ... +try: + from faebryk.library.has_defined_resistance import has_defined_resistance +except AttributeError: ... +try: + from faebryk.library.has_descriptive_properties import has_descriptive_properties +except AttributeError: ... +try: + from faebryk.library.has_designator import has_designator +except AttributeError: ... +try: + from faebryk.library.has_designator_defined import has_designator_defined +except AttributeError: ... +try: + from faebryk.library.has_designator_prefix import has_designator_prefix +except AttributeError: ... +try: + from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined +except AttributeError: ... +try: + from faebryk.library.has_equal_pins import has_equal_pins +except AttributeError: ... +try: + from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs +except AttributeError: ... +try: + from faebryk.library.has_esphome_config import has_esphome_config +except AttributeError: ... +try: + from faebryk.library.has_esphome_config_defined import has_esphome_config_defined +except AttributeError: ... +try: + from faebryk.library.has_footprint import has_footprint +except AttributeError: ... +try: + from faebryk.library.has_footprint_defined import has_footprint_defined +except AttributeError: ... +try: + from faebryk.library.has_footprint_impl import has_footprint_impl +except AttributeError: ... +try: + from faebryk.library.has_footprint_requirement import has_footprint_requirement +except AttributeError: ... +try: + from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined +except AttributeError: ... +try: + from faebryk.library.has_kicad_footprint import has_kicad_footprint +except AttributeError: ... +try: + from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs +except AttributeError: ... +try: + from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined +except AttributeError: ... +try: + from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint +except AttributeError: ... +try: + from faebryk.library.has_kicad_ref import has_kicad_ref +except AttributeError: ... +try: + from faebryk.library.has_linked_pad import has_linked_pad +except AttributeError: ... +try: + from faebryk.library.has_linked_pad_defined import has_linked_pad_defined +except AttributeError: ... +try: + from faebryk.library.has_multi_picker import has_multi_picker +except AttributeError: ... +try: + from faebryk.library.has_overriden_name import has_overriden_name +except AttributeError: ... +try: + from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +except AttributeError: ... +try: + from faebryk.library.has_pcb_layout import has_pcb_layout +except AttributeError: ... +try: + from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined +except AttributeError: ... +try: + from faebryk.library.has_pcb_position import has_pcb_position +except AttributeError: ... +try: + from faebryk.library.has_pcb_position_defined import has_pcb_position_defined +except AttributeError: ... +try: + from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative +except AttributeError: ... +try: + from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent +except AttributeError: ... +try: + from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy +except AttributeError: ... +try: + from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line +except AttributeError: ... +try: + from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual +except AttributeError: ... +try: + from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer +except AttributeError: ... +try: + from faebryk.library.has_picker import has_picker +except AttributeError: ... +try: + from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic +except AttributeError: ... +try: + from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table +except AttributeError: ... +try: + from faebryk.library.has_resistance import has_resistance +except AttributeError: ... +try: + from faebryk.library.has_simple_value_representation import has_simple_value_representation +except AttributeError: ... +try: + from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param +except AttributeError: ... +try: + from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params +except AttributeError: ... +try: + from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined +except AttributeError: ... +try: + from faebryk.library.has_single_connection import has_single_connection +except AttributeError: ... +try: + from faebryk.library.has_single_connection_impl import has_single_connection_impl +except AttributeError: ... +try: + from faebryk.library.has_single_electric_reference import has_single_electric_reference +except AttributeError: ... +try: + from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined +except AttributeError: ... +try: + from faebryk.library.is_decoupled import is_decoupled +except AttributeError: ... +try: + from faebryk.library.is_decoupled_nodes import is_decoupled_nodes +except AttributeError: ... +try: + from faebryk.library.is_esphome_bus import is_esphome_bus +except AttributeError: ... +try: + from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined +except AttributeError: ... +try: + from faebryk.library.is_representable_by_single_value import is_representable_by_single_value +except AttributeError: ... +try: + from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined +except AttributeError: ... +try: + from faebryk.library.is_surge_protected import is_surge_protected +except AttributeError: ... +try: + from faebryk.library.is_surge_protected_defined import is_surge_protected_defined +except AttributeError: ... +try: + from faebryk.library.pf_533984002 import pf_533984002 +except AttributeError: ... +try: + from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 +except AttributeError: ... diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index 4601923a..0b92f883 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -43,6 +43,11 @@ def main(): logger.info(f"Found {len(modules_out)} classes") + def try_(stmt: str, exc: str | type[Exception]): + if isinstance(exc, type): + exc = exc.__name__ + return f"try:\n {stmt}\nexcept {exc}: ..." + OUT.write_text( "# This file is part of the faebryk project\n" "# SPDX-License-Identifier: MIT\n" @@ -62,7 +67,7 @@ def main(): "# flake8: noqa: E501\n" "\n" + "\n".join( - f"from faebryk.library.{module} import {class_}" + try_(f"from faebryk.library.{module} import {class_}", AttributeError) for module, class_ in sorted(modules_out.items(), key=lambda x: x[0]) ) + "\n" From 2e0f7ceaf97ec8327eed5e266cb7591dbff470a9 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 00:03:35 +0200 Subject: [PATCH 18/63] gen_F fix --- src/faebryk/library/_F.py | 398 +++++++++++++++++++------------------- tools/library/gen_F.py | 11 +- 2 files changed, 208 insertions(+), 201 deletions(-) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 44f8cf87..f8a62660 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -17,598 +17,598 @@ try: from faebryk.library.ANY import ANY -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.BH1750FVI_TR import BH1750FVI_TR -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.BJT import BJT -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Battery import Battery -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Button import Button -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ButtonCell import ButtonCell -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.CD4011 import CD4011 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.CH340x import CH340x -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Capacitor import Capacitor -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Common_Mode_Filter import Common_Mode_Filter -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Comparator import Comparator -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Constant import Constant -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Crystal import Crystal -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Crystal_Oscillator import Crystal_Oscillator -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.DIP import DIP -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.DifferentialPair import DifferentialPair -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Diode import Diode -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.EEPROM import EEPROM -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ESP32 import ESP32 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ESP32_C3 import ESP32_C3 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ElectricLogic import ElectricLogic -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ElectricLogicGate import ElectricLogicGate -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ElectricLogicGates import ElectricLogicGates -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ElectricPower import ElectricPower -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Electrical import Electrical -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Ethernet import Ethernet -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Fan import Fan -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Footprint import Footprint -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Fuse import Fuse -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.GDT import GDT -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.GenericBusProtection import GenericBusProtection -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Header import Header -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.I2C import I2C -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Inductor import Inductor -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.JTAG import JTAG -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.KicadFootprint import KicadFootprint -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.LDO import LDO -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.LED import LED -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.LEDIndicator import LEDIndicator -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Logic import Logic -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Logic74xx import Logic74xx -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.LogicGate import LogicGate -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.LogicGates import LogicGates -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.LogicOps import LogicOps -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.MCP2221A import MCP2221A -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.MOSFET import MOSFET -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Mechanical import Mechanical -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Mounting_Hole import Mounting_Hole -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.MultiSPI import MultiSPI -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Net import Net -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.OLED_Module import OLED_Module -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.OpAmp import OpAmp -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Operation import Operation -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.PJ398SM import PJ398SM -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.PM1006 import PM1006 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Pad import Pad -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Potentiometer import Potentiometer -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Power import Power -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.PowerSwitch import PowerSwitch -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.PowerSwitchStatic import PowerSwitchStatic -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.PoweredLED import PoweredLED -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Powered_Relay import Powered_Relay -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.QFN import QFN -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.QWIIC import QWIIC -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.QWIIC_Connector import QWIIC_Connector -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.RJ45_Receptacle import RJ45_Receptacle -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.RP2040 import RP2040 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.RS232 import RS232 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.RS485 import RS485 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Range import Range -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Relay import Relay -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Resistor import Resistor -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SCD40 import SCD40 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SK9822_EC20 import SK9822_EC20 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SMDTwoPin import SMDTwoPin -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SNx4LVC541A import SNx4LVC541A -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SOIC import SOIC -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SPI import SPI -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SPIFlash import SPIFlash -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SWD import SWD -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.SWDConnector import SWDConnector -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Sercom import Sercom -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Set import Set -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.Switch import Switch -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.TBD import TBD -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.TD541S485H import TD541S485H -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.TI_CD4011BE import TI_CD4011BE -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.TVS import TVS -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.TXS0102DCUR import TXS0102DCUR -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.UART import UART -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.UART_Base import UART_Base -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.UART_RS485 import UART_RS485 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB2514B import USB2514B -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB2_0 import USB2_0 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB2_0_IF import USB2_0_IF -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB3 import USB3 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB3_IF import USB3_IF -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB3_connector import USB3_connector -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USBLC6_2P6 import USBLC6_2P6 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_C import USB_C -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_RS485 import USB_RS485 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_be_decoupled import can_be_decoupled -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_be_surge_protected import can_be_surge_protected -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_bridge import can_bridge -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_bridge_defined import can_bridge_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_switch_power import can_switch_power -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.can_switch_power_defined import can_switch_power_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_capacitance import has_capacitance -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_datasheet import has_datasheet -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_datasheet_defined import has_datasheet_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_defined_capacitance import has_defined_capacitance -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_defined_resistance import has_defined_resistance -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_descriptive_properties import has_descriptive_properties -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_designator import has_designator -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_designator_defined import has_designator_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_designator_prefix import has_designator_prefix -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_equal_pins import has_equal_pins -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_esphome_config import has_esphome_config -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_footprint import has_footprint -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_footprint_defined import has_footprint_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_footprint_impl import has_footprint_impl -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_footprint_requirement import has_footprint_requirement -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_kicad_footprint import has_kicad_footprint -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_kicad_ref import has_kicad_ref -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_linked_pad import has_linked_pad -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_linked_pad_defined import has_linked_pad_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_multi_picker import has_multi_picker -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_overriden_name import has_overriden_name -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_layout import has_pcb_layout -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_position import has_pcb_position -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_picker import has_picker -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_resistance import has_resistance -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_simple_value_representation import has_simple_value_representation -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_single_connection import has_single_connection -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_single_connection_impl import has_single_connection_impl -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_single_electric_reference import has_single_electric_reference -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_decoupled import is_decoupled -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_decoupled_nodes import is_decoupled_nodes -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_esphome_bus import is_esphome_bus -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_representable_by_single_value import is_representable_by_single_value -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_surge_protected import is_surge_protected -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.is_surge_protected_defined import is_surge_protected_defined -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.pf_533984002 import pf_533984002 -except AttributeError: ... +except (AttributeError, ImportError): ... try: from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 -except AttributeError: ... +except (AttributeError, ImportError): ... diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index 0b92f883..76a140b2 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -8,6 +8,7 @@ import logging import os from pathlib import Path +from typing import Iterable logger = logging.getLogger(__name__) @@ -43,9 +44,12 @@ def main(): logger.info(f"Found {len(modules_out)} classes") - def try_(stmt: str, exc: str | type[Exception]): + def try_(stmt: str, exc: str | type[Exception] | Iterable[type[Exception]]): if isinstance(exc, type): exc = exc.__name__ + if not isinstance(exc, str): + exc = f'({", ".join(e.__name__ for e in exc)})' + return f"try:\n {stmt}\nexcept {exc}: ..." OUT.write_text( @@ -67,7 +71,10 @@ def try_(stmt: str, exc: str | type[Exception]): "# flake8: noqa: E501\n" "\n" + "\n".join( - try_(f"from faebryk.library.{module} import {class_}", AttributeError) + try_( + f"from faebryk.library.{module} import {class_}", + (AttributeError, ImportError), + ) for module, class_ in sorted(modules_out.items(), key=lambda x: x[0]) ) + "\n" From 6bcb0c4c197e99501f1f3536ad6cd467d5fcdaa9 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 04:09:07 +0200 Subject: [PATCH 19/63] Fix init & Fix F_ --- new_holders_flat.py | 45 +- src/faebryk/core/node.py | 22 +- src/faebryk/core/trait.py | 5 +- src/faebryk/core/util.py | 6 +- src/faebryk/exporters/netlist/graph.py | 8 +- .../exporters/pcb/kicad/transformer.py | 3 +- src/faebryk/exporters/pcb/layout/absolute.py | 15 +- src/faebryk/exporters/pcb/layout/extrude.py | 19 +- src/faebryk/exporters/pcb/layout/font.py | 11 +- src/faebryk/exporters/pcb/layout/layout.py | 2 +- src/faebryk/exporters/pcb/layout/matrix.py | 19 +- .../exporters/pcb/layout/typehierarchy.py | 6 +- src/faebryk/exporters/pcb/routing/util.py | 29 +- .../project/faebryk/project_faebryk.py | 4 +- src/faebryk/library/BH1750FVI_TR.py | 2 +- src/faebryk/library/Comparator.py | 2 +- src/faebryk/library/EEPROM.py | 2 +- src/faebryk/library/ESP32_C3.py | 2 +- src/faebryk/library/ElectricLogic.py | 20 +- src/faebryk/library/ElectricPower.py | 2 +- src/faebryk/library/Footprint.py | 3 +- src/faebryk/library/HLK_LD2410B_P.py | 2 +- src/faebryk/library/PM1006.py | 2 +- src/faebryk/library/SMDTwoPin.py | 2 +- src/faebryk/library/UART_Base.py | 2 +- src/faebryk/library/USB2514B.py | 2 +- src/faebryk/library/_F.py | 796 +++++------------- src/faebryk/library/has_footprint.py | 7 +- src/faebryk/library/has_kicad_footprint.py | 6 +- src/faebryk/library/has_linked_pad.py | 7 +- src/faebryk/library/has_linked_pad_defined.py | 9 +- .../library/has_pcb_routing_strategy.py | 9 +- .../library/has_single_electric_reference.py | 6 +- .../has_single_electric_reference_defined.py | 9 +- src/faebryk/libs/app/erc.py | 14 +- src/faebryk/libs/examples/pickers.py | 20 +- src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 5 +- src/faebryk/libs/picker/picker.py | 38 +- src/faebryk/tools/libadd.py | 2 +- tools/library/gen_F.py | 91 +- 40 files changed, 458 insertions(+), 798 deletions(-) diff --git a/new_holders_flat.py b/new_holders_flat.py index cc603b0d..936ea129 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -2,19 +2,10 @@ import typer +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.parameter import Parameter from faebryk.core.util import as_unit -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Electrical import Electrical -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_simple_value_representation import ( - has_simple_value_representation, -) -from faebryk.library.has_simple_value_representation_based_on_param import ( - has_simple_value_representation_based_on_param, -) -from faebryk.library.TBD import TBD from faebryk.libs.library import L from faebryk.libs.units import P, Quantity from faebryk.libs.util import times @@ -23,21 +14,21 @@ class Diode2(Module): - forward_voltage: TBD[Quantity] - max_current: TBD[Quantity] - current: TBD[Quantity] - reverse_working_voltage: TBD[Quantity] - reverse_leakage_current: TBD[Quantity] + forward_voltage: F.TBD[Quantity] + max_current: F.TBD[Quantity] + current: F.TBD[Quantity] + reverse_working_voltage: F.TBD[Quantity] + reverse_leakage_current: F.TBD[Quantity] # static param bla_voltage: Parameter[Quantity] = L.d_field(lambda: 5 * P.V) # bla_dep: Parameter[Quantity] = L.rt_field(lambda self: self.bla_voltage) - anode: Electrical - cathode: Electrical + anode: F.Electrical + cathode: F.Electrical # static trait - designator_prefix = L.f_field(has_designator_prefix_defined)("D") + designator_prefix = L.f_field(F.has_designator_prefix_defined)("D") @L.rt_field def bla_dep2(self): @@ -46,22 +37,26 @@ def bla_dep2(self): # dynamic trait @L.rt_field def bridge(self): - return can_bridge_defined(self.anode, self.cathode) + return F.can_bridge_defined(self.anode, self.cathode) def __preinit__(self): print("Called Diode __preinit__") # anonymous dynamic trait self.add( - has_simple_value_representation_based_on_param( + F.has_simple_value_representation_based_on_param( self.forward_voltage, lambda p: as_unit(p, "V"), ) ) + def __init__(self): + super().__init__() + print("INIT DIODE") + class LED2(Diode2): - color: TBD[float] + color: F.TBD[float] def __preinit__(self): print("Called LED __preinit__") @@ -73,12 +68,12 @@ def __preinit__(self): class LED2_WITHEXTRAT_IFS(LED2): - extra: list[Electrical] = field(default_factory=lambda: times(2, Electrical)) - extra2: list[Electrical] = L.if_list(2, Electrical) + extra: list[F.Electrical] = field(default_factory=lambda: times(2, F.Electrical)) + extra2: list[F.Electrical] = L.if_list(2, F.Electrical) @L.rt_field def bridge(self): - return can_bridge_defined(self.extra2[0], self.extra2[1]) + return F.can_bridge_defined(self.extra2[0], self.extra2[1]) def __preinit__(self): print("Called LED_WITHEXTRAT_IFS __preinit__") @@ -98,7 +93,7 @@ def main(): assert L3.cathode.is_connected_to(L2.cathode) L3.forward_voltage.merge(5 * P.V) - L3.get_trait(has_simple_value_representation).get_value() + L3.get_trait(F.has_simple_value_representation).get_value() assert L3.designator_prefix.prefix == "D" diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index d830ffb3..ab5b51b2 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -59,6 +59,9 @@ def __init__(self, default_factory: Callable[[], T]) -> None: self.type = None self.default_factory = default_factory + def __repr__(self) -> str: + return f"{super().__repr__()}({self.type=}, {self.default_factory=})" + def d_field[T](default_factory: Callable[[], T]) -> T: return _d_field(default_factory) # type: ignore @@ -79,9 +82,14 @@ def __() -> T: # ----------------------------------------------------------------------------- +class PostInitCaller(type): + def __call__(cls, *args, **kwargs): + obj = type.__call__(cls, *args, **kwargs) + obj.__post_init__(*args, **kwargs) + return obj -class Node(FaebrykLibObject): +class Node(FaebrykLibObject, metaclass=PostInitCaller): runtime_anon: list["Node"] runtime: dict[str, "Node"] specialized: list["Node"] @@ -106,6 +114,8 @@ def add[T: Node]( name: str | None = None, container: list | dict[str, Any] | None = None, ) -> T: + assert obj is not None + if container is None: container = self.runtime_anon if name: @@ -233,6 +243,7 @@ def append(name, inst): objects[name] = inst elif isinstance(inst, list): for i, obj in enumerate(inst): + assert obj is not None objects[f"{name}[{i}]"] = obj elif isinstance(inst, dict): for k, obj in inst.items(): @@ -291,7 +302,6 @@ def setup_gen_alias(name, obj): def __new__(cls, *args, **kwargs): out = super().__new__(cls) - out._setup() return out def _setup(self) -> None: @@ -326,10 +336,16 @@ def _setup(self) -> None: if hasattr(base, "__postinit__"): base.__postinit__(self) - def __init__(self): ... + def __init__(self): + assert not hasattr(self, "_is_setup") + self._is_setup = True + def __preinit__(self): ... def __postinit__(self): ... + def __post_init__(self, *args, **kwargs): + self._setup() + def _handle_add_gif(self, name: str, gif: GraphInterface): gif.node = self gif.name = name diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index f6c05bf4..2cee3b92 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -1,7 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT import logging -from abc import ABC from faebryk.core.node import Node from faebryk.libs.util import cast_assert @@ -17,7 +16,7 @@ class _Impl(TraitImpl, cls): ... return _Impl -class TraitImpl(ABC): +class TraitImpl: _trait: type[Trait] def __preinit__(self) -> None: @@ -37,7 +36,7 @@ def __preinit__(self) -> None: ] assert len(bases) > 0 - assert type(self._trait) is type + assert isinstance(self._trait, type) assert issubclass(self._trait, Trait) assert self._trait is not TraitImpl diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 90172497..8f198782 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -652,7 +652,7 @@ def use_interface_names_as_net_names(node: Node, name: str | None = None): for c in connections if (p := c.get_parent()) and isinstance(n := p[0], Net) - and n.IFs.part_of in connections + and n.part_of in connections }: # logger.warning(f"Skipped, attached to Net: {el_if}: {matched_nets!r}") resolved.update(connections) @@ -686,12 +686,12 @@ def use_interface_names_as_net_names(node: Node, name: str | None = None): + "\n\t".join(map(str, el_if.get_direct_connections())) + f"\n{'-'*80}" + "\nNet Connections\n\t" - + "\n\t".join(map(str, net.IFs.part_of.get_direct_connections())) + + "\n\t".join(map(str, net.part_of.get_direct_connections())) ) net = Net() net.add_trait(has_overriden_name_defined(net_name)) - net.IFs.part_of.connect(el_if) + net.part_of.connect(el_if) logger.debug(f"Created {net_name} for {el_if}") nets[net_name] = net, el_if diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index 3cacfd10..bf2b1aeb 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -87,10 +87,10 @@ def get_name_and_value(self): return get_or_set_name_and_value_of_node(self.component) def get_pin_name(self, pin: Pad): - return self.get_obj().get_trait(has_kicad_footprint).get_pin_names()[pin] + return self.obj.get_trait(has_kicad_footprint).get_pin_names()[pin] def get_kicad_obj(self): - fp = self.get_obj() + fp = self.get_obj(Footprint) properties = { "footprint": fp.get_trait(has_kicad_footprint).get_kicad_footprint() @@ -120,7 +120,7 @@ def add_or_get_net(interface: Electrical): } if not nets: net = Net() - net.IFs.part_of.connect(interface) + net.part_of.connect(interface) return net if len(nets) > 1: raise Exception(f"Multiple nets interconnected: {nets}") @@ -154,4 +154,4 @@ def attach_nets_and_kicad_info(g: Graph): for fp in node_fps.values(): # TODO use graph for mif in get_children(fp, direct_only=True, types=Pad): - add_or_get_net(mif.IFs.net) + add_or_get_net(mif.net) diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index cb313668..5f958fde 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -412,8 +412,7 @@ def _get_pad(ffp: FFootprint, intf: Electrical): pin_map = ffp.get_trait(has_kicad_footprint).get_pin_names() pin_name = find( pin_map.items(), - lambda pad_and_name: intf.is_connected_to(pad_and_name[0].IFs.net) - is not None, + lambda pad_and_name: intf.is_connected_to(pad_and_name[0].net) is not None, )[1] fp = PCB_Transformer.get_fp(ffp) diff --git a/src/faebryk/exporters/pcb/layout/absolute.py b/src/faebryk/exporters/pcb/layout/absolute.py index bf98801a..8d0020fa 100644 --- a/src/faebryk/exporters/pcb/layout/absolute.py +++ b/src/faebryk/exporters/pcb/layout/absolute.py @@ -4,28 +4,23 @@ import logging from dataclasses import dataclass -from faebryk.core.core import ( - Node, -) +import faebryk.library._F as F +from faebryk.core.node import Node from faebryk.exporters.pcb.layout.layout import Layout -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined_relative_to_parent import ( - has_pcb_position_defined_relative_to_parent, -) logger = logging.getLogger(__name__) @dataclass(frozen=True, eq=True) class LayoutAbsolute(Layout): - pos: has_pcb_position.Point + pos: F.has_pcb_position.Point def apply(self, *node: Node): """ Tip: Make sure at least one parent of node has an absolute position defined """ # Remove nodes that have a position defined - node = tuple(n for n in node if not n.has_trait(has_pcb_position)) + node = tuple(n for n in node if not n.has_trait(F.has_pcb_position)) for n in node: - n.add_trait(has_pcb_position_defined_relative_to_parent(self.pos)) + n.add_trait(F.has_pcb_position_defined_relative_to_parent(self.pos)) diff --git a/src/faebryk/exporters/pcb/layout/extrude.py b/src/faebryk/exporters/pcb/layout/extrude.py index 5e815c38..f3ce1265 100644 --- a/src/faebryk/exporters/pcb/layout/extrude.py +++ b/src/faebryk/exporters/pcb/layout/extrude.py @@ -4,14 +4,9 @@ import logging from dataclasses import dataclass -from faebryk.core.core import ( - Node, -) +import faebryk.library._F as F +from faebryk.core.node import Node from faebryk.exporters.pcb.layout.layout import Layout -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined_relative_to_parent import ( - has_pcb_position_defined_relative_to_parent, -) from faebryk.libs.geometry.basic import Geometry logger = logging.getLogger(__name__) @@ -30,8 +25,8 @@ class LayoutExtrude(Layout): """ vector: tuple[float, float] | tuple[float, float, float] - base: has_pcb_position.Point = has_pcb_position.Point( - (0, 0, 0, has_pcb_position.layer_type.NONE) + base: F.has_pcb_position.Point = F.has_pcb_position.Point( + (0, 0, 0, F.has_pcb_position.layer_type.NONE) ) dynamic_rotation: bool = False @@ -41,7 +36,7 @@ def apply(self, *node: Node): """ # Remove nodes that have a position defined - node = tuple(n for n in node if not n.has_trait(has_pcb_position)) + node = tuple(n for n in node if not n.has_trait(F.has_pcb_position)) vector = self.vector if len(self.vector) == 3 else (*self.vector, 0) @@ -50,8 +45,8 @@ def apply(self, *node: Node): vector[0] * i, vector[1] * i, (vector[2] * (i if self.dynamic_rotation else 1)) % 360, - has_pcb_position.layer_type.NONE, + F.has_pcb_position.layer_type.NONE, ) pos = Geometry.abs_pos(self.base, vec_i) - n.add_trait(has_pcb_position_defined_relative_to_parent(pos)) + n.add_trait(F.has_pcb_position_defined_relative_to_parent(pos)) diff --git a/src/faebryk/exporters/pcb/layout/font.py b/src/faebryk/exporters/pcb/layout/font.py index 4617e578..0a8e9aa6 100644 --- a/src/faebryk/exporters/pcb/layout/font.py +++ b/src/faebryk/exporters/pcb/layout/font.py @@ -5,12 +5,9 @@ from rich.progress import track -from faebryk.core.core import Node +import faebryk.library._F as F +from faebryk.core.node import Node from faebryk.exporters.pcb.layout.layout import Layout -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined_relative_to_parent import ( - has_pcb_position_defined_relative_to_parent, -) from faebryk.libs.font import Font from faebryk.libs.geometry.basic import get_distributed_points_in_polygon @@ -74,11 +71,11 @@ def apply(self, *nodes_to_distribute: Node) -> None: for coord, node in zip(self.coords, nodes_to_distribute): node.add_trait( - has_pcb_position_defined_relative_to_parent( + F.has_pcb_position_defined_relative_to_parent( ( *coord, 0, - has_pcb_position.layer_type.NONE, + F.has_pcb_position.layer_type.NONE, ) ) ) diff --git a/src/faebryk/exporters/pcb/layout/layout.py b/src/faebryk/exporters/pcb/layout/layout.py index 7da7705a..62551936 100644 --- a/src/faebryk/exporters/pcb/layout/layout.py +++ b/src/faebryk/exporters/pcb/layout/layout.py @@ -1,6 +1,6 @@ from abc import abstractmethod -from faebryk.core.core import Node +from faebryk.core.node import Node class Layout: diff --git a/src/faebryk/exporters/pcb/layout/matrix.py b/src/faebryk/exporters/pcb/layout/matrix.py index a0d164ba..5215cb72 100644 --- a/src/faebryk/exporters/pcb/layout/matrix.py +++ b/src/faebryk/exporters/pcb/layout/matrix.py @@ -4,14 +4,9 @@ import logging from dataclasses import dataclass -from faebryk.core.core import ( - Node, -) +import faebryk.library._F as F +from faebryk.core.node import Node from faebryk.exporters.pcb.layout.layout import Layout -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined_relative_to_parent import ( - has_pcb_position_defined_relative_to_parent, -) from faebryk.libs.geometry.basic import Geometry logger = logging.getLogger(__name__) @@ -30,8 +25,8 @@ class LayoutMatrix(Layout): vector: tuple[float, float] | tuple[float, float, float] distribution: tuple[int, int] - base: has_pcb_position.Point = has_pcb_position.Point( - (0, 0, 0, has_pcb_position.layer_type.NONE) + base: F.has_pcb_position.Point = F.has_pcb_position.Point( + (0, 0, 0, F.has_pcb_position.layer_type.NONE) ) def apply(self, *node: Node): @@ -40,7 +35,7 @@ def apply(self, *node: Node): """ # Remove nodes that have a position defined - node = tuple(n for n in node if not n.has_trait(has_pcb_position)) + node = tuple(n for n in node if not n.has_trait(F.has_pcb_position)) vector = self.vector if len(self.vector) == 3 else (*self.vector, 0) @@ -63,11 +58,11 @@ def apply(self, *node: Node): vector[0] * x, vector[1] * y, vector[2], - has_pcb_position.layer_type.NONE, + F.has_pcb_position.layer_type.NONE, ) pos = Geometry.abs_pos(self.base, vec_i) node[node_index].add_trait( - has_pcb_position_defined_relative_to_parent(pos) + F.has_pcb_position_defined_relative_to_parent(pos) ) node_index += 1 diff --git a/src/faebryk/exporters/pcb/layout/typehierarchy.py b/src/faebryk/exporters/pcb/layout/typehierarchy.py index eb6ebd79..fe286ba7 100644 --- a/src/faebryk/exporters/pcb/layout/typehierarchy.py +++ b/src/faebryk/exporters/pcb/layout/typehierarchy.py @@ -4,10 +4,8 @@ import logging from dataclasses import dataclass -from faebryk.core.core import ( - Module, - Node, -) +from faebryk.core.module import Module +from faebryk.core.node import Node from faebryk.core.util import get_node_direct_children from faebryk.exporters.pcb.layout.layout import Layout from faebryk.libs.util import NotNone, find_or, flatten, groupby diff --git a/src/faebryk/exporters/pcb/routing/util.py b/src/faebryk/exporters/pcb/routing/util.py index 7e17d461..4f8bdeef 100644 --- a/src/faebryk/exporters/pcb/routing/util.py +++ b/src/faebryk/exporters/pcb/routing/util.py @@ -5,11 +5,9 @@ from dataclasses import dataclass from typing import Iterable, Sequence -from faebryk.core.core import ( - Module, - ModuleInterface, - Node, -) +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node from faebryk.core.util import ( get_all_nodes, get_connected_mifs, @@ -95,6 +93,9 @@ def __add__(self, other: "Path"): class Route(Module): + net_: Electrical + pcb: ModuleInterface + def __init__( self, pads: Iterable[Pad], @@ -104,22 +105,16 @@ def __init__( self.path = path or Path() - class _IFs(super().IFS()): - net = Electrical() - pcb = ModuleInterface() - - self.IFs = _IFs(self) - for pad in pads: - self.IFs.pcb.connect(pad.IFs.pcb) - self.IFs.net.connect(pad.IFs.net) + self.pcb.connect(pad.pcb) + self.net_.connect(pad.net) def add(self, obj: Path.Obj): self.path.add(obj) @property def net(self): - net = get_net(self.IFs.net) + net = get_net(self.net_) assert net return net @@ -188,7 +183,7 @@ def get_internal_nets_of_node( from faebryk.libs.util import groupby if isinstance(node, Net): - return {node: get_connected_mifs(node.IFs.part_of.connected)} + return {node: get_connected_mifs(node.part_of.connected)} mifs = {n for n in get_all_nodes(node) + [node] if isinstance(n, Electrical)} nets = groupby(mifs, lambda mif: get_net(mif)) @@ -211,7 +206,7 @@ def group_pads_that_are_connected_already( for pad in pads: for group in out: # Only need to check first, because transitively connected - if pad.IFs.pcb.is_connected_to(next(iter(group)).IFs.pcb): + if pad.pcb.is_connected_to(next(iter(group)).pcb): group.add(pad) break else: @@ -222,6 +217,6 @@ def group_pads_that_are_connected_already( def get_routes_of_pad(pad: Pad): return { route - for mif in pad.IFs.pcb.get_direct_connections() + for mif in pad.pcb.get_direct_connections() if (route := get_parent_of_type(mif, Route)) } diff --git a/src/faebryk/exporters/project/faebryk/project_faebryk.py b/src/faebryk/exporters/project/faebryk/project_faebryk.py index abdcbdd9..b190a07e 100644 --- a/src/faebryk/exporters/project/faebryk/project_faebryk.py +++ b/src/faebryk/exporters/project/faebryk/project_faebryk.py @@ -91,7 +91,7 @@ class _IFs(Component.InterfacesCls()): unnamed = {unnamed_ifs} {named_if_expr} - self.IFs = _IFs(self) + self = _IFs(self) {trait_expr} @@ -145,7 +145,7 @@ def get_comp_name(component): name = get_comp_name(component) pinmap = { - pin: (f"{{name}}.IFs.P{pin}", f"P{pin}") + pin: (f"{{name}}.P{pin}", f"P{pin}") for pin in component["neighbors"].keys() } diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 4f13f1b9..05750080 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -78,7 +78,7 @@ def __preinit__(self): self.power.voltage.merge(F.Range(2.4 * P.V, 3.6 * P.V)) self.power.decoupled.decouple().capacitance.merge(0.1 * P.uF) - # TODO: self.dvi.low_pass(self.IF.dvi_capacitor, self.IF.dvi_resistor) + # TODO: self.dvi.low_pass(self.dvi_capacitor, self.dvi_resistor) @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/Comparator.py b/src/faebryk/library/Comparator.py index 3cf3dd0a..934c772a 100644 --- a/src/faebryk/library/Comparator.py +++ b/src/faebryk/library/Comparator.py @@ -21,7 +21,7 @@ class OutputType(Enum): input_hysteresis_voltage: F.TBD[Quantity] input_offset_voltage: F.TBD[Quantity] propagation_delay: F.TBD[Quantity] - output_type: F.TBD[F.Comparator.OutputType] + output_type: F.TBD[OutputType] power: F.ElectricPower inverting_input: F.Electrical diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index 02890dd2..f2a885e1 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -28,7 +28,7 @@ def set_address(self, addr: int): memory_size: F.TBD[Quantity] power: F.ElectricPower - i2c = F.I2C() + i2c: F.I2C write_protect: F.ElectricLogic address = L.if_list(3, F.ElectricLogic) diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index c91a4c62..38a523a7 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -27,7 +27,7 @@ class ESP32_C3(Module): gpio = L.if_list(22, F.ElectricLogic) # TODO: map peripherals to GPIOs with pinmux usb: F.USB2_0 - i2c = F.I2C() + i2c: F.I2C uart = L.if_list(2, F.UART_Base) # ... etc diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 9d198ada..8cb77e85 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -41,8 +41,8 @@ def pull(self, up: bool): obj = self.obj up_r, down_r = None, None - if obj.has_trait(F.ElectricLogic.has_pulls): - up_r, down_r = obj.get_trait(F.ElectricLogic.has_pulls).get_pulls() + if obj.has_trait(ElectricLogic.has_pulls): + up_r, down_r = obj.get_trait(ElectricLogic.has_pulls).get_pulls() if up and up_r: return up_r @@ -59,7 +59,7 @@ def pull(self, up: bool): self.signal.connect_via(resistor, self.ref.hv if up else self.ref.lv) - obj.add_trait(F.ElectricLogic.has_pulls_defined(up_r, down_r)) + obj.add_trait(ElectricLogic.has_pulls_defined(up_r, down_r)) return resistor # class can_be_buffered(Trait): @@ -69,7 +69,7 @@ def pull(self, up: bool): # # # class can_be_buffered_defined(can_be_buffered.impl()): - # def __init__(self, signal: "F.ElectricLogic") -> None: + # def __init__(self, signal: "ElectricLogic") -> None: # super().__init__() # self.signal = signal # @@ -90,7 +90,7 @@ class PushPull(Enum): OPEN_DRAIN = auto() OPEN_SOURCE = auto() - push_pull: F.TBD[F.ElectricLogic.PushPull] + push_pull: F.TBD[PushPull] reference: F.ElectricPower signal: F.Electrical @@ -115,7 +115,7 @@ def protect(_self): @L.rt_field def pulled(self): - return F.ElectricLogic.can_be_pulled_defined(self.signal, self.reference) + return ElectricLogic.can_be_pulled_defined(self.signal, self.reference) def connect_to_electric(self, signal: F.Electrical, reference: F.ElectricPower): self.reference.connect(reference) @@ -132,7 +132,7 @@ def connect_reference(self, reference: F.ElectricPower, invert: bool = False): # reference = inverted self.reference.connect(reference) - def connect_references(self, other: "F.ElectricLogic", invert: bool = False): + def connect_references(self, other: "ElectricLogic", invert: bool = False): self.connect_reference(other.reference, invert=invert) def set(self, on: bool): @@ -144,7 +144,7 @@ def set_weak(self, on: bool): return self.get_trait(self.can_be_pulled).pull(up=on) @staticmethod - def connect_all_references(ifs: Iterable["F.ElectricLogic"]) -> F.ElectricPower: + def connect_all_references(ifs: Iterable["ElectricLogic"]) -> F.ElectricPower: out = connect_all_interfaces([x.reference for x in ifs]) assert out return out @@ -153,7 +153,7 @@ def connect_all_references(ifs: Iterable["F.ElectricLogic"]) -> F.ElectricPower: def connect_all_node_references( nodes: Iterable[Node], gnd_only=False ) -> F.ElectricPower: - # TODO check if any child contains F.ElectricLogic which is not connected + # TODO check if any child contains ElectricLogic which is not connected # e.g find them in graph and check if any has parent without "single reference" refs = { @@ -179,7 +179,7 @@ def connect_all_module_references( gnd_only=gnd_only, ) - # def connect_shallow(self, other: "F.ElectricLogic"): + # def connect_shallow(self, other: "ElectricLogic"): # self.connect( # other, # linkcls=self.LinkDirectShallowLogic, diff --git a/src/faebryk/library/ElectricPower.py b/src/faebryk/library/ElectricPower.py index 665009fa..a0cb2e59 100644 --- a/src/faebryk/library/ElectricPower.py +++ b/src/faebryk/library/ElectricPower.py @@ -61,7 +61,7 @@ def __preinit__(self) -> None: def _on_connect(self, other: ModuleInterface) -> None: super()._on_connect(other) - if not isinstance(other, F.ElectricPower): + if not isinstance(other, ElectricPower): return self.voltage.merge(other.voltage) diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index f53ba3f5..24ec4949 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -7,6 +7,7 @@ from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node from faebryk.core.trait import Trait +from faebryk.core.util import get_parent_with_trait class Footprint(Module): @@ -16,7 +17,5 @@ class TraitT(Trait): ... def get_footprint_of_parent( intf: ModuleInterface, ) -> "tuple[Node, Footprint]": - from faebryk.core.util import get_parent_with_trait - parent, trait = get_parent_with_trait(intf, F.has_footprint) return parent, trait.get_footprint() diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index 1aaac33d..017d93af 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -61,7 +61,7 @@ def get_config(self) -> dict: # interfaces power: F.ElectricPower - uart = F.UART_Base() + uart: F.UART_Base out: F.ElectricLogic esphome_config: _ld2410b_esphome_config diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index 8734f1ae..1c85ec01 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -63,7 +63,7 @@ def get_config(self) -> dict: # --------------------------------------------------------------------- datasheet = L.f_field(F.has_datasheet_defined)( - "http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_F.LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf" + "http://www.jdscompany.co.kr/download.asp?gubun=07&filename=PM1006_LED_PARTICLE_SENSOR_MODULE_SPECIFICATIONS.pdf" ) # --------------------------------------------------------------------- diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index 15a160a7..5d95833a 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -42,7 +42,7 @@ def get_kicad_footprint(self) -> str: SMDTwoPin.Type._2010: "5025", SMDTwoPin.Type._2512: "6332", } - return "F.Resistor_SMD:R_{imperial}_{metric}Metric".format( + return "Resistor_SMD:R_{imperial}_{metric}Metric".format( imperial=obj._type.name[1:], metric=table[obj._type] ) diff --git a/src/faebryk/library/UART_Base.py b/src/faebryk/library/UART_Base.py index ecf7a297..025fe017 100644 --- a/src/faebryk/library/UART_Base.py +++ b/src/faebryk/library/UART_Base.py @@ -19,7 +19,7 @@ def single_electric_reference(self): F.ElectricLogic.connect_all_module_references(self) ) - def _on_connect(self, other: "F.UART_Base"): + def _on_connect(self, other: "UART_Base"): super()._on_connect(other) self.baud.merge(other.baud) diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 8c92cdd4..e50604cd 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -53,7 +53,7 @@ class InterfaceConfiguration(Enum): i2c: F.I2C gnd: F.Electrical - interface_configuration: F.TBD[F.USB2514B.InterfaceConfiguration] + interface_configuration: F.TBD[InterfaceConfiguration] designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") def __preinit__(self): diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index f8a62660..d6fc7675 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,600 +15,202 @@ # flake8: noqa: I001 # flake8: noqa: E501 -try: - from faebryk.library.ANY import ANY -except (AttributeError, ImportError): ... -try: - from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF -except (AttributeError, ImportError): ... -try: - from faebryk.library.BH1750FVI_TR import BH1750FVI_TR -except (AttributeError, ImportError): ... -try: - from faebryk.library.BJT import BJT -except (AttributeError, ImportError): ... -try: - from faebryk.library.Battery import Battery -except (AttributeError, ImportError): ... -try: - from faebryk.library.Button import Button -except (AttributeError, ImportError): ... -try: - from faebryk.library.ButtonCell import ButtonCell -except (AttributeError, ImportError): ... -try: - from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG -except (AttributeError, ImportError): ... -try: - from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design -except (AttributeError, ImportError): ... -try: - from faebryk.library.CD4011 import CD4011 -except (AttributeError, ImportError): ... -try: - from faebryk.library.CH340x import CH340x -except (AttributeError, ImportError): ... -try: - from faebryk.library.Capacitor import Capacitor -except (AttributeError, ImportError): ... -try: - from faebryk.library.Common_Mode_Filter import Common_Mode_Filter -except (AttributeError, ImportError): ... -try: - from faebryk.library.Comparator import Comparator -except (AttributeError, ImportError): ... -try: - from faebryk.library.Constant import Constant -except (AttributeError, ImportError): ... -try: - from faebryk.library.Crystal import Crystal -except (AttributeError, ImportError): ... -try: - from faebryk.library.Crystal_Oscillator import Crystal_Oscillator -except (AttributeError, ImportError): ... -try: - from faebryk.library.DIP import DIP -except (AttributeError, ImportError): ... -try: - from faebryk.library.DifferentialPair import DifferentialPair -except (AttributeError, ImportError): ... -try: - from faebryk.library.Diode import Diode -except (AttributeError, ImportError): ... -try: - from faebryk.library.EEPROM import EEPROM -except (AttributeError, ImportError): ... -try: - from faebryk.library.ESP32 import ESP32 -except (AttributeError, ImportError): ... -try: - from faebryk.library.ESP32_C3 import ESP32_C3 -except (AttributeError, ImportError): ... -try: - from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 -except (AttributeError, ImportError): ... -try: - from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design -except (AttributeError, ImportError): ... -try: - from faebryk.library.ElectricLogic import ElectricLogic -except (AttributeError, ImportError): ... -try: - from faebryk.library.ElectricLogicGate import ElectricLogicGate -except (AttributeError, ImportError): ... -try: - from faebryk.library.ElectricLogicGates import ElectricLogicGates -except (AttributeError, ImportError): ... -try: - from faebryk.library.ElectricPower import ElectricPower -except (AttributeError, ImportError): ... -try: - from faebryk.library.Electrical import Electrical -except (AttributeError, ImportError): ... -try: - from faebryk.library.Ethernet import Ethernet -except (AttributeError, ImportError): ... -try: - from faebryk.library.Fan import Fan -except (AttributeError, ImportError): ... -try: - from faebryk.library.Footprint import Footprint -except (AttributeError, ImportError): ... -try: - from faebryk.library.Fuse import Fuse -except (AttributeError, ImportError): ... -try: - from faebryk.library.GDT import GDT -except (AttributeError, ImportError): ... -try: - from faebryk.library.GenericBusProtection import GenericBusProtection -except (AttributeError, ImportError): ... -try: - from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P -except (AttributeError, ImportError): ... -try: - from faebryk.library.Header import Header -except (AttributeError, ImportError): ... -try: - from faebryk.library.I2C import I2C -except (AttributeError, ImportError): ... -try: - from faebryk.library.Inductor import Inductor -except (AttributeError, ImportError): ... -try: - from faebryk.library.JTAG import JTAG -except (AttributeError, ImportError): ... -try: - from faebryk.library.KicadFootprint import KicadFootprint -except (AttributeError, ImportError): ... -try: - from faebryk.library.LDO import LDO -except (AttributeError, ImportError): ... -try: - from faebryk.library.LED import LED -except (AttributeError, ImportError): ... -try: - from faebryk.library.LEDIndicator import LEDIndicator -except (AttributeError, ImportError): ... -try: - from faebryk.library.Logic import Logic -except (AttributeError, ImportError): ... -try: - from faebryk.library.Logic74xx import Logic74xx -except (AttributeError, ImportError): ... -try: - from faebryk.library.LogicGate import LogicGate -except (AttributeError, ImportError): ... -try: - from faebryk.library.LogicGates import LogicGates -except (AttributeError, ImportError): ... -try: - from faebryk.library.LogicOps import LogicOps -except (AttributeError, ImportError): ... -try: - from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP -except (AttributeError, ImportError): ... -try: - from faebryk.library.MCP2221A import MCP2221A -except (AttributeError, ImportError): ... -try: - from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N -except (AttributeError, ImportError): ... -try: - from faebryk.library.MOSFET import MOSFET -except (AttributeError, ImportError): ... -try: - from faebryk.library.Mechanical import Mechanical -except (AttributeError, ImportError): ... -try: - from faebryk.library.Mounting_Hole import Mounting_Hole -except (AttributeError, ImportError): ... -try: - from faebryk.library.MultiSPI import MultiSPI -except (AttributeError, ImportError): ... -try: - from faebryk.library.Net import Net -except (AttributeError, ImportError): ... -try: - from faebryk.library.OLED_Module import OLED_Module -except (AttributeError, ImportError): ... -try: - from faebryk.library.OpAmp import OpAmp -except (AttributeError, ImportError): ... -try: - from faebryk.library.Operation import Operation -except (AttributeError, ImportError): ... -try: - from faebryk.library.PJ398SM import PJ398SM -except (AttributeError, ImportError): ... -try: - from faebryk.library.PM1006 import PM1006 -except (AttributeError, ImportError): ... -try: - from faebryk.library.Pad import Pad -except (AttributeError, ImportError): ... -try: - from faebryk.library.Potentiometer import Potentiometer -except (AttributeError, ImportError): ... -try: - from faebryk.library.Power import Power -except (AttributeError, ImportError): ... -try: - from faebryk.library.PowerSwitch import PowerSwitch -except (AttributeError, ImportError): ... -try: - from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET -except (AttributeError, ImportError): ... -try: - from faebryk.library.PowerSwitchStatic import PowerSwitchStatic -except (AttributeError, ImportError): ... -try: - from faebryk.library.PoweredLED import PoweredLED -except (AttributeError, ImportError): ... -try: - from faebryk.library.Powered_Relay import Powered_Relay -except (AttributeError, ImportError): ... -try: - from faebryk.library.QFN import QFN -except (AttributeError, ImportError): ... -try: - from faebryk.library.QWIIC import QWIIC -except (AttributeError, ImportError): ... -try: - from faebryk.library.QWIIC_Connector import QWIIC_Connector -except (AttributeError, ImportError): ... -try: - from faebryk.library.RJ45_Receptacle import RJ45_Receptacle -except (AttributeError, ImportError): ... -try: - from faebryk.library.RP2040 import RP2040 -except (AttributeError, ImportError): ... -try: - from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design -except (AttributeError, ImportError): ... -try: - from faebryk.library.RS232 import RS232 -except (AttributeError, ImportError): ... -try: - from faebryk.library.RS485 import RS485 -except (AttributeError, ImportError): ... -try: - from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection -except (AttributeError, ImportError): ... -try: - from faebryk.library.Range import Range -except (AttributeError, ImportError): ... -try: - from faebryk.library.Relay import Relay -except (AttributeError, ImportError): ... -try: - from faebryk.library.Resistor import Resistor -except (AttributeError, ImportError): ... -try: - from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider -except (AttributeError, ImportError): ... -try: - from faebryk.library.SCD40 import SCD40 -except (AttributeError, ImportError): ... -try: - from faebryk.library.SK9822_EC20 import SK9822_EC20 -except (AttributeError, ImportError): ... -try: - from faebryk.library.SMDTwoPin import SMDTwoPin -except (AttributeError, ImportError): ... -try: - from faebryk.library.SNx4LVC541A import SNx4LVC541A -except (AttributeError, ImportError): ... -try: - from faebryk.library.SOIC import SOIC -except (AttributeError, ImportError): ... -try: - from faebryk.library.SPI import SPI -except (AttributeError, ImportError): ... -try: - from faebryk.library.SPIFlash import SPIFlash -except (AttributeError, ImportError): ... -try: - from faebryk.library.SWD import SWD -except (AttributeError, ImportError): ... -try: - from faebryk.library.SWDConnector import SWDConnector -except (AttributeError, ImportError): ... -try: - from faebryk.library.Sercom import Sercom -except (AttributeError, ImportError): ... -try: - from faebryk.library.Set import Set -except (AttributeError, ImportError): ... -try: - from faebryk.library.Switch import Switch -except (AttributeError, ImportError): ... -try: - from faebryk.library.TBD import TBD -except (AttributeError, ImportError): ... -try: - from faebryk.library.TD541S485H import TD541S485H -except (AttributeError, ImportError): ... -try: - from faebryk.library.TI_CD4011BE import TI_CD4011BE -except (AttributeError, ImportError): ... -try: - from faebryk.library.TVS import TVS -except (AttributeError, ImportError): ... -try: - from faebryk.library.TXS0102DCUR import TXS0102DCUR -except (AttributeError, ImportError): ... -try: - from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART -except (AttributeError, ImportError): ... -try: - from faebryk.library.UART import UART -except (AttributeError, ImportError): ... -try: - from faebryk.library.UART_Base import UART_Base -except (AttributeError, ImportError): ... -try: - from faebryk.library.UART_RS485 import UART_RS485 -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB2514B import USB2514B -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB2_0 import USB2_0 -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB2_0_IF import USB2_0_IF -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB3 import USB3 -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB3_IF import USB3_IF -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB3_connector import USB3_connector -except (AttributeError, ImportError): ... -try: - from faebryk.library.USBLC6_2P6 import USBLC6_2P6 -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_C import USB_C -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_RS485 import USB_RS485 -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin -except (AttributeError, ImportError): ... -try: - from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin -except (AttributeError, ImportError): ... -try: - from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_be_decoupled import can_be_decoupled -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_be_surge_protected import can_be_surge_protected -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_bridge import can_bridge -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_bridge_defined import can_bridge_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_switch_power import can_switch_power -except (AttributeError, ImportError): ... -try: - from faebryk.library.can_switch_power_defined import can_switch_power_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_capacitance import has_capacitance -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_datasheet import has_datasheet -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_datasheet_defined import has_datasheet_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_defined_capacitance import has_defined_capacitance -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_defined_resistance import has_defined_resistance -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_descriptive_properties import has_descriptive_properties -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_designator import has_designator -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_designator_defined import has_designator_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_designator_prefix import has_designator_prefix -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_equal_pins import has_equal_pins -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_esphome_config import has_esphome_config -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_footprint import has_footprint -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_footprint_defined import has_footprint_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_footprint_impl import has_footprint_impl -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_footprint_requirement import has_footprint_requirement -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_kicad_footprint import has_kicad_footprint -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_kicad_ref import has_kicad_ref -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_linked_pad import has_linked_pad -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_linked_pad_defined import has_linked_pad_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_multi_picker import has_multi_picker -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_overriden_name import has_overriden_name -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_layout import has_pcb_layout -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_position import has_pcb_position -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_picker import has_picker -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_resistance import has_resistance -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_simple_value_representation import has_simple_value_representation -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_single_connection import has_single_connection -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_single_connection_impl import has_single_connection_impl -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_single_electric_reference import has_single_electric_reference -except (AttributeError, ImportError): ... -try: - from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_decoupled import is_decoupled -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_decoupled_nodes import is_decoupled_nodes -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_esphome_bus import is_esphome_bus -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_representable_by_single_value import is_representable_by_single_value -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_surge_protected import is_surge_protected -except (AttributeError, ImportError): ... -try: - from faebryk.library.is_surge_protected_defined import is_surge_protected_defined -except (AttributeError, ImportError): ... -try: - from faebryk.library.pf_533984002 import pf_533984002 -except (AttributeError, ImportError): ... -try: - from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 -except (AttributeError, ImportError): ... +from faebryk.library.has_pcb_position import has_pcb_position +from faebryk.library.TBD import TBD +from faebryk.library.Range import Range +from faebryk.library.Operation import Operation +from faebryk.library.has_overriden_name import has_overriden_name +from faebryk.library.has_capacitance import has_capacitance +from faebryk.library.has_footprint import has_footprint +from faebryk.library.has_datasheet import has_datasheet +from faebryk.library.has_esphome_config import has_esphome_config +from faebryk.library.has_descriptive_properties import has_descriptive_properties +from faebryk.library.has_single_electric_reference import has_single_electric_reference +from faebryk.library.is_esphome_bus import is_esphome_bus +from faebryk.library.has_kicad_ref import has_kicad_ref +from faebryk.library.has_simple_value_representation import has_simple_value_representation +from faebryk.library.has_pcb_layout import has_pcb_layout +from faebryk.library.has_designator_prefix import has_designator_prefix +from faebryk.library.Power import Power +from faebryk.library.has_resistance import has_resistance +from faebryk.library.has_single_connection import has_single_connection +from faebryk.library.has_designator import has_designator +from faebryk.library.has_linked_pad import has_linked_pad +from faebryk.library.can_bridge import can_bridge +from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy +from faebryk.library.has_footprint_requirement import has_footprint_requirement +from faebryk.library.has_picker import has_picker +from faebryk.library.Mechanical import Mechanical +from faebryk.library.is_representable_by_single_value import is_representable_by_single_value +from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative +from faebryk.library.has_pcb_position_defined import has_pcb_position_defined +from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent +from faebryk.library.Electrical import Electrical +from faebryk.library.ANY import ANY +from faebryk.library.Logic import Logic +from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +from faebryk.library.has_defined_capacitance import has_defined_capacitance +from faebryk.library.Footprint import Footprint +from faebryk.library.has_datasheet_defined import has_datasheet_defined +from faebryk.library.has_esphome_config_defined import has_esphome_config_defined +from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties +from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined +from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined +from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref +from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined +from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params +from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined +from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined +from faebryk.library.has_defined_resistance import has_defined_resistance +from faebryk.library.has_single_connection_impl import has_single_connection_impl +from faebryk.library.has_designator_defined import has_designator_defined +from faebryk.library.has_linked_pad_defined import has_linked_pad_defined +from faebryk.library.can_bridge_defined import can_bridge_defined +from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line +from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined +from faebryk.library.has_multi_picker import has_multi_picker +from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined +from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic +from faebryk.library.SPI import SPI +from faebryk.library.DifferentialPair import DifferentialPair +from faebryk.library.LogicOps import LogicOps +from faebryk.library.has_footprint_impl import has_footprint_impl +from faebryk.library.can_attach_to_footprint import can_attach_to_footprint +from faebryk.library.has_kicad_footprint import has_kicad_footprint +from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap +from faebryk.library.PJ398SM import PJ398SM +from faebryk.library.Common_Mode_Filter import Common_Mode_Filter +from faebryk.library.RJ45_Receptacle import RJ45_Receptacle +from faebryk.library.Crystal import Crystal +from faebryk.library.Header import Header +from faebryk.library.Relay import Relay +from faebryk.library.Pad import Pad +from faebryk.library.GDT import GDT +from faebryk.library.Button import Button +from faebryk.library.Constant import Constant +from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table +from faebryk.library.RS485 import RS485 +from faebryk.library.Ethernet import Ethernet +from faebryk.library.has_footprint_defined import has_footprint_defined +from faebryk.library.Net import Net +from faebryk.library.has_equal_pins import has_equal_pins +from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint +from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist +from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param +from faebryk.library.Set import Set +from faebryk.library.LogicGate import LogicGate +from faebryk.library.MOSFET import MOSFET +from faebryk.library.BJT import BJT +from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap +from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically +from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer +from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual +from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal +from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs +from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs +from faebryk.library.KicadFootprint import KicadFootprint +from faebryk.library.Diode import Diode +from faebryk.library.LogicGates import LogicGates +from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF +from faebryk.library.pf_533984002 import pf_533984002 +from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin +from faebryk.library.Fuse import Fuse +from faebryk.library.Switch import Switch +from faebryk.library.Resistor import Resistor +from faebryk.library.Inductor import Inductor +from faebryk.library.Capacitor import Capacitor +from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined +from faebryk.library.DIP import DIP +from faebryk.library.SMDTwoPin import SMDTwoPin +from faebryk.library.QFN import QFN +from faebryk.library.SOIC import SOIC +from faebryk.library.Mounting_Hole import Mounting_Hole +from faebryk.library.TVS import TVS +from faebryk.library.Potentiometer import Potentiometer +from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider +from faebryk.library.is_decoupled import is_decoupled +from faebryk.library.can_be_decoupled import can_be_decoupled +from faebryk.library.can_be_surge_protected import can_be_surge_protected +from faebryk.library.is_surge_protected import is_surge_protected +from faebryk.library.is_decoupled_nodes import is_decoupled_nodes +from faebryk.library.is_surge_protected_defined import is_surge_protected_defined +from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined +from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined +from faebryk.library.ElectricPower import ElectricPower +from faebryk.library.Comparator import Comparator +from faebryk.library.ElectricLogic import ElectricLogic +from faebryk.library.OpAmp import OpAmp +from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection +from faebryk.library.LED import LED +from faebryk.library.USB2_0_IF import USB2_0_IF +from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin +from faebryk.library.Fan import Fan +from faebryk.library.Crystal_Oscillator import Crystal_Oscillator +from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N +from faebryk.library.Battery import Battery +from faebryk.library.Sercom import Sercom +from faebryk.library.SNx4LVC541A import SNx4LVC541A +from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B +from faebryk.library.ElectricLogicGate import ElectricLogicGate +from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 +from faebryk.library.LDO import LDO +from faebryk.library.can_switch_power import can_switch_power +from faebryk.library.SK9822_EC20 import SK9822_EC20 +from faebryk.library.RS232 import RS232 +from faebryk.library.MultiSPI import MultiSPI +from faebryk.library.GenericBusProtection import GenericBusProtection +from faebryk.library.JTAG import JTAG +from faebryk.library.I2C import I2C +from faebryk.library.SWD import SWD +from faebryk.library.TXS0102DCUR import TXS0102DCUR +from faebryk.library.UART_Base import UART_Base +from faebryk.library.PoweredLED import PoweredLED +from faebryk.library.USB2_0 import USB2_0 +from faebryk.library.USB3_IF import USB3_IF +from faebryk.library.ButtonCell import ButtonCell +from faebryk.library.ElectricLogicGates import ElectricLogicGates +from faebryk.library.Logic74xx import Logic74xx +from faebryk.library.can_switch_power_defined import can_switch_power_defined +from faebryk.library.SPIFlash import SPIFlash +from faebryk.library.OLED_Module import OLED_Module +from faebryk.library.SCD40 import SCD40 +from faebryk.library.QWIIC_Connector import QWIIC_Connector +from faebryk.library.BH1750FVI_TR import BH1750FVI_TR +from faebryk.library.EEPROM import EEPROM +from faebryk.library.QWIIC import QWIIC +from faebryk.library.USB2514B import USB2514B +from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP +from faebryk.library.SWDConnector import SWDConnector +from faebryk.library.UART import UART +from faebryk.library.ESP32 import ESP32 +from faebryk.library.UART_RS485 import UART_RS485 +from faebryk.library.TD541S485H import TD541S485H +from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART +from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P +from faebryk.library.PM1006 import PM1006 +from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection +from faebryk.library.USBLC6_2P6 import USBLC6_2P6 +from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG +from faebryk.library.ESP32_C3 import ESP32_C3 +from faebryk.library.RP2040 import RP2040 +from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical +from faebryk.library.MCP2221A import MCP2221A +from faebryk.library.USB3 import USB3 +from faebryk.library.CD4011 import CD4011 +from faebryk.library.PowerSwitch import PowerSwitch +from faebryk.library.CH340x import CH340x +from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design +from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 +from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design +from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical +from faebryk.library.USB_C import USB_C +from faebryk.library.USB3_connector import USB3_connector +from faebryk.library.TI_CD4011BE import TI_CD4011BE +from faebryk.library.PowerSwitchStatic import PowerSwitchStatic +from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET +from faebryk.library.USB_RS485 import USB_RS485 +from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design +from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly +from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU +from faebryk.library.LEDIndicator import LEDIndicator +from faebryk.library.Powered_Relay import Powered_Relay diff --git a/src/faebryk/library/has_footprint.py b/src/faebryk/library/has_footprint.py index 58f15694..5d320f45 100644 --- a/src/faebryk/library/has_footprint.py +++ b/src/faebryk/library/has_footprint.py @@ -2,11 +2,14 @@ # SPDX-License-Identifier: MIT from abc import abstractmethod +from typing import TYPE_CHECKING -import faebryk.library._F as F from faebryk.core.module import Module +if TYPE_CHECKING: + from faebryk.library.Footprint import Footprint + class has_footprint(Module.TraitT): @abstractmethod - def get_footprint(self) -> F.Footprint: ... + def get_footprint(self) -> "Footprint": ... diff --git a/src/faebryk/library/has_kicad_footprint.py b/src/faebryk/library/has_kicad_footprint.py index 71ef6688..dd8fad7d 100644 --- a/src/faebryk/library/has_kicad_footprint.py +++ b/src/faebryk/library/has_kicad_footprint.py @@ -2,16 +2,20 @@ # SPDX-License-Identifier: MIT from abc import abstractmethod +from typing import TYPE_CHECKING import faebryk.library._F as F +if TYPE_CHECKING: + from faebryk.library.Pad import Pad + class has_kicad_footprint(F.Footprint.TraitT): @abstractmethod def get_kicad_footprint(self) -> str: ... @abstractmethod - def get_pin_names(self) -> dict[F.Pad, str]: ... + def get_pin_names(self) -> dict["Pad", str]: ... def get_kicad_footprint_name(self) -> str: return self.get_kicad_footprint().split(":")[-1] diff --git a/src/faebryk/library/has_linked_pad.py b/src/faebryk/library/has_linked_pad.py index 0a169157..9164f19e 100644 --- a/src/faebryk/library/has_linked_pad.py +++ b/src/faebryk/library/has_linked_pad.py @@ -2,11 +2,14 @@ # SPDX-License-Identifier: MIT from abc import abstractmethod +from typing import TYPE_CHECKING -import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +if TYPE_CHECKING: + from faebryk.library.Pad import Pad + class has_linked_pad(ModuleInterface.TraitT): @abstractmethod - def get_pad(self) -> F.Pad: ... + def get_pad(self) -> "Pad": ... diff --git a/src/faebryk/library/has_linked_pad_defined.py b/src/faebryk/library/has_linked_pad_defined.py index 5eee8bfa..68db2681 100644 --- a/src/faebryk/library/has_linked_pad_defined.py +++ b/src/faebryk/library/has_linked_pad_defined.py @@ -2,13 +2,18 @@ # SPDX-License-Identifier: MIT +from typing import TYPE_CHECKING + import faebryk.library._F as F +if TYPE_CHECKING: + from faebryk.library.Pad import Pad + class has_linked_pad_defined(F.has_linked_pad.impl()): - def __init__(self, pad: F.Pad) -> None: + def __init__(self, pad: "Pad") -> None: super().__init__() self.pad = pad - def get_pad(self) -> F.Pad: + def get_pad(self) -> "Pad": return self.pad diff --git a/src/faebryk/library/has_pcb_routing_strategy.py b/src/faebryk/library/has_pcb_routing_strategy.py index 64a8af60..26301f98 100644 --- a/src/faebryk/library/has_pcb_routing_strategy.py +++ b/src/faebryk/library/has_pcb_routing_strategy.py @@ -2,16 +2,19 @@ # SPDX-License-Identifier: MIT from abc import abstractmethod +from typing import TYPE_CHECKING from faebryk.core.trait import Trait -from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer -from faebryk.exporters.pcb.routing.util import Route + +if TYPE_CHECKING: + from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer + from faebryk.exporters.pcb.routing.util import Route # TODO remove transformer from here class has_pcb_routing_strategy(Trait): @abstractmethod - def calculate(self, transformer: PCB_Transformer) -> list[Route]: ... + def calculate(self, transformer: "PCB_Transformer") -> list["Route"]: ... def __preinit__(self): self.priority = 0.0 diff --git a/src/faebryk/library/has_single_electric_reference.py b/src/faebryk/library/has_single_electric_reference.py index f9d23a87..a8f6481a 100644 --- a/src/faebryk/library/has_single_electric_reference.py +++ b/src/faebryk/library/has_single_electric_reference.py @@ -3,11 +3,15 @@ from abc import abstractmethod +from typing import TYPE_CHECKING import faebryk.library._F as F from faebryk.core.trait import Trait +if TYPE_CHECKING: + from faebryk.library.ElectricPower import ElectricPower + class has_single_electric_reference(Trait): @abstractmethod - def get_reference(self) -> F.ElectricPower: ... + def get_reference(self) -> "ElectricPower": ... diff --git a/src/faebryk/library/has_single_electric_reference_defined.py b/src/faebryk/library/has_single_electric_reference_defined.py index dd957dc3..0aa751fd 100644 --- a/src/faebryk/library/has_single_electric_reference_defined.py +++ b/src/faebryk/library/has_single_electric_reference_defined.py @@ -1,13 +1,18 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +from typing import TYPE_CHECKING + import faebryk.library._F as F +if TYPE_CHECKING: + from faebryk.library.ElectricPower import ElectricPower + class has_single_electric_reference_defined(F.has_single_electric_reference.impl()): - def __init__(self, reference: F.ElectricPower) -> None: + def __init__(self, reference: "ElectricPower") -> None: super().__init__() self.reference = reference - def get_reference(self) -> F.ElectricPower: + def get_reference(self) -> "ElectricPower": return self.reference diff --git a/src/faebryk/libs/app/erc.py b/src/faebryk/libs/app/erc.py index 4b337725..0a850519 100644 --- a/src/faebryk/libs/app/erc.py +++ b/src/faebryk/libs/app/erc.py @@ -66,7 +66,7 @@ def simple_erc(G: Graph): electricpower = get_all_nodes_of_type(G, ElectricPower) logger.info(f"Checking {len(electricpower)} Power") for ep in electricpower: - if ep.IFs.lv.is_connected_to(ep.IFs.hv): + if ep.lv.is_connected_to(ep.hv): raise ERCFaultShort([ep], "shorted power") # shorted nets @@ -75,14 +75,14 @@ def simple_erc(G: Graph): for net in nets: collisions = { p[0] - for mif in net.IFs.part_of.get_direct_connections() + for mif in net.part_of.get_direct_connections() if (p := mif.get_parent()) and isinstance(p[0], Net) } if collisions: shorted = collisions | {net} raise ERCFaultShort( - [n.IFs.part_of for n in shorted], f"shorted nets: {shorted}" + [n.part_of for n in shorted], f"shorted nets: {shorted}" ) # net name collisions @@ -105,7 +105,7 @@ def simple_erc(G: Graph): # ] # logger.info(f"Checking {len(sym_fps)} symmetric footprints") # for fp in sym_fps: - # mifs = set(fp.IFs.get_all()) + # mifs = set(fp.get_all()) # checked = set() # for mif in mifs: # checked.add(mif) @@ -120,14 +120,14 @@ def simple_erc(G: Graph): and comp.get_trait(has_part_picked).get_part().partno == "REMOVE" ): continue - if comp.IFs.unnamed[0].is_connected_to(comp.IFs.unnamed[1]): - raise ERCFaultShort(comp.IFs.unnamed, "shorted component") + if comp.unnamed[0].is_connected_to(comp.unnamed[1]): + raise ERCFaultShort(comp.unnamed, "shorted component") ## unmapped Electricals # fps = [n for n in nodes if isinstance(n, Footprint)] # logger.info(f"Checking {len(fps)} footprints") # for fp in fps: - # for mif in fp.IFs.get_all(): + # for mif in fp.get_all(): # if not mif.get_direct_connections(): # raise ERCFault([mif], "no connections") diff --git a/src/faebryk/libs/examples/pickers.py b/src/faebryk/libs/examples/pickers.py index 16410df2..50f3e1a9 100644 --- a/src/faebryk/libs/examples/pickers.py +++ b/src/faebryk/libs/examples/pickers.py @@ -46,9 +46,9 @@ def pick_fuse(module: F.Fuse): def pick_mosfet(module: F.MOSFET): standard_pinmap = { - "1": module.IFs.gate, - "2": module.IFs.source, - "3": module.IFs.drain, + "1": module.gate, + "2": module.source, + "3": module.drain, } pick_module_by_params( module, @@ -189,7 +189,7 @@ def pick_led(module: F.LED): "forward_voltage": Constant(3.7 * P.volt), "max_current": Constant(100 * P.mA), }, - pinmap={"1": module.IFs.cathode, "2": module.IFs.anode}, + pinmap={"1": module.cathode, "2": module.anode}, ), PickerOption( part=LCSC_Part(partno="C72041"), @@ -199,7 +199,7 @@ def pick_led(module: F.LED): "forward_voltage": Constant(3.1 * P.volt), "max_current": Constant(100 * P.mA), }, - pinmap={"1": module.IFs.cathode, "2": module.IFs.anode}, + pinmap={"1": module.cathode, "2": module.anode}, ), PickerOption( part=LCSC_Part(partno="C72038"), @@ -209,7 +209,7 @@ def pick_led(module: F.LED): "forward_voltage": Constant(2.3 * P.volt), "max_current": Constant(60 * P.mA), }, - pinmap={"1": module.IFs.cathode, "2": module.IFs.anode}, + pinmap={"1": module.cathode, "2": module.anode}, ), ], ) @@ -225,8 +225,8 @@ def pick_tvs(module: F.TVS): "reverse_working_voltage": Constant(5 * P.V), }, pinmap={ - "1": module.IFs.cathode, - "2": module.IFs.anode, + "1": module.cathode, + "2": module.anode, }, ), ], @@ -256,8 +256,8 @@ def pick_battery(module: F.Battery): "shape": Constant(F.ButtonCell.Shape.Round), }, pinmap={ - "1": module.IFs.power.IFs.lv, - "2": module.IFs.power.IFs.hv, + "1": module.power.lv, + "2": module.power.hv, }, ), ], diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index 1bdeca58..6c06fa82 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -21,7 +21,8 @@ from tortoise.models import Model import faebryk.library._F as F -from faebryk.core.module import Module, Parameter +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter from faebryk.core.util import pretty_param_tree, pretty_params from faebryk.library.Set import Set from faebryk.libs.e_series import ( @@ -337,7 +338,7 @@ def attach( ) for name, value in zip([m.param_name for m in mapping], params): - getattr(module.PARAMs, name).override(value) + getattr(module, name).override(value) F.has_defined_descriptive_properties.add_properties_to( module, diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index b7218045..9e4ad242 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -12,6 +12,7 @@ from rich.progress import Progress +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.parameter import Parameter @@ -20,12 +21,6 @@ get_children, pretty_params, ) -from faebryk.library.ANY import ANY -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.Electrical import Electrical -from faebryk.library.has_picker import has_picker from faebryk.libs.util import NotNone, flatten logger = logging.getLogger(__name__) @@ -53,7 +48,7 @@ class PickerOption: part: Part params: dict[str, Parameter] | None = None filter: Callable[[Module], bool] | None = None - pinmap: dict[str, Electrical] | None = None + pinmap: dict[str, F.Electrical] | None = None info: dict[str | DescriptiveProperties, str] | None = None @@ -152,7 +147,8 @@ def pick_module_by_params(module: Module, options: Iterable[PickerOption]): return params = { - NotNone(p.get_parent())[1]: p.get_most_narrow() for p in module.PARAMs.get_all() + NotNone(p.get_parent())[1]: p.get_most_narrow() + for p in get_children(module, direct_only=True, types=Parameter) } options = list(options) @@ -162,7 +158,7 @@ def pick_module_by_params(module: Module, options: Iterable[PickerOption]): filter( lambda o: (not o.filter or o.filter(module)) and all( - v.is_subset_of(params.get(k, ANY())) + v.is_subset_of(params.get(k, F.ANY())) for k, v in (o.params or {}).items() if not k.startswith("_") ), @@ -173,7 +169,7 @@ def pick_module_by_params(module: Module, options: Iterable[PickerOption]): raise PickErrorParams(module, options) if option.pinmap: - module.add_trait(can_attach_to_footprint_via_pinmap(option.pinmap)) + module.add_trait(F.can_attach_to_footprint_via_pinmap(option.pinmap)) option.part.supplier.attach(module, option) module.add_trait(has_part_picked_defined(option.part)) @@ -188,10 +184,12 @@ def pick_module_by_params(module: Module, options: Iterable[PickerOption]): return option -def _get_mif_top_level_modules(mif: ModuleInterface): - return [n for n in mif.NODEs.get_all() if isinstance(n, Module)] + [ - m for nmif in mif.IFs.get_all() for m in _get_mif_top_level_modules(nmif) - ] +def _get_mif_top_level_modules(mif: ModuleInterface) -> set[Module]: + return get_children(mif, direct_only=True, types=Module) | { + m + for nmif in get_children(mif, direct_only=True, types=ModuleInterface) + for m in _get_mif_top_level_modules(nmif) + } class PickerProgress: @@ -241,7 +239,7 @@ def get_not_picked(m: Module): out = flatten( [ get_not_picked(mod) - for mif in m.IFs.get_all() + for mif in get_children(m, direct_only=True, types=ModuleInterface) for mod in _get_mif_top_level_modules(mif) ] ) @@ -249,7 +247,7 @@ def get_not_picked(m: Module): if m.has_trait(has_part_picked): return out - children = [c for c in m.NODEs.get_all() if isinstance(c, Module)] + children = get_children(m, direct_only=True, types=Module) if not children: return out + [m] @@ -271,19 +269,19 @@ def _pick_part_recursively(module: Module, progress: PickerProgress | None = Non # pick mif module parts - for mif in module.IFs.get_all(): + for mif in get_children(module, direct_only=True, types=ModuleInterface): for mod in _get_mif_top_level_modules(mif): _pick_part_recursively(mod, progress) # pick - if module.has_trait(has_picker): + if module.has_trait(F.has_picker): try: - module.get_trait(has_picker).pick() + module.get_trait(F.has_picker).pick() except PickError as e: # if no children, raise # This whole logic will be so much easier if the recursive # picker is just a normal picker - if not module.NODEs.get_all(): + if not get_children(module, direct_only=True): raise e if module.has_trait(has_part_picked): diff --git a/src/faebryk/tools/libadd.py b/src/faebryk/tools/libadd.py index 96ea458d..34277b0b 100644 --- a/src/faebryk/tools/libadd.py +++ b/src/faebryk/tools/libadd.py @@ -122,7 +122,7 @@ class _IFS(super().IFS()): def __init__(self): # boilerplate super().__init__() - self.IFs = self.IFS()(self) + self = self.IFS()(self) self.PARAMs = self.PARAMS()(self) self.NODEs = self.NODES()(self) diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index 76a140b2..7194033f 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -4,9 +4,9 @@ This file generates faebryk/src/faebryk/library/__init__.py """ -import glob import logging -import os +import re +from graphlib import TopologicalSorter from pathlib import Path from typing import Iterable @@ -16,19 +16,70 @@ OUT = DIR / "_F.py" +def try_(stmt: str, exc: str | type[Exception] | Iterable[type[Exception]]): + if isinstance(exc, type): + exc = exc.__name__ + if not isinstance(exc, str): + exc = f'({", ".join(e.__name__ for e in exc)})' + + return ( + f"try:\n {stmt}\nexcept {exc} as e:\n print('{stmt.split(' ')[-1]}', e)" + ) + + +def topo_sort(modules_out: dict[str, tuple[Path, str]]): + def find_deps(module_path: Path) -> set[str]: + f = module_path.read_text() + p = re.compile(r"[^a-zA-Z_0-9]F\.([a-zA-Z_][a-zA-Z_0-9]*)") + return set(p.findall(f)) + + if True: + # TODO careful collisions + all_modules = [ + (p.stem, p) + for p in DIR.parent.parent.rglob("*.py") + if not p.stem.startswith("_") + ] + else: + all_modules = [ + (module_name, module_path) + for module_name, (module_path, _) in modules_out.items() + ] + + topo_graph = { + module_name: find_deps(module_path) for module_name, module_path in all_modules + } + # for k, v in topo_graph.items(): + # print(k, v) + order = list(TopologicalSorter(topo_graph).static_order()) + + # TEST + seen = set() + for m in order: + if m not in topo_graph: + continue + for sub in topo_graph[m]: + if sub not in seen and sub in topo_graph: + raise Exception(f"Collision: {sub} after {m}") + seen.add(m) + + return [ + (module_name, modules_out[module_name][1]) + for module_name in order + if module_name in modules_out + ] + + def main(): assert DIR.exists() logger.info(f"Scanning {DIR} for modules") - module_files = glob.glob(str(DIR / "*.py")) - module_files = [ - os.path.basename(f)[:-3] for f in module_files if os.path.basename(f) != "_F.py" - ] + module_files = [p for p in DIR.glob("*.py") if not p.name.startswith("_")] logger.info(f"Found {len(module_files)} modules") - modules_out: dict[str, str] = {} + modules_out: dict[str, tuple[Path, str]] = {} # Import each module and add its class to the current namespace # for module_name in module_files: @@ -40,17 +91,15 @@ def main(): # # globals()[class_name] = getattr(module, class_name) # modules_out[module_name] = class_name - modules_out = {module_name: module_name for module_name in module_files} + # assuming class name is equal to file stem + modules_out = { + module_path.stem: (module_path, module_path.stem) + for module_path in module_files + } - logger.info(f"Found {len(modules_out)} classes") + modules_ordered = topo_sort(modules_out) - def try_(stmt: str, exc: str | type[Exception] | Iterable[type[Exception]]): - if isinstance(exc, type): - exc = exc.__name__ - if not isinstance(exc, str): - exc = f'({", ".join(e.__name__ for e in exc)})' - - return f"try:\n {stmt}\nexcept {exc}: ..." + logger.info(f"Found {len(modules_out)} classes") OUT.write_text( "# This file is part of the faebryk project\n" @@ -71,11 +120,11 @@ def try_(stmt: str, exc: str | type[Exception] | Iterable[type[Exception]]): "# flake8: noqa: E501\n" "\n" + "\n".join( - try_( - f"from faebryk.library.{module} import {class_}", - (AttributeError, ImportError), - ) - for module, class_ in sorted(modules_out.items(), key=lambda x: x[0]) + # try_( + f"from faebryk.library.{module} import {class_}" + # (AttributeError,), + # ) + for module, class_ in modules_ordered ) + "\n" ) From b25ddb1a6130cfb962ba56ba5a2a70fc4dedd527 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 04:40:23 +0200 Subject: [PATCH 20/63] syntax fix examples --- examples/iterative_design_nand.py | 67 ++++----- examples/minimal_led.py | 21 +-- examples/pcb_layout.py | 32 ++--- examples/route.py | 231 ++++++++++++++---------------- 4 files changed, 150 insertions(+), 201 deletions(-) diff --git a/examples/iterative_design_nand.py b/examples/iterative_design_nand.py index e319cbca..36489f0c 100644 --- a/examples/iterative_design_nand.py +++ b/examples/iterative_design_nand.py @@ -23,42 +23,31 @@ specialize_interface, specialize_module, ) -from faebryk.library._F import Constant from faebryk.libs.brightness import TypicalLuminousIntensity from faebryk.libs.examples.buildutil import apply_design_to_pcb +from faebryk.libs.library import L from faebryk.libs.logging import setup_basic_logging from faebryk.libs.units import P -from faebryk.libs.util import times logger = logging.getLogger(__name__) class PowerSource(Module): - def __init__(self) -> None: - super().__init__() - - class IFS(Module.IFS()): - power = F.ElectricPower() - - self.IFs = IFS(self) + power: F.ElectricPower class XOR_with_NANDS(F.LogicGates.XOR): - def __init__( - self, - ): - super().__init__(Constant(2)) - - class NODES(Module.NODES()): - nands = times(4, lambda: F.LogicGates.NAND(Constant(2))) + nands = L.if_list(4, lambda: F.LogicGates.NAND(F.Constant(2))) - self.NODEs = NODES(self) + def __init__(self): + super().__init__(F.Constant(2)) - A = self.IFs.inputs[0] - B = self.IFs.inputs[1] + def __preinit__(self): + A = self.inputs[0] + B = self.inputs[1] - G = self.NODEs.nands - Q = self.IFs.outputs[0] + G = self.nands + Q = self.outputs[0] # ~(a&b) q0 = G[0].get_trait(F.LogicOps.can_logic_nand).nand(A, B) @@ -81,18 +70,18 @@ def App(): power_source = PowerSource() # alias - power = power_source.IFs.power + power = power_source.power # logic logic_in = F.Logic() logic_out = F.Logic() - xor = F.LogicGates.XOR(Constant(2)) + xor = F.LogicGates.XOR(F.Constant(2)) logic_out.connect(xor.get_trait(F.LogicOps.can_logic_xor).xor(logic_in, on)) # led led = F.LEDIndicator() - led.IFs.power_in.connect(power) + led.power_in.connect(power) # application switch = F.Switch(F.Logic)() @@ -104,15 +93,15 @@ def App(): e_out = specialize_interface(logic_out, F.ElectricLogic()) e_on = specialize_interface(on, F.ElectricLogic()) e_off = specialize_interface(off, F.ElectricLogic()) - e_in.IFs.reference.connect(power) - e_out.IFs.reference.connect(power) - e_on.IFs.reference.connect(power) - e_off.IFs.reference.connect(power) + e_in.reference.connect(power) + e_out.reference.connect(power) + e_on.reference.connect(power) + e_off.reference.connect(power) e_in.set_weak(on=False) e_on.set(on=True) e_off.set(on=False) - e_out.connect(led.IFs.logic_in) + e_out.connect(led.logic_in) nxor = specialize_module(xor, XOR_with_NANDS()) battery = specialize_module(power_source, F.Battery()) @@ -122,36 +111,34 @@ def App(): e_switch = specialize_module( el_switch, e_switch, - matrix=[ - (e, el.IFs.signal) - for e, el in zip(e_switch.IFs.unnamed, el_switch.IFs.unnamed) - ], + matrix=[(e, el.signal) for e, el in zip(e_switch.unnamed, el_switch.unnamed)], ) # build graph app = Module() - app.NODEs.components = [ + for c in [ led, switch, battery, e_switch, - ] + ]: + app.add(c) # parametrizing for _, t in get_all_nodes_with_trait(app.get_graph(), F.ElectricLogic.has_pulls): for pull_resistor in (r for r in t.get_pulls() if r): - pull_resistor.PARAMs.resistance.merge(100 * P.kohm) - power_source.IFs.power.PARAMs.voltage.merge(3 * P.V) - led.NODEs.led.NODEs.led.PARAMs.brightness.merge( + pull_resistor.resistance.merge(100 * P.kohm) + power_source.power.voltage.merge(3 * P.V) + led.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) # packages single nands as explicit IC nand_ic = F.TI_CD4011BE() - for ic_nand, xor_nand in zip(nand_ic.NODEs.gates, nxor.NODEs.nands): + for ic_nand, xor_nand in zip(nand_ic.gates, nxor.nands): specialize_module(xor_nand, ic_nand) - app.NODEs.nand_ic = nand_ic + app.add(nand_ic) return app diff --git a/examples/minimal_led.py b/examples/minimal_led.py index 327590b3..a48349a7 100644 --- a/examples/minimal_led.py +++ b/examples/minimal_led.py @@ -12,29 +12,22 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.brightness import TypicalLuminousIntensity -from faebryk.libs.examples.buildutil import ( - apply_design_to_pcb, -) +from faebryk.libs.examples.buildutil import apply_design_to_pcb from faebryk.libs.logging import setup_basic_logging logger = logging.getLogger(__name__) class App(Module): - def __init__(self) -> None: - super().__init__() + led: F.PoweredLED + battery: F.Battery - class _NODES(Module.NODES()): - led = F.PoweredLED() - battery = F.Battery() - - self.NODEs = _NODES(self) - - self.NODEs.led.IFs.power.connect(self.NODEs.battery.IFs.power) + def __preinit__(self) -> None: + self.led.power.connect(self.battery.power) # Parametrize - self.NODEs.led.NODEs.led.PARAMs.color.merge(F.LED.Color.YELLOW) - self.NODEs.led.NODEs.led.PARAMs.brightness.merge( + self.led.led.color.merge(F.LED.Color.YELLOW) + self.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) diff --git a/examples/pcb_layout.py b/examples/pcb_layout.py index e68ee6ac..d9d18816 100644 --- a/examples/pcb_layout.py +++ b/examples/pcb_layout.py @@ -14,39 +14,29 @@ from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy -from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined import has_pcb_position_defined from faebryk.libs.brightness import TypicalLuminousIntensity -from faebryk.libs.examples.buildutil import ( - apply_design_to_pcb, -) +from faebryk.libs.examples.buildutil import apply_design_to_pcb from faebryk.libs.logging import setup_basic_logging logger = logging.getLogger(__name__) class App(Module): - def __init__(self) -> None: - super().__init__() + leds: F.PoweredLED + battery: F.Battery - class _NODES(Module.NODES()): - leds = F.PoweredLED() - battery = F.Battery() - - self.NODEs = _NODES(self) - - self.NODEs.leds.IFs.power.connect(self.NODEs.battery.IFs.power) + def __preinit__(self) -> None: + self.leds.power.connect(self.battery.power) # Parametrize - self.NODEs.leds.NODEs.led.PARAMs.color.merge(F.LED.Color.YELLOW) - self.NODEs.leds.NODEs.led.PARAMs.brightness.merge( + self.leds.led.color.merge(F.LED.Color.YELLOW) + self.leds.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) # Layout - Point = has_pcb_position.Point - L = has_pcb_position.layer_type + Point = F.has_pcb_position.Point + L = F.has_pcb_position.layer_type layout = LayoutTypeHierarchy( layouts=[ @@ -68,8 +58,8 @@ class _NODES(Module.NODES()): ), ] ) - self.add_trait(has_pcb_layout_defined(layout)) - self.add_trait(has_pcb_position_defined(Point((50, 50, 0, L.NONE)))) + self.add_trait(F.has_pcb_layout_defined(layout)) + self.add_trait(F.has_pcb_position_defined(Point((50, 50, 0, L.NONE)))) # Boilerplate ----------------------------------------------------------------- diff --git a/examples/route.py b/examples/route.py index 8259b2b5..f4a74e91 100644 --- a/examples/route.py +++ b/examples/route.py @@ -14,19 +14,10 @@ from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy from faebryk.exporters.pcb.routing.util import Path -from faebryk.library.Electrical import Electrical -from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import ( - has_pcb_routing_strategy_greedy_direct_line, -) -from faebryk.library.has_pcb_routing_strategy_manual import ( - has_pcb_routing_strategy_manual, -) from faebryk.libs.examples.buildutil import ( apply_design_to_pcb, ) +from faebryk.libs.library import L from faebryk.libs.logging import setup_basic_logging from faebryk.libs.units import P from faebryk.libs.util import times @@ -35,139 +26,126 @@ class SubArray(Module): + unnamed = L.if_list(2, F.Electrical) + resistors = L.if_list(2, F.Resistor) + def __init__(self, extrude_y: float): super().__init__() - - class _IFs(Module.IFS()): - unnamed = times(2, Electrical) - - self.IFs = _IFs(self) - - class _NODES(Module.NODES()): - resistors = times(2, F.Resistor) - - self.NODEs = _NODES(self) - - for resistor in self.NODEs.resistors: - resistor.PARAMs.resistance.merge(F.Constant(1000 * P.ohm)) - resistor.IFs.unnamed[0].connect(self.IFs.unnamed[0]) - resistor.IFs.unnamed[1].connect(self.IFs.unnamed[1]) - - self.add_trait( - has_pcb_layout_defined( - LayoutTypeHierarchy( - layouts=[ - LayoutTypeHierarchy.Level( - mod_type=F.Resistor, - layout=LayoutExtrude((0, extrude_y)), - ), - ] - ) - ) - ) - - self.add_trait( - has_pcb_routing_strategy_greedy_direct_line( - has_pcb_routing_strategy_greedy_direct_line.Topology.DIRECT + self._extrude_y = extrude_y + + def __preinit__(self): + for resistor in self.resistors: + resistor.resistance.merge(F.Constant(1000 * P.ohm)) + resistor.unnamed[0].connect(self.unnamed[0]) + resistor.unnamed[1].connect(self.unnamed[1]) + + @L.rt_field + def pcb_layout(self): + F.has_pcb_layout_defined( + LayoutTypeHierarchy( + layouts=[ + LayoutTypeHierarchy.Level( + mod_type=F.Resistor, + layout=LayoutExtrude((0, self._extrude_y)), + ), + ] ) ) - self.add_trait( - has_pcb_routing_strategy_manual( - [ - ( - [r.IFs.unnamed[1] for r in self.NODEs.resistors], - Path( - [ - Path.Track( - 0.1, - "F.Cu", - [ - (0, 0), - (2.5, 0), - (2.5, extrude_y), - (0, extrude_y), - ], - ), - ] - ), + pcb_routing_strategy = L.f_field(F.has_pcb_routing_strategy_greedy_direct_line)( + F.has_pcb_routing_strategy_greedy_direct_line.Topology.DIRECT + ) + + @L.rt_field + def pcb_routing_stategy_manual(self): + return F.has_pcb_routing_strategy_manual( + [ + ( + [r.unnamed[1] for r in self.resistors], + Path( + [ + Path.Track( + 0.1, + "F.Cu", + [ + (0, 0), + (2.5, 0), + (2.5, extrude_y), + (0, extrude_y), + ], + ), + ] ), - ( - [r.IFs.unnamed[0] for r in self.NODEs.resistors], - Path( - [ - Path.Track( - 0.1, - "F.Cu", - [ - (0, 0), - (-2.5, 0), - (-2.5, extrude_y), - (0, extrude_y), - ], - ), - ] - ), + ), + ( + [r.unnamed[0] for r in self.resistors], + Path( + [ + Path.Track( + 0.1, + "F.Cu", + [ + (0, 0), + (-2.5, 0), + (-2.5, extrude_y), + (0, extrude_y), + ], + ), + ] ), - ] - ) + ), + ] ) class ResistorArray(Module): + unnamed = L.if_list(2, F.Electrical) + resistors = L.if_list(2, F.Resistor) + def __init__(self, count: int, extrude_y: tuple[float, float]): super().__init__() - class _IFs(Module.IFS()): - unnamed = times(2, Electrical) - - self.IFs = _IFs(self) - - class _NODES(Module.NODES()): - resistors = times(count, lambda: SubArray(extrude_y[1])) - - self.NODEs = _NODES(self) - - for resistor in self.NODEs.resistors: - resistor.IFs.unnamed[0].connect(self.IFs.unnamed[0]) - resistor.IFs.unnamed[1].connect(self.IFs.unnamed[1]) - - self.add_trait( - has_pcb_layout_defined( - LayoutTypeHierarchy( - layouts=[ - LayoutTypeHierarchy.Level( - mod_type=SubArray, - layout=LayoutExtrude((0, extrude_y[0])), - ), - ] - ) + self._count = count + self._extrude_y = extrude_y + + def __preinit__(self): + for resistor in self.resistors: + resistor.unnamed[0].connect(self.unnamed[0]) + resistor.unnamed[1].connect(self.unnamed[1]) + + @L.rt_field + def pcb_layout(self): + return F.has_pcb_layout_defined( + LayoutTypeHierarchy( + layouts=[ + LayoutTypeHierarchy.Level( + mod_type=SubArray, + layout=LayoutExtrude((0, self._extrude_y[0])), + ), + ] ) ) - self.add_trait( - has_pcb_routing_strategy_greedy_direct_line( - has_pcb_routing_strategy_greedy_direct_line.Topology.DIRECT - ) - ) + pcb_routing_strategy = L.f_field(F.has_pcb_routing_strategy_greedy_direct_line)( + F.has_pcb_routing_strategy_greedy_direct_line.Topology.DIRECT + ) class App(Module): + @L.rt_field + def arrays(self): + return times(2, lambda: ResistorArray(self._count, self._extrude_y)) + def __init__(self, count: int, extrude_y: tuple[float, float]) -> None: super().__init__() + self._count = count + self._extrude_y = extrude_y - class _NODES(Module.NODES()): - arrays = times(2, lambda: ResistorArray(count, extrude_y)) - - self.NODEs = _NODES(self) - - self.NODEs.arrays[0].IFs.unnamed[1].connect(self.NODEs.arrays[1].IFs.unnamed[0]) + def __preinit__(self): + self.arrays[0].unnamed[1].connect(self.arrays[1].unnamed[0]) - # Layout - Point = has_pcb_position.Point - L = has_pcb_position.layer_type - - layout = LayoutTypeHierarchy( + pcb_layout = L.f_field(F.has_pcb_layout_defined)( + LayoutTypeHierarchy( layouts=[ LayoutTypeHierarchy.Level( mod_type=ResistorArray, @@ -175,14 +153,15 @@ class _NODES(Module.NODES()): ), ] ) - self.add_trait(has_pcb_layout_defined(layout)) - self.add_trait(has_pcb_position_defined(Point((20, 20, 0, L.TOP_LAYER)))) + ) - self.add_trait( - has_pcb_routing_strategy_greedy_direct_line( - has_pcb_routing_strategy_greedy_direct_line.Topology.STAR - ) - ) + pcb_position = L.f_field(F.has_pcb_position_defined)( + F.has_pcb_position.Point((20, 20, 0, F.has_pcb_position.layer_type.TOP_LAYER)) + ) + + pcb_routing_strategy = L.f_field(F.has_pcb_routing_strategy_greedy_direct_line)( + F.has_pcb_routing_strategy_greedy_direct_line.Topology.STAR + ) # Boilerplate ----------------------------------------------------------------- From 39d8dede7e98e5d6cc80c04e8a17ca015178c43d Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 04:43:29 +0200 Subject: [PATCH 21/63] graph import errors --- src/faebryk/exporters/esphome/esphome.py | 2 +- src/faebryk/exporters/netlist/netlist.py | 2 +- src/faebryk/libs/app/designators.py | 2 +- src/faebryk/libs/app/erc.py | 4 +++- src/faebryk/libs/examples/buildutil.py | 13 +------------ test/core/test_performance.py | 6 +++--- 6 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/faebryk/exporters/esphome/esphome.py b/src/faebryk/exporters/esphome/esphome.py index 86fb2e2a..a28d942d 100644 --- a/src/faebryk/exporters/esphome/esphome.py +++ b/src/faebryk/exporters/esphome/esphome.py @@ -6,7 +6,7 @@ import yaml -from faebryk.core.core import Graph, Parameter +from faebryk.core.graphinterface import Graph, Parameter from faebryk.core.util import get_all_nodes_with_trait from faebryk.library.Constant import Constant from faebryk.library.has_esphome_config import has_esphome_config diff --git a/src/faebryk/exporters/netlist/netlist.py b/src/faebryk/exporters/netlist/netlist.py index eadde0f5..f2ba6b62 100644 --- a/src/faebryk/exporters/netlist/netlist.py +++ b/src/faebryk/exporters/netlist/netlist.py @@ -4,7 +4,7 @@ import logging from dataclasses import dataclass -from faebryk.core.core import Graph +from faebryk.core.graphinterface import Graph from faebryk.core.util import get_all_nodes_of_type, get_all_nodes_with_trait from faebryk.library.has_footprint import has_footprint from faebryk.library.has_overriden_name import has_overriden_name diff --git a/src/faebryk/libs/app/designators.py b/src/faebryk/libs/app/designators.py index 7e93f49c..dc199154 100644 --- a/src/faebryk/libs/app/designators.py +++ b/src/faebryk/libs/app/designators.py @@ -8,7 +8,7 @@ from pathlib import Path from typing import cast -from faebryk.core.core import Graph +from faebryk.core.graphinterface import Graph from faebryk.core.util import ( get_all_nodes_by_names, get_all_nodes_with_trait, diff --git a/src/faebryk/libs/app/erc.py b/src/faebryk/libs/app/erc.py index 0a850519..b33bac5c 100644 --- a/src/faebryk/libs/app/erc.py +++ b/src/faebryk/libs/app/erc.py @@ -5,7 +5,9 @@ import logging from typing import Callable, Iterable, Sequence -from faebryk.core.core import Graph, Module, ModuleInterface +from faebryk.core.graphinterface import Graph +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.util import ( get_all_nodes_of_type, get_all_nodes_of_types, diff --git a/src/faebryk/libs/examples/buildutil.py b/src/faebryk/libs/examples/buildutil.py index 8176293f..b86c64f6 100644 --- a/src/faebryk/libs/examples/buildutil.py +++ b/src/faebryk/libs/examples/buildutil.py @@ -8,7 +8,6 @@ import faebryk.libs.picker.lcsc as lcsc from faebryk.core.module import Module from faebryk.core.util import get_all_modules -from faebryk.exporters.visualize.graph import render_sidebyside from faebryk.libs.app.checks import run_checks from faebryk.libs.app.parameters import replace_tbd_with_any from faebryk.libs.app.pcb import apply_design @@ -84,14 +83,4 @@ def apply_design_to_pcb(m: Module): def export_graph(g, show): - plt = render_sidebyside(g) - - GRAPH_OUT.parent.mkdir( - parents=True, - exist_ok=True, - ) - logging.info("Writing Experiment graph to {}".format(GRAPH_OUT.absolute())) - plt.savefig(GRAPH_OUT, format="png", bbox_inches="tight") - - if show: - plt.show() + raise NotImplementedError() diff --git a/test/core/test_performance.py b/test/core/test_performance.py index af32fe29..74ac8b3a 100644 --- a/test/core/test_performance.py +++ b/test/core/test_performance.py @@ -8,7 +8,7 @@ from typing import Callable import faebryk.core.util as core_util -from faebryk.core.core import GraphInterface, Module, ModuleInterface +from faebryk.core.graphinterface import GraphInterface, Module, ModuleInterface from faebryk.library.Resistor import Resistor from faebryk.libs.util import times @@ -177,7 +177,7 @@ def rec_connect(gs_sub: list[GraphInterface]): # self.assertLess(timings.times["connect"], 1200e-3) print(timings) print(f"----> Avg/connect: {per_connect*1e6:.2f} us") - from faebryk.core.core import GraphImpl + from faebryk.core.graphinterface import GraphImpl print("Counter", GraphImpl.counter, GraphImpl.counter - count) @@ -203,7 +203,7 @@ def test_graph_merge_it(self): print(timings) print(f"----> Avg/connect: {per_connect*1e6:.2f} us") - from faebryk.core.core import GraphImpl + from faebryk.core.graphinterface import GraphImpl print("Counter", GraphImpl.counter, GraphImpl.counter - count) From 1a133f397b82dbd1b292331f6dd3595e51a68d5a Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 23:01:24 +0200 Subject: [PATCH 22/63] Fix some examples & lib stuff; Add better trait handling --- README.md | 17 ++-- src/faebryk/core/node.py | 77 +++++++++++++------ src/faebryk/core/trait.py | 28 ++++++- src/faebryk/core/util.py | 6 +- .../parameters/parameters_to_file.py | 7 +- src/faebryk/library/has_footprint_impl.py | 11 ++- src/faebryk/libs/app/parameters.py | 5 +- src/faebryk/libs/logging.py | 17 ++++ src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 2 +- src/faebryk/libs/picker/jlcpcb/picker_lib.py | 6 +- src/faebryk/libs/picker/picker.py | 2 +- 11 files changed, 123 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index e155f6e0..f011ddce 100644 --- a/README.md +++ b/README.md @@ -37,20 +37,15 @@ from faebryk.libs.brightness import TypicalLuminousIntensity from faebryk.libs.examples.buildutil import apply_design_to_pcb class App(Module): - def __init__(self) -> None: - super().__init__() + led : F.PoweredLED + battery : F.Battery - class _NODES(Module.NODES()): - led = F.PoweredLED() - battery = F.Battery() - - self.NODEs = _NODES(self) - - self.NODEs.led.IFs.power.connect(self.NODEs.battery.IFs.power) + def __preinit__(self) -> None: + self.led.power.connect(self.battery.power) # Parametrize - self.NODEs.led.NODEs.led.PARAMs.color.merge(F.LED.Color.YELLOW) - self.NODEs.led.NODEs.led.PARAMs.brightness.merge( + self.led.led.color.merge(F.LED.Color.YELLOW) + self.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index ab5b51b2..6c1021d0 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -13,7 +13,14 @@ GraphInterfaceSelf, ) from faebryk.core.link import LinkNamedParent, LinkSibling -from faebryk.libs.util import KeyErrorNotFound, find, times, try_avoid_endless_recursion +from faebryk.libs.exceptions import FaebrykException +from faebryk.libs.util import ( + KeyErrorNotFound, + cast_assert, + find, + times, + try_avoid_endless_recursion, +) if TYPE_CHECKING: from faebryk.core.trait import Trait, TraitImpl @@ -33,8 +40,10 @@ class FieldContainerError(FieldError): pass -def if_list[T](n: int, if_type: Callable[[], T]) -> list[T]: - return d_field(lambda: times(n, if_type)) +def if_list[T: Node](n: int, if_type: type[T]) -> list[T]: + out = d_field(lambda: times(n, if_type)) + out.type = if_type + return out class fab_field: @@ -89,6 +98,12 @@ def __call__(cls, *args, **kwargs): return obj +class NodeException(FaebrykException): + def __init__(self, node: "Node", *args: object) -> None: + super().__init__(*args) + self.node = node + + class Node(FaebrykLibObject, metaclass=PostInitCaller): runtime_anon: list["Node"] runtime: dict[str, "Node"] @@ -356,7 +371,20 @@ def _handle_add_node(self, name: str, node: "Node"): assert not ( other_p := node.get_parent() ), f"{node} already has parent: {other_p}" + + from faebryk.core.trait import TraitImpl + + if isinstance(node, TraitImpl): + if self.has_trait(node._trait): + node.handle_duplicate( + cast_assert(TraitImpl, self.get_trait(node._trait)) + ) + node.parent.connect(self.children, LinkNamedParent.curry(name)) + node.on_obj_set() + + # TODO rename + def on_obj_set(self): ... def handle_added_to_parent(self): ... @@ -410,42 +438,41 @@ def add_trait[_TImpl: "TraitImpl"](self, trait: _TImpl) -> _TImpl: return trait - def _find(self, trait, only_implemented: bool): + def _find[V: "Trait"](self, trait: type[V], only_implemented: bool) -> V | None: from faebryk.core.trait import TraitImpl from faebryk.core.util import get_children - impls = get_children(self, direct_only=True, types=TraitImpl) - - return [ - impl - for impl in impls - if impl.implements(trait) - and (impl.is_implemented() or not only_implemented) - ] + out = get_children( + self, + direct_only=True, + types=TraitImpl, + f_filter=lambda impl: impl.implements(trait) + and (impl.is_implemented() or not only_implemented), + ) + assert len(out) <= 1 + return cast_assert(trait, next(iter(out))) if out else None def del_trait(self, trait): - candidates = self._find(trait, only_implemented=False) - assert len(candidates) <= 1 - if len(candidates) == 0: + impl = self._find(trait, only_implemented=False) + if not impl: return - assert len(candidates) == 1, "{} not in {}[{}]".format(trait, type(self), self) - impl = candidates[0] impl.parent.disconnect(impl) + def try_get_trait[V: "Trait"](self, trait: Type[V]) -> V | None: + return self._find(trait, only_implemented=True) + def has_trait(self, trait) -> bool: - return len(self._find(trait, only_implemented=True)) > 0 + return self.try_get_trait(trait) is not None def get_trait[V: "Trait"](self, trait: Type[V]) -> V: - from faebryk.core.trait import TraitImpl + from faebryk.core.trait import TraitImpl, TraitNotFound assert not issubclass( trait, TraitImpl ), "You need to specify the trait, not an impl" - candidates = self._find(trait, only_implemented=True) - assert len(candidates) <= 1 - assert len(candidates) == 1, "{} not in {}[{}]".format(trait, type(self), self) + impl = self._find(trait, only_implemented=True) + if not impl: + raise TraitNotFound(self, trait) - out = candidates[0] - assert isinstance(out, trait) - return out + return cast_assert(trait, impl) diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index 2cee3b92..b71dd910 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -2,12 +2,32 @@ # SPDX-License-Identifier: MIT import logging -from faebryk.core.node import Node +from faebryk.core.node import Node, NodeException from faebryk.libs.util import cast_assert logger = logging.getLogger(__name__) +class TraitNotFound(NodeException): + def __init__(self, node: Node, trait: type["Trait"], *args: object) -> None: + super().__init__( + node, *args, f"Trait {trait} not found in {type(node)}[{node}]" + ) + self.trait = trait + + +class TraitAlreadyExists(NodeException): + def __init__(self, node: Node, trait: "TraitImpl", *args: object) -> None: + trait_type = trait._trait + super().__init__( + node, + *args, + f"Trait {trait_type} already exists in {node}: {node.get_trait(trait_type)}," + f" trying to add {trait}", + ) + self.trait = trait + + class Trait(Node): @classmethod def impl[T: "Trait"](cls: type[T]): @@ -16,7 +36,7 @@ class _Impl(TraitImpl, cls): ... return _Impl -class TraitImpl: +class TraitImpl(Node): _trait: type[Trait] def __preinit__(self) -> None: @@ -48,6 +68,10 @@ def on_obj_set(self): ... def remove_obj(self): self._obj = None + def handle_duplicate(self, other: "TraitImpl"): + assert other is not self + raise TraitAlreadyExists(self.obj, other) + @property def obj(self) -> Node: p = self.get_parent() diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 8f198782..6743ead9 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -1,6 +1,7 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +from ast import Call import logging from enum import Enum from textwrap import indent @@ -277,6 +278,7 @@ def get_children[T: Node]( direct_only: bool, types: type[T] | tuple[type[T], ...] = Node, include_root: bool = False, + f_filter: Callable[[T], bool] | None = None, ): if direct_only: children = get_node_direct_children_(node) @@ -285,7 +287,9 @@ def get_children[T: Node]( else: children = get_node_children_all(node, include_root=include_root) - filtered = {n for n in children if isinstance(n, types)} + filtered = { + n for n in children if isinstance(n, types) and (not f_filter or f_filter(n)) + } return filtered diff --git a/src/faebryk/exporters/parameters/parameters_to_file.py b/src/faebryk/exporters/parameters/parameters_to_file.py index b34d795c..8a295dc3 100644 --- a/src/faebryk/exporters/parameters/parameters_to_file.py +++ b/src/faebryk/exporters/parameters/parameters_to_file.py @@ -4,8 +4,9 @@ import logging from pathlib import Path -from faebryk.core.module import Module, Parameter -from faebryk.core.util import get_all_modules +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.core.util import get_all_modules, get_children logger = logging.getLogger(__name__) @@ -21,7 +22,7 @@ def export_parameters_to_file(module: Module, path: Path): }: parameters[m.get_full_name(types=True).split(".", maxsplit=1)[-1]] = [ {param.get_full_name().split(".")[-1]: param} - for param in m.PARAMs.get_all() + for param in get_children(m, direct_only=True, types=Parameter) ] logger.info(f"Writing parameters to {path}") diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index e3ae8b5c..ea2b7dab 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -2,15 +2,14 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.core.link import LinkNamedParent +from faebryk.core.util import get_children class has_footprint_impl(F.has_footprint.impl()): def set_footprint(self, fp: F.Footprint): - self.obj.children.connect(fp.parent, LinkNamedParent.curry("footprint")) + self.obj.add(fp, name="footprint") def get_footprint(self) -> F.Footprint: - children = self.obj.children.get_children() - fps = [c for _, c in children if isinstance(c, F.Footprint)] - assert len(fps) == 1, f"candidates: {fps}" - return fps[0] + fps = get_children(self.obj, direct_only=True, types=F.Footprint) + assert len(fps) == 1, f"In obj: {self.obj}: candidates: {fps}" + return next(iter(fps)) diff --git a/src/faebryk/libs/app/parameters.py b/src/faebryk/libs/app/parameters.py index 1fb3a9ed..40cb59ee 100644 --- a/src/faebryk/libs/app/parameters.py +++ b/src/faebryk/libs/app/parameters.py @@ -4,7 +4,8 @@ import logging from faebryk.core.module import Module -from faebryk.core.util import get_all_modules +from faebryk.core.parameter import Parameter +from faebryk.core.util import get_all_modules, get_children from faebryk.library.ANY import ANY from faebryk.library.TBD import TBD @@ -24,7 +25,7 @@ def replace_tbd_with_any(module: Module, recursive: bool, loglvl: int | None = N module = module.get_most_special() - for param in module.PARAMs.get_all(): + for param in get_children(module, direct_only=True, types=Parameter): if isinstance(param.get_most_narrow(), TBD): logger.debug(f"Replacing in {module}: {param} with ANY") param.merge(ANY()) diff --git a/src/faebryk/libs/logging.py b/src/faebryk/libs/logging.py index a53477f0..84b01aa8 100644 --- a/src/faebryk/libs/logging.py +++ b/src/faebryk/libs/logging.py @@ -8,6 +8,8 @@ from rich.logging import RichHandler from rich.theme import Theme +from faebryk.libs.util import ConfigFlag + class NodeHighlighter(RegexHighlighter): """ @@ -44,6 +46,9 @@ class NodeHighlighter(RegexHighlighter): } ) +PLOG = ConfigFlag("PLOG", descr="Enable picker debug log") +JLOG = ConfigFlag("JLOG", descr="Enable jlcpcb picker debug log") + def setup_basic_logging(rich: bool = True): logging.basicConfig( @@ -61,3 +66,15 @@ def setup_basic_logging(rich: bool = True): if rich else None, ) + + if PLOG: + from faebryk.library.has_multi_picker import logger as plog + + plog.setLevel(logging.DEBUG) + from faebryk.libs.picker.picker import logger as rlog + + rlog.setLevel(logging.DEBUG) + if JLOG: + from faebryk.libs.picker.jlcpcb.jlcpcb import logger as jlog + + jlog.setLevel(logging.DEBUG) diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index 6c06fa82..1aa903ef 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -512,7 +512,7 @@ def filter_by_module_params( if not all( pm := [ - p.is_subset_of(getattr(module.PARAMs, m.param_name)) + p.is_subset_of(getattr(module, m.param_name)) for p, m in zip(params, mapping) ] ): diff --git a/src/faebryk/libs/picker/jlcpcb/picker_lib.py b/src/faebryk/libs/picker/jlcpcb/picker_lib.py index a3682302..03c35426 100644 --- a/src/faebryk/libs/picker/jlcpcb/picker_lib.py +++ b/src/faebryk/libs/picker/jlcpcb/picker_lib.py @@ -154,7 +154,7 @@ def find_resistor(cmp: Module): ComponentQuery() .filter_by_category("Resistors", "Chip Resistor - Surface Mount") .filter_by_stock(qty) - .filter_by_value(cmp.PARAMs.resistance, "Ω", E_SERIES_VALUES.E96) + .filter_by_value(cmp.resistance, "Ω", E_SERIES_VALUES.E96) .filter_by_traits(cmp) .sort_by_price(qty) .filter_by_module_params_and_attach(cmp, mapping, qty) @@ -192,7 +192,7 @@ def find_capacitor(cmp: Module): ) .filter_by_stock(qty) .filter_by_traits(cmp) - .filter_by_value(cmp.PARAMs.capacitance, "F", E_SERIES_VALUES.E24) + .filter_by_value(cmp.capacitance, "F", E_SERIES_VALUES.E24) .sort_by_price(qty) .filter_by_module_params_and_attach(cmp, mapping, qty) ) @@ -236,7 +236,7 @@ def find_inductor(cmp: Module): .filter_by_category("Inductors", "Inductors") .filter_by_stock(qty) .filter_by_traits(cmp) - .filter_by_value(cmp.PARAMs.inductance, "H", E_SERIES_VALUES.E24) + .filter_by_value(cmp.inductance, "H", E_SERIES_VALUES.E24) .sort_by_price(qty) .filter_by_module_params_and_attach(cmp, mapping, qty) ) diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index 9e4ad242..68cd3702 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -281,7 +281,7 @@ def _pick_part_recursively(module: Module, progress: PickerProgress | None = Non # if no children, raise # This whole logic will be so much easier if the recursive # picker is just a normal picker - if not get_children(module, direct_only=True): + if not get_children(module, direct_only=True, types=Module): raise e if module.has_trait(has_part_picked): From cf0c31d2f5123a4e5e0378fad7c36f718042c09f Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 23:08:12 +0200 Subject: [PATCH 23/63] fix duplicate handle call --- src/faebryk/core/node.py | 2 +- src/faebryk/core/trait.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 6c1021d0..efb06c17 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -377,7 +377,7 @@ def _handle_add_node(self, name: str, node: "Node"): if isinstance(node, TraitImpl): if self.has_trait(node._trait): node.handle_duplicate( - cast_assert(TraitImpl, self.get_trait(node._trait)) + cast_assert(TraitImpl, self.get_trait(node._trait)), self ) node.parent.connect(self.children, LinkNamedParent.curry(name)) diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index b71dd910..5aa7beb7 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -68,9 +68,9 @@ def on_obj_set(self): ... def remove_obj(self): self._obj = None - def handle_duplicate(self, other: "TraitImpl"): + def handle_duplicate(self, other: "TraitImpl", node: Node): assert other is not self - raise TraitAlreadyExists(self.obj, other) + raise TraitAlreadyExists(node, other) @property def obj(self) -> Node: From b882590c454a5d9b091ddc68a531ef9395114c8d Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 23:38:56 +0200 Subject: [PATCH 24/63] implement trait deletion --- src/faebryk/core/graph.py | 4 ++++ src/faebryk/core/graph_backends/graphpy.py | 10 ++++++++++ src/faebryk/core/graphinterface.py | 3 +++ src/faebryk/core/node.py | 9 ++++++--- src/faebryk/core/trait.py | 6 +++--- src/faebryk/library/Constant.py | 4 ---- src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 2 +- 7 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/faebryk/core/graph.py b/src/faebryk/core/graph.py index a2a1ee27..a22e28ec 100644 --- a/src/faebryk/core/graph.py +++ b/src/faebryk/core/graph.py @@ -94,6 +94,10 @@ def v(self, obj: T): ... @abstractmethod def add_edge(self, from_obj: T, to_obj: T, link: "Link"): ... + # TODO implement everywhere + @abstractmethod + def remove_edge(self, from_obj: T, to_obj: T | None = None): ... + @abstractmethod def is_connected(self, from_obj: T, to_obj: T) -> "Link | None": ... diff --git a/src/faebryk/core/graph_backends/graphpy.py b/src/faebryk/core/graph_backends/graphpy.py index ab3dbbc5..1f382b17 100644 --- a/src/faebryk/core/graph_backends/graphpy.py +++ b/src/faebryk/core/graph_backends/graphpy.py @@ -40,6 +40,13 @@ def add_edge(self, from_obj: T, to_obj: T, link: L): self._v.add(from_obj) self._v.add(to_obj) + def remove_edge(self, from_obj: T, to_obj: T | None = None): + targets = [to_obj] if to_obj else list(self.edges(from_obj).keys()) + for target in targets: + self._e.remove((from_obj, target, self._e_cache[from_obj][target])) + del self._e_cache[from_obj][target] + del self._e_cache[target][from_obj] + def update(self, other: "PyGraph[T]"): self._v.update(other._v) self._e.extend(other._e) @@ -103,6 +110,9 @@ def v(self, obj: T): def add_edge(self, from_obj: T, to_obj: T, link: L): self().add_edge(from_obj, to_obj, link=link) + def remove_edge(self, from_obj: T, to_obj: T | None = None): + return self().remove_edge(from_obj, to_obj) + def is_connected(self, from_obj: T, to_obj: T) -> "Link | None": return self.get_edges(from_obj).get(to_obj) diff --git a/src/faebryk/core/graphinterface.py b/src/faebryk/core/graphinterface.py index 27317095..5d7718e2 100644 --- a/src/faebryk/core/graphinterface.py +++ b/src/faebryk/core/graphinterface.py @@ -133,5 +133,8 @@ def get_parent(self) -> tuple["Node", str] | None: return parent.node, conn.name + def disconnect_parent(self): + self.G.remove_edge(self) + class GraphInterfaceSelf(GraphInterface): ... diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index efb06c17..c2b996cf 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -383,6 +383,9 @@ def _handle_add_node(self, name: str, node: "Node"): node.parent.connect(self.children, LinkNamedParent.curry(name)) node.on_obj_set() + def _remove_child(self, node: "Node"): + node.parent.disconnect_parent() + # TODO rename def on_obj_set(self): ... @@ -452,16 +455,16 @@ def _find[V: "Trait"](self, trait: type[V], only_implemented: bool) -> V | None: assert len(out) <= 1 return cast_assert(trait, next(iter(out))) if out else None - def del_trait(self, trait): + def del_trait(self, trait: type["Trait"]): impl = self._find(trait, only_implemented=False) if not impl: return - impl.parent.disconnect(impl) + self._remove_child(impl) def try_get_trait[V: "Trait"](self, trait: Type[V]) -> V | None: return self._find(trait, only_implemented=True) - def has_trait(self, trait) -> bool: + def has_trait(self, trait: type["Trait"]) -> bool: return self.try_get_trait(trait) is not None def get_trait[V: "Trait"](self, trait: Type[V]) -> V: diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index 5aa7beb7..71d6db9c 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -22,8 +22,8 @@ def __init__(self, node: Node, trait: "TraitImpl", *args: object) -> None: super().__init__( node, *args, - f"Trait {trait_type} already exists in {node}: {node.get_trait(trait_type)}," - f" trying to add {trait}", + f"Trait {trait_type} already exists in {node}: {node.get_trait(trait_type)}" + f", trying to add {trait}", ) self.trait = trait @@ -70,7 +70,7 @@ def remove_obj(self): def handle_duplicate(self, other: "TraitImpl", node: Node): assert other is not self - raise TraitAlreadyExists(node, other) + raise TraitAlreadyExists(node, self) @property def obj(self) -> Node: diff --git a/src/faebryk/library/Constant.py b/src/faebryk/library/Constant.py index 66be93bd..3bb09406 100644 --- a/src/faebryk/library/Constant.py +++ b/src/faebryk/library/Constant.py @@ -12,10 +12,6 @@ class Constant[PV](Parameter[PV], Parameter[PV].SupportsSetOps): type LIT_OR_PARAM = Parameter[PV].LIT_OR_PARAM - @L.rt_field - def representable_by_single_value(self): - return F.is_representable_by_single_value_defined(self.value) - def __init__(self, value: LIT_OR_PARAM) -> None: super().__init__() self.value = value diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index 1aa903ef..2af891aa 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -356,8 +356,8 @@ def attach( }, ) - module.add_trait(has_part_picked_defined(JLCPCB_Part(self.partno))) attach(module, self.partno) + module.add_trait(has_part_picked_defined(JLCPCB_Part(self.partno))) if logger.isEnabledFor(logging.DEBUG): logger.debug( f"Attached component {self.partno} to module {module}: \n" From 2acc91a606900e70b906bd340eff249b0194a638 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Tue, 27 Aug 2024 23:48:02 +0200 Subject: [PATCH 25/63] cleaner handle_parent_add --- src/faebryk/core/node.py | 7 ++----- src/faebryk/core/trait.py | 23 +++++++++++------------ test/libs/picker/test_jlcpcb.py | 5 ++++- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index c2b996cf..9cd402aa 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -381,15 +381,12 @@ def _handle_add_node(self, name: str, node: "Node"): ) node.parent.connect(self.children, LinkNamedParent.curry(name)) - node.on_obj_set() + node._handle_added_to_parent() def _remove_child(self, node: "Node"): node.parent.disconnect_parent() - # TODO rename - def on_obj_set(self): ... - - def handle_added_to_parent(self): ... + def _handle_added_to_parent(self): ... def get_graph(self): return self.self_gif.G diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index 71d6db9c..3a473cf2 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -60,18 +60,6 @@ def __preinit__(self) -> None: assert issubclass(self._trait, Trait) assert self._trait is not TraitImpl - def handle_added_to_parent(self): - self.on_obj_set() - - def on_obj_set(self): ... - - def remove_obj(self): - self._obj = None - - def handle_duplicate(self, other: "TraitImpl", node: Node): - assert other is not self - raise TraitAlreadyExists(node, self) - @property def obj(self) -> Node: p = self.get_parent() @@ -100,6 +88,17 @@ def implements(self, trait: type): return issubclass(self._trait, trait) + # Overwriteable -------------------------------------------------------------------- + + def _handle_added_to_parent(self): + self.on_obj_set() + + def on_obj_set(self): ... + + def handle_duplicate(self, other: "TraitImpl", node: Node): + assert other is not self + raise TraitAlreadyExists(node, self) + # override this to implement a dynamic trait def is_implemented(self): return True diff --git a/test/libs/picker/test_jlcpcb.py b/test/libs/picker/test_jlcpcb.py index 4d659d21..ae03dc22 100644 --- a/test/libs/picker/test_jlcpcb.py +++ b/test/libs/picker/test_jlcpcb.py @@ -8,6 +8,8 @@ import faebryk.library._F as F import faebryk.libs.picker.lcsc as lcsc from faebryk.core.module import Module +from faebryk.core.parameter import Parameter +from faebryk.core.util import get_children from faebryk.libs.logging import setup_basic_logging from faebryk.libs.picker.jlcpcb.jlcpcb import JLCPCB_DB from faebryk.libs.picker.jlcpcb.pickers import add_jlcpcb_pickers @@ -92,7 +94,8 @@ def satisfies_requirements(self): ) for req, res in zip( - self.requirement.PARAMs.get_all(), self.result.PARAMs.get_all() + get_children(self.requirement, direct_only=True, types=Parameter), + get_children(self.result, direct_only=True, types=Parameter), ): req = req.get_most_narrow() res = res.get_most_narrow() From c66b86cdaffdb62a0b4fdf8349bedfb5e47ceb6b Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Wed, 28 Aug 2024 00:13:19 +0200 Subject: [PATCH 26/63] Move util imports --- src/faebryk/core/node.py | 1 + src/faebryk/core/util.py | 60 ++++++++----------- .../exporters/pcb/kicad/transformer.py | 48 +++++++-------- .../CBM9002A_56ILG_Reference_Design.py | 2 +- src/faebryk/library/Capacitor.py | 11 ++-- src/faebryk/library/Comparator.py | 3 +- src/faebryk/library/Diode.py | 3 +- src/faebryk/library/ESP32_C3.py | 3 +- src/faebryk/library/ElectricLogic.py | 6 +- src/faebryk/library/ElectricLogicGate.py | 3 +- src/faebryk/library/Footprint.py | 3 +- src/faebryk/library/GenericBusProtection.py | 3 +- src/faebryk/library/Inductor.py | 9 +-- src/faebryk/library/LDO.py | 3 +- src/faebryk/library/ME6211C33M5G_N.py | 3 +- src/faebryk/library/Net.py | 5 +- src/faebryk/library/OpAmp.py | 3 +- src/faebryk/library/Pad.py | 5 +- src/faebryk/library/Powered_Relay.py | 3 +- src/faebryk/library/Resistor.py | 9 +-- src/faebryk/library/USB2514B.py | 3 +- src/faebryk/library/USB_C_PSU_Vertical.py | 3 +- src/faebryk/library/_F.py | 24 ++++---- .../can_attach_to_footprint_symmetrically.py | 3 +- src/faebryk/library/has_equal_pins_in_ifs.py | 3 +- src/faebryk/library/has_footprint_impl.py | 3 +- ...pcb_routing_strategy_greedy_direct_line.py | 7 ++- .../has_pcb_routing_strategy_manual.py | 3 +- test/core/test_core.py | 10 ++-- 29 files changed, 132 insertions(+), 113 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 9cd402aa..09bcee4f 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -356,6 +356,7 @@ def __init__(self): self._is_setup = True def __preinit__(self): ... + def __postinit__(self): ... def __post_init__(self, *args, **kwargs): diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 6743ead9..36003126 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -1,7 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from ast import Call import logging from enum import Enum from textwrap import indent @@ -13,6 +12,7 @@ from typing_extensions import deprecated +import faebryk.library._F as F from faebryk.core.graphinterface import ( Graph, GraphInterface, @@ -25,14 +25,6 @@ from faebryk.core.node import Node from faebryk.core.parameter import Parameter from faebryk.core.trait import Trait -from faebryk.library.ANY import ANY -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.Constant import Constant -from faebryk.library.Electrical import Electrical -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.Range import Range -from faebryk.library.Set import Set -from faebryk.library.TBD import TBD from faebryk.libs.units import Quantity, UnitsContainer, to_si_str from faebryk.libs.util import NotNone, cast_assert, zip_dicts_by_key @@ -42,18 +34,18 @@ def enum_parameter_representation(param: Parameter, required: bool = False) -> str: - if isinstance(param, Constant): + if isinstance(param, F.Constant): return param.value.name if isinstance(param.value, Enum) else str(param.value) - elif isinstance(param, Range): + elif isinstance(param, F.Range): return ( f"{enum_parameter_representation(param.min)} - " f"{enum_parameter_representation(param.max)}" ) - elif isinstance(param, Set): + elif isinstance(param, F.Set): return f"Set({', '.join(map(enum_parameter_representation, param.params))})" - elif isinstance(param, TBD): + elif isinstance(param, F.TBD): return "TBD" if required else "" - elif isinstance(param, ANY): + elif isinstance(param, F.ANY): return "ANY" if required else "" else: return type(param).__name__ @@ -67,23 +59,23 @@ def as_unit( ) -> str: if base != 1000: raise NotImplementedError("Only base 1000 supported") - if isinstance(param, Constant): + if isinstance(param, F.Constant): return to_si_str(param.value, unit) - elif isinstance(param, Range): + elif isinstance(param, F.Range): return ( as_unit(param.min, unit, base=base) + " - " + as_unit(param.max, unit, base=base, required=True) ) - elif isinstance(param, Set): + elif isinstance(param, F.Set): return ( "Set(" + ", ".join(map(lambda x: as_unit(x, unit, required=True), param.params)) + ")" ) - elif isinstance(param, TBD): + elif isinstance(param, F.TBD): return "TBD" if required else "" - elif isinstance(param, ANY): + elif isinstance(param, F.ANY): return "ANY" if required else "" raise ValueError(f"Unsupported {param=}") @@ -92,15 +84,15 @@ def as_unit( def as_unit_with_tolerance( param: Parameter, unit: str, base: int = 1000, required: bool = False ) -> str: - if isinstance(param, Constant): + if isinstance(param, F.Constant): return as_unit(param, unit, base=base) - elif isinstance(param, Range): + elif isinstance(param, F.Range): center, delta = param.as_center_tuple(relative=True) delta_percent_str = f"±{to_si_str(delta.value, "%", 0)}" return ( f"{as_unit(center, unit, base=base, required=required)} {delta_percent_str}" ) - elif isinstance(param, Set): + elif isinstance(param, F.Set): return ( "Set(" + ", ".join( @@ -108,25 +100,25 @@ def as_unit_with_tolerance( ) + ")" ) - elif isinstance(param, TBD): + elif isinstance(param, F.TBD): return "TBD" if required else "" - elif isinstance(param, ANY): + elif isinstance(param, F.ANY): return "ANY" if required else "" raise ValueError(f"Unsupported {param=}") def get_parameter_max(param: Parameter): - if isinstance(param, Constant): + if isinstance(param, F.Constant): return param.value - if isinstance(param, Range): + if isinstance(param, F.Range): return param.max - if isinstance(param, Set): + if isinstance(param, F.Set): return max(map(get_parameter_max, param.params)) raise ValueError(f"Can't get max for {param}") def with_same_unit(to_convert: float | int, param: Parameter | Quantity | float | int): - if isinstance(param, Constant) and isinstance(param.value, Quantity): + if isinstance(param, F.Constant) and isinstance(param.value, Quantity): return Quantity(to_convert, param.value.units) if isinstance(param, Quantity): return Quantity(to_convert, param.units) @@ -257,7 +249,7 @@ def get_direct_connected_nodes[T: Node]( return cast(set[T], out) -def get_net(mif: Electrical): +def get_net(mif: F.Electrical): from faebryk.library.Net import Net nets = { @@ -446,7 +438,7 @@ def __init__(self) -> None: if_in = bridge_trait.get_in() if_out = bridge_trait.get_out() - self.add_trait(can_bridge_defined(if_out, if_in)) + self.add_trait(F.can_bridge_defined(if_out, if_in)) return _reversed_bridge() @@ -632,7 +624,7 @@ def use_interface_names_as_net_names(node: Node, name: str | None = None): name_prefix = node.get_full_name() - el_ifs = {n for n in get_all_nodes(node) if isinstance(n, Electrical)} + el_ifs = {n for n in get_all_nodes(node) if isinstance(n, F.Electrical)} # for el_if in el_ifs: # print(el_if) @@ -642,7 +634,7 @@ def use_interface_names_as_net_names(node: Node, name: str | None = None): resolved: set[ModuleInterface] = set() # get representative interfaces that determine the name of the Net - to_use: set[Electrical] = set() + to_use: set[F.Electrical] = set() for el_if in el_ifs: # performance if el_if in resolved: @@ -675,7 +667,7 @@ def use_interface_names_as_net_names(node: Node, name: str | None = None): # performance resolved.update(group) - nets: dict[str, tuple[Net, Electrical]] = {} + nets: dict[str, tuple[Net, F.Electrical]] = {} for el_if in to_use: net_name = f"{name}{el_if.get_full_name().removeprefix(name_prefix)}" @@ -694,7 +686,7 @@ def use_interface_names_as_net_names(node: Node, name: str | None = None): ) net = Net() - net.add_trait(has_overriden_name_defined(net_name)) + net.add_trait(F.has_overriden_name_defined(net_name)) net.part_of.connect(el_if) logger.debug(f"Created {net_name} for {el_if}") nets[net_name] = net, el_if diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index 5f958fde..f03c4984 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -14,6 +14,7 @@ from shapely import Polygon from typing_extensions import deprecated +import faebryk.library._F as F from faebryk.core.graphinterface import Graph from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface @@ -23,16 +24,6 @@ get_all_nodes_with_traits, get_children, ) -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import ( - Footprint as FFootprint, -) -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_kicad_footprint import has_kicad_footprint -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.Net import Net as FNet -from faebryk.library.Pad import Pad as FPad from faebryk.libs.geometry.basic import Geometry from faebryk.libs.kicad.fileformats import ( UUID, @@ -56,6 +47,9 @@ logger = logging.getLogger(__name__) +FPad = F.Pad +FNet = F.Net +FFootprint = F.Footprint PCB = C_kicad_pcb_file.C_kicad_pcb Footprint = PCB.C_pcb_footprint @@ -237,15 +231,15 @@ def attach(self): (f.propertys["Reference"].value, f.name): f for f in self.pcb.footprints } - for node, fpt in get_all_nodes_with_trait(self.graph, has_footprint): - if not node.has_trait(has_overriden_name): + for node, fpt in get_all_nodes_with_trait(self.graph, F.has_footprint): + if not node.has_trait(F.has_overriden_name): continue g_fp = fpt.get_footprint() - if not g_fp.has_trait(has_kicad_footprint): + if not g_fp.has_trait(F.has_kicad_footprint): continue - fp_ref = node.get_trait(has_overriden_name).get_name() - fp_name = g_fp.get_trait(has_kicad_footprint).get_kicad_footprint() + fp_ref = node.get_trait(F.has_overriden_name).get_name() + fp_name = g_fp.get_trait(F.has_kicad_footprint).get_kicad_footprint() assert ( fp_ref, @@ -259,7 +253,7 @@ def attach(self): g_fp.add_trait(self.has_linked_kicad_footprint_defined(fp, self)) node.add_trait(self.has_linked_kicad_footprint_defined(fp, self)) - pin_names = g_fp.get_trait(has_kicad_footprint).get_pin_names() + pin_names = g_fp.get_trait(F.has_kicad_footprint).get_pin_names() for fpad in get_children(g_fp, direct_only=True, types=ModuleInterface): pads = [ pad @@ -317,7 +311,7 @@ def get_fp(cmp) -> Footprint: def get_net(self, net: FNet) -> Net: nets = {pcb_net.name: pcb_net for pcb_net in self.pcb.nets} - return nets[net.get_trait(has_overriden_name).get_name()] + return nets[net.get_trait(F.has_overriden_name).get_name()] def get_edge(self) -> list[Point2D]: def geo_to_lines( @@ -408,8 +402,8 @@ def geo_to_lines( return list(poly.exterior.coords) @staticmethod - def _get_pad(ffp: FFootprint, intf: Electrical): - pin_map = ffp.get_trait(has_kicad_footprint).get_pin_names() + def _get_pad(ffp: FFootprint, intf: F.Electrical): + pin_map = ffp.get_trait(F.has_kicad_footprint).get_pin_names() pin_name = find( pin_map.items(), lambda pad_and_name: intf.is_connected_to(pad_and_name[0].net) is not None, @@ -421,14 +415,14 @@ def _get_pad(ffp: FFootprint, intf: Electrical): return fp, pad @staticmethod - def get_pad(intf: Electrical) -> tuple[Footprint, Pad, Node]: + def get_pad(intf: F.Electrical) -> tuple[Footprint, Pad, Node]: obj, ffp = FFootprint.get_footprint_of_parent(intf) fp, pad = PCB_Transformer._get_pad(ffp, intf) return fp, pad, obj @staticmethod - def get_pad_pos_any(intf: Electrical) -> list[tuple[FPad, Point]]: + def get_pad_pos_any(intf: F.Electrical) -> list[tuple[FPad, Point]]: try: fpads = FPad.find_pad_for_intf_with_parent_that_has_footprint(intf) except ValueError: @@ -438,7 +432,7 @@ def get_pad_pos_any(intf: Electrical) -> list[tuple[FPad, Point]]: return [PCB_Transformer._get_pad_pos(fpad) for fpad in fpads] @staticmethod - def get_pad_pos(intf: Electrical) -> tuple[FPad, Point] | None: + def get_pad_pos(intf: F.Electrical) -> tuple[FPad, Point] | None: try: fpad = FPad.find_pad_for_intf_with_parent_that_has_footprint_unique(intf) except ValueError: @@ -709,20 +703,20 @@ def insert_zone(self, net: Net, layers: str | list[str], polygon: list[Point2D]) def move_footprints(self): # position modules with defined positions pos_mods = get_all_nodes_with_traits( - self.graph, (has_pcb_position, self.has_linked_kicad_footprint) + self.graph, (F.has_pcb_position, self.has_linked_kicad_footprint) ) logger.info(f"Positioning {len(pos_mods)} footprints") for module, _ in pos_mods: fp = module.get_trait(self.has_linked_kicad_footprint).get_fp() - coord = module.get_trait(has_pcb_position).get_position() + coord = module.get_trait(F.has_pcb_position).get_position() layer_name = { - has_pcb_position.layer_type.TOP_LAYER: "F.Cu", - has_pcb_position.layer_type.BOTTOM_LAYER: "B.Cu", + F.has_pcb_position.layer_type.TOP_LAYER: "F.Cu", + F.has_pcb_position.layer_type.BOTTOM_LAYER: "B.Cu", } - if coord[3] == has_pcb_position.layer_type.NONE: + if coord[3] == F.has_pcb_position.layer_type.NONE: raise Exception(f"Component {module}({fp.name}) has no layer defined") logger.debug(f"Placing {fp.name} at {coord} layer {layer_name[coord[3]]}") diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index c392d6cd..7e6edc1f 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import connect_module_mifs_by_name from faebryk.libs.library import L from faebryk.libs.units import P @@ -49,6 +48,7 @@ class CBM9002A_56ILG_Reference_Design(Module): # ---------------------------------------- def __preinit__(self): gnd = self.vcc.lv + from faebryk.core.util import connect_module_mifs_by_name connect_module_mifs_by_name(self, self.mcu, allow_partial=True) diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index 81b4ada2..ecb132a8 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -6,11 +6,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import ( - as_unit, - as_unit_with_tolerance, - enum_parameter_representation, -) from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -43,6 +38,12 @@ def can_bridge(self): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import ( + as_unit, + as_unit_with_tolerance, + enum_parameter_representation, + ) + return F.has_simple_value_representation_based_on_params( ( self.capacitance, diff --git a/src/faebryk/library/Comparator.py b/src/faebryk/library/Comparator.py index 934c772a..e7c2905a 100644 --- a/src/faebryk/library/Comparator.py +++ b/src/faebryk/library/Comparator.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import as_unit from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -30,6 +29,8 @@ class OutputType(Enum): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import as_unit + return F.has_simple_value_representation_based_on_params( [ self.common_mode_rejection_ratio, diff --git a/src/faebryk/library/Diode.py b/src/faebryk/library/Diode.py index bcb74d77..caa64319 100644 --- a/src/faebryk/library/Diode.py +++ b/src/faebryk/library/Diode.py @@ -4,7 +4,6 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.parameter import Parameter -from faebryk.core.util import as_unit from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -25,6 +24,8 @@ def can_bridge(self): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import as_unit + return F.has_simple_value_representation_based_on_param( self.forward_voltage, lambda p: as_unit(p, "V"), diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 38a523a7..86896a10 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import connect_to_all_interfaces from faebryk.libs.library import L from faebryk.libs.units import P @@ -37,6 +36,8 @@ class ESP32_C3(Module): ) def __preinit__(self): + from faebryk.core.util import connect_to_all_interfaces + x = self # https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#uart diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 8cb77e85..29187a80 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -9,7 +9,6 @@ from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node -from faebryk.core.util import connect_all_interfaces, get_children from faebryk.libs.library import L @@ -145,6 +144,8 @@ def set_weak(self, on: bool): @staticmethod def connect_all_references(ifs: Iterable["ElectricLogic"]) -> F.ElectricPower: + from faebryk.core.util import connect_all_interfaces + out = connect_all_interfaces([x.reference for x in ifs]) assert out return out @@ -153,6 +154,7 @@ def connect_all_references(ifs: Iterable["ElectricLogic"]) -> F.ElectricPower: def connect_all_node_references( nodes: Iterable[Node], gnd_only=False ) -> F.ElectricPower: + from faebryk.core.util import connect_all_interfaces # TODO check if any child contains ElectricLogic which is not connected # e.g find them in graph and check if any has parent without "single reference" @@ -174,6 +176,8 @@ def connect_all_node_references( def connect_all_module_references( cls, node: Module | ModuleInterface, gnd_only=False ) -> F.ElectricPower: + from faebryk.core.util import get_children + return cls.connect_all_node_references( get_children(node, direct_only=True, types=(Module, ModuleInterface)), gnd_only=gnd_only, diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index 49acdb34..c99d714a 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.trait import TraitImpl -from faebryk.core.util import specialize_interface from faebryk.libs.library import L from faebryk.libs.util import times @@ -19,6 +18,8 @@ def __init__( output_cnt: F.Constant[int], *functions: TraitImpl, ) -> None: + from faebryk.core.util import specialize_interface + super().__init__(input_cnt, output_cnt, *functions) self.input_cnt = input_cnt diff --git a/src/faebryk/library/Footprint.py b/src/faebryk/library/Footprint.py index 24ec4949..f53ba3f5 100644 --- a/src/faebryk/library/Footprint.py +++ b/src/faebryk/library/Footprint.py @@ -7,7 +7,6 @@ from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node from faebryk.core.trait import Trait -from faebryk.core.util import get_parent_with_trait class Footprint(Module): @@ -17,5 +16,7 @@ class TraitT(Trait): ... def get_footprint_of_parent( intf: ModuleInterface, ) -> "tuple[Node, Footprint]": + from faebryk.core.util import get_parent_with_trait + parent, trait = get_parent_with_trait(intf, F.has_footprint) return parent, trait.get_footprint() diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index 1bdf1cd2..dc695aa4 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -6,7 +6,6 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface -from faebryk.core.util import get_children from faebryk.libs.library import L @@ -25,6 +24,8 @@ def __init__(self, bus_factory: Callable[[], T]) -> None: def __preinit__(self): def get_mifs[U: ModuleInterface](bus: T, mif_type: type[U]) -> set[U]: + from faebryk.core.util import get_children + return get_children(bus, direct_only=True, types=mif_type) raw = list( diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index 6a58f5d9..c624adf3 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -4,10 +4,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import ( - as_unit, - as_unit_with_tolerance, -) from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -28,6 +24,11 @@ def can_bridge(self): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import ( + as_unit, + as_unit_with_tolerance, + ) + return F.has_simple_value_representation_based_on_params( ( self.inductance, diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index 18e5ec6e..422d007e 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import as_unit, as_unit_with_tolerance from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -51,6 +50,8 @@ def can_bridge(self): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import as_unit, as_unit_with_tolerance + return F.has_simple_value_representation_based_on_params( ( self.output_polarity, diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index d7a802c5..679077af 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import connect_to_all_interfaces from faebryk.libs.library import L from faebryk.libs.units import P @@ -26,6 +25,8 @@ def __init__(self, default_enabled: bool = True) -> None: self._default_enabled = default_enabled def __preinit__(self): + from faebryk.core.util import connect_to_all_interfaces + # set constraints self.power_out.voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) diff --git a/src/faebryk/library/Net.py b/src/faebryk/library/Net.py index baae172b..7528e9ee 100644 --- a/src/faebryk/library/Net.py +++ b/src/faebryk/library/Net.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import get_connected_mifs, get_parent_of_type from faebryk.libs.library import L logger = logging.getLogger(__name__) @@ -43,6 +42,8 @@ def get_name(_self): return _() def get_fps(self): + from faebryk.core.util import get_parent_of_type + return { pad: fp for mif in self.get_connected_interfaces() @@ -52,6 +53,8 @@ def get_fps(self): # TODO should this be here? def get_connected_interfaces(self): + from faebryk.core.util import get_connected_mifs + return { mif for mif in get_connected_mifs(self.part_of.connected) diff --git a/src/faebryk/library/OpAmp.py b/src/faebryk/library/OpAmp.py index e33d0ea2..5dfef26d 100644 --- a/src/faebryk/library/OpAmp.py +++ b/src/faebryk/library/OpAmp.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import as_unit from faebryk.libs.library import L from faebryk.libs.units import Quantity @@ -24,6 +23,8 @@ class OpAmp(Module): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import as_unit + return F.has_simple_value_representation_based_on_params( [ self.bandwidth, diff --git a/src/faebryk/library/Pad.py b/src/faebryk/library/Pad.py index 465f11d1..2686a4a2 100644 --- a/src/faebryk/library/Pad.py +++ b/src/faebryk/library/Pad.py @@ -4,7 +4,6 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.core.util import get_children, get_parent_of_type class Pad(ModuleInterface): @@ -28,6 +27,8 @@ def find_pad_for_intf_with_parent_that_has_footprint_unique( def find_pad_for_intf_with_parent_that_has_footprint( intf: ModuleInterface, ) -> list["Pad"]: + from faebryk.core.util import get_children + # This only finds directly attached pads # -> misses from parents / children nodes if intf.has_trait(F.has_linked_pad): @@ -43,6 +44,8 @@ def find_pad_for_intf_with_parent_that_has_footprint( return pads def get_fp(self) -> F.Footprint: + from faebryk.core.util import get_parent_of_type + fp = get_parent_of_type(self, F.Footprint) assert fp return fp diff --git a/src/faebryk/library/Powered_Relay.py b/src/faebryk/library/Powered_Relay.py index 28d0b124..02f12fad 100644 --- a/src/faebryk/library/Powered_Relay.py +++ b/src/faebryk/library/Powered_Relay.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import connect_module_mifs_by_name from faebryk.libs.library import L logger = logging.getLogger(__name__) @@ -27,6 +26,8 @@ class Powered_Relay(Module): power: F.ElectricPower def __preinit__(self): + from faebryk.core.util import connect_module_mifs_by_name + connect_module_mifs_by_name(self, self.relay) self.relay_driver.power_in.connect(self.power) diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index 99d5d7ae..7f6a5a1e 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -6,10 +6,6 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.parameter import Parameter -from faebryk.core.util import ( - as_unit, - as_unit_with_tolerance, -) from faebryk.libs.library import L from faebryk.libs.picker.picker import PickError, has_part_picked_remove from faebryk.libs.units import P, Quantity @@ -31,6 +27,11 @@ def can_bridge(self): @L.rt_field def simple_value_representation(self): + from faebryk.core.util import ( + as_unit, + as_unit_with_tolerance, + ) + return F.has_simple_value_representation_based_on_params( ( self.resistance, diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index e50604cd..f784c5dc 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -6,7 +6,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import get_children from faebryk.libs.library import L logger = logging.getLogger(__name__) @@ -57,6 +56,8 @@ class InterfaceConfiguration(Enum): designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") def __preinit__(self): + from faebryk.core.util import get_children + if self.interface_configuration == USB2514B.InterfaceConfiguration.DEFAULT: self.CFG_SEL[0].pulled.pull(up=False) self.CFG_SEL[1].pulled.pull(up=False) diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index 92ee353b..c58cf23a 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -3,7 +3,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.util import connect_all_interfaces from faebryk.libs.library import L from faebryk.libs.units import P @@ -23,6 +22,8 @@ class USB_C_PSU_Vertical(Module): fuse: F.Fuse def __preinit__(self): + from faebryk.core.util import connect_all_interfaces + self.gnd_capacitor.capacitance.merge(100 * P.nF) self.gnd_capacitor.rated_voltage.merge(16 * P.V) self.gnd_resistor.resistance.merge(1 * P.Mohm) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index d6fc7675..670f73b8 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -16,9 +16,10 @@ # flake8: noqa: E501 from faebryk.library.has_pcb_position import has_pcb_position +from faebryk.library.Constant import Constant +from faebryk.library.Operation import Operation from faebryk.library.TBD import TBD from faebryk.library.Range import Range -from faebryk.library.Operation import Operation from faebryk.library.has_overriden_name import has_overriden_name from faebryk.library.has_capacitance import has_capacitance from faebryk.library.has_footprint import has_footprint @@ -48,6 +49,7 @@ from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY from faebryk.library.Logic import Logic +from faebryk.library.Set import Set from faebryk.library.has_overriden_name_defined import has_overriden_name_defined from faebryk.library.has_defined_capacitance import has_defined_capacitance from faebryk.library.Footprint import Footprint @@ -57,6 +59,7 @@ from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref +from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined @@ -87,20 +90,19 @@ from faebryk.library.Pad import Pad from faebryk.library.GDT import GDT from faebryk.library.Button import Button -from faebryk.library.Constant import Constant from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table from faebryk.library.RS485 import RS485 from faebryk.library.Ethernet import Ethernet +from faebryk.library.LogicGate import LogicGate from faebryk.library.has_footprint_defined import has_footprint_defined from faebryk.library.Net import Net from faebryk.library.has_equal_pins import has_equal_pins from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist -from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.Set import Set -from faebryk.library.LogicGate import LogicGate from faebryk.library.MOSFET import MOSFET +from faebryk.library.Diode import Diode from faebryk.library.BJT import BJT +from faebryk.library.LogicGates import LogicGates from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer @@ -109,8 +111,7 @@ from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs from faebryk.library.KicadFootprint import KicadFootprint -from faebryk.library.Diode import Diode -from faebryk.library.LogicGates import LogicGates +from faebryk.library.TVS import TVS from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF from faebryk.library.pf_533984002 import pf_533984002 from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin @@ -125,17 +126,16 @@ from faebryk.library.QFN import QFN from faebryk.library.SOIC import SOIC from faebryk.library.Mounting_Hole import Mounting_Hole -from faebryk.library.TVS import TVS +from faebryk.library.can_be_surge_protected import can_be_surge_protected +from faebryk.library.is_surge_protected import is_surge_protected from faebryk.library.Potentiometer import Potentiometer from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider from faebryk.library.is_decoupled import is_decoupled from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.can_be_surge_protected import can_be_surge_protected -from faebryk.library.is_surge_protected import is_surge_protected -from faebryk.library.is_decoupled_nodes import is_decoupled_nodes from faebryk.library.is_surge_protected_defined import is_surge_protected_defined -from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined +from faebryk.library.is_decoupled_nodes import is_decoupled_nodes from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined +from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined from faebryk.library.ElectricPower import ElectricPower from faebryk.library.Comparator import Comparator from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/can_attach_to_footprint_symmetrically.py b/src/faebryk/library/can_attach_to_footprint_symmetrically.py index a6ebf7e9..ae98cfe4 100644 --- a/src/faebryk/library/can_attach_to_footprint_symmetrically.py +++ b/src/faebryk/library/can_attach_to_footprint_symmetrically.py @@ -3,11 +3,12 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface -from faebryk.core.util import zip_children_by_name class can_attach_to_footprint_symmetrically(F.can_attach_to_footprint.impl()): def attach(self, footprint: F.Footprint): + from faebryk.core.util import zip_children_by_name + self.obj.add_trait(F.has_footprint_defined(footprint)) for i, j in zip_children_by_name(footprint, self.obj, ModuleInterface): diff --git a/src/faebryk/library/has_equal_pins_in_ifs.py b/src/faebryk/library/has_equal_pins_in_ifs.py index 08c0d671..6d00b5e0 100644 --- a/src/faebryk/library/has_equal_pins_in_ifs.py +++ b/src/faebryk/library/has_equal_pins_in_ifs.py @@ -2,11 +2,12 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.core.util import get_children class has_equal_pins_in_ifs(F.has_equal_pins.impl()): def get_pin_map(self): + from faebryk.core.util import get_children + return { p: str(i + 1) for i, p in enumerate(get_children(self.obj, direct_only=True, types=F.Pad)) diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index ea2b7dab..721eac75 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.core.util import get_children class has_footprint_impl(F.has_footprint.impl()): @@ -10,6 +9,8 @@ def set_footprint(self, fp: F.Footprint): self.obj.add(fp, name="footprint") def get_footprint(self) -> F.Footprint: + from faebryk.core.util import get_children + fps = get_children(self.obj, direct_only=True, types=F.Footprint) assert len(fps) == 1, f"In obj: {self.obj}: candidates: {fps}" return next(iter(fps)) diff --git a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py index 8e3286ae..2cbefa53 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py +++ b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py @@ -3,9 +3,9 @@ import logging from enum import Enum, auto +from typing import TYPE_CHECKING import faebryk.library._F as F -from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import ( DEFAULT_TRACE_WIDTH, Path, @@ -16,6 +16,9 @@ ) from faebryk.libs.geometry.basic import Geometry +if TYPE_CHECKING: + from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer + logger = logging.getLogger(__name__) @@ -29,7 +32,7 @@ def __init__(self, topology: Topology = Topology.DIRECT, priority: float = 0.0): super().__init__() self.topology = topology - def calculate(self, transformer: PCB_Transformer): + def calculate(self, transformer: "PCB_Transformer"): node = self.obj nets = get_internal_nets_of_node(node) diff --git a/src/faebryk/library/has_pcb_routing_strategy_manual.py b/src/faebryk/library/has_pcb_routing_strategy_manual.py index c2307395..8bf6794e 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_manual.py +++ b/src/faebryk/library/has_pcb_routing_strategy_manual.py @@ -5,7 +5,6 @@ import faebryk.library._F as F from faebryk.core.node import Node -from faebryk.core.util import get_parent_with_trait from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import ( Path, @@ -31,6 +30,8 @@ def __init__( self.absolute = absolute def calculate(self, transformer: PCB_Transformer): + from faebryk.core.util import get_parent_with_trait + node = self.obj nets = get_internal_nets_of_node(node) diff --git a/test/core/test_core.py b/test/core/test_core.py index 8612105d..567094af 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -5,9 +5,9 @@ from abc import abstractmethod from typing import cast -from faebryk.core.core import LinkDirect, LinkParent, LinkSibling, TraitImpl +from faebryk.core.link import LinkDirect, LinkParent, LinkSibling from faebryk.core.node import Node -from faebryk.core.trait import Trait +from faebryk.core.trait import Trait, TraitImpl class TestTraits(unittest.TestCase): @@ -140,12 +140,12 @@ class impl2(trait2.impl()): self.assertFalse(obj.has_trait(trait1)) # Test get obj - self.assertRaises(AssertionError, lambda: trait1_inst.get_obj()) + self.assertRaises(AssertionError, lambda: trait1_inst.obj) obj.add_trait(trait1_inst) _impl: TraitImpl = cast(TraitImpl, obj.get_trait(trait1)) - self.assertEqual(_impl.get_obj(), obj) + self.assertEqual(_impl.obj, obj) obj.del_trait(trait1) - self.assertRaises(AssertionError, lambda: trait1_inst.get_obj()) + self.assertRaises(AssertionError, lambda: trait1_inst.obj) # Test specific override obj.add_trait(impl2_inst) From c89546e0f9b752c12bda3a89de9a2588d61fc85c Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Wed, 28 Aug 2024 00:41:07 +0200 Subject: [PATCH 27/63] move around util import --- src/faebryk/core/node.py | 2 ++ src/faebryk/exporters/esphome/esphome.py | 6 +++-- src/faebryk/exporters/netlist/graph.py | 8 +++---- src/faebryk/exporters/netlist/netlist.py | 2 +- .../parameters/parameters_to_file.py | 2 +- .../exporters/pcb/kicad/transformer.py | 8 +++---- .../exporters/pcb/layout/typehierarchy.py | 2 +- src/faebryk/exporters/pcb/routing/routing.py | 7 +++--- src/faebryk/exporters/pcb/routing/util.py | 23 +++++++++++-------- src/faebryk/library/Mounting_Hole.py | 13 ++++++++--- src/faebryk/library/_F.py | 12 +++++----- src/faebryk/libs/app/parameters.py | 3 ++- src/faebryk/libs/picker/picker.py | 19 +++++++++++---- 13 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 09bcee4f..495a8645 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -477,3 +477,5 @@ def get_trait[V: "Trait"](self, trait: Type[V]) -> V: raise TraitNotFound(self, trait) return cast_assert(trait, impl) + + # Graph stuff ---------------------------------------------------------------------- diff --git a/src/faebryk/exporters/esphome/esphome.py b/src/faebryk/exporters/esphome/esphome.py index a28d942d..11b8dac2 100644 --- a/src/faebryk/exporters/esphome/esphome.py +++ b/src/faebryk/exporters/esphome/esphome.py @@ -6,8 +6,8 @@ import yaml -from faebryk.core.graphinterface import Graph, Parameter -from faebryk.core.util import get_all_nodes_with_trait +from faebryk.core.graphinterface import Graph +from faebryk.core.parameter import Parameter from faebryk.library.Constant import Constant from faebryk.library.has_esphome_config import has_esphome_config @@ -54,6 +54,8 @@ def merge_dicts(*dicts: dict) -> dict: def make_esphome_config(G: Graph) -> dict: + from faebryk.core.util import get_all_nodes_with_trait + esphome_components = get_all_nodes_with_trait(G, has_esphome_config) esphome_config = merge_dicts(*[t.get_config() for _, t in esphome_components]) diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index bf2b1aeb..1bb338e3 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -8,11 +8,6 @@ from faebryk.core.graphinterface import Graph from faebryk.core.module import Module -from faebryk.core.util import ( - get_all_nodes_with_trait, - get_children, - get_connected_mifs, -) from faebryk.exporters.netlist.netlist import T2Netlist from faebryk.library.Electrical import Electrical from faebryk.library.Footprint import Footprint @@ -112,6 +107,8 @@ def get_kicad_obj(self): def add_or_get_net(interface: Electrical): + from faebryk.core.util import get_connected_mifs + mifs = get_connected_mifs(interface.connected) nets = { p[0] @@ -128,6 +125,7 @@ def add_or_get_net(interface: Electrical): def attach_nets_and_kicad_info(g: Graph): + from faebryk.core.util import get_all_nodes_with_trait, get_children # g has to be closed Gclosed = g diff --git a/src/faebryk/exporters/netlist/netlist.py b/src/faebryk/exporters/netlist/netlist.py index f2ba6b62..cd8cb571 100644 --- a/src/faebryk/exporters/netlist/netlist.py +++ b/src/faebryk/exporters/netlist/netlist.py @@ -5,7 +5,6 @@ from dataclasses import dataclass from faebryk.core.graphinterface import Graph -from faebryk.core.util import get_all_nodes_of_type, get_all_nodes_with_trait from faebryk.library.has_footprint import has_footprint from faebryk.library.has_overriden_name import has_overriden_name @@ -38,6 +37,7 @@ class Vertex: def make_t2_netlist_from_graph(G: Graph) -> T2Netlist: + from faebryk.core.util import get_all_nodes_of_type, get_all_nodes_with_trait from faebryk.exporters.netlist.graph import can_represent_kicad_footprint from faebryk.library.Net import Net as FNet diff --git a/src/faebryk/exporters/parameters/parameters_to_file.py b/src/faebryk/exporters/parameters/parameters_to_file.py index 8a295dc3..1b35db65 100644 --- a/src/faebryk/exporters/parameters/parameters_to_file.py +++ b/src/faebryk/exporters/parameters/parameters_to_file.py @@ -6,13 +6,13 @@ from faebryk.core.module import Module from faebryk.core.parameter import Parameter -from faebryk.core.util import get_all_modules, get_children logger = logging.getLogger(__name__) def export_parameters_to_file(module: Module, path: Path): """Write all parameters of the given module to a file.""" + from faebryk.core.util import get_all_modules, get_children # {module_name: [{param_name: param_value}, {param_name: param_value},...]} parameters = dict[str, list[dict[str, Parameter]]]() diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index f03c4984..a16ccfb4 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -19,11 +19,6 @@ from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node -from faebryk.core.util import ( - get_all_nodes_with_trait, - get_all_nodes_with_traits, - get_children, -) from faebryk.libs.geometry.basic import Geometry from faebryk.libs.kicad.fileformats import ( UUID, @@ -230,6 +225,7 @@ def attach(self): footprints = { (f.propertys["Reference"].value, f.name): f for f in self.pcb.footprints } + from faebryk.core.util import get_all_nodes_with_trait, get_children for node, fpt in get_all_nodes_with_trait(self.graph, F.has_footprint): if not node.has_trait(F.has_overriden_name): @@ -701,6 +697,8 @@ def insert_zone(self, net: Net, layers: str | list[str], polygon: list[Point2D]) # Positioning ---------------------------------------------------------------------- def move_footprints(self): + from faebryk.core.util import get_all_nodes_with_traits + # position modules with defined positions pos_mods = get_all_nodes_with_traits( self.graph, (F.has_pcb_position, self.has_linked_kicad_footprint) diff --git a/src/faebryk/exporters/pcb/layout/typehierarchy.py b/src/faebryk/exporters/pcb/layout/typehierarchy.py index fe286ba7..3eb1f6e3 100644 --- a/src/faebryk/exporters/pcb/layout/typehierarchy.py +++ b/src/faebryk/exporters/pcb/layout/typehierarchy.py @@ -6,7 +6,6 @@ from faebryk.core.module import Module from faebryk.core.node import Node -from faebryk.core.util import get_node_direct_children from faebryk.exporters.pcb.layout.layout import Layout from faebryk.libs.util import NotNone, find_or, flatten, groupby @@ -27,6 +26,7 @@ def apply(self, *node: Node): """ Tip: Make sure at least one parent of node has an absolute position defined """ + from faebryk.core.util import get_node_direct_children # Find the layout for each node and group by matched level levels = groupby( diff --git a/src/faebryk/exporters/pcb/routing/routing.py b/src/faebryk/exporters/pcb/routing/routing.py index 57b76576..177f72b4 100644 --- a/src/faebryk/exporters/pcb/routing/routing.py +++ b/src/faebryk/exporters/pcb/routing/routing.py @@ -10,10 +10,6 @@ import networkx as nx -from faebryk.core.util import ( - get_all_nodes_of_type, - get_net, -) from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.grid import ( Coord, @@ -129,6 +125,7 @@ def draw_circle(self, coord: OutCoord, size=0.5, layer="User.9"): ) def route_all(self): + from faebryk.core.util import get_all_nodes_of_type from faebryk.library.Net import Net as FNet nets = get_all_nodes_of_type(self.transformer.graph, FNet) @@ -239,6 +236,8 @@ def route_net(self, net: Net): ) def route_if_net(self, mif): + from faebryk.core.util import get_net + net = get_net(mif) assert net is not None self.route_net(net) diff --git a/src/faebryk/exporters/pcb/routing/util.py b/src/faebryk/exporters/pcb/routing/util.py index 4f8bdeef..824a3868 100644 --- a/src/faebryk/exporters/pcb/routing/util.py +++ b/src/faebryk/exporters/pcb/routing/util.py @@ -3,23 +3,19 @@ import logging from dataclasses import dataclass -from typing import Iterable, Sequence +from typing import TYPE_CHECKING, Iterable, Sequence from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node -from faebryk.core.util import ( - get_all_nodes, - get_connected_mifs, - get_net, - get_parent_of_type, -) -from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.library.Electrical import Electrical from faebryk.library.Net import Net from faebryk.library.Pad import Pad from faebryk.libs.geometry.basic import Geometry +if TYPE_CHECKING: + from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer + # logging settings logger = logging.getLogger(__name__) @@ -119,7 +115,7 @@ def net(self): return net -def apply_route_in_pcb(route: Route, transformer: PCB_Transformer): +def apply_route_in_pcb(route: Route, transformer: "PCB_Transformer"): pcb_net = transformer.get_net(route.net) logger.debug(f"Insert tracks for net {pcb_net.name}, {pcb_net.number}, {route}") @@ -180,6 +176,11 @@ def get_internal_nets_of_node( For Nets returns all connected mifs """ + from faebryk.core.util import ( + get_all_nodes, + get_connected_mifs, + get_net, + ) from faebryk.libs.util import groupby if isinstance(node, Net): @@ -192,6 +193,8 @@ def get_internal_nets_of_node( def get_pads_pos_of_mifs(mifs: Sequence[Electrical]): + from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer + return { pad_pos[0]: pad_pos[1] for mif in mifs @@ -215,6 +218,8 @@ def group_pads_that_are_connected_already( def get_routes_of_pad(pad: Pad): + from faebryk.core.util import get_parent_of_type + return { route for mif in pad.pcb.get_direct_connections() diff --git a/src/faebryk/library/Mounting_Hole.py b/src/faebryk/library/Mounting_Hole.py index 87c7e8c1..2babd569 100644 --- a/src/faebryk/library/Mounting_Hole.py +++ b/src/faebryk/library/Mounting_Hole.py @@ -21,6 +21,13 @@ def __preinit__(self): # Only 3.2mm supported for now self.diameter.merge(F.Constant(3.2 * P.mm)) - footprint = L.f_field(F.has_footprint_defined)( - F.KicadFootprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) - ) + # footprint = L.f_field(F.has_footprint_defined)( + # F.KicadFootprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) + # ) + + # TODO make back to f_field, rt_field because of imports + @L.rt_field + def footprint(self): + return F.has_footprint_defined( + F.KicadFootprint("MountingHole:MountingHole_3.2mm_M3_Pad", pin_names=[]) + ) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 670f73b8..634431b9 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -16,10 +16,10 @@ # flake8: noqa: E501 from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.Constant import Constant from faebryk.library.Operation import Operation -from faebryk.library.TBD import TBD from faebryk.library.Range import Range +from faebryk.library.TBD import TBD +from faebryk.library.Constant import Constant from faebryk.library.has_overriden_name import has_overriden_name from faebryk.library.has_capacitance import has_capacitance from faebryk.library.has_footprint import has_footprint @@ -46,9 +46,9 @@ from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative from faebryk.library.has_pcb_position_defined import has_pcb_position_defined from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent +from faebryk.library.Logic import Logic from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY -from faebryk.library.Logic import Logic from faebryk.library.Set import Set from faebryk.library.has_overriden_name_defined import has_overriden_name_defined from faebryk.library.has_defined_capacitance import has_defined_capacitance @@ -73,10 +73,10 @@ from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined from faebryk.library.has_multi_picker import has_multi_picker from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined +from faebryk.library.LogicOps import LogicOps from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic from faebryk.library.SPI import SPI from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.LogicOps import LogicOps from faebryk.library.has_footprint_impl import has_footprint_impl from faebryk.library.can_attach_to_footprint import can_attach_to_footprint from faebryk.library.has_kicad_footprint import has_kicad_footprint @@ -90,19 +90,19 @@ from faebryk.library.Pad import Pad from faebryk.library.GDT import GDT from faebryk.library.Button import Button +from faebryk.library.LogicGate import LogicGate from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table from faebryk.library.RS485 import RS485 from faebryk.library.Ethernet import Ethernet -from faebryk.library.LogicGate import LogicGate from faebryk.library.has_footprint_defined import has_footprint_defined from faebryk.library.Net import Net from faebryk.library.has_equal_pins import has_equal_pins from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist +from faebryk.library.LogicGates import LogicGates from faebryk.library.MOSFET import MOSFET from faebryk.library.Diode import Diode from faebryk.library.BJT import BJT -from faebryk.library.LogicGates import LogicGates from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer diff --git a/src/faebryk/libs/app/parameters.py b/src/faebryk/libs/app/parameters.py index 40cb59ee..79d1f3b4 100644 --- a/src/faebryk/libs/app/parameters.py +++ b/src/faebryk/libs/app/parameters.py @@ -5,7 +5,6 @@ from faebryk.core.module import Module from faebryk.core.parameter import Parameter -from faebryk.core.util import get_all_modules, get_children from faebryk.library.ANY import ANY from faebryk.library.TBD import TBD @@ -19,6 +18,8 @@ def replace_tbd_with_any(module: Module, recursive: bool, loglvl: int | None = N :param module: The module to replace TBD instances in. :param recursive: If True, replace TBD instances in submodules as well. """ + from faebryk.core.util import get_all_modules, get_children + lvl = logger.getEffectiveLevel() if loglvl is not None: logger.setLevel(loglvl) diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index 68cd3702..0a36e665 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -16,11 +16,6 @@ from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.parameter import Parameter -from faebryk.core.util import ( - get_all_modules, - get_children, - pretty_params, -) from faebryk.libs.util import NotNone, flatten logger = logging.getLogger(__name__) @@ -92,6 +87,8 @@ def get_all_children(self): class PickErrorParams(PickError): def __init__(self, module: Module, options: list[PickerOption]): + from faebryk.core.util import pretty_params + self.options = options MAX = 5 @@ -142,6 +139,8 @@ def get_part(self) -> Part: def pick_module_by_params(module: Module, options: Iterable[PickerOption]): + from faebryk.core.util import get_children + if module.has_trait(has_part_picked): logger.debug(f"Ignoring already picked module: {module}") return @@ -185,6 +184,8 @@ def pick_module_by_params(module: Module, options: Iterable[PickerOption]): def _get_mif_top_level_modules(mif: ModuleInterface) -> set[Module]: + from faebryk.core.util import get_children + return get_children(mif, direct_only=True, types=Module) | { m for nmif in get_children(mif, direct_only=True, types=ModuleInterface) @@ -200,10 +201,14 @@ def __init__(self): @classmethod def from_module(cls, module: Module) -> "PickerProgress": self = cls() + from faebryk.core.util import get_all_modules + self.progress.update(self.task, total=len(get_all_modules(module))) return self def advance(self, module: Module): + from faebryk.core.util import get_all_modules + self.progress.advance(self.task, len(get_all_modules(module))) @contextmanager @@ -226,6 +231,8 @@ def pick_part_recursively(module: Module): # check if lowest children are picked def get_not_picked(m: Module): + from faebryk.core.util import get_children + ms = m.get_most_special() # check if parent is picked @@ -259,6 +266,8 @@ def get_not_picked(m: Module): def _pick_part_recursively(module: Module, progress: PickerProgress | None = None): + from faebryk.core.util import get_children + assert isinstance(module, Module) # pick only for most specialized module From a4ec66d0fd8643a9c78153a921858df7f780d366 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Wed, 28 Aug 2024 00:56:52 +0200 Subject: [PATCH 28/63] move some util stuff to node --- src/faebryk/core/moduleinterface.py | 6 +- src/faebryk/core/node.py | 60 ++++++++++++++- src/faebryk/core/util.py | 75 +++---------------- src/faebryk/exporters/netlist/graph.py | 4 +- .../parameters/parameters_to_file.py | 4 +- .../exporters/pcb/kicad/transformer.py | 4 +- src/faebryk/library/ElectricLogic.py | 4 +- src/faebryk/library/GenericBusProtection.py | 4 +- src/faebryk/library/Pad.py | 4 +- src/faebryk/library/USB2514B.py | 4 +- src/faebryk/library/has_equal_pins_in_ifs.py | 4 +- src/faebryk/library/has_footprint_impl.py | 4 +- src/faebryk/libs/app/parameters.py | 4 +- src/faebryk/libs/picker/picker.py | 24 ++---- 14 files changed, 89 insertions(+), 116 deletions(-) diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py index bc14a7bb..38e10c60 100644 --- a/src/faebryk/core/moduleinterface.py +++ b/src/faebryk/core/moduleinterface.py @@ -195,8 +195,6 @@ def _try_connect_down(self, other: "ModuleInterface", linkcls: type[Link]) -> No src.connect(dst, linkcls=linkcls) def _try_connect_up(self, other: "ModuleInterface") -> None: - from faebryk.core.util import get_children - p1 = self.get_parent() p2 = other.get_parent() if not ( @@ -217,8 +215,8 @@ def _is_connected(a, b): assert isinstance(b, ModuleInterface) return a.is_connected_to(b) - src_m_is = get_children(src_m, direct_only=True, types=ModuleInterface) - dst_m_is = get_children(dst_m, direct_only=True, types=ModuleInterface) + src_m_is = src_m.get_children(direct_only=True, types=ModuleInterface) + dst_m_is = dst_m.get_children(direct_only=True, types=ModuleInterface) connection_map = [ (src_i, dst_i, _is_connected(src_i, dst_i)) for src_i, dst_i in zip(src_m_is, dst_m_is) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 495a8645..90ba40d1 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT import logging from itertools import chain -from typing import TYPE_CHECKING, Any, Callable, Type, get_args, get_origin +from typing import TYPE_CHECKING, Any, Callable, Iterable, Type, get_args, get_origin from deprecated import deprecated @@ -441,10 +441,8 @@ def add_trait[_TImpl: "TraitImpl"](self, trait: _TImpl) -> _TImpl: def _find[V: "Trait"](self, trait: type[V], only_implemented: bool) -> V | None: from faebryk.core.trait import TraitImpl - from faebryk.core.util import get_children - out = get_children( - self, + out = self.get_children( direct_only=True, types=TraitImpl, f_filter=lambda impl: impl.implements(trait) @@ -479,3 +477,57 @@ def get_trait[V: "Trait"](self, trait: Type[V]) -> V: return cast_assert(trait, impl) # Graph stuff ---------------------------------------------------------------------- + + def get_node_direct_children_(self): + return { + gif.node + for gif, link in self.get_graph().get_edges(self.children).items() + if isinstance(link, LinkNamedParent) + } + + def get_children[T: Node]( + self, + direct_only: bool, + types: type[T] | tuple[type[T], ...], + include_root: bool = False, + f_filter: Callable[[T], bool] | None = None, + ): + if direct_only: + children = self.get_node_direct_children_() + if include_root: + children.add(self) + else: + children = self.get_node_children_all(include_root=include_root) + + filtered = { + n + for n in children + if isinstance(n, types) and (not f_filter or f_filter(n)) + } + + return filtered + + def get_node_children_all(self, include_root=True) -> list["Node"]: + # TODO looks like get_node_tree is 2x faster + + out = self.bfs_node( + lambda x: isinstance(x, (GraphInterfaceSelf, GraphInterfaceHierarchical)) + and x is not self.parent, + ) + + if not include_root: + out.remove(self) + + return list(out) + + def bfs_node(self, filter: Callable[[GraphInterface], bool]): + return Node.get_nodes_from_gifs( + self.get_graph().bfs_visit(filter, [self.self_gif]) + ) + + @staticmethod + def get_nodes_from_gifs(gifs: Iterable[GraphInterface]): + # TODO move this to gif? + return {gif.node for gif in gifs} + # TODO what is faster + # return {n.node for n in gifs if isinstance(n, GraphInterfaceSelf)} diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 36003126..03691a67 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -16,10 +16,9 @@ from faebryk.core.graphinterface import ( Graph, GraphInterface, - GraphInterfaceHierarchical, GraphInterfaceSelf, ) -from faebryk.core.link import Link, LinkDirect, LinkNamedParent +from faebryk.core.link import Link, LinkDirect from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node @@ -132,16 +131,6 @@ def with_same_unit(to_convert: float | int, param: Parameter | Quantity | float # Graph Querying ----------------------------------------------------------------------- -def bfs_node(node: Node, filter: Callable[[GraphInterface], bool]): - return get_nodes_from_gifs(node.get_graph().bfs_visit(filter, [node.self_gif])) - - -def get_nodes_from_gifs(gifs: Iterable[GraphInterface]): - return {gif.node for gif in gifs} - # TODO what is faster - # return {n.node for n in gifs if isinstance(n, GraphInterfaceSelf)} - - # Make all kinds of graph filtering functions so we can optimize them in the future # Avoid letting user query all graph nodes always because quickly very slow @@ -150,27 +139,12 @@ def node_projected_graph(g: Graph) -> set[Node]: """ Don't call this directly, use get_all_nodes_by/of/with instead """ - return get_nodes_from_gifs(g.subgraph_type(GraphInterfaceSelf)) + return Node.get_nodes_from_gifs(g.subgraph_type(GraphInterfaceSelf)) @deprecated("Use get_node_children_all") def get_all_nodes(node: Node, include_root=False) -> list[Node]: - return get_node_children_all(node, include_root=include_root) - - -def get_node_children_all(node: Node, include_root=True) -> list[Node]: - # TODO looks like get_node_tree is 2x faster - - out = bfs_node( - node, - lambda x: isinstance(x, (GraphInterfaceSelf, GraphInterfaceHierarchical)) - and x is not node.parent, - ) - - if not include_root: - out.remove(node) - - return list(out) + return node.get_node_children_all(include_root=include_root) def get_all_modules(node: Node) -> set[Module]: @@ -242,7 +216,7 @@ def get_connected_mifs_with_link(gif: GraphInterface): def get_direct_connected_nodes[T: Node]( gif: GraphInterface, ty: type[T] = Node ) -> set[T]: - out = get_nodes_from_gifs( + out = Node.get_nodes_from_gifs( g for g, t in get_all_connected(gif) if isinstance(t, LinkDirect) ) assert all(isinstance(n, ty) for n in out) @@ -265,27 +239,6 @@ def get_net(mif: F.Electrical): return next(iter(nets)) -def get_children[T: Node]( - node: Node, - direct_only: bool, - types: type[T] | tuple[type[T], ...] = Node, - include_root: bool = False, - f_filter: Callable[[T], bool] | None = None, -): - if direct_only: - children = get_node_direct_children_(node) - if include_root: - children.add(node) - else: - children = get_node_children_all(node, include_root=include_root) - - filtered = { - n for n in children if isinstance(n, types) and (not f_filter or f_filter(n)) - } - - return filtered - - @deprecated("Use get_node_direct_mods_or_mifs") def get_node_direct_children(node: Node, include_mifs: bool = True): return get_node_direct_mods_or_mifs(node, include_mifs=include_mifs) @@ -293,15 +246,7 @@ def get_node_direct_children(node: Node, include_mifs: bool = True): def get_node_direct_mods_or_mifs(node: Node, include_mifs: bool = True): types = (Module, ModuleInterface) if include_mifs else Module - return get_children(node, direct_only=True, types=types) - - -def get_node_direct_children_(node: Node): - return { - gif.node - for gif, link in node.get_graph().get_edges(node.children).items() - if isinstance(link, LinkNamedParent) - } + return node.get_children(direct_only=True, types=types) def get_node_tree( @@ -341,7 +286,7 @@ def zip_exhaust(*args): def get_mif_tree( obj: ModuleInterface | Module, ) -> dict[ModuleInterface, dict[ModuleInterface, dict]]: - mifs = get_children(obj, direct_only=True, types=ModuleInterface) + mifs = obj.get_children(direct_only=True, types=ModuleInterface) return {mif: get_mif_tree(mif) for mif in mifs} @@ -448,9 +393,7 @@ def zip_children_by_name[N: Node]( ) -> dict[str, tuple[N, N]]: nodes = (node1, node2) children = tuple( - with_names( - get_children(n, direct_only=True, include_root=False, types=sub_type) - ) + with_names(n.get_children(direct_only=True, include_root=False, types=sub_type)) for n in nodes ) return zip_dicts_by_key(*children) @@ -556,7 +499,7 @@ def get_parent_with_trait[TR: Trait](node: Node, trait: type[TR]): def get_children_of_type[U: Node](node: Node, child_type: type[U]) -> list[U]: - return list(get_children(node, direct_only=False, types=child_type)) + return list(node.get_children(direct_only=False, types=child_type)) def get_first_child_of_type[U: Node](node: Node, child_type: type[U]) -> U: @@ -575,7 +518,7 @@ def get_first_child_of_type[U: Node](node: Node, child_type: type[U]) -> U: def pretty_params(node: Module | ModuleInterface) -> str: params = { NotNone(p.get_parent())[1]: p.get_most_narrow() - for p in get_children(node, direct_only=True, types=Parameter) + for p in node.get_children(direct_only=True, types=Parameter) } params_str = "\n".join(f"{k}: {v}" for k, v in params.items()) diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index 1bb338e3..7c88dcca 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -125,7 +125,7 @@ def add_or_get_net(interface: Electrical): def attach_nets_and_kicad_info(g: Graph): - from faebryk.core.util import get_all_nodes_with_trait, get_children + from faebryk.core.util import get_all_nodes_with_trait # g has to be closed Gclosed = g @@ -151,5 +151,5 @@ def attach_nets_and_kicad_info(g: Graph): for fp in node_fps.values(): # TODO use graph - for mif in get_children(fp, direct_only=True, types=Pad): + for mif in fp.get_children(direct_only=True, types=Pad): add_or_get_net(mif.net) diff --git a/src/faebryk/exporters/parameters/parameters_to_file.py b/src/faebryk/exporters/parameters/parameters_to_file.py index 1b35db65..4e49f7ae 100644 --- a/src/faebryk/exporters/parameters/parameters_to_file.py +++ b/src/faebryk/exporters/parameters/parameters_to_file.py @@ -12,7 +12,7 @@ def export_parameters_to_file(module: Module, path: Path): """Write all parameters of the given module to a file.""" - from faebryk.core.util import get_all_modules, get_children + from faebryk.core.util import get_all_modules # {module_name: [{param_name: param_value}, {param_name: param_value},...]} parameters = dict[str, list[dict[str, Parameter]]]() @@ -22,7 +22,7 @@ def export_parameters_to_file(module: Module, path: Path): }: parameters[m.get_full_name(types=True).split(".", maxsplit=1)[-1]] = [ {param.get_full_name().split(".")[-1]: param} - for param in get_children(m, direct_only=True, types=Parameter) + for param in m.get_children(direct_only=True, types=Parameter) ] logger.info(f"Writing parameters to {path}") diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index a16ccfb4..5462dc5d 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -225,7 +225,7 @@ def attach(self): footprints = { (f.propertys["Reference"].value, f.name): f for f in self.pcb.footprints } - from faebryk.core.util import get_all_nodes_with_trait, get_children + from faebryk.core.util import get_all_nodes_with_trait for node, fpt in get_all_nodes_with_trait(self.graph, F.has_footprint): if not node.has_trait(F.has_overriden_name): @@ -250,7 +250,7 @@ def attach(self): node.add_trait(self.has_linked_kicad_footprint_defined(fp, self)) pin_names = g_fp.get_trait(F.has_kicad_footprint).get_pin_names() - for fpad in get_children(g_fp, direct_only=True, types=ModuleInterface): + for fpad in g_fp.get_children(direct_only=True, types=ModuleInterface): pads = [ pad for pad in fp.pads diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 29187a80..5e573ea6 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -176,10 +176,8 @@ def connect_all_node_references( def connect_all_module_references( cls, node: Module | ModuleInterface, gnd_only=False ) -> F.ElectricPower: - from faebryk.core.util import get_children - return cls.connect_all_node_references( - get_children(node, direct_only=True, types=(Module, ModuleInterface)), + node.get_children(direct_only=True, types=(Module, ModuleInterface)), gnd_only=gnd_only, ) diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index dc695aa4..07dc46f4 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -24,9 +24,7 @@ def __init__(self, bus_factory: Callable[[], T]) -> None: def __preinit__(self): def get_mifs[U: ModuleInterface](bus: T, mif_type: type[U]) -> set[U]: - from faebryk.core.util import get_children - - return get_children(bus, direct_only=True, types=mif_type) + return bus.get_children(direct_only=True, types=mif_type) raw = list( zip( diff --git a/src/faebryk/library/Pad.py b/src/faebryk/library/Pad.py index 2686a4a2..e7ac5703 100644 --- a/src/faebryk/library/Pad.py +++ b/src/faebryk/library/Pad.py @@ -27,8 +27,6 @@ def find_pad_for_intf_with_parent_that_has_footprint_unique( def find_pad_for_intf_with_parent_that_has_footprint( intf: ModuleInterface, ) -> list["Pad"]: - from faebryk.core.util import get_children - # This only finds directly attached pads # -> misses from parents / children nodes if intf.has_trait(F.has_linked_pad): @@ -38,7 +36,7 @@ def find_pad_for_intf_with_parent_that_has_footprint( _, footprint = F.Footprint.get_footprint_of_parent(intf) pads = [ pad - for pad in get_children(footprint, direct_only=True, types=Pad) + for pad in footprint.get_children(direct_only=True, types=Pad) if pad.net.is_connected_to(intf) is not None ] return pads diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index f784c5dc..1eed0cab 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -56,8 +56,6 @@ class InterfaceConfiguration(Enum): designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") def __preinit__(self): - from faebryk.core.util import get_children - if self.interface_configuration == USB2514B.InterfaceConfiguration.DEFAULT: self.CFG_SEL[0].pulled.pull(up=False) self.CFG_SEL[1].pulled.pull(up=False) @@ -75,7 +73,7 @@ def __preinit__(self): # Add decoupling capacitors to power pins and connect all lv to gnd # TODO: decouple with 1.0uF and 0.1uF and maybe 4.7uF - for g in get_children(self, direct_only=True, types=F.ElectricPower): + for g in self.get_children(direct_only=True, types=F.ElectricPower): g.decoupled.decouple() g.lv.connect(self.gnd) diff --git a/src/faebryk/library/has_equal_pins_in_ifs.py b/src/faebryk/library/has_equal_pins_in_ifs.py index 6d00b5e0..0de72169 100644 --- a/src/faebryk/library/has_equal_pins_in_ifs.py +++ b/src/faebryk/library/has_equal_pins_in_ifs.py @@ -6,9 +6,7 @@ class has_equal_pins_in_ifs(F.has_equal_pins.impl()): def get_pin_map(self): - from faebryk.core.util import get_children - return { p: str(i + 1) - for i, p in enumerate(get_children(self.obj, direct_only=True, types=F.Pad)) + for i, p in enumerate(self.obj.get_children(direct_only=True, types=F.Pad)) } diff --git a/src/faebryk/library/has_footprint_impl.py b/src/faebryk/library/has_footprint_impl.py index 721eac75..6d9bb2f3 100644 --- a/src/faebryk/library/has_footprint_impl.py +++ b/src/faebryk/library/has_footprint_impl.py @@ -9,8 +9,6 @@ def set_footprint(self, fp: F.Footprint): self.obj.add(fp, name="footprint") def get_footprint(self) -> F.Footprint: - from faebryk.core.util import get_children - - fps = get_children(self.obj, direct_only=True, types=F.Footprint) + fps = self.obj.get_children(direct_only=True, types=F.Footprint) assert len(fps) == 1, f"In obj: {self.obj}: candidates: {fps}" return next(iter(fps)) diff --git a/src/faebryk/libs/app/parameters.py b/src/faebryk/libs/app/parameters.py index 79d1f3b4..66c5f5af 100644 --- a/src/faebryk/libs/app/parameters.py +++ b/src/faebryk/libs/app/parameters.py @@ -18,7 +18,7 @@ def replace_tbd_with_any(module: Module, recursive: bool, loglvl: int | None = N :param module: The module to replace TBD instances in. :param recursive: If True, replace TBD instances in submodules as well. """ - from faebryk.core.util import get_all_modules, get_children + from faebryk.core.util import get_all_modules lvl = logger.getEffectiveLevel() if loglvl is not None: @@ -26,7 +26,7 @@ def replace_tbd_with_any(module: Module, recursive: bool, loglvl: int | None = N module = module.get_most_special() - for param in get_children(module, direct_only=True, types=Parameter): + for param in module.get_children(direct_only=True, types=Parameter): if isinstance(param.get_most_narrow(), TBD): logger.debug(f"Replacing in {module}: {param} with ANY") param.merge(ANY()) diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index 0a36e665..afa2d933 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -139,15 +139,13 @@ def get_part(self) -> Part: def pick_module_by_params(module: Module, options: Iterable[PickerOption]): - from faebryk.core.util import get_children - if module.has_trait(has_part_picked): logger.debug(f"Ignoring already picked module: {module}") return params = { NotNone(p.get_parent())[1]: p.get_most_narrow() - for p in get_children(module, direct_only=True, types=Parameter) + for p in module.get_children(direct_only=True, types=Parameter) } options = list(options) @@ -184,11 +182,9 @@ def pick_module_by_params(module: Module, options: Iterable[PickerOption]): def _get_mif_top_level_modules(mif: ModuleInterface) -> set[Module]: - from faebryk.core.util import get_children - - return get_children(mif, direct_only=True, types=Module) | { + return mif.get_children(direct_only=True, types=Module) | { m - for nmif in get_children(mif, direct_only=True, types=ModuleInterface) + for nmif in mif.get_children(direct_only=True, types=ModuleInterface) for m in _get_mif_top_level_modules(nmif) } @@ -231,8 +227,6 @@ def pick_part_recursively(module: Module): # check if lowest children are picked def get_not_picked(m: Module): - from faebryk.core.util import get_children - ms = m.get_most_special() # check if parent is picked @@ -246,7 +240,7 @@ def get_not_picked(m: Module): out = flatten( [ get_not_picked(mod) - for mif in get_children(m, direct_only=True, types=ModuleInterface) + for mif in m.get_children(direct_only=True, types=ModuleInterface) for mod in _get_mif_top_level_modules(mif) ] ) @@ -254,7 +248,7 @@ def get_not_picked(m: Module): if m.has_trait(has_part_picked): return out - children = get_children(m, direct_only=True, types=Module) + children = m.get_children(direct_only=True, types=Module) if not children: return out + [m] @@ -266,8 +260,6 @@ def get_not_picked(m: Module): def _pick_part_recursively(module: Module, progress: PickerProgress | None = None): - from faebryk.core.util import get_children - assert isinstance(module, Module) # pick only for most specialized module @@ -278,7 +270,7 @@ def _pick_part_recursively(module: Module, progress: PickerProgress | None = Non # pick mif module parts - for mif in get_children(module, direct_only=True, types=ModuleInterface): + for mif in module.get_children(direct_only=True, types=ModuleInterface): for mod in _get_mif_top_level_modules(mif): _pick_part_recursively(mod, progress) @@ -290,7 +282,7 @@ def _pick_part_recursively(module: Module, progress: PickerProgress | None = Non # if no children, raise # This whole logic will be so much easier if the recursive # picker is just a normal picker - if not get_children(module, direct_only=True, types=Module): + if not module.get_children(direct_only=True, types=Module): raise e if module.has_trait(has_part_picked): @@ -306,7 +298,7 @@ def _pick_part_recursively(module: Module, progress: PickerProgress | None = Non # go level lower to_pick: set[Module] = { c - for c in get_children(module, types=Module, direct_only=True) + for c in module.get_children(types=Module, direct_only=True) if not c.has_trait(has_part_picked) } failed: dict[Module, PickError] = {} From 0661a458e42fdc751b28aa1f803ac687f2762b6b Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Wed, 28 Aug 2024 02:44:18 +0200 Subject: [PATCH 29/63] fix trait override --- src/faebryk/core/graph.py | 2 +- src/faebryk/core/graph_backends/graphgt.py | 2 +- src/faebryk/core/graph_backends/graphnx.py | 2 +- src/faebryk/core/graph_backends/graphpy.py | 2 +- src/faebryk/core/node.py | 20 ++- src/faebryk/core/trait.py | 18 ++- test/core/test_core.py | 18 ++- test/core/test_hierarchy_connect.py | 82 +++++----- test/core/test_parameters.py | 49 +++--- test/core/test_performance.py | 8 +- test/core/test_util.py | 31 ++-- .../netlist/kicad/test_netlist_kicad.py | 16 +- test/libs/picker/test_jlcpcb.py | 149 +++++++----------- 13 files changed, 197 insertions(+), 202 deletions(-) diff --git a/src/faebryk/core/graph.py b/src/faebryk/core/graph.py index a22e28ec..1dff6c16 100644 --- a/src/faebryk/core/graph.py +++ b/src/faebryk/core/graph.py @@ -20,7 +20,7 @@ # only for typechecker if TYPE_CHECKING: - from faebryk.core.core import Link + from faebryk.core.link import Link # TODO create GraphView base class diff --git a/src/faebryk/core/graph_backends/graphgt.py b/src/faebryk/core/graph_backends/graphgt.py index a1701f02..d8f25bc8 100644 --- a/src/faebryk/core/graph_backends/graphgt.py +++ b/src/faebryk/core/graph_backends/graphgt.py @@ -15,7 +15,7 @@ # only for typechecker if TYPE_CHECKING: - from faebryk.core.core import Link + from faebryk.core.link import Link class GraphGT[T](Graph[T, gt.Graph]): diff --git a/src/faebryk/core/graph_backends/graphnx.py b/src/faebryk/core/graph_backends/graphnx.py index 440cb674..ea22051f 100644 --- a/src/faebryk/core/graph_backends/graphnx.py +++ b/src/faebryk/core/graph_backends/graphnx.py @@ -13,7 +13,7 @@ # only for typechecker if TYPE_CHECKING: - from faebryk.core.core import Link + from faebryk.core.link import Link class GraphNX[T](Graph[T, nx.Graph]): diff --git a/src/faebryk/core/graph_backends/graphpy.py b/src/faebryk/core/graph_backends/graphpy.py index 1f382b17..40f95ef1 100644 --- a/src/faebryk/core/graph_backends/graphpy.py +++ b/src/faebryk/core/graph_backends/graphpy.py @@ -12,7 +12,7 @@ # only for typechecker if TYPE_CHECKING: - from faebryk.core.core import Link + from faebryk.core.link import Link type L = "Link" diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 90ba40d1..eefd3317 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -104,6 +104,16 @@ def __init__(self, node: "Node", *args: object) -> None: self.node = node +class NodeAlreadyBound(NodeException): + def __init__(self, node: "Node", other: "Node", *args: object) -> None: + super().__init__( + node, + *args, + f"Node {other} already bound to" + f" {other.get_parent()}, can't bind to {node}", + ) + + class Node(FaebrykLibObject, metaclass=PostInitCaller): runtime_anon: list["Node"] runtime: dict[str, "Node"] @@ -369,17 +379,17 @@ def _handle_add_gif(self, name: str, gif: GraphInterface): gif.connect(self.self_gif, linkcls=LinkSibling) def _handle_add_node(self, name: str, node: "Node"): - assert not ( - other_p := node.get_parent() - ), f"{node} already has parent: {other_p}" + if node.get_parent(): + raise NodeAlreadyBound(self, node) from faebryk.core.trait import TraitImpl if isinstance(node, TraitImpl): if self.has_trait(node._trait): - node.handle_duplicate( + if not node.handle_duplicate( cast_assert(TraitImpl, self.get_trait(node._trait)), self - ) + ): + return node.parent.connect(self.children, LinkNamedParent.curry(name)) node._handle_added_to_parent() diff --git a/src/faebryk/core/trait.py b/src/faebryk/core/trait.py index 3a473cf2..0a727212 100644 --- a/src/faebryk/core/trait.py +++ b/src/faebryk/core/trait.py @@ -28,6 +28,11 @@ def __init__(self, node: Node, trait: "TraitImpl", *args: object) -> None: self.trait = trait +class TraitUnbound(NodeException): + def __init__(self, node: Node, *args: object) -> None: + super().__init__(node, *args, f"Trait {node} is not bound to a node") + + class Trait(Node): @classmethod def impl[T: "Trait"](cls: type[T]): @@ -64,7 +69,7 @@ def __preinit__(self) -> None: def obj(self) -> Node: p = self.get_parent() if not p: - raise Exception("trait is not linked to node") + raise TraitUnbound(self) return p[0] def get_obj[T: Node](self, type: type[T]) -> T: @@ -95,9 +100,16 @@ def _handle_added_to_parent(self): def on_obj_set(self): ... - def handle_duplicate(self, other: "TraitImpl", node: Node): + def handle_duplicate(self, other: "TraitImpl", node: Node) -> bool: assert other is not self - raise TraitAlreadyExists(node, self) + _, candidate = other.cmp(self) + if candidate is not self: + return False + + node.del_trait(other._trait) + return True + + # raise TraitAlreadyExists(node, self) # override this to implement a dynamic trait def is_implemented(self): diff --git a/test/core/test_core.py b/test/core/test_core.py index 567094af..7f497ae1 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -6,8 +6,14 @@ from typing import cast from faebryk.core.link import LinkDirect, LinkParent, LinkSibling -from faebryk.core.node import Node -from faebryk.core.trait import Trait, TraitImpl +from faebryk.core.node import Node, NodeAlreadyBound +from faebryk.core.trait import ( + Trait, + TraitAlreadyExists, + TraitImpl, + TraitNotFound, + TraitUnbound, +) class TestTraits(unittest.TestCase): @@ -111,7 +117,7 @@ class impl2(trait2.impl()): # Test failure on getting non existent self.assertFalse(obj.has_trait(trait1)) - self.assertRaises(AssertionError, lambda: obj.get_trait(trait1)) + self.assertRaises(TraitNotFound, lambda: obj.get_trait(trait1)) trait1_inst = trait1impl() cfgtrait1_inst = cfgtrait1(5) @@ -124,7 +130,7 @@ class impl2(trait2.impl()): self.assertEqual(trait1_inst.do(), obj.get_trait(trait1).do()) # Test double add - self.assertRaises(AssertionError, lambda: obj.add_trait(trait1_inst)) + self.assertRaises(NodeAlreadyBound, lambda: obj.add_trait(trait1_inst)) # Test replace obj.add_trait(cfgtrait1_inst) @@ -140,12 +146,12 @@ class impl2(trait2.impl()): self.assertFalse(obj.has_trait(trait1)) # Test get obj - self.assertRaises(AssertionError, lambda: trait1_inst.obj) + self.assertRaises(TraitUnbound, lambda: trait1_inst.obj) obj.add_trait(trait1_inst) _impl: TraitImpl = cast(TraitImpl, obj.get_trait(trait1)) self.assertEqual(_impl.obj, obj) obj.del_trait(trait1) - self.assertRaises(AssertionError, lambda: trait1_inst.obj) + self.assertRaises(TraitUnbound, lambda: trait1_inst.obj) # Test specific override obj.add_trait(impl2_inst) diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index d03d220a..ffec1f04 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -5,14 +5,10 @@ import unittest from itertools import chain -from faebryk.core.core import ( - LinkDirect, - LinkDirectShallow, - Module, - ModuleInterface, - _TLinkDirectShallow, -) from faebryk.core.core import logger as core_logger +from faebryk.core.link import LinkDirect, LinkDirectShallow, _TLinkDirectShallow +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.util import specialize_interface from faebryk.library.Electrical import Electrical from faebryk.library.ElectricLogic import ElectricLogic @@ -38,18 +34,18 @@ class _IFs(super().IFS()): self.IFs = _IFs(self) - bus_in = self.IFs.bus_in - bus_out = self.IFs.bus_out + bus_in = self.bus_in + bus_out = self.bus_out - bus_in.IFs.rx.IFs.signal.connect(bus_out.IFs.rx.IFs.signal) - bus_in.IFs.tx.IFs.signal.connect(bus_out.IFs.tx.IFs.signal) - bus_in.IFs.rx.IFs.reference.connect(bus_out.IFs.rx.IFs.reference) + bus_in.rx.signal.connect(bus_out.rx.signal) + bus_in.tx.signal.connect(bus_out.tx.signal) + bus_in.rx.reference.connect(bus_out.rx.reference) app = UARTBuffer() - self.assertTrue(app.IFs.bus_in.IFs.rx.is_connected_to(app.IFs.bus_out.IFs.rx)) - self.assertTrue(app.IFs.bus_in.IFs.tx.is_connected_to(app.IFs.bus_out.IFs.tx)) - self.assertTrue(app.IFs.bus_in.is_connected_to(app.IFs.bus_out)) + self.assertTrue(app.bus_in.rx.is_connected_to(app.bus_out.rx)) + self.assertTrue(app.bus_in.tx.is_connected_to(app.bus_out.tx)) + self.assertTrue(app.bus_in.is_connected_to(app.bus_out)) def test_chains(self): mifs = times(3, ModuleInterface) @@ -76,16 +72,16 @@ def test_chains(self): self.assertTrue(mifs[0].is_connected_to(mifs[2])) self.assertIsInstance(mifs[0].is_connected_to(mifs[2]), _TLinkDirectShallow) - self.assertTrue(mifs[1].IFs.signal.is_connected_to(mifs[2].IFs.signal)) - self.assertTrue(mifs[1].IFs.reference.is_connected_to(mifs[2].IFs.reference)) - self.assertFalse(mifs[0].IFs.signal.is_connected_to(mifs[1].IFs.signal)) - self.assertFalse(mifs[0].IFs.reference.is_connected_to(mifs[1].IFs.reference)) - self.assertFalse(mifs[0].IFs.signal.is_connected_to(mifs[2].IFs.signal)) - self.assertFalse(mifs[0].IFs.reference.is_connected_to(mifs[2].IFs.reference)) + self.assertTrue(mifs[1].signal.is_connected_to(mifs[2].signal)) + self.assertTrue(mifs[1].reference.is_connected_to(mifs[2].reference)) + self.assertFalse(mifs[0].signal.is_connected_to(mifs[1].signal)) + self.assertFalse(mifs[0].reference.is_connected_to(mifs[1].reference)) + self.assertFalse(mifs[0].signal.is_connected_to(mifs[2].signal)) + self.assertFalse(mifs[0].reference.is_connected_to(mifs[2].reference)) # Test duplicate resolution - mifs[0].IFs.signal.connect(mifs[1].IFs.signal) - mifs[0].IFs.reference.connect(mifs[1].IFs.reference) + mifs[0].signal.connect(mifs[1].signal) + mifs[0].reference.connect(mifs[1].reference) self.assertIsInstance(mifs[0].is_connected_to(mifs[1]), LinkDirect) self.assertIsInstance(mifs[0].is_connected_to(mifs[2]), LinkDirect) @@ -107,12 +103,12 @@ class _IFs(super().IFS()): self.add_trait(has_single_electric_reference_defined(ref)) for el, lo in chain( - zip(self.IFs.ins, self.IFs.ins_l), - zip(self.IFs.outs, self.IFs.outs_l), + zip(self.ins, self.ins_l), + zip(self.outs, self.outs_l), ): - lo.IFs.signal.connect(el) + lo.signal.connect(el) - for l1, l2 in zip(self.IFs.ins_l, self.IFs.outs_l): + for l1, l2 in zip(self.ins_l, self.outs_l): l1.connect_shallow(l2) class UARTBuffer(Module): @@ -131,14 +127,14 @@ class _IFs(super().IFS()): ElectricLogic.connect_all_module_references(self) - bus1 = self.IFs.bus_in - bus2 = self.IFs.bus_out - buf = self.NODEs.buf + bus1 = self.bus_in + bus2 = self.bus_out + buf = self.buf - bus1.IFs.tx.IFs.signal.connect(buf.IFs.ins[0]) - bus1.IFs.rx.IFs.signal.connect(buf.IFs.ins[1]) - bus2.IFs.tx.IFs.signal.connect(buf.IFs.outs[0]) - bus2.IFs.rx.IFs.signal.connect(buf.IFs.outs[1]) + bus1.tx.signal.connect(buf.ins[0]) + bus1.rx.signal.connect(buf.ins[1]) + bus2.tx.signal.connect(buf.outs[0]) + bus2.rx.signal.connect(buf.outs[1]) import faebryk.core.core as c @@ -153,19 +149,19 @@ def _assert_no_link(mif1, mif2): err = "\n" + print_stack(link.tb) self.assertFalse(link, err) - bus1 = app.IFs.bus_in - bus2 = app.IFs.bus_out - buf = app.NODEs.buf + bus1 = app.bus_in + bus2 = app.bus_out + buf = app.buf # Check that the two buffer sides are not connected electrically - _assert_no_link(buf.IFs.ins[0], buf.IFs.outs[0]) - _assert_no_link(buf.IFs.ins[1], buf.IFs.outs[1]) - _assert_no_link(bus1.IFs.rx.IFs.signal, bus2.IFs.rx.IFs.signal) - _assert_no_link(bus1.IFs.tx.IFs.signal, bus2.IFs.tx.IFs.signal) + _assert_no_link(buf.ins[0], buf.outs[0]) + _assert_no_link(buf.ins[1], buf.outs[1]) + _assert_no_link(bus1.rx.signal, bus2.rx.signal) + _assert_no_link(bus1.tx.signal, bus2.tx.signal) # Check that the two buffer sides are connected logically - self.assertTrue(bus1.IFs.rx.is_connected_to(bus2.IFs.rx)) - self.assertTrue(bus1.IFs.tx.is_connected_to(bus2.IFs.tx)) + self.assertTrue(bus1.rx.is_connected_to(bus2.rx)) + self.assertTrue(bus1.tx.is_connected_to(bus2.tx)) self.assertTrue(bus1.is_connected_to(bus2)) def test_specialize(self): diff --git a/test/core/test_parameters.py b/test/core/test_parameters.py index 8c1c2977..688fcade 100644 --- a/test/core/test_parameters.py +++ b/test/core/test_parameters.py @@ -7,7 +7,8 @@ from typing import TypeVar from faebryk.core.core import logger as core_logger -from faebryk.core.module import Module, Parameter +from faebryk.core.module import Module +from faebryk.core.parameter import Parameter from faebryk.core.util import specialize_module from faebryk.library.ANY import ANY from faebryk.library.Constant import Constant @@ -271,26 +272,26 @@ class NODES(super().NODES()): m = Modules() - UART_A = m.NODEs.UART_A - UART_B = m.NODEs.UART_B - UART_C = m.NODEs.UART_C + UART_A = m.UART_A + UART_B = m.UART_B + UART_C = m.UART_C UART_A.connect(UART_B) - UART_A.PARAMs.baud.merge(Constant(9600 * P.baud)) + UART_A.baud.merge(Constant(9600 * P.baud)) for uart in [UART_A, UART_B]: self.assertEqual( - assertIsInstance(uart.PARAMs.baud.get_most_narrow(), Constant).value, + assertIsInstance(uart.baud.get_most_narrow(), Constant).value, 9600 * P.baud, ) - UART_C.PARAMs.baud.merge(Range(1200 * P.baud, 115200 * P.baud)) + UART_C.baud.merge(Range(1200 * P.baud, 115200 * P.baud)) UART_A.connect(UART_C) for uart in [UART_A, UART_B, UART_C]: self.assertEqual( - assertIsInstance(uart.PARAMs.baud.get_most_narrow(), Constant).value, + assertIsInstance(uart.baud.get_most_narrow(), Constant).value, 9600 * P.baud, ) @@ -343,34 +344,34 @@ class _NODES(Module.NODES()): self.NODEs = _NODES(self) - self.NODEs.led.IFs.power.connect(self.NODEs.battery.IFs.power) + self.led.power.connect(self.battery.power) # Parametrize - self.NODEs.led.NODEs.led.PARAMs.color.merge(F.LED.Color.YELLOW) - self.NODEs.led.NODEs.led.PARAMs.brightness.merge( + self.led.led.color.merge(F.LED.Color.YELLOW) + self.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) app = App() - bcell = specialize_module(app.NODEs.battery, F.ButtonCell()) - bcell.PARAMs.voltage.merge(3 * P.V) - bcell.PARAMs.capacity.merge(Range.from_center(225 * P.mAh, 50 * P.mAh)) - bcell.PARAMs.material.merge(F.ButtonCell.Material.Lithium) - bcell.PARAMs.size.merge(F.ButtonCell.Size.N_2032) - bcell.PARAMs.shape.merge(F.ButtonCell.Shape.Round) + bcell = specialize_module(app.battery, F.ButtonCell()) + bcell.voltage.merge(3 * P.V) + bcell.capacity.merge(Range.from_center(225 * P.mAh, 50 * P.mAh)) + bcell.material.merge(F.ButtonCell.Material.Lithium) + bcell.size.merge(F.ButtonCell.Size.N_2032) + bcell.shape.merge(F.ButtonCell.Shape.Round) - app.NODEs.led.NODEs.led.PARAMs.color.merge(F.LED.Color.YELLOW) - app.NODEs.led.NODEs.led.PARAMs.max_brightness.merge(500 * P.millicandela) - app.NODEs.led.NODEs.led.PARAMs.forward_voltage.merge(1.2 * P.V) - app.NODEs.led.NODEs.led.PARAMs.max_current.merge(20 * P.mA) + app.led.led.color.merge(F.LED.Color.YELLOW) + app.led.led.max_brightness.merge(500 * P.millicandela) + app.led.led.forward_voltage.merge(1.2 * P.V) + app.led.led.max_current.merge(20 * P.mA) - v = app.NODEs.battery.PARAMs.voltage - # vbcell = bcell.PARAMs.voltage + v = app.battery.voltage + # vbcell = bcell.voltage # print(pretty_param_tree_top(v)) # print(pretty_param_tree_top(vbcell)) self.assertEqual(v.get_most_narrow(), 3 * P.V) - r = app.NODEs.led.NODEs.current_limiting_resistor.PARAMs.resistance + r = app.led.current_limiting_resistor.resistance r = r.get_most_narrow() self.assertIsInstance(r, Range, f"{type(r)}") diff --git a/test/core/test_performance.py b/test/core/test_performance.py index 74ac8b3a..6f1e6a59 100644 --- a/test/core/test_performance.py +++ b/test/core/test_performance.py @@ -8,7 +8,9 @@ from typing import Callable import faebryk.core.util as core_util -from faebryk.core.graphinterface import GraphInterface, Module, ModuleInterface +from faebryk.core.graphinterface import GraphInterface +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface from faebryk.library.Resistor import Resistor from faebryk.libs.util import times @@ -71,7 +73,7 @@ class NODES(super().NODES()): timings.add("set NODES") core_util.connect_all_interfaces( - r.IFs.unnamed[0] for r in self.NODEs.resistors + r.unnamed[0] for r in self.resistors ) timings.add("connect") @@ -95,7 +97,7 @@ def _common_timings( core_util.node_projected_graph(G) timings.add("get_all_nodes_graph") - for n in [app, app.NODEs.resistors[0]]: + for n in [app, app.resistors[0]]: name = type(n).__name__[0] core_util.get_node_children_all(n) diff --git a/test/core/test_util.py b/test/core/test_util.py index 79e17192..640eeadc 100644 --- a/test/core/test_util.py +++ b/test/core/test_util.py @@ -5,8 +5,11 @@ from enum import StrEnum from typing import Iterable -from faebryk.core.module import Module, ModuleInterface, Node, Parameter -from faebryk.core.util import get_children, get_node_tree, iter_tree_by_depth +from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface +from faebryk.core.node import Node +from faebryk.core.parameter import Parameter +from faebryk.core.util import get_node_tree, iter_tree_by_depth class TestUtil(unittest.TestCase): @@ -45,9 +48,9 @@ def assertEqual(n1: list[Node], n2: list[Node]): assertEqual(levels[0], [n]) n_i = n for i in range(1, level_count + 1): - assertEqual(levels[i], [n_i.NODEs.n, n_i.IFs.mif]) - n_i = n_i.NODEs.n - assertEqual(levels[level_count + 1], [n_i.IFs.mif]) + assertEqual(levels[i], [n_i.n, n_i.mif]) + n_i = n_i.n + assertEqual(levels[level_count + 1], [n_i.mif]) def test_children(self): # TODO this is a really annoying to debug test @@ -152,28 +155,28 @@ def visit_tree(t, keys=None, typ=EN): mod = moduleFromTree(tree, EN)() - direct_children_top = get_children(mod, direct_only=True, types=Module) + direct_children_top = mod.get_children(direct_only=True, types=Module) assertEqual(direct_children_top, tree[EN]) - direct_children_top_all_types = get_children(mod, direct_only=True) + direct_children_top_all_types = mod.get_children(direct_only=True, types=Node) assertEqual(direct_children_top_all_types, tree[EN] + tree[EI] + tree[EP]) - all_children_top = get_children(mod, direct_only=False, include_root=True) + all_children_top = mod.get_children( + direct_only=False, include_root=True, types=Node + ) assertEqual(all_children_top, list(visit_tree(tree))) - all_children_top_typed = get_children( - mod, direct_only=False, types=Module, include_root=True + all_children_top_typed = mod.get_children( + direct_only=False, types=Module, include_root=True ) assertEqual(all_children_top_typed, list(visit_tree(tree, [EN]))) - direct_children_middle = get_children(mod.NODEs.i0, direct_only=True) + direct_children_middle = mod.i0.get_children(direct_only=True) assertEqual( direct_children_middle, tree[EN][0][EN] + tree[EN][0][EI] + tree[EN][0][EP] ) - all_children_middle = get_children( - mod.NODEs.i0, direct_only=False, include_root=True - ) + all_children_middle = mod.i0.get_children(direct_only=False, include_root=True) assertEqual( all_children_middle, list(visit_tree(tree[EN][0])), diff --git a/test/exporters/netlist/kicad/test_netlist_kicad.py b/test/exporters/netlist/kicad/test_netlist_kicad.py index 61811df5..1fb260d7 100644 --- a/test/exporters/netlist/kicad/test_netlist_kicad.py +++ b/test/exporters/netlist/kicad/test_netlist_kicad.py @@ -25,21 +25,21 @@ def _test_netlist_graph(): from faebryk.library.Resistor import Resistor from faebryk.library.SMDTwoPin import SMDTwoPin - resistor1 = Resistor().builder(lambda r: r.PARAMs.resistance.merge(100)) - resistor2 = Resistor().builder(lambda r: r.PARAMs.resistance.merge(200)) + resistor1 = Resistor().builder(lambda r: r.resistance.merge(100)) + resistor2 = Resistor().builder(lambda r: r.resistance.merge(200)) power = ElectricPower() # net labels vcc = Net.with_name("+3V3") gnd = Net.with_name("GND") - power.IFs.hv.connect(vcc.IFs.part_of) - power.IFs.lv.connect(gnd.IFs.part_of) + power.hv.connect(vcc.part_of) + power.lv.connect(gnd.part_of) # connect - resistor1.IFs.unnamed[0].connect(power.IFs.hv) - resistor1.IFs.unnamed[1].connect(power.IFs.lv) - resistor2.IFs.unnamed[0].connect(resistor1.IFs.unnamed[0]) - resistor2.IFs.unnamed[1].connect(resistor1.IFs.unnamed[1]) + resistor1.unnamed[0].connect(power.hv) + resistor1.unnamed[1].connect(power.lv) + resistor2.unnamed[0].connect(resistor1.unnamed[0]) + resistor2.unnamed[1].connect(resistor1.unnamed[1]) # attach footprint & designator for i, r in enumerate([resistor1, resistor2]): diff --git a/test/libs/picker/test_jlcpcb.py b/test/libs/picker/test_jlcpcb.py index ae03dc22..10ab7aaf 100644 --- a/test/libs/picker/test_jlcpcb.py +++ b/test/libs/picker/test_jlcpcb.py @@ -9,7 +9,6 @@ import faebryk.libs.picker.lcsc as lcsc from faebryk.core.module import Module from faebryk.core.parameter import Parameter -from faebryk.core.util import get_children from faebryk.libs.logging import setup_basic_logging from faebryk.libs.picker.jlcpcb.jlcpcb import JLCPCB_DB from faebryk.libs.picker.jlcpcb.pickers import add_jlcpcb_pickers @@ -94,8 +93,8 @@ def satisfies_requirements(self): ) for req, res in zip( - get_children(self.requirement, direct_only=True, types=Parameter), - get_children(self.result, direct_only=True, types=Parameter), + self.requirement.get_children(direct_only=True, types=Parameter), + self.result.get_children(direct_only=True, types=Parameter), ): req = req.get_most_narrow() res = res.get_most_narrow() @@ -160,17 +159,15 @@ def test(self): def test_find_manufacturer_partnumber(self): requirement = F.OpAmp().builder( lambda r: ( - r.PARAMs.bandwidth.merge(F.Range.upper_bound(1 * P.Mhertz)), - r.PARAMs.common_mode_rejection_ratio.merge( + r.bandwidth.merge(F.Range.upper_bound(1 * P.Mhertz)), + r.common_mode_rejection_ratio.merge( F.Range.lower_bound(Quantity(50, P.dB)) ), - r.PARAMs.input_bias_current.merge(F.Range.upper_bound(1 * P.nA)), - r.PARAMs.input_offset_voltage.merge(F.Range.upper_bound(1 * P.mV)), - r.PARAMs.gain_bandwidth_product.merge( - F.Range.upper_bound(1 * P.Mhertz) - ), - r.PARAMs.output_current.merge(F.Range.upper_bound(1 * P.mA)), - r.PARAMs.slew_rate.merge(F.Range.upper_bound(1 * P.MV / P.us)), + r.input_bias_current.merge(F.Range.upper_bound(1 * P.nA)), + r.input_offset_voltage.merge(F.Range.upper_bound(1 * P.mV)), + r.gain_bandwidth_product.merge(F.Range.upper_bound(1 * P.Mhertz)), + r.output_current.merge(F.Range.upper_bound(1 * P.mA)), + r.slew_rate.merge(F.Range.upper_bound(1 * P.MV / P.us)), ) ) requirement.add_trait( @@ -190,17 +187,15 @@ def test_find_manufacturer_partnumber(self): def test_find_lcsc_partnumber(self): requirement = F.OpAmp().builder( lambda r: ( - r.PARAMs.bandwidth.merge(F.Range.upper_bound(1 * P.Mhertz)), - r.PARAMs.common_mode_rejection_ratio.merge( + r.bandwidth.merge(F.Range.upper_bound(1 * P.Mhertz)), + r.common_mode_rejection_ratio.merge( F.Range.lower_bound(Quantity(50, P.dB)) ), - r.PARAMs.input_bias_current.merge(F.Range.upper_bound(1 * P.nA)), - r.PARAMs.input_offset_voltage.merge(F.Range.upper_bound(1 * P.mV)), - r.PARAMs.gain_bandwidth_product.merge( - F.Range.upper_bound(1 * P.Mhertz) - ), - r.PARAMs.output_current.merge(F.Range.upper_bound(1 * P.mA)), - r.PARAMs.slew_rate.merge(F.Range.upper_bound(1 * P.MV / P.us)), + r.input_bias_current.merge(F.Range.upper_bound(1 * P.nA)), + r.input_offset_voltage.merge(F.Range.upper_bound(1 * P.mV)), + r.gain_bandwidth_product.merge(F.Range.upper_bound(1 * P.Mhertz)), + r.output_current.merge(F.Range.upper_bound(1 * P.mA)), + r.slew_rate.merge(F.Range.upper_bound(1 * P.MV / P.us)), ) ) requirement.add_trait( @@ -221,11 +216,9 @@ def test_find_resistor(self): self, requirement=F.Resistor().builder( lambda r: ( - r.PARAMs.resistance.merge( - F.Range.from_center(10 * P.kohm, 1 * P.kohm) - ), - r.PARAMs.rated_power.merge(F.Range.lower_bound(0.05 * P.W)), - r.PARAMs.rated_voltage.merge(F.Range.lower_bound(25 * P.V)), + r.resistance.merge(F.Range.from_center(10 * P.kohm, 1 * P.kohm)), + r.rated_power.merge(F.Range.lower_bound(0.05 * P.W)), + r.rated_voltage.merge(F.Range.lower_bound(25 * P.V)), ) ), footprint=[("0402", 2)], @@ -235,11 +228,9 @@ def test_find_resistor(self): self, requirement=F.Resistor().builder( lambda r: ( - r.PARAMs.resistance.merge( - F.Range.from_center(69 * P.kohm, 2 * P.kohm) - ), - r.PARAMs.rated_power.merge(F.Range.lower_bound(0.1 * P.W)), - r.PARAMs.rated_voltage.merge(F.Range.lower_bound(50 * P.V)), + r.resistance.merge(F.Range.from_center(69 * P.kohm, 2 * P.kohm)), + r.rated_power.merge(F.Range.lower_bound(0.1 * P.W)), + r.rated_voltage.merge(F.Range.lower_bound(50 * P.V)), ) ), footprint=[("0603", 2)], @@ -250,11 +241,9 @@ def test_find_capacitor(self): self, requirement=F.Capacitor().builder( lambda c: ( - c.PARAMs.capacitance.merge( - F.Range.from_center(100 * P.nF, 10 * P.nF) - ), - c.PARAMs.rated_voltage.merge(F.Range.lower_bound(25 * P.V)), - c.PARAMs.temperature_coefficient.merge( + c.capacitance.merge(F.Range.from_center(100 * P.nF, 10 * P.nF)), + c.rated_voltage.merge(F.Range.lower_bound(25 * P.V)), + c.temperature_coefficient.merge( F.Range.lower_bound(F.Capacitor.TemperatureCoefficient.X7R) ), ) @@ -266,11 +255,9 @@ def test_find_capacitor(self): self, requirement=F.Capacitor().builder( lambda c: ( - c.PARAMs.capacitance.merge( - F.Range.from_center(47 * P.pF, 4.7 * P.pF) - ), - c.PARAMs.rated_voltage.merge(F.Range.lower_bound(50 * P.V)), - c.PARAMs.temperature_coefficient.merge( + c.capacitance.merge(F.Range.from_center(47 * P.pF, 4.7 * P.pF)), + c.rated_voltage.merge(F.Range.lower_bound(50 * P.V)), + c.temperature_coefficient.merge( F.Range.lower_bound(F.Capacitor.TemperatureCoefficient.C0G) ), ) @@ -283,12 +270,10 @@ def test_find_inductor(self): self, requirement=F.Inductor().builder( lambda i: ( - i.PARAMs.inductance.merge( - F.Range.from_center(4.7 * P.nH, 0.47 * P.nH) - ), - i.PARAMs.rated_current.merge(F.Range.lower_bound(0.01 * P.A)), - i.PARAMs.dc_resistance.merge(F.Range.upper_bound(1 * P.ohm)), - i.PARAMs.self_resonant_frequency.merge( + i.inductance.merge(F.Range.from_center(4.7 * P.nH, 0.47 * P.nH)), + i.rated_current.merge(F.Range.lower_bound(0.01 * P.A)), + i.dc_resistance.merge(F.Range.upper_bound(1 * P.ohm)), + i.self_resonant_frequency.merge( F.Range.lower_bound(100 * P.Mhertz) ), ) @@ -301,22 +286,14 @@ def test_find_mosfet(self): self, requirement=F.MOSFET().builder( lambda m: ( - m.PARAMs.channel_type.merge( - F.Constant(F.MOSFET.ChannelType.N_CHANNEL) - ), - m.PARAMs.saturation_type.merge( + m.channel_type.merge(F.Constant(F.MOSFET.ChannelType.N_CHANNEL)), + m.saturation_type.merge( F.Constant(F.MOSFET.SaturationType.ENHANCEMENT) ), - m.PARAMs.gate_source_threshold_voltage.merge( - F.Range(0.4 * P.V, 3 * P.V) - ), - m.PARAMs.max_drain_source_voltage.merge( - F.Range.lower_bound(20 * P.V) - ), - m.PARAMs.max_continuous_drain_current.merge( - F.Range.lower_bound(2 * P.A) - ), - m.PARAMs.on_resistance.merge(F.Range.upper_bound(0.1 * P.ohm)), + m.gate_source_threshold_voltage.merge(F.Range(0.4 * P.V, 3 * P.V)), + m.max_drain_source_voltage.merge(F.Range.lower_bound(20 * P.V)), + m.max_continuous_drain_current.merge(F.Range.lower_bound(2 * P.A)), + m.on_resistance.merge(F.Range.upper_bound(0.1 * P.ohm)), ) ), footprint=[("SOT-23", 3)], @@ -327,15 +304,11 @@ def test_find_diode(self): self, requirement=F.Diode().builder( lambda d: ( - d.PARAMs.current.merge(F.Range.lower_bound(1 * P.A)), - d.PARAMs.forward_voltage.merge(F.Range.upper_bound(1.7 * P.V)), - d.PARAMs.reverse_working_voltage.merge( - F.Range.lower_bound(20 * P.V) - ), - d.PARAMs.reverse_leakage_current.merge( - F.Range.upper_bound(100 * P.uA) - ), - d.PARAMs.max_current.merge(F.Range.lower_bound(1 * P.A)), + d.current.merge(F.Range.lower_bound(1 * P.A)), + d.forward_voltage.merge(F.Range.upper_bound(1.7 * P.V)), + d.reverse_working_voltage.merge(F.Range.lower_bound(20 * P.V)), + d.reverse_leakage_current.merge(F.Range.upper_bound(100 * P.uA)), + d.max_current.merge(F.Range.lower_bound(1 * P.A)), ) ), footprint=[("SOD-123", 2)], @@ -348,16 +321,12 @@ def test_find_tvs(self): lambda t: ( # TODO: There is no current specified for TVS diodes, only peak # current - t.PARAMs.current.merge(F.ANY()), - t.PARAMs.forward_voltage.merge(F.ANY()), - t.PARAMs.reverse_working_voltage.merge( - F.Range.lower_bound(5 * P.V) - ), - t.PARAMs.reverse_leakage_current.merge(F.ANY()), - t.PARAMs.max_current.merge(F.Range.lower_bound(10 * P.A)), - t.PARAMs.reverse_breakdown_voltage.merge( - F.Range.upper_bound(8 * P.V) - ), + t.current.merge(F.ANY()), + t.forward_voltage.merge(F.ANY()), + t.reverse_working_voltage.merge(F.Range.lower_bound(5 * P.V)), + t.reverse_leakage_current.merge(F.ANY()), + t.max_current.merge(F.Range.lower_bound(10 * P.A)), + t.reverse_breakdown_voltage.merge(F.Range.upper_bound(8 * P.V)), ) ), footprint=[("SMB(DO-214AA)", 2)], @@ -368,18 +337,14 @@ def test_find_ldo(self): self, F.LDO().builder( lambda u: ( - u.PARAMs.output_voltage.merge( - F.Range.from_center(3.3 * P.V, 0.1 * P.V) - ), - u.PARAMs.output_current.merge(F.Range.lower_bound(0.1 * P.A)), - u.PARAMs.max_input_voltage.merge(F.Range.lower_bound(5 * P.V)), - u.PARAMs.dropout_voltage.merge(F.Range.upper_bound(1 * P.V)), - u.PARAMs.output_polarity.merge( - F.Constant(F.LDO.OutputPolarity.POSITIVE) - ), - u.PARAMs.output_type.merge(F.Constant(F.LDO.OutputType.FIXED)), - u.PARAMs.psrr.merge(F.ANY()), - u.PARAMs.quiescent_current.merge(F.ANY()), + u.output_voltage.merge(F.Range.from_center(3.3 * P.V, 0.1 * P.V)), + u.output_current.merge(F.Range.lower_bound(0.1 * P.A)), + u.max_input_voltage.merge(F.Range.lower_bound(5 * P.V)), + u.dropout_voltage.merge(F.Range.upper_bound(1 * P.V)), + u.output_polarity.merge(F.Constant(F.LDO.OutputPolarity.POSITIVE)), + u.output_type.merge(F.Constant(F.LDO.OutputType.FIXED)), + u.psrr.merge(F.ANY()), + u.quiescent_current.merge(F.ANY()), ) ), footprint=[ From 3e089bb7e82cbca05fbbff0843680cbab07416b2 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Wed, 28 Aug 2024 03:27:14 +0200 Subject: [PATCH 30/63] Fix rt_field init order --- src/faebryk/core/node.py | 37 ++++++++++++++++++++----------- src/faebryk/library/ButtonCell.py | 6 ++--- test/core/test_core.py | 17 +++++++++++++- test/core/test_parameters.py | 29 +++++++++--------------- test/core/test_performance.py | 35 +++++++++++++---------------- 5 files changed, 70 insertions(+), 54 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index eefd3317..3052da81 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -21,6 +21,7 @@ times, try_avoid_endless_recursion, ) +from more_itertools import partition if TYPE_CHECKING: from faebryk.core.trait import Trait, TraitImpl @@ -263,6 +264,14 @@ def is_genalias_node(obj): objects: dict[str, Node | GraphInterface] = {} + def handle_add(name, obj): + if isinstance(obj, GraphInterface): + self._handle_add_gif(name, obj) + elif isinstance(obj, Node): + self._handle_add_node(name, obj) + else: + assert False + def append(name, inst): if isinstance(inst, LL_Types): objects[name] = inst @@ -320,9 +329,22 @@ def setup_gen_alias(name, obj): raise NotImplementedError() - for name, obj in clsfields.items(): + nonrt, rt = partition(lambda x: isinstance(x[1], rt_field), clsfields.items()) + for name, obj in nonrt: + setup_field(name, obj) + + for name, obj in objects.items(): + handle_add(name, obj) + obj_old = dict(objects) + + # rt fields depend on full self + for name, obj in rt: setup_field(name, obj) + for name, obj in objects.items(): + if name not in obj_old: + handle_add(name, obj) + return objects, clsfields def __new__(cls, *args, **kwargs): @@ -339,18 +361,7 @@ def _setup(self) -> None: raise FieldError(f"Node instances not allowed: {node_instances}") # Construct Fields - objects, _ = self._setup_fields(cls) - - # Add Fields to Node - for name, obj in sorted( - objects.items(), key=lambda x: isinstance(x[1], GraphInterfaceSelf) - ): - if isinstance(obj, GraphInterface): - self._handle_add_gif(name, obj) - elif isinstance(obj, Node): - self._handle_add_node(name, obj) - else: - assert False + _, _ = self._setup_fields(cls) # Call 2-stage constructors if self._init: diff --git a/src/faebryk/library/ButtonCell.py b/src/faebryk/library/ButtonCell.py index c0b3eae2..4da5e251 100644 --- a/src/faebryk/library/ButtonCell.py +++ b/src/faebryk/library/ButtonCell.py @@ -53,9 +53,9 @@ class Size(IntEnum): N_2430 = 2430 N_2450 = 2450 - material = F.TBD[Material] - shape = F.TBD[Shape] - size = F.TBD[Size] + material: F.TBD[Material] + shape: F.TBD[Shape] + size: F.TBD[Size] designator_prefix = L.f_field(F.has_designator_prefix_defined)("B") diff --git a/test/core/test_core.py b/test/core/test_core.py index 7f497ae1..91b45edb 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -9,11 +9,11 @@ from faebryk.core.node import Node, NodeAlreadyBound from faebryk.core.trait import ( Trait, - TraitAlreadyExists, TraitImpl, TraitNotFound, TraitUnbound, ) +from faebryk.libs.library import L class TestTraits(unittest.TestCase): @@ -211,6 +211,21 @@ def test_node_gifs(self): self.assertEqual(n1.self_gif.G, n2.self_gif.G) + # TODO move to own file + def test_fab_ll_simple_hierarchy(self): + class N(Node): + SN1: Node + SN2: Node + SN3 = L.if_list(2, Node) + + @L.rt_field + def SN4(self): + return Node() + + n = N() + children = n.get_children(direct_only=True, types=Node) + self.assertEqual(children, {n.SN1, n.SN2, n.SN3[0], n.SN3[1], n.SN4}) + if __name__ == "__main__": unittest.main() diff --git a/test/core/test_parameters.py b/test/core/test_parameters.py index 688fcade..39e0284e 100644 --- a/test/core/test_parameters.py +++ b/test/core/test_parameters.py @@ -260,15 +260,9 @@ def assertIsInstance(obj, cls: type[T]) -> T: return obj class Modules(Module): - def __init__(self) -> None: - super().__init__() - - class NODES(super().NODES()): - UART_A = UART_Base() - UART_B = UART_Base() - UART_C = UART_Base() - - self.NODEs = NODES(self) + UART_A: UART_Base + UART_B: UART_Base + UART_C: UART_Base m = Modules() @@ -335,15 +329,10 @@ def test_specialize(self): for i in range(10): class App(Module): - def __init__(self) -> None: - super().__init__() - - class _NODES(Module.NODES()): - led = F.PoweredLED() - battery = F.Battery() - - self.NODEs = _NODES(self) + led: F.PoweredLED + battery: F.Battery + def __preinit__(self) -> None: self.led.power.connect(self.battery.power) # Parametrize @@ -377,4 +366,8 @@ class _NODES(Module.NODES()): if __name__ == "__main__": - unittest.main() + # unittest.main() + + import typer + + typer.run(TestParameters().test_modules) diff --git a/test/core/test_performance.py b/test/core/test_performance.py index 6f1e6a59..106b0f3d 100644 --- a/test/core/test_performance.py +++ b/test/core/test_performance.py @@ -8,10 +8,11 @@ from typing import Callable import faebryk.core.util as core_util +import faebryk.library._F as F from faebryk.core.graphinterface import GraphInterface from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface -from faebryk.library.Resistor import Resistor +from faebryk.libs.library import L from faebryk.libs.util import times @@ -46,31 +47,27 @@ class TestPerformance(unittest.TestCase): def test_get_all(self): def _factory_simple_resistors(count: int): class App(Module): + resistors = L.if_list(count, F.Resistor) + def __init__(self, timings: Times) -> None: super().__init__() + self._timings = timings - class NODES(super().NODES()): - resistors = times(count, Resistor) - - timings.add("NODES") - - self.NODEs = NODES(self) - timings.add("set NODES") + def __preinit__(self): + self._timings.add("setup") return App def _factory_interconnected_resistors(count: int): class App(Module): + resistors = L.if_list(count, F.Resistor) + def __init__(self, timings: Times) -> None: super().__init__() + self._timings = timings - class NODES(super().NODES()): - resistors = times(count, Resistor) - - timings.add("NODES") - - self.NODEs = NODES(self) - timings.add("set NODES") + def __preinit__(self): + self._timings.add("setup") core_util.connect_all_interfaces( r.unnamed[0] for r in self.resistors @@ -84,11 +81,11 @@ def _common_timings( ): timings = Times() - App = factory() + AppF = factory() timings.add("classdef") now = time.time() - app = App(timings) + app = AppF(timings) timings.times["instance"] = time.time() - now G = app.get_graph() @@ -100,7 +97,7 @@ def _common_timings( for n in [app, app.resistors[0]]: name = type(n).__name__[0] - core_util.get_node_children_all(n) + n.get_node_children_all() timings.add(f"get_node_children_all {name}") core_util.get_node_tree(n) @@ -112,7 +109,7 @@ def _common_timings( core_util.get_node_direct_mods_or_mifs(n) timings.add(f"get_module_direct_children {name}") - core_util.get_children(n, direct_only=True, types=ModuleInterface) + n.get_children(direct_only=True, types=ModuleInterface) timings.add(f"get_mifs {name}") print(f"{test_name:-<80}") From 63e8790af95dc2fb4b48e8d5bc3342f0e87fae75 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Wed, 28 Aug 2024 03:31:59 +0200 Subject: [PATCH 31/63] started fixing more core tests --- test/core/test_parameters.py | 6 +----- test/core/test_util.py | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/test/core/test_parameters.py b/test/core/test_parameters.py index 39e0284e..ce6c79b0 100644 --- a/test/core/test_parameters.py +++ b/test/core/test_parameters.py @@ -366,8 +366,4 @@ def __preinit__(self) -> None: if __name__ == "__main__": - # unittest.main() - - import typer - - typer.run(TestParameters().test_modules) + unittest.main() diff --git a/test/core/test_util.py b/test/core/test_util.py index 640eeadc..745f450a 100644 --- a/test/core/test_util.py +++ b/test/core/test_util.py @@ -10,26 +10,24 @@ from faebryk.core.node import Node from faebryk.core.parameter import Parameter from faebryk.core.util import get_node_tree, iter_tree_by_depth +from faebryk.libs.library import L class TestUtil(unittest.TestCase): def test_trees(self): class N(Module): - def __init__(self, depth: int): - super().__init__() - - class _IFs(Module.IFS()): - mif = ModuleInterface() - - self.IFs = _IFs(self) + mif: ModuleInterface - if depth == 0: - return + @L.rt_field + def n(self): + if self._depth == 0: + # TODO does this work? + return [] + return N(self._depth - 1) - class _NODES(Module.NODES()): - n = N(depth - 1) - - self.NODEs = _NODES(self) + def __init__(self, depth: int): + super().__init__() + self._depth = depth level_count = 5 n = N(level_count) From ffd37b710e566c6e3fe44850d904312c9b66e358 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 01:23:57 +0200 Subject: [PATCH 32/63] Fix connect_up; Add connect comment --- src/faebryk/core/link.py | 2 +- src/faebryk/core/moduleinterface.py | 29 ++++++++++-- test/core/test_hierarchy_connect.py | 68 +++++++++++------------------ 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/src/faebryk/core/link.py b/src/faebryk/core/link.py index d8920dee..deee44a1 100644 --- a/src/faebryk/core/link.py +++ b/src/faebryk/core/link.py @@ -101,7 +101,7 @@ def __new__(cls, *args, **kwargs): raise TypeError( "Can't instantiate abstract class _TLinkDirectShallow directly" ) - return LinkDirect.__new__(cls, *args, **kwargs) + return super().__new__(cls) def LinkDirectShallow(if_filter: Callable[[LinkDirect, "GraphInterface"], bool]): diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py index 38e10c60..8c70ced3 100644 --- a/src/faebryk/core/moduleinterface.py +++ b/src/faebryk/core/moduleinterface.py @@ -90,6 +90,25 @@ class GraphInterfaceModuleSibling(GraphInterfaceHierarchical): ... class GraphInterfaceModuleConnection(GraphInterface): ... +# CONNECT PROCEDURE +# connect +# connect_siblings +# - check not same ref +# - check not connected +# - connect_hierarchies +# - resolve link (if exists) +# - connect gifs +# - signal on_connect +# - connect_down +# - connect direct children by name +# - connect_up +# - check for each parent if all direct children by name connected +# - connect +# - check not filtered +# - cross connect_hierarchies transitive hull +# - cross connect_hierarchies siblings + + class ModuleInterface(Node): class TraitT(Trait): ... @@ -115,7 +134,7 @@ class _LinkDirectShallowMif( _LinkDirectShallow: type[_TLinkDirectShallow] | None = None - def __finit__(self) -> None: + def __preinit__(self) -> None: if not type(self)._LinkDirectShallow: type(self)._LinkDirectShallow = type(self).LinkDirectShallow() @@ -215,11 +234,13 @@ def _is_connected(a, b): assert isinstance(b, ModuleInterface) return a.is_connected_to(b) - src_m_is = src_m.get_children(direct_only=True, types=ModuleInterface) - dst_m_is = dst_m.get_children(direct_only=True, types=ModuleInterface) + from faebryk.core.util import zip_children_by_name + connection_map = [ (src_i, dst_i, _is_connected(src_i, dst_i)) - for src_i, dst_i in zip(src_m_is, dst_m_is) + for src_i, dst_i in zip_children_by_name( + src_m, dst_m, sub_type=ModuleInterface + ).values() ] assert connection_map diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index ffec1f04..39bb9018 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -5,17 +5,13 @@ import unittest from itertools import chain +import faebryk.library._F as F from faebryk.core.core import logger as core_logger from faebryk.core.link import LinkDirect, LinkDirectShallow, _TLinkDirectShallow from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.util import specialize_interface -from faebryk.library.Electrical import Electrical -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.has_single_electric_reference_defined import ( - has_single_electric_reference_defined, -) -from faebryk.library.UART_Base import UART_Base +from faebryk.libs.library import L from faebryk.libs.util import print_stack, times logger = logging.getLogger(__name__) @@ -25,15 +21,10 @@ class TestHierarchy(unittest.TestCase): def test_up_connect(self): class UARTBuffer(Module): - def __init__(self) -> None: - super().__init__() - - class _IFs(super().IFS()): - bus_in = UART_Base() - bus_out = UART_Base() - - self.IFs = _IFs(self) + bus_in: F.UART_Base + bus_out: F.UART_Base + def __preinit__(self) -> None: bus_in = self.bus_in bus_out = self.bus_out @@ -66,7 +57,7 @@ def test_chains(self): self.assertIsInstance(mifs[0].is_connected_to(mifs[2]), _TLinkDirectShallow) # Test hierarchy down filter & chain resolution - mifs = times(3, ElectricLogic) + mifs = times(3, F.ElectricLogic) mifs[0].connect_shallow(mifs[1]) mifs[1].connect(mifs[2]) self.assertTrue(mifs[0].is_connected_to(mifs[2])) @@ -87,21 +78,13 @@ def test_chains(self): def test_bridge(self): class Buffer(Module): - def __init__(self) -> None: - super().__init__() - - class _IFs(super().IFS()): - ins = times(2, Electrical) - outs = times(2, Electrical) - - ins_l = times(2, ElectricLogic) - outs_l = times(2, ElectricLogic) - - self.IFs = _IFs(self) + ins = L.if_list(2, F.Electrical) + outs = L.if_list(2, F.Electrical) - ref = ElectricLogic.connect_all_module_references(self) - self.add_trait(has_single_electric_reference_defined(ref)) + ins_l = L.if_list(2, F.ElectricLogic) + outs_l = L.if_list(2, F.ElectricLogic) + def __preinit__(self) -> None: for el, lo in chain( zip(self.ins, self.ins_l), zip(self.outs, self.outs_l), @@ -111,21 +94,19 @@ class _IFs(super().IFS()): for l1, l2 in zip(self.ins_l, self.outs_l): l1.connect_shallow(l2) - class UARTBuffer(Module): - def __init__(self) -> None: - super().__init__() - - class _NODES(super().NODES()): - buf = Buffer() - - class _IFs(super().IFS()): - bus_in = UART_Base() - bus_out = UART_Base() + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) - self.IFs = _IFs(self) - self.NODEs = _NODES(self) + class UARTBuffer(Module): + buf: Buffer + bus_in: F.UART_Base + bus_out: F.UART_Base - ElectricLogic.connect_all_module_references(self) + def __preinit__(self) -> None: + F.ElectricLogic.connect_all_module_references(self) bus1 = self.bus_in bus2 = self.bus_out @@ -207,4 +188,7 @@ class _Link(LinkDirectShallow(lambda link, gif: True)): ... if __name__ == "__main__": - unittest.main() + # unittest.main() + import typer + + typer.run(TestHierarchy().test_bridge) From 94e3bbecd587df140f9f08361e70f4270697b27b Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 02:57:57 +0200 Subject: [PATCH 33/63] fix rt fields --- src/faebryk/core/node.py | 17 +++++++---- test/core/test_core.py | 22 +++++++++++++++ test/core/test_hierarchy_connect.py | 44 +++++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index 3052da81..e31f8081 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -51,17 +51,22 @@ class fab_field: pass -class rt_field[T](property, fab_field): - def __init__(self, fget: Callable[[T], Any]) -> None: +class rt_field[T, O](property, fab_field): + def __init__(self, fget: Callable[[T], O]) -> None: super().__init__() self.func = fget + self.lookup: dict[T, O] = {} def _construct(self, obj: T): - self.constructed = self.func(obj) - return self.constructed + constructed = self.func(obj) + # TODO find a better way for this + # in python 3.13 name support + self.lookup[obj] = constructed - def __get__(self, instance: Any, owner: type | None = None) -> Any: - return self.constructed + return constructed + + def __get__(self, instance: T, owner: type | None = None) -> Any: + return self.lookup[instance] class _d_field[T](fab_field): diff --git a/test/core/test_core.py b/test/core/test_core.py index 91b45edb..ab99dad4 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -226,6 +226,28 @@ def SN4(self): children = n.get_children(direct_only=True, types=Node) self.assertEqual(children, {n.SN1, n.SN2, n.SN3[0], n.SN3[1], n.SN4}) + def test_fab_ll_chain_names(self): + root = Node() + x = root + for i in range(10): + y = Node() + x.add(y, f"i{i}") + x = y + + self.assertEqual(x.get_full_name(), "*.i0.i1.i2.i3.i4.i5.i6.i7.i8.i9") + + def test_fab_ll_chain_tree(self): + root = Node() + x = root + for i in range(10): + y = Node() + z = Node() + x.add(y, f"i{i}") + x.add(z, f"j{i}") + x = y + + self.assertEqual(x.get_full_name(), "*.i0.i1.i2.i3.i4.i5.i6.i7.i8.i9") + if __name__ == "__main__": unittest.main() diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index 39bb9018..559d3596 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -77,6 +77,8 @@ def test_chains(self): self.assertIsInstance(mifs[0].is_connected_to(mifs[2]), LinkDirect) def test_bridge(self): + self_ = self + class Buffer(Module): ins = L.if_list(2, F.Electrical) outs = L.if_list(2, F.Electrical) @@ -85,6 +87,11 @@ class Buffer(Module): outs_l = L.if_list(2, F.ElectricLogic) def __preinit__(self) -> None: + self_.assertIs( + self.ins_l[0].reference, + self.ins_l[0].single_electric_reference.get_reference(), + ) + for el, lo in chain( zip(self.ins, self.ins_l), zip(self.outs, self.outs_l), @@ -106,8 +113,6 @@ class UARTBuffer(Module): bus_out: F.UART_Base def __preinit__(self) -> None: - F.ElectricLogic.connect_all_module_references(self) - bus1 = self.bus_in bus2 = self.bus_out buf = self.buf @@ -117,6 +122,12 @@ def __preinit__(self) -> None: bus2.tx.signal.connect(buf.outs[0]) bus2.rx.signal.connect(buf.outs[1]) + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) + import faebryk.core.core as c # Enable to see the stack trace of invalid connections @@ -130,6 +141,13 @@ def _assert_no_link(mif1, mif2): err = "\n" + print_stack(link.tb) self.assertFalse(link, err) + def _assert_link(mif1: ModuleInterface, mif2: ModuleInterface, link=None): + out = mif1.is_connected_to(mif2) + if link: + self.assertIsInstance(out, link) + return + self.assertIsNotNone(out) + bus1 = app.bus_in bus2 = app.bus_out buf = app.buf @@ -140,10 +158,26 @@ def _assert_no_link(mif1, mif2): _assert_no_link(bus1.rx.signal, bus2.rx.signal) _assert_no_link(bus1.tx.signal, bus2.tx.signal) + # direct connect + _assert_link(bus1.tx.signal, buf.ins[0]) + _assert_link(bus1.rx.signal, buf.ins[1]) + _assert_link(bus2.tx.signal, buf.outs[0]) + _assert_link(bus2.rx.signal, buf.outs[1]) + + # connect through trait + self.assertIs( + buf.ins_l[0].single_electric_reference.get_reference(), + buf.ins_l[0].reference, + ) + _assert_link(buf.ins_l[0].reference, buf.outs_l[0].reference) + _assert_link(buf.outs_l[1].reference, buf.ins_l[0].reference) + + _assert_link(bus1.rx.reference, bus2.rx.reference, LinkDirect) + # Check that the two buffer sides are connected logically - self.assertTrue(bus1.rx.is_connected_to(bus2.rx)) - self.assertTrue(bus1.tx.is_connected_to(bus2.tx)) - self.assertTrue(bus1.is_connected_to(bus2)) + _assert_link(bus1.rx, bus2.rx) + _assert_link(bus1.tx, bus2.tx) + _assert_link(bus1, bus2) def test_specialize(self): class Specialized(ModuleInterface): ... From 1151050fe35de992d129e0cbd077129c589c3cd5 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 03:55:51 +0200 Subject: [PATCH 34/63] Fix link shallow; Add util:once --- src/faebryk/core/moduleinterface.py | 13 +++++----- src/faebryk/libs/util.py | 18 +++++++++++++ test/core/test_hierarchy_connect.py | 20 ++++++++++----- test/libs/util.py | 40 ++++++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/faebryk/core/moduleinterface.py b/src/faebryk/core/moduleinterface.py index 8c70ced3..ae3f0c7c 100644 --- a/src/faebryk/core/moduleinterface.py +++ b/src/faebryk/core/moduleinterface.py @@ -22,7 +22,7 @@ ) from faebryk.core.node import Node from faebryk.core.trait import Trait -from faebryk.libs.util import print_stack +from faebryk.libs.util import once, print_stack logger = logging.getLogger(__name__) @@ -118,6 +118,7 @@ class TraitT(Trait): ... # TODO rename @classmethod + @once def LinkDirectShallow(cls): """ Make link that only connects up but not down @@ -130,13 +131,11 @@ class _LinkDirectShallowMif( LinkDirectShallow(lambda link, gif: test(gif.node)) ): ... - return _LinkDirectShallowMif + print("Make shallow for", cls) - _LinkDirectShallow: type[_TLinkDirectShallow] | None = None + return _LinkDirectShallowMif - def __preinit__(self) -> None: - if not type(self)._LinkDirectShallow: - type(self)._LinkDirectShallow = type(self).LinkDirectShallow() + def __preinit__(self) -> None: ... def _connect_siblings_and_connections( self, other: "ModuleInterface", linkcls: type[Link] @@ -335,7 +334,7 @@ def connect_via( intf.connect(other, linkcls=linkcls) def connect_shallow(self, other: Self) -> Self: - return self.connect(other, linkcls=type(self)._LinkDirectShallow) + return self.connect(other, linkcls=type(self).LinkDirectShallow()) def is_connected_to(self, other: "ModuleInterface"): return self.connected.is_connected(other.connected) diff --git a/src/faebryk/libs/util.py b/src/faebryk/libs/util.py index 8f68a717..10266b89 100644 --- a/src/faebryk/libs/util.py +++ b/src/faebryk/libs/util.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT import asyncio +import functools import inspect import logging from abc import abstractmethod @@ -797,3 +798,20 @@ def __() -> T: return __ return _ + + +def once[T, **P](f: Callable[P, T]) -> Callable[P, T]: + class _once: + def __init__(self) -> None: + self.cache = {} + + def __call__(self, *args: P.args, **kwds: P.kwargs) -> Any: + lookup = (args, tuple(kwds.items())) + if lookup in self.cache: + return self.cache[lookup] + + result = f(*args, **kwds) + self.cache[lookup] = result + return result + + return _once() diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index 559d3596..ed9e78b9 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -79,6 +79,11 @@ def test_chains(self): def test_bridge(self): self_ = self + # U1 ---> _________B________ ---> U2 + # TX IL ===> OL TX + # S --> I -> S S -> O --> S + # R -------- R ----- R -------- R + class Buffer(Module): ins = L.if_list(2, F.Electrical) outs = L.if_list(2, F.Electrical) @@ -171,12 +176,18 @@ def _assert_link(mif1: ModuleInterface, mif2: ModuleInterface, link=None): ) _assert_link(buf.ins_l[0].reference, buf.outs_l[0].reference) _assert_link(buf.outs_l[1].reference, buf.ins_l[0].reference) - _assert_link(bus1.rx.reference, bus2.rx.reference, LinkDirect) + # connect through up + _assert_link(bus1.tx, buf.ins_l[0], LinkDirect) + _assert_link(bus2.tx, buf.outs_l[0], LinkDirect) + + # connect shallow + _assert_link(buf.ins_l[0], buf.outs_l[0], _TLinkDirectShallow) + # Check that the two buffer sides are connected logically - _assert_link(bus1.rx, bus2.rx) _assert_link(bus1.tx, bus2.tx) + _assert_link(bus1.rx, bus2.rx) _assert_link(bus1, bus2) def test_specialize(self): @@ -222,7 +233,4 @@ class _Link(LinkDirectShallow(lambda link, gif: True)): ... if __name__ == "__main__": - # unittest.main() - import typer - - typer.run(TestHierarchy().test_bridge) + unittest.main() diff --git a/test/libs/util.py b/test/libs/util.py index 97c3fb37..445c4bf6 100644 --- a/test/libs/util.py +++ b/test/libs/util.py @@ -5,7 +5,7 @@ from itertools import combinations from faebryk.libs.logging import setup_basic_logging -from faebryk.libs.util import SharedReference, zip_non_locked +from faebryk.libs.util import SharedReference, once, zip_non_locked class TestUtil(unittest.TestCase): @@ -54,6 +54,44 @@ def all_equal(*args: SharedReference): all_equal(r1, r2, r3, r4, r5) + def test_once(self): + global ran + ran = False + + @once + def do(val: int): + global ran + ran = True + return val + + self.assertFalse(ran) + + self.assertEqual(do(5), 5) + self.assertTrue(ran) + ran = False + + self.assertEqual(do(5), 5) + self.assertFalse(ran) + + self.assertEqual(do(6), 6) + self.assertTrue(ran) + ran = False + + class A: + @classmethod + @once + def do(cls): + global ran + ran = True + return cls + + self.assertEqual(A.do(), A) + self.assertTrue(ran) + ran = False + + self.assertEqual(A.do(), A) + self.assertFalse(ran) + if __name__ == "__main__": setup_basic_logging() From 829ec7f98999df8cf3c4e8e56e9a539f7f0b5e98 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 04:04:43 +0200 Subject: [PATCH 35/63] dont autoupdate db in nopromptmode --- src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index 2af891aa..d18f1543 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -624,7 +624,7 @@ def init(self) -> None: else: raise FileNotFoundError(f"No JLCPCB database found at {self.db_file}") elif not self.is_db_up_to_date(): - if no_download_prompt or self.prompt_db_update( + if not no_download_prompt and self.prompt_db_update( f"JLCPCB database at {self.db_file} is older than 7 days, update?" ): self.download() From a003fcad3578c91cacd62de71e4efc7bd032af69 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 04:28:01 +0200 Subject: [PATCH 36/63] sort children by default --- src/faebryk/core/node.py | 18 +-- .../can_attach_to_footprint_symmetrically.py | 11 +- test/core/test_util.py | 137 ------------------ .../netlist/kicad/test_netlist_kicad.py | 35 ++--- 4 files changed, 31 insertions(+), 170 deletions(-) diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index e31f8081..aa55d496 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -517,21 +517,21 @@ def get_children[T: Node]( types: type[T] | tuple[type[T], ...], include_root: bool = False, f_filter: Callable[[T], bool] | None = None, + sort: bool = True, ): if direct_only: - children = self.get_node_direct_children_() + out = self.get_node_direct_children_() if include_root: - children.add(self) + out.add(self) else: - children = self.get_node_children_all(include_root=include_root) + out = self.get_node_children_all(include_root=include_root) - filtered = { - n - for n in children - if isinstance(n, types) and (not f_filter or f_filter(n)) - } + out = {n for n in out if isinstance(n, types) and (not f_filter or f_filter(n))} + + if sort: + out = set(sorted(out, key=lambda n: n.get_name())) - return filtered + return out def get_node_children_all(self, include_root=True) -> list["Node"]: # TODO looks like get_node_tree is 2x faster diff --git a/src/faebryk/library/can_attach_to_footprint_symmetrically.py b/src/faebryk/library/can_attach_to_footprint_symmetrically.py index ae98cfe4..5b2ee040 100644 --- a/src/faebryk/library/can_attach_to_footprint_symmetrically.py +++ b/src/faebryk/library/can_attach_to_footprint_symmetrically.py @@ -2,17 +2,14 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.core.moduleinterface import ModuleInterface class can_attach_to_footprint_symmetrically(F.can_attach_to_footprint.impl()): def attach(self, footprint: F.Footprint): - from faebryk.core.util import zip_children_by_name - self.obj.add_trait(F.has_footprint_defined(footprint)) - for i, j in zip_children_by_name(footprint, self.obj, ModuleInterface): - assert isinstance(i, F.Pad) - assert isinstance(j, F.Electrical) - assert type(i.net) is type(j) + for i, j in zip( + footprint.get_children(direct_only=True, types=F.Pad), + self.obj.get_children(direct_only=True, types=F.Electrical), + ): i.attach(j) diff --git a/test/core/test_util.py b/test/core/test_util.py index 745f450a..7b10f1fe 100644 --- a/test/core/test_util.py +++ b/test/core/test_util.py @@ -2,13 +2,10 @@ # SPDX-License-Identifier: MIT import unittest -from enum import StrEnum -from typing import Iterable from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node -from faebryk.core.parameter import Parameter from faebryk.core.util import get_node_tree, iter_tree_by_depth from faebryk.libs.library import L @@ -49,137 +46,3 @@ def assertEqual(n1: list[Node], n2: list[Node]): assertEqual(levels[i], [n_i.n, n_i.mif]) n_i = n_i.n assertEqual(levels[level_count + 1], [n_i.mif]) - - def test_children(self): - # TODO this is a really annoying to debug test - - class E(StrEnum): - I_ = "IF" - N = "NODE" - P = "PARAM" - - EI = E.I_ - EN = E.N - EP = E.P - - def moduleFromTree( - t: dict[E, dict | type] | type, root_type: E - ) -> type[Module]: - root_type_t = { - EN: Module, - EI: ModuleInterface, - EP: Parameter, - }[root_type] - - class _(root_type_t): - inner_tree = t - - def __init__(self): - super().__init__() - - if isinstance(t, dict): - for k, vs in t.items(): - assert isinstance(vs, list) - name = f"{k}s" - for i, v in enumerate(vs): - setattr( - getattr(self, name), f"i{i}", moduleFromTree(v, k)() - ) - - return _ - - def assertEqual(n1: Iterable[Node], n2: list): - t = list(sorted([n.inner_tree for n in n1], key=id)) - t2 = list(sorted(n2, key=id)) - from pprint import pformat - - if t != t2: - print("Compare", "-" * 40) - for x in t: - print(f"{id(x)} \n{pformat(x, indent=4)}") - print("=" * 20) - for x in t2: - print(f"{id(x)} \n{pformat(x, indent=4)}") - print("~" * 40) - for x1, x2 in zip(t, t2): - print( - f"{x1==x2:>5}| " - f"{id(x1):<20} {pformat(x1, indent=4).splitlines()[0]:<80}" - " -- " - f"{id(x2):<20} {pformat(x2, indent=4).splitlines()[0]}" - ) - self.assertEqual(t, t2) - - tree = { - EI: [ - ModuleInterface, - { - EN: [Module, Module], - EI: [ModuleInterface], - }, - ], - EN: [ - { - EN: [Module, Module], - EI: [ModuleInterface], - EP: [ - { - EP: [Parameter], - } - ], - }, - { - EN: [Module, Module], - EI: [ModuleInterface], - }, - { - EN: [Module, Module], - EI: [ModuleInterface], - }, - ], - EP: [], - } - - def visit_tree(t, keys=None, typ=EN): - if not keys or typ in keys: - yield t - - if isinstance(t, dict): - for k, vs in t.items(): - for v in vs: - yield from visit_tree(v, keys=keys, typ=k) - else: - assert isinstance(t, type) - - mod = moduleFromTree(tree, EN)() - - direct_children_top = mod.get_children(direct_only=True, types=Module) - assertEqual(direct_children_top, tree[EN]) - - direct_children_top_all_types = mod.get_children(direct_only=True, types=Node) - assertEqual(direct_children_top_all_types, tree[EN] + tree[EI] + tree[EP]) - - all_children_top = mod.get_children( - direct_only=False, include_root=True, types=Node - ) - assertEqual(all_children_top, list(visit_tree(tree))) - - all_children_top_typed = mod.get_children( - direct_only=False, types=Module, include_root=True - ) - assertEqual(all_children_top_typed, list(visit_tree(tree, [EN]))) - - direct_children_middle = mod.i0.get_children(direct_only=True) - assertEqual( - direct_children_middle, tree[EN][0][EN] + tree[EN][0][EI] + tree[EN][0][EP] - ) - - all_children_middle = mod.i0.get_children(direct_only=False, include_root=True) - assertEqual( - all_children_middle, - list(visit_tree(tree[EN][0])), - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/exporters/netlist/kicad/test_netlist_kicad.py b/test/exporters/netlist/kicad/test_netlist_kicad.py index 1fb260d7..9ac0dec9 100644 --- a/test/exporters/netlist/kicad/test_netlist_kicad.py +++ b/test/exporters/netlist/kicad/test_netlist_kicad.py @@ -4,34 +4,28 @@ import logging import unittest +import faebryk.library._F as F from faebryk.exporters.netlist.graph import attach_nets_and_kicad_info from faebryk.exporters.netlist.kicad.netlist_kicad import from_faebryk_t2_netlist from faebryk.exporters.netlist.netlist import make_t2_netlist_from_graph -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.has_designator_defined import has_designator_defined -from faebryk.library.has_designator_prefix import has_designator_prefix -from faebryk.library.Net import Net from faebryk.libs.app.designators import ( attach_random_designators, override_names_with_designators, ) +from faebryk.libs.units import P logger = logging.getLogger(__name__) # Netlists -------------------------------------------------------------------- def _test_netlist_graph(): - from faebryk.library.Resistor import Resistor - from faebryk.library.SMDTwoPin import SMDTwoPin - - resistor1 = Resistor().builder(lambda r: r.resistance.merge(100)) - resistor2 = Resistor().builder(lambda r: r.resistance.merge(200)) - power = ElectricPower() + resistor1 = F.Resistor().builder(lambda r: r.resistance.merge(100 * P.ohm)) + resistor2 = F.Resistor().builder(lambda r: r.resistance.merge(200 * P.ohm)) + power = F.ElectricPower() # net labels - vcc = Net.with_name("+3V3") - gnd = Net.with_name("GND") + vcc = F.Net.with_name("+3V3") + gnd = F.Net.with_name("GND") power.hv.connect(vcc.part_of) power.lv.connect(gnd.part_of) @@ -43,10 +37,12 @@ def _test_netlist_graph(): # attach footprint & designator for i, r in enumerate([resistor1, resistor2]): - r.get_trait(can_attach_to_footprint).attach(SMDTwoPin(SMDTwoPin.Type._0805)) + r.get_trait(F.can_attach_to_footprint).attach( + F.SMDTwoPin(F.SMDTwoPin.Type._0805) + ) r.add_trait( - has_designator_defined( - resistor1.get_trait(has_designator_prefix).get_prefix() + str(i + 1) + F.has_designator_defined( + resistor1.get_trait(F.has_designator_prefix).get_prefix() + str(i + 1) ) ) @@ -67,7 +63,7 @@ def _test_netlist_graph(): if not success: logger.error("Graph != T2") logger.error("T2: %s", kicad_netlist_t2) - logger.error("Graph: %s", netlist) + logger.error("Gr: %s", netlist) return success, netlist @@ -218,3 +214,8 @@ def test_netlist(self): ok, _ = _test_netlist_graph() self.assertTrue(ok) + + +import typer + +typer.run(TestNetlist().test_netlist) From 0fd29549fccf0f135ac7585387ff55fa858a2f12 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 04:33:20 +0200 Subject: [PATCH 37/63] capacitor instances; all TESTS PASS --- src/faebryk/library/Capacitor.py | 6 +++--- test/exporters/netlist/kicad/test_netlist_kicad.py | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index ecb132a8..9519b01d 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -25,9 +25,9 @@ class TemperatureCoefficient(IntEnum): unnamed = L.if_list(2, F.Electrical) - capacitance = F.TBD[Quantity]() - rated_voltage = F.TBD[Quantity]() - temperature_coefficient = F.TBD[TemperatureCoefficient]() + capacitance: F.TBD[Quantity] + rated_voltage: F.TBD[Quantity] + temperature_coefficient: F.TBD[TemperatureCoefficient] attach_to_footprint: F.can_attach_to_footprint_symmetrically designator_prefix = L.f_field(F.has_designator_prefix_defined)("C") diff --git a/test/exporters/netlist/kicad/test_netlist_kicad.py b/test/exporters/netlist/kicad/test_netlist_kicad.py index 9ac0dec9..2118a5fd 100644 --- a/test/exporters/netlist/kicad/test_netlist_kicad.py +++ b/test/exporters/netlist/kicad/test_netlist_kicad.py @@ -214,8 +214,3 @@ def test_netlist(self): ok, _ = _test_netlist_graph() self.assertTrue(ok) - - -import typer - -typer.run(TestNetlist().test_netlist) From 4456278b6209deea7fcbcefb3b873342f2d3a4bd Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 04:51:05 +0200 Subject: [PATCH 38/63] rename if_list -> node_list --- examples/iterative_design_nand.py | 2 +- examples/route.py | 19 +++++++++++-------- new_holders_flat.py | 2 +- src/faebryk/core/node.py | 2 +- src/faebryk/exporters/pcb/routing/util.py | 7 +++++-- src/faebryk/library/B4B_ZR_SM4_TF.py | 4 ++-- src/faebryk/library/Button.py | 2 +- src/faebryk/library/CBM9002A_56ILG.py | 10 +++++----- .../CBM9002A_56ILG_Reference_Design.py | 10 +++++----- src/faebryk/library/Capacitor.py | 2 +- src/faebryk/library/Common_Mode_Filter.py | 4 ++-- src/faebryk/library/Crystal.py | 2 +- src/faebryk/library/Crystal_Oscillator.py | 2 +- src/faebryk/library/EEPROM.py | 2 +- src/faebryk/library/ESP32.py | 18 +++++++++--------- src/faebryk/library/ESP32_C3.py | 4 ++-- src/faebryk/library/ESP32_C3_MINI_1.py | 2 +- src/faebryk/library/Fuse.py | 2 +- src/faebryk/library/GenericBusProtection.py | 2 +- src/faebryk/library/Inductor.py | 2 +- src/faebryk/library/LogicGate.py | 2 +- src/faebryk/library/M24C08_FMN6TP.py | 2 +- src/faebryk/library/MCP2221A.py | 2 +- src/faebryk/library/Potentiometer.py | 4 ++-- src/faebryk/library/RJ45_Receptacle.py | 2 +- src/faebryk/library/RP2040.py | 2 +- .../library/RP2040_Reference_Design.py | 2 +- src/faebryk/library/RS485_Bus_Protection.py | 4 ++-- src/faebryk/library/Resistor.py | 2 +- .../library/Resistor_Voltage_Divider.py | 4 ++-- src/faebryk/library/SMDTwoPin.py | 2 +- src/faebryk/library/SNx4LVC541A.py | 6 +++--- src/faebryk/library/Sercom.py | 2 +- src/faebryk/library/Switch.py | 2 +- src/faebryk/library/TXS0102DCUR.py | 2 +- src/faebryk/library/USB2514B.py | 16 ++++++++-------- src/faebryk/library/USB2_0_ESD_Protection.py | 2 +- src/faebryk/library/USB_C_5V_PSU.py | 2 +- src/faebryk/library/USB_C_PSU_Vertical.py | 2 +- src/faebryk/library/USB_RS485.py | 2 +- .../library/USB_Type_C_Receptacle_24_pin.py | 4 ++-- src/faebryk/library/pf_533984002.py | 4 ++-- src/faebryk/libs/library/L.py | 2 +- test/core/test_core.py | 2 +- test/core/test_hierarchy_connect.py | 8 ++++---- test/core/test_performance.py | 4 ++-- 46 files changed, 97 insertions(+), 91 deletions(-) diff --git a/examples/iterative_design_nand.py b/examples/iterative_design_nand.py index 36489f0c..f8ae891e 100644 --- a/examples/iterative_design_nand.py +++ b/examples/iterative_design_nand.py @@ -37,7 +37,7 @@ class PowerSource(Module): class XOR_with_NANDS(F.LogicGates.XOR): - nands = L.if_list(4, lambda: F.LogicGates.NAND(F.Constant(2))) + nands = L.node_list(4, lambda: F.LogicGates.NAND(F.Constant(2))) def __init__(self): super().__init__(F.Constant(2)) diff --git a/examples/route.py b/examples/route.py index f4a74e91..5c36ad71 100644 --- a/examples/route.py +++ b/examples/route.py @@ -26,8 +26,8 @@ class SubArray(Module): - unnamed = L.if_list(2, F.Electrical) - resistors = L.if_list(2, F.Resistor) + unnamed = L.node_list(2, F.Electrical) + resistors = L.node_list(2, F.Resistor) def __init__(self, extrude_y: float): super().__init__() @@ -70,8 +70,8 @@ def pcb_routing_stategy_manual(self): [ (0, 0), (2.5, 0), - (2.5, extrude_y), - (0, extrude_y), + (2.5, self._extrude_y), + (0, self._extrude_y), ], ), ] @@ -87,8 +87,8 @@ def pcb_routing_stategy_manual(self): [ (0, 0), (-2.5, 0), - (-2.5, extrude_y), - (0, extrude_y), + (-2.5, self._extrude_y), + (0, self._extrude_y), ], ), ] @@ -99,8 +99,11 @@ def pcb_routing_stategy_manual(self): class ResistorArray(Module): - unnamed = L.if_list(2, F.Electrical) - resistors = L.if_list(2, F.Resistor) + unnamed = L.node_list(2, F.Electrical) + + @L.rt_field + def resistors(self): + return times(self._count, lambda: SubArray(self._extrude_y[1])) def __init__(self, count: int, extrude_y: tuple[float, float]): super().__init__() diff --git a/new_holders_flat.py b/new_holders_flat.py index 936ea129..2b3fda33 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -69,7 +69,7 @@ def __preinit__(self): class LED2_WITHEXTRAT_IFS(LED2): extra: list[F.Electrical] = field(default_factory=lambda: times(2, F.Electrical)) - extra2: list[F.Electrical] = L.if_list(2, F.Electrical) + extra2: list[F.Electrical] = L.node_list(2, F.Electrical) @L.rt_field def bridge(self): diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index aa55d496..fb16d74a 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -41,7 +41,7 @@ class FieldContainerError(FieldError): pass -def if_list[T: Node](n: int, if_type: type[T]) -> list[T]: +def node_list[T: Node](n: int, if_type: type[T]) -> list[T]: out = d_field(lambda: times(n, if_type)) out.type = if_type return out diff --git a/src/faebryk/exporters/pcb/routing/util.py b/src/faebryk/exporters/pcb/routing/util.py index 824a3868..3e395df6 100644 --- a/src/faebryk/exporters/pcb/routing/util.py +++ b/src/faebryk/exporters/pcb/routing/util.py @@ -98,10 +98,11 @@ def __init__( path: Path | None = None, ): super().__init__() - self.path = path or Path() + self._pads = pads - for pad in pads: + def __preinit__(self): + for pad in self._pads: self.pcb.connect(pad.pcb) self.net_.connect(pad.net) @@ -110,6 +111,8 @@ def add(self, obj: Path.Obj): @property def net(self): + from faebryk.core.util import get_net + net = get_net(self.net_) assert net return net diff --git a/src/faebryk/library/B4B_ZR_SM4_TF.py b/src/faebryk/library/B4B_ZR_SM4_TF.py index 5aaf64ad..a2391a9e 100644 --- a/src/faebryk/library/B4B_ZR_SM4_TF.py +++ b/src/faebryk/library/B4B_ZR_SM4_TF.py @@ -7,8 +7,8 @@ class B4B_ZR_SM4_TF(Module): - pin = L.if_list(4, F.Electrical) - mount = L.if_list(2, F.Electrical) + pin = L.node_list(4, F.Electrical) + mount = L.node_list(2, F.Electrical) datasheet = L.f_field(F.has_datasheet_defined)( "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2304140030_BOOMELE-Boom-Precision-Elec-1-5-4P_C145997.pdf" diff --git a/src/faebryk/library/Button.py b/src/faebryk/library/Button.py index 6a41d491..85d7d8be 100644 --- a/src/faebryk/library/Button.py +++ b/src/faebryk/library/Button.py @@ -11,7 +11,7 @@ class Button(Module): - unnamed = L.if_list(2, F.Electrical) + unnamed = L.node_list(2, F.Electrical) designator_prefix = L.f_field(F.has_designator_prefix_defined)("S") diff --git a/src/faebryk/library/CBM9002A_56ILG.py b/src/faebryk/library/CBM9002A_56ILG.py index 81ab71f9..ea40cbc2 100644 --- a/src/faebryk/library/CBM9002A_56ILG.py +++ b/src/faebryk/library/CBM9002A_56ILG.py @@ -16,17 +16,17 @@ class CBM9002A_56ILG(Module): # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- - PA = L.if_list(8, F.ElectricLogic) - PB = L.if_list(8, F.ElectricLogic) - PD = L.if_list(8, F.ElectricLogic) + PA = L.node_list(8, F.ElectricLogic) + PB = L.node_list(8, F.ElectricLogic) + PD = L.node_list(8, F.ElectricLogic) usb: F.USB2_0 i2c: F.I2C avcc: F.ElectricPower vcc: F.ElectricPower - rdy = L.if_list(2, F.ElectricLogic) - ctl = L.if_list(3, F.ElectricLogic) + rdy = L.node_list(2, F.ElectricLogic) + ctl = L.node_list(3, F.ElectricLogic) reset: F.ElectricLogic wakeup: F.ElectricLogic diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index 7e6edc1f..ee0d2088 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -20,17 +20,17 @@ class CBM9002A_56ILG_Reference_Design(Module): reset_lowpass_cap: F.Capacitor oscillator: F.Crystal_Oscillator - PA = L.if_list(8, F.ElectricLogic) - PB = L.if_list(8, F.ElectricLogic) - PD = L.if_list(8, F.ElectricLogic) + PA = L.node_list(8, F.ElectricLogic) + PB = L.node_list(8, F.ElectricLogic) + PD = L.node_list(8, F.ElectricLogic) usb: F.USB2_0 i2c: F.I2C avcc: F.ElectricPower vcc: F.ElectricPower - rdy = L.if_list(2, F.ElectricLogic) - ctl = L.if_list(3, F.ElectricLogic) + rdy = L.node_list(2, F.ElectricLogic) + ctl = L.node_list(3, F.ElectricLogic) reset: F.ElectricLogic wakeup: F.ElectricLogic diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index 9519b01d..a84cf4fd 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -23,7 +23,7 @@ class TemperatureCoefficient(IntEnum): X8R = auto() C0G = auto() - unnamed = L.if_list(2, F.Electrical) + unnamed = L.node_list(2, F.Electrical) capacitance: F.TBD[Quantity] rated_voltage: F.TBD[Quantity] diff --git a/src/faebryk/library/Common_Mode_Filter.py b/src/faebryk/library/Common_Mode_Filter.py index f85c1466..16dcbdc2 100644 --- a/src/faebryk/library/Common_Mode_Filter.py +++ b/src/faebryk/library/Common_Mode_Filter.py @@ -11,7 +11,7 @@ class Common_Mode_Filter(Module): - c_a = L.if_list(2, F.Electrical) - c_b = L.if_list(2, F.Electrical) + c_a = L.node_list(2, F.Electrical) + c_b = L.node_list(2, F.Electrical) designator_prefix = L.f_field(F.has_designator_prefix_defined)("FL") diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index 8a1963bc..f4b6ace8 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -21,7 +21,7 @@ class Crystal(Module): load_impedance: F.TBD[Quantity] gnd: F.Electrical - unnamed = L.if_list(2, F.Electrical) + unnamed = L.node_list(2, F.Electrical) # ---------------------------------------- # parameters diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 53954d25..085582ff 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -15,7 +15,7 @@ class Crystal_Oscillator(Module): # modules, interfaces, parameters # ---------------------------------------- crystal: F.Crystal - capacitors = L.if_list(2, F.Capacitor) + capacitors = L.node_list(2, F.Capacitor) power: F.ElectricPower p: F.Electrical diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index f2a885e1..d0624bb7 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -30,7 +30,7 @@ def set_address(self, addr: int): power: F.ElectricPower i2c: F.I2C write_protect: F.ElectricLogic - address = L.if_list(3, F.ElectricLogic) + address = L.node_list(3, F.ElectricLogic) # ---------------------------------------- # traits diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index 4b684736..222ef533 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -27,15 +27,15 @@ def CHANNELS(self): class _ESP_SDIO(ModuleInterface): - DATA = L.if_list(4, F.Electrical) + DATA = L.node_list(4, F.Electrical) CLK: F.Electrical CMD: F.Electrical GND: F.Electrical class _ESP32_EMAC(ModuleInterface): - TXD = L.if_list(4, F.Electrical) - RXD = L.if_list(4, F.Electrical) + TXD = L.node_list(4, F.Electrical) + RXD = L.node_list(4, F.Electrical) TX_CLK: F.Electrical RX_CLK: F.Electrical TX_EN: F.Electrical @@ -123,14 +123,14 @@ class ESP32(Module): GND: F.Electrical # High Level Functions - F.I2C = L.if_list(2, F.I2C) + F.I2C = L.node_list(2, F.I2C) SDIO_SLAVE: _ESP_SDIO - SDIO_HOST = L.if_list(2, _ESP_SDIO) + SDIO_HOST = L.node_list(2, _ESP_SDIO) UART: F.UART_Base JTAG: F.JTAG - TOUCH = L.if_list(10, F.Electrical) - GPIO = L.if_list(40 - 6, F.Electrical) - RTC_GPIO = L.if_list(18, F.Electrical) + TOUCH = L.node_list(10, F.Electrical) + GPIO = L.node_list(40 - 6, F.Electrical) + RTC_GPIO = L.node_list(18, F.Electrical) ADC = L.d_field( lambda: ( None, @@ -138,7 +138,7 @@ class ESP32(Module): _ESP_ADC(channel_count=10), ) ) - SPI = L.if_list(4, _ESP32_SPI) + SPI = L.node_list(4, _ESP32_SPI) EMAC: _ESP32_EMAC # Power diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 86896a10..a054bf29 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -23,11 +23,11 @@ class ESP32_C3(Module): enable: F.ElectricLogic xtal_p: F.Electrical xtal_n: F.Electrical - gpio = L.if_list(22, F.ElectricLogic) + gpio = L.node_list(22, F.ElectricLogic) # TODO: map peripherals to GPIOs with pinmux usb: F.USB2_0 i2c: F.I2C - uart = L.if_list(2, F.UART_Base) + uart = L.node_list(2, F.UART_Base) # ... etc designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/ESP32_C3_MINI_1.py b/src/faebryk/library/ESP32_C3_MINI_1.py index f65d6b60..fca437d4 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1.py +++ b/src/faebryk/library/ESP32_C3_MINI_1.py @@ -18,7 +18,7 @@ class ESP32_C3_MINI_1(Module): rf_output: F.Electrical chip_enable: F.ElectricLogic - gpio = L.if_list( + gpio = L.node_list( 22, F.ElectricLogic ) # TODO: Only GPIO 0 to 10 and 18, 19 are exposed uart: F.UART_Base diff --git a/src/faebryk/library/Fuse.py b/src/faebryk/library/Fuse.py index c24203ed..861d8142 100644 --- a/src/faebryk/library/Fuse.py +++ b/src/faebryk/library/Fuse.py @@ -21,7 +21,7 @@ class ResponseType(Enum): SLOW = auto() FAST = auto() - unnamed = L.if_list(2, F.Electrical) + unnamed = L.node_list(2, F.Electrical) fuse_type: F.TBD[FuseType] response_type: F.TBD[ResponseType] trip_current: F.TBD[Quantity] diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index 07dc46f4..894c9fbc 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -45,7 +45,7 @@ def get_mifs[U: ModuleInterface](bus: T, mif_type: type[U]) -> set[U]: ) ) - fuse = L.if_list(len(power), F.Fuse) + fuse = L.node_list(len(power), F.Fuse) # Pass through except hv for power_unprotected, power_protected in power: diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index c624adf3..c40eb9aa 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -9,7 +9,7 @@ class Inductor(Module): - unnamed = L.if_list(2, F.Electrical) + unnamed = L.node_list(2, F.Electrical) inductance: F.TBD[Quantity] self_resonant_frequency: F.TBD[Quantity] diff --git a/src/faebryk/library/LogicGate.py b/src/faebryk/library/LogicGate.py index 731741ee..d9917341 100644 --- a/src/faebryk/library/LogicGate.py +++ b/src/faebryk/library/LogicGate.py @@ -56,7 +56,7 @@ def __init__( super().__init__() self._input_cnt = input_cnt self._output_cnt = output_cnt - self._functions = functions + self._functions = list(functions) @L.rt_field def functions(self): diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index 5751c6af..b99ad729 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -16,7 +16,7 @@ class M24C08_FMN6TP(Module): power: F.ElectricPower data: F.I2C nwc: F.ElectricLogic - e = L.if_list(3, F.ElectricLogic) + e = L.node_list(3, F.ElectricLogic) @L.rt_field def attach_to_footprint(self): diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 20751227..00972f07 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -15,7 +15,7 @@ class MCP2221A(Module): power_vusb: F.ElectricPower uart: F.UART_Base i2c: F.I2C - gpio = L.if_list(4, F.Electrical) + gpio = L.node_list(4, F.Electrical) reset: F.ElectricLogic usb: F.USB2_0 diff --git a/src/faebryk/library/Potentiometer.py b/src/faebryk/library/Potentiometer.py index 568775e4..09047a6f 100644 --- a/src/faebryk/library/Potentiometer.py +++ b/src/faebryk/library/Potentiometer.py @@ -8,10 +8,10 @@ class Potentiometer(Module): - resistors_ifs = L.if_list(2, F.Electrical) + resistors_ifs = L.node_list(2, F.Electrical) wiper: F.Electrical total_resistance: F.TBD[Quantity] - resistors = L.if_list(2, F.Resistor) + resistors = L.node_list(2, F.Resistor) def __preinit__(self): for i, resistor in enumerate(self.resistors): diff --git a/src/faebryk/library/RJ45_Receptacle.py b/src/faebryk/library/RJ45_Receptacle.py index 47a619e5..55ccd2e6 100644 --- a/src/faebryk/library/RJ45_Receptacle.py +++ b/src/faebryk/library/RJ45_Receptacle.py @@ -15,7 +15,7 @@ class Mounting(Enum): # interfaces - pin = L.if_list(8, F.Electrical) + pin = L.node_list(8, F.Electrical) shield: F.Electrical designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index 08574d76..daf1db79 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -17,7 +17,7 @@ class RP2040(Module): vreg_in: F.ElectricPower vreg_out: F.ElectricPower power_vusb: F.ElectricPower - gpio = L.if_list(30, F.Electrical) + gpio = L.node_list(30, F.Electrical) run: F.ElectricLogic usb: F.USB2_0 qspi = L.f_field(F.MultiSPI)(data_lane_count=4) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index ec027400..907c0399 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -26,7 +26,7 @@ class RP2040_Reference_Design(Module): rp2040: F.RP2040 flash: F.SPIFlash led: F.PoweredLED - usb_current_limit_resistor = L.if_list(2, F.Resistor) + usb_current_limit_resistor = L.node_list(2, F.Resistor) # TODO: add crystal oscillator # TODO: add voltage divider with switch # TODO: add boot button diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 7744ebb6..2f652768 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -34,11 +34,11 @@ def __init__(self, termination: bool = True, polarization: bool = True) -> None: gdt: F.GDT tvs: F.TVS - current_limmiter_resistors = L.if_list(2, F.Resistor) + current_limmiter_resistors = L.node_list(2, F.Resistor) common_mode_filter: F.Common_Mode_Filter gnd_couple_resistor: F.Resistor gnd_couple_capacitor: F.Capacitor - clamping_diodes = L.if_list(2, F.Diode) + clamping_diodes = L.node_list(2, F.Diode) power: F.ElectricPower rs485_in: F.RS485 rs485_out: F.RS485 diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index 7f6a5a1e..b392423a 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -12,7 +12,7 @@ class Resistor(Module): - unnamed = L.if_list(2, F.Electrical) + unnamed = L.node_list(2, F.Electrical) resistance: F.TBD[Quantity] rated_power: F.TBD[Quantity] diff --git a/src/faebryk/library/Resistor_Voltage_Divider.py b/src/faebryk/library/Resistor_Voltage_Divider.py index 0d589288..a402d1ad 100644 --- a/src/faebryk/library/Resistor_Voltage_Divider.py +++ b/src/faebryk/library/Resistor_Voltage_Divider.py @@ -12,8 +12,8 @@ class Resistor_Voltage_Divider(Module): - resistor = L.if_list(2, F.Resistor) - node = L.if_list(3, F.Electrical) + resistor = L.node_list(2, F.Resistor) + node = L.node_list(3, F.Electrical) ratio: F.TBD[Quantity] max_current: F.TBD[Quantity] diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index 5d95833a..c960b1c4 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -24,7 +24,7 @@ def __init__(self, type: Type) -> None: super().__init__() self._type = type - pins = L.if_list(2, F.Pad) + pins = L.node_list(2, F.Pad) class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): def get_kicad_footprint(self) -> str: diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index b6869fd4..e097440c 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -17,12 +17,12 @@ class SNx4LVC541A(Module): # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- - A = L.if_list(8, F.ElectricLogic) - Y = L.if_list(8, F.ElectricLogic) + A = L.node_list(8, F.ElectricLogic) + Y = L.node_list(8, F.ElectricLogic) power: F.ElectricPower - OE = L.if_list(2, F.ElectricLogic) + OE = L.node_list(2, F.ElectricLogic) # ---------------------------------------- # traits diff --git a/src/faebryk/library/Sercom.py b/src/faebryk/library/Sercom.py index 11d8f1ca..a8623915 100644 --- a/src/faebryk/library/Sercom.py +++ b/src/faebryk/library/Sercom.py @@ -7,7 +7,7 @@ class Sercom(ModuleInterface): - unnamed = L.if_list(4, F.ElectricLogic) + unnamed = L.node_list(4, F.ElectricLogic) @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index c3f8cb28..fbd990dd 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -29,7 +29,7 @@ def __init__(self) -> None: designator_prefix = L.f_field(F.has_designator_prefix_defined)("SW") attach_to_footprint: F.can_attach_to_footprint_symmetrically - unnamed = L.if_list(2, interface_type) + unnamed = L.node_list(2, interface_type) @L.rt_field def can_bridge(self): diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index f0789fdf..ec63c335 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -29,7 +29,7 @@ def can_bridge(self): voltage_b_power: F.ElectricPower n_oe: F.ElectricLogic - shifters = L.if_list(2, _BidirectionalLevelShifter) + shifters = L.node_list(2, _BidirectionalLevelShifter) def __preinit__(self): gnd = self.voltage_a_power.lv diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 1eed0cab..966b3195 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -26,7 +26,7 @@ class InterfaceConfiguration(Enum): VBUS_DET: F.Electrical - usb_downstream = L.if_list(4, F.DifferentialPair) + usb_downstream = L.node_list(4, F.DifferentialPair) usb_upstream = F.DifferentialPair XTALIN: F.Electrical @@ -36,18 +36,18 @@ class InterfaceConfiguration(Enum): SUSP_IND: F.ElectricLogic RESET_N: F.Electrical RBIAS: F.Electrical - NON_REM = L.if_list(2, F.ElectricLogic) + NON_REM = L.node_list(2, F.ElectricLogic) LOCAL_PWR: F.Electrical CLKIN: F.Electrical - CFG_SEL = L.if_list(2, F.ElectricLogic) + CFG_SEL = L.node_list(2, F.ElectricLogic) HS_IND: F.ElectricLogic - PRTPWR = L.if_list(4, F.ElectricLogic) - PRT_DIS_P = L.if_list(4, F.ElectricLogic) - PRT_DIS_M = L.if_list(4, F.ElectricLogic) - OCS_N = L.if_list(4, F.ElectricLogic) - BC_EN = L.if_list(4, F.ElectricLogic) + PRTPWR = L.node_list(4, F.ElectricLogic) + PRT_DIS_P = L.node_list(4, F.ElectricLogic) + PRT_DIS_M = L.node_list(4, F.ElectricLogic) + OCS_N = L.node_list(4, F.ElectricLogic) + BC_EN = L.node_list(4, F.ElectricLogic) i2c: F.I2C gnd: F.Electrical diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index d6c58f7d..436b171a 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -12,7 +12,7 @@ class USB2_0_ESD_Protection(Module): - usb = L.if_list(2, F.USB2_0) + usb = L.node_list(2, F.USB2_0) vbus_esd_protection: F.TBD[bool] data_esd_protection: F.TBD[bool] diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index 2f0950b9..265fcd3d 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -13,7 +13,7 @@ class USB_C_5V_PSU(Module): usb: F.USB_C # components - configuration_resistors = L.if_list( + configuration_resistors = L.node_list( 2, lambda: F.Resistor().builder( lambda r: r.resistance.merge(F.Constant(5.1 * P.kohm)) diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index c58cf23a..e0f688ce 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -15,7 +15,7 @@ class USB_C_PSU_Vertical(Module): # components usb_connector: F.USB_Type_C_Receptacle_14_pin_Vertical # TODO: make generic - configuration_resistors = L.if_list(2, F.Resistor) + configuration_resistors = L.node_list(2, F.Resistor) gnd_resistor: F.Resistor gnd_capacitor: F.Capacitor esd: F.USB2_0_ESD_Protection diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index 5d37a8e6..ae98f0f1 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -15,7 +15,7 @@ class USB_RS485(Module): usb_uart: F.CH340x uart_rs485: F.UART_RS485 termination: F.Resistor - polarization = L.if_list(2, F.Resistor) + polarization = L.node_list(2, F.Resistor) usb: F.USB2_0 rs485: F.RS485 diff --git a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py index 418f0c4d..92192bbd 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py @@ -16,8 +16,8 @@ class USB_Type_C_Receptacle_24_pin(Module): sbu2: F.Electrical shield: F.Electrical # power - gnd = L.if_list(4, F.Electrical) - vbus = L.if_list(4, F.Electrical) + gnd = L.node_list(4, F.Electrical) + vbus = L.node_list(4, F.Electrical) # diffpairs: p, n rx1: F.DifferentialPair rx2: F.DifferentialPair diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index 627af979..42c6bfbb 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -8,8 +8,8 @@ class pf_533984002(Module): # interfaces - pin = L.if_list(2, F.Electrical) - mount = L.if_list(2, F.Electrical) + pin = L.node_list(2, F.Electrical) + mount = L.node_list(2, F.Electrical) @L.rt_field def attach_to_footprint(self): diff --git a/src/faebryk/libs/library/L.py b/src/faebryk/libs/library/L.py index 16f40cf9..452f080e 100644 --- a/src/faebryk/libs/library/L.py +++ b/src/faebryk/libs/library/L.py @@ -8,7 +8,7 @@ Node, d_field, f_field, - if_list, + node_list, rt_field, ) diff --git a/test/core/test_core.py b/test/core/test_core.py index ab99dad4..a7aadd6b 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -216,7 +216,7 @@ def test_fab_ll_simple_hierarchy(self): class N(Node): SN1: Node SN2: Node - SN3 = L.if_list(2, Node) + SN3 = L.node_list(2, Node) @L.rt_field def SN4(self): diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index ed9e78b9..9ddef5b1 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -85,11 +85,11 @@ def test_bridge(self): # R -------- R ----- R -------- R class Buffer(Module): - ins = L.if_list(2, F.Electrical) - outs = L.if_list(2, F.Electrical) + ins = L.node_list(2, F.Electrical) + outs = L.node_list(2, F.Electrical) - ins_l = L.if_list(2, F.ElectricLogic) - outs_l = L.if_list(2, F.ElectricLogic) + ins_l = L.node_list(2, F.ElectricLogic) + outs_l = L.node_list(2, F.ElectricLogic) def __preinit__(self) -> None: self_.assertIs( diff --git a/test/core/test_performance.py b/test/core/test_performance.py index 106b0f3d..90612ce8 100644 --- a/test/core/test_performance.py +++ b/test/core/test_performance.py @@ -47,7 +47,7 @@ class TestPerformance(unittest.TestCase): def test_get_all(self): def _factory_simple_resistors(count: int): class App(Module): - resistors = L.if_list(count, F.Resistor) + resistors = L.node_list(count, F.Resistor) def __init__(self, timings: Times) -> None: super().__init__() @@ -60,7 +60,7 @@ def __preinit__(self): def _factory_interconnected_resistors(count: int): class App(Module): - resistors = L.if_list(count, F.Resistor) + resistors = L.node_list(count, F.Resistor) def __init__(self, timings: Times) -> None: super().__init__() From e632092c4ddeef53a433627868200d20475ec9f8 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 05:24:36 +0200 Subject: [PATCH 39/63] removed type from d_field; fix rt_field init order --- examples/iterative_design_nand.py | 2 +- examples/route.py | 6 +- new_holders_flat.py | 2 +- src/faebryk/core/node.py | 59 ++++++------------- .../exporters/pcb/kicad/transformer.py | 6 +- src/faebryk/library/B4B_ZR_SM4_TF.py | 4 +- src/faebryk/library/Button.py | 2 +- src/faebryk/library/CBM9002A_56ILG.py | 10 ++-- .../CBM9002A_56ILG_Reference_Design.py | 10 ++-- src/faebryk/library/Capacitor.py | 2 +- src/faebryk/library/Common_Mode_Filter.py | 4 +- src/faebryk/library/Crystal.py | 2 +- src/faebryk/library/Crystal_Oscillator.py | 2 +- src/faebryk/library/DIP.py | 2 +- src/faebryk/library/EEPROM.py | 2 +- src/faebryk/library/ESP32.py | 18 +++--- src/faebryk/library/ESP32_C3.py | 4 +- src/faebryk/library/ESP32_C3_MINI_1.py | 2 +- src/faebryk/library/ElectricLogicGate.py | 8 +-- src/faebryk/library/Fuse.py | 2 +- src/faebryk/library/GenericBusProtection.py | 2 +- src/faebryk/library/Inductor.py | 2 +- src/faebryk/library/M24C08_FMN6TP.py | 2 +- src/faebryk/library/MCP2221A.py | 2 +- src/faebryk/library/Potentiometer.py | 4 +- src/faebryk/library/RJ45_Receptacle.py | 2 +- src/faebryk/library/RP2040.py | 2 +- .../library/RP2040_Reference_Design.py | 2 +- src/faebryk/library/RS485_Bus_Protection.py | 4 +- src/faebryk/library/Resistor.py | 2 +- .../library/Resistor_Voltage_Divider.py | 4 +- src/faebryk/library/SMDTwoPin.py | 2 +- src/faebryk/library/SNx4LVC541A.py | 6 +- src/faebryk/library/Sercom.py | 2 +- src/faebryk/library/Switch.py | 2 +- src/faebryk/library/TXS0102DCUR.py | 2 +- src/faebryk/library/USB2514B.py | 16 ++--- src/faebryk/library/USB2_0_ESD_Protection.py | 2 +- src/faebryk/library/USB_C_5V_PSU.py | 2 +- src/faebryk/library/USB_C_PSU_Vertical.py | 2 +- src/faebryk/library/USB_RS485.py | 2 +- .../library/USB_Type_C_Receptacle_24_pin.py | 4 +- src/faebryk/library/pf_533984002.py | 4 +- src/faebryk/libs/library/L.py | 2 +- test/core/test_core.py | 2 +- test/core/test_hierarchy_connect.py | 8 +-- test/core/test_performance.py | 4 +- 47 files changed, 108 insertions(+), 131 deletions(-) diff --git a/examples/iterative_design_nand.py b/examples/iterative_design_nand.py index f8ae891e..305c2f15 100644 --- a/examples/iterative_design_nand.py +++ b/examples/iterative_design_nand.py @@ -37,7 +37,7 @@ class PowerSource(Module): class XOR_with_NANDS(F.LogicGates.XOR): - nands = L.node_list(4, lambda: F.LogicGates.NAND(F.Constant(2))) + nands = L.list_field(4, lambda: F.LogicGates.NAND(F.Constant(2))) def __init__(self): super().__init__(F.Constant(2)) diff --git a/examples/route.py b/examples/route.py index 5c36ad71..862f5efe 100644 --- a/examples/route.py +++ b/examples/route.py @@ -26,8 +26,8 @@ class SubArray(Module): - unnamed = L.node_list(2, F.Electrical) - resistors = L.node_list(2, F.Resistor) + unnamed = L.list_field(2, F.Electrical) + resistors = L.list_field(2, F.Resistor) def __init__(self, extrude_y: float): super().__init__() @@ -99,7 +99,7 @@ def pcb_routing_stategy_manual(self): class ResistorArray(Module): - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) @L.rt_field def resistors(self): diff --git a/new_holders_flat.py b/new_holders_flat.py index 2b3fda33..568ebc5c 100644 --- a/new_holders_flat.py +++ b/new_holders_flat.py @@ -69,7 +69,7 @@ def __preinit__(self): class LED2_WITHEXTRAT_IFS(LED2): extra: list[F.Electrical] = field(default_factory=lambda: times(2, F.Electrical)) - extra2: list[F.Electrical] = L.node_list(2, F.Electrical) + extra2: list[F.Electrical] = L.list_field(2, F.Electrical) @L.rt_field def bridge(self): diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index fb16d74a..bcb87660 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Any, Callable, Iterable, Type, get_args, get_origin from deprecated import deprecated +from more_itertools import partition from faebryk.core.core import ID_REPR, FaebrykLibObject from faebryk.core.graphinterface import ( @@ -21,7 +22,6 @@ times, try_avoid_endless_recursion, ) -from more_itertools import partition if TYPE_CHECKING: from faebryk.core.trait import Trait, TraitImpl @@ -41,10 +41,8 @@ class FieldContainerError(FieldError): pass -def node_list[T: Node](n: int, if_type: type[T]) -> list[T]: - out = d_field(lambda: times(n, if_type)) - out.type = if_type - return out +def list_field[T: Node](n: int, if_type: Callable[[], T]) -> list[T]: + return d_field(lambda: times(n, if_type)) class fab_field: @@ -71,11 +69,10 @@ def __get__(self, instance: T, owner: type | None = None) -> Any: class _d_field[T](fab_field): def __init__(self, default_factory: Callable[[], T]) -> None: - self.type = None self.default_factory = default_factory def __repr__(self) -> str: - return f"{super().__repr__()}({self.type=}, {self.default_factory=})" + return f"{super().__repr__()}{self.default_factory=})" def d_field[T](default_factory: Callable[[], T]) -> T: @@ -89,9 +86,7 @@ def _(*args: P.args, **kwargs: P.kwargs) -> Callable[[], T]: def __() -> T: return con(*args, **kwargs) - out = _d_field(__) - out.type = con - return out + return _d_field(__) return _ @@ -120,6 +115,9 @@ def __init__(self, node: "Node", other: "Node", *args: object) -> None: ) +class NodeNoParent(NodeException): ... + + class Node(FaebrykLibObject, metaclass=PostInitCaller): runtime_anon: list["Node"] runtime: dict[str, "Node"] @@ -203,9 +201,6 @@ def all_anno(cls): annos = all_anno(cls) vars_ = all_vars(cls) - for name, obj in vars_.items(): - if isinstance(obj, _d_field) and obj.type is None: - obj.type = annos[name] def is_node_field(obj): def is_genalias_node(obj): @@ -229,12 +224,7 @@ def is_genalias_node(obj): return issubclass(obj, LL_Types) if isinstance(obj, _d_field): - t = obj.type - if isinstance(t, type): - return issubclass(t, LL_Types) - - if get_origin(t): - return is_genalias_node(t) + return True if get_origin(obj): return is_genalias_node(obj) @@ -267,9 +257,12 @@ def is_genalias_node(obj): # "| {type(obj)}" # ) + added_objects: dict[str, Node | GraphInterface] = {} objects: dict[str, Node | GraphInterface] = {} def handle_add(name, obj): + del objects[name] + added_objects[name] = obj if isinstance(obj, GraphInterface): self._handle_add_gif(name, obj) elif isinstance(obj, Node): @@ -307,22 +300,8 @@ def setup_gen_alias(name, obj): return if isinstance(obj, _d_field): - t = obj.type - - if isinstance(obj, _d_field): - inst = append(name, obj.default_factory()) - setattr(self, name, inst) - return - - if isinstance(t, type): - setattr(self, name, append(name, t())) - return - - if get_origin(t): - setup_gen_alias(name, t) - return - - raise NotImplementedError() + setattr(self, name, append(name, obj.default_factory())) + return if isinstance(obj, type): setattr(self, name, append(name, obj())) @@ -338,19 +317,17 @@ def setup_gen_alias(name, obj): for name, obj in nonrt: setup_field(name, obj) - for name, obj in objects.items(): + for name, obj in list(objects.items()): handle_add(name, obj) - obj_old = dict(objects) # rt fields depend on full self for name, obj in rt: setup_field(name, obj) - for name, obj in objects.items(): - if name not in obj_old: + for name, obj in list(objects.items()): handle_add(name, obj) - return objects, clsfields + return added_objects, clsfields def __new__(cls, *args, **kwargs): out = super().__new__(cls) @@ -424,7 +401,7 @@ def get_parent(self): def get_name(self): p = self.get_parent() if not p: - raise Exception("Parent required for name") + raise NodeNoParent(self, "Parent required for name") return p[1] def get_hierarchy(self) -> list[tuple["Node", str]]: diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index 5462dc5d..65fedc49 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -516,7 +516,7 @@ def mark(node: R) -> R: def insert(self, obj: Any): self._insert(obj) - def _get_pcb_node_list(self, node: R, prefix: str = "") -> list[R]: + def _get_pcb_list_field(self, node: R, prefix: str = "") -> list[R]: root = self.pcb key = prefix + type(node).__name__.removeprefix("C_") + "s" @@ -529,10 +529,10 @@ def _get_pcb_node_list(self, node: R, prefix: str = "") -> list[R]: def _insert(self, obj: Any, prefix: str = ""): obj = PCB_Transformer.mark(obj) - self._get_pcb_node_list(obj, prefix=prefix).append(obj) + self._get_pcb_list_field(obj, prefix=prefix).append(obj) def _delete(self, obj: Any, prefix: str = ""): - self._get_pcb_node_list(obj, prefix=prefix).remove(obj) + self._get_pcb_list_field(obj, prefix=prefix).remove(obj) def insert_via( self, coord: tuple[float, float], net: str, size_drill: tuple[float, float] diff --git a/src/faebryk/library/B4B_ZR_SM4_TF.py b/src/faebryk/library/B4B_ZR_SM4_TF.py index a2391a9e..b44f6f52 100644 --- a/src/faebryk/library/B4B_ZR_SM4_TF.py +++ b/src/faebryk/library/B4B_ZR_SM4_TF.py @@ -7,8 +7,8 @@ class B4B_ZR_SM4_TF(Module): - pin = L.node_list(4, F.Electrical) - mount = L.node_list(2, F.Electrical) + pin = L.list_field(4, F.Electrical) + mount = L.list_field(2, F.Electrical) datasheet = L.f_field(F.has_datasheet_defined)( "https://wmsc.lcsc.com/wmsc/upload/file/pdf/v2/lcsc/2304140030_BOOMELE-Boom-Precision-Elec-1-5-4P_C145997.pdf" diff --git a/src/faebryk/library/Button.py b/src/faebryk/library/Button.py index 85d7d8be..0a47e77c 100644 --- a/src/faebryk/library/Button.py +++ b/src/faebryk/library/Button.py @@ -11,7 +11,7 @@ class Button(Module): - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) designator_prefix = L.f_field(F.has_designator_prefix_defined)("S") diff --git a/src/faebryk/library/CBM9002A_56ILG.py b/src/faebryk/library/CBM9002A_56ILG.py index ea40cbc2..438dbbe4 100644 --- a/src/faebryk/library/CBM9002A_56ILG.py +++ b/src/faebryk/library/CBM9002A_56ILG.py @@ -16,17 +16,17 @@ class CBM9002A_56ILG(Module): # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- - PA = L.node_list(8, F.ElectricLogic) - PB = L.node_list(8, F.ElectricLogic) - PD = L.node_list(8, F.ElectricLogic) + PA = L.list_field(8, F.ElectricLogic) + PB = L.list_field(8, F.ElectricLogic) + PD = L.list_field(8, F.ElectricLogic) usb: F.USB2_0 i2c: F.I2C avcc: F.ElectricPower vcc: F.ElectricPower - rdy = L.node_list(2, F.ElectricLogic) - ctl = L.node_list(3, F.ElectricLogic) + rdy = L.list_field(2, F.ElectricLogic) + ctl = L.list_field(3, F.ElectricLogic) reset: F.ElectricLogic wakeup: F.ElectricLogic diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index ee0d2088..cfe0694f 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -20,17 +20,17 @@ class CBM9002A_56ILG_Reference_Design(Module): reset_lowpass_cap: F.Capacitor oscillator: F.Crystal_Oscillator - PA = L.node_list(8, F.ElectricLogic) - PB = L.node_list(8, F.ElectricLogic) - PD = L.node_list(8, F.ElectricLogic) + PA = L.list_field(8, F.ElectricLogic) + PB = L.list_field(8, F.ElectricLogic) + PD = L.list_field(8, F.ElectricLogic) usb: F.USB2_0 i2c: F.I2C avcc: F.ElectricPower vcc: F.ElectricPower - rdy = L.node_list(2, F.ElectricLogic) - ctl = L.node_list(3, F.ElectricLogic) + rdy = L.list_field(2, F.ElectricLogic) + ctl = L.list_field(3, F.ElectricLogic) reset: F.ElectricLogic wakeup: F.ElectricLogic diff --git a/src/faebryk/library/Capacitor.py b/src/faebryk/library/Capacitor.py index a84cf4fd..3e4e6244 100644 --- a/src/faebryk/library/Capacitor.py +++ b/src/faebryk/library/Capacitor.py @@ -23,7 +23,7 @@ class TemperatureCoefficient(IntEnum): X8R = auto() C0G = auto() - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) capacitance: F.TBD[Quantity] rated_voltage: F.TBD[Quantity] diff --git a/src/faebryk/library/Common_Mode_Filter.py b/src/faebryk/library/Common_Mode_Filter.py index 16dcbdc2..5f60bbda 100644 --- a/src/faebryk/library/Common_Mode_Filter.py +++ b/src/faebryk/library/Common_Mode_Filter.py @@ -11,7 +11,7 @@ class Common_Mode_Filter(Module): - c_a = L.node_list(2, F.Electrical) - c_b = L.node_list(2, F.Electrical) + c_a = L.list_field(2, F.Electrical) + c_b = L.list_field(2, F.Electrical) designator_prefix = L.f_field(F.has_designator_prefix_defined)("FL") diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index f4b6ace8..3a43b905 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -21,7 +21,7 @@ class Crystal(Module): load_impedance: F.TBD[Quantity] gnd: F.Electrical - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) # ---------------------------------------- # parameters diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 085582ff..bf5b3023 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -15,7 +15,7 @@ class Crystal_Oscillator(Module): # modules, interfaces, parameters # ---------------------------------------- crystal: F.Crystal - capacitors = L.node_list(2, F.Capacitor) + capacitors = L.list_field(2, F.Capacitor) power: F.ElectricPower p: F.Electrical diff --git a/src/faebryk/library/DIP.py b/src/faebryk/library/DIP.py index cfc5f392..e628d359 100644 --- a/src/faebryk/library/DIP.py +++ b/src/faebryk/library/DIP.py @@ -31,7 +31,7 @@ def get_kicad_footprint() -> str: longpads="_LongPads" if self.long_pads else "", ) - return _has_kicad_footprint + return _has_kicad_footprint() equal_pins_in_ifs: F.has_equal_pins_in_ifs attach_via_pinmap: F.can_attach_via_pinmap_equal diff --git a/src/faebryk/library/EEPROM.py b/src/faebryk/library/EEPROM.py index d0624bb7..a14f0e26 100644 --- a/src/faebryk/library/EEPROM.py +++ b/src/faebryk/library/EEPROM.py @@ -30,7 +30,7 @@ def set_address(self, addr: int): power: F.ElectricPower i2c: F.I2C write_protect: F.ElectricLogic - address = L.node_list(3, F.ElectricLogic) + address = L.list_field(3, F.ElectricLogic) # ---------------------------------------- # traits diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py index 222ef533..a9f5c7a2 100644 --- a/src/faebryk/library/ESP32.py +++ b/src/faebryk/library/ESP32.py @@ -27,15 +27,15 @@ def CHANNELS(self): class _ESP_SDIO(ModuleInterface): - DATA = L.node_list(4, F.Electrical) + DATA = L.list_field(4, F.Electrical) CLK: F.Electrical CMD: F.Electrical GND: F.Electrical class _ESP32_EMAC(ModuleInterface): - TXD = L.node_list(4, F.Electrical) - RXD = L.node_list(4, F.Electrical) + TXD = L.list_field(4, F.Electrical) + RXD = L.list_field(4, F.Electrical) TX_CLK: F.Electrical RX_CLK: F.Electrical TX_EN: F.Electrical @@ -123,14 +123,14 @@ class ESP32(Module): GND: F.Electrical # High Level Functions - F.I2C = L.node_list(2, F.I2C) + F.I2C = L.list_field(2, F.I2C) SDIO_SLAVE: _ESP_SDIO - SDIO_HOST = L.node_list(2, _ESP_SDIO) + SDIO_HOST = L.list_field(2, _ESP_SDIO) UART: F.UART_Base JTAG: F.JTAG - TOUCH = L.node_list(10, F.Electrical) - GPIO = L.node_list(40 - 6, F.Electrical) - RTC_GPIO = L.node_list(18, F.Electrical) + TOUCH = L.list_field(10, F.Electrical) + GPIO = L.list_field(40 - 6, F.Electrical) + RTC_GPIO = L.list_field(18, F.Electrical) ADC = L.d_field( lambda: ( None, @@ -138,7 +138,7 @@ class ESP32(Module): _ESP_ADC(channel_count=10), ) ) - SPI = L.node_list(4, _ESP32_SPI) + SPI = L.list_field(4, _ESP32_SPI) EMAC: _ESP32_EMAC # Power diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index a054bf29..3942495d 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -23,11 +23,11 @@ class ESP32_C3(Module): enable: F.ElectricLogic xtal_p: F.Electrical xtal_n: F.Electrical - gpio = L.node_list(22, F.ElectricLogic) + gpio = L.list_field(22, F.ElectricLogic) # TODO: map peripherals to GPIOs with pinmux usb: F.USB2_0 i2c: F.I2C - uart = L.node_list(2, F.UART_Base) + uart = L.list_field(2, F.UART_Base) # ... etc designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/ESP32_C3_MINI_1.py b/src/faebryk/library/ESP32_C3_MINI_1.py index fca437d4..07ab53aa 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1.py +++ b/src/faebryk/library/ESP32_C3_MINI_1.py @@ -18,7 +18,7 @@ class ESP32_C3_MINI_1(Module): rf_output: F.Electrical chip_enable: F.ElectricLogic - gpio = L.node_list( + gpio = L.list_field( 22, F.ElectricLogic ) # TODO: Only GPIO 0 to 10 and 18, 19 are exposed uart: F.UART_Base diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index c99d714a..a27f0ef4 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -18,12 +18,12 @@ def __init__( output_cnt: F.Constant[int], *functions: TraitImpl, ) -> None: - from faebryk.core.util import specialize_interface - - super().__init__(input_cnt, output_cnt, *functions) - self.input_cnt = input_cnt self.output_cnt = output_cnt + super().__init__(input_cnt, output_cnt, *functions) + + def __preinit__(self): + from faebryk.core.util import specialize_interface self_logic = self diff --git a/src/faebryk/library/Fuse.py b/src/faebryk/library/Fuse.py index 861d8142..27cbd851 100644 --- a/src/faebryk/library/Fuse.py +++ b/src/faebryk/library/Fuse.py @@ -21,7 +21,7 @@ class ResponseType(Enum): SLOW = auto() FAST = auto() - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) fuse_type: F.TBD[FuseType] response_type: F.TBD[ResponseType] trip_current: F.TBD[Quantity] diff --git a/src/faebryk/library/GenericBusProtection.py b/src/faebryk/library/GenericBusProtection.py index 894c9fbc..ba7865bb 100644 --- a/src/faebryk/library/GenericBusProtection.py +++ b/src/faebryk/library/GenericBusProtection.py @@ -45,7 +45,7 @@ def get_mifs[U: ModuleInterface](bus: T, mif_type: type[U]) -> set[U]: ) ) - fuse = L.node_list(len(power), F.Fuse) + fuse = L.list_field(len(power), F.Fuse) # Pass through except hv for power_unprotected, power_protected in power: diff --git a/src/faebryk/library/Inductor.py b/src/faebryk/library/Inductor.py index c40eb9aa..727b4ac4 100644 --- a/src/faebryk/library/Inductor.py +++ b/src/faebryk/library/Inductor.py @@ -9,7 +9,7 @@ class Inductor(Module): - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) inductance: F.TBD[Quantity] self_resonant_frequency: F.TBD[Quantity] diff --git a/src/faebryk/library/M24C08_FMN6TP.py b/src/faebryk/library/M24C08_FMN6TP.py index b99ad729..c331f51d 100644 --- a/src/faebryk/library/M24C08_FMN6TP.py +++ b/src/faebryk/library/M24C08_FMN6TP.py @@ -16,7 +16,7 @@ class M24C08_FMN6TP(Module): power: F.ElectricPower data: F.I2C nwc: F.ElectricLogic - e = L.node_list(3, F.ElectricLogic) + e = L.list_field(3, F.ElectricLogic) @L.rt_field def attach_to_footprint(self): diff --git a/src/faebryk/library/MCP2221A.py b/src/faebryk/library/MCP2221A.py index 00972f07..349ff3e4 100644 --- a/src/faebryk/library/MCP2221A.py +++ b/src/faebryk/library/MCP2221A.py @@ -15,7 +15,7 @@ class MCP2221A(Module): power_vusb: F.ElectricPower uart: F.UART_Base i2c: F.I2C - gpio = L.node_list(4, F.Electrical) + gpio = L.list_field(4, F.Electrical) reset: F.ElectricLogic usb: F.USB2_0 diff --git a/src/faebryk/library/Potentiometer.py b/src/faebryk/library/Potentiometer.py index 09047a6f..587859d6 100644 --- a/src/faebryk/library/Potentiometer.py +++ b/src/faebryk/library/Potentiometer.py @@ -8,10 +8,10 @@ class Potentiometer(Module): - resistors_ifs = L.node_list(2, F.Electrical) + resistors_ifs = L.list_field(2, F.Electrical) wiper: F.Electrical total_resistance: F.TBD[Quantity] - resistors = L.node_list(2, F.Resistor) + resistors = L.list_field(2, F.Resistor) def __preinit__(self): for i, resistor in enumerate(self.resistors): diff --git a/src/faebryk/library/RJ45_Receptacle.py b/src/faebryk/library/RJ45_Receptacle.py index 55ccd2e6..fe311f50 100644 --- a/src/faebryk/library/RJ45_Receptacle.py +++ b/src/faebryk/library/RJ45_Receptacle.py @@ -15,7 +15,7 @@ class Mounting(Enum): # interfaces - pin = L.node_list(8, F.Electrical) + pin = L.list_field(8, F.Electrical) shield: F.Electrical designator_prefix = L.f_field(F.has_designator_prefix_defined)("J") diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index daf1db79..be8d03ce 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -17,7 +17,7 @@ class RP2040(Module): vreg_in: F.ElectricPower vreg_out: F.ElectricPower power_vusb: F.ElectricPower - gpio = L.node_list(30, F.Electrical) + gpio = L.list_field(30, F.Electrical) run: F.ElectricLogic usb: F.USB2_0 qspi = L.f_field(F.MultiSPI)(data_lane_count=4) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index 907c0399..fa1b0145 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -26,7 +26,7 @@ class RP2040_Reference_Design(Module): rp2040: F.RP2040 flash: F.SPIFlash led: F.PoweredLED - usb_current_limit_resistor = L.node_list(2, F.Resistor) + usb_current_limit_resistor = L.list_field(2, F.Resistor) # TODO: add crystal oscillator # TODO: add voltage divider with switch # TODO: add boot button diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 2f652768..7f9f5216 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -34,11 +34,11 @@ def __init__(self, termination: bool = True, polarization: bool = True) -> None: gdt: F.GDT tvs: F.TVS - current_limmiter_resistors = L.node_list(2, F.Resistor) + current_limmiter_resistors = L.list_field(2, F.Resistor) common_mode_filter: F.Common_Mode_Filter gnd_couple_resistor: F.Resistor gnd_couple_capacitor: F.Capacitor - clamping_diodes = L.node_list(2, F.Diode) + clamping_diodes = L.list_field(2, F.Diode) power: F.ElectricPower rs485_in: F.RS485 rs485_out: F.RS485 diff --git a/src/faebryk/library/Resistor.py b/src/faebryk/library/Resistor.py index b392423a..465e3328 100644 --- a/src/faebryk/library/Resistor.py +++ b/src/faebryk/library/Resistor.py @@ -12,7 +12,7 @@ class Resistor(Module): - unnamed = L.node_list(2, F.Electrical) + unnamed = L.list_field(2, F.Electrical) resistance: F.TBD[Quantity] rated_power: F.TBD[Quantity] diff --git a/src/faebryk/library/Resistor_Voltage_Divider.py b/src/faebryk/library/Resistor_Voltage_Divider.py index a402d1ad..cc7dd64a 100644 --- a/src/faebryk/library/Resistor_Voltage_Divider.py +++ b/src/faebryk/library/Resistor_Voltage_Divider.py @@ -12,8 +12,8 @@ class Resistor_Voltage_Divider(Module): - resistor = L.node_list(2, F.Resistor) - node = L.node_list(3, F.Electrical) + resistor = L.list_field(2, F.Resistor) + node = L.list_field(3, F.Electrical) ratio: F.TBD[Quantity] max_current: F.TBD[Quantity] diff --git a/src/faebryk/library/SMDTwoPin.py b/src/faebryk/library/SMDTwoPin.py index c960b1c4..03a4e29e 100644 --- a/src/faebryk/library/SMDTwoPin.py +++ b/src/faebryk/library/SMDTwoPin.py @@ -24,7 +24,7 @@ def __init__(self, type: Type) -> None: super().__init__() self._type = type - pins = L.node_list(2, F.Pad) + pins = L.list_field(2, F.Pad) class _has_kicad_footprint(F.has_kicad_footprint_equal_ifs): def get_kicad_footprint(self) -> str: diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index e097440c..3cbf9df2 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -17,12 +17,12 @@ class SNx4LVC541A(Module): # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- - A = L.node_list(8, F.ElectricLogic) - Y = L.node_list(8, F.ElectricLogic) + A = L.list_field(8, F.ElectricLogic) + Y = L.list_field(8, F.ElectricLogic) power: F.ElectricPower - OE = L.node_list(2, F.ElectricLogic) + OE = L.list_field(2, F.ElectricLogic) # ---------------------------------------- # traits diff --git a/src/faebryk/library/Sercom.py b/src/faebryk/library/Sercom.py index a8623915..ca3b42df 100644 --- a/src/faebryk/library/Sercom.py +++ b/src/faebryk/library/Sercom.py @@ -7,7 +7,7 @@ class Sercom(ModuleInterface): - unnamed = L.node_list(4, F.ElectricLogic) + unnamed = L.list_field(4, F.ElectricLogic) @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index fbd990dd..a18eda04 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -29,7 +29,7 @@ def __init__(self) -> None: designator_prefix = L.f_field(F.has_designator_prefix_defined)("SW") attach_to_footprint: F.can_attach_to_footprint_symmetrically - unnamed = L.node_list(2, interface_type) + unnamed = L.list_field(2, interface_type) @L.rt_field def can_bridge(self): diff --git a/src/faebryk/library/TXS0102DCUR.py b/src/faebryk/library/TXS0102DCUR.py index ec63c335..2fa0bf11 100644 --- a/src/faebryk/library/TXS0102DCUR.py +++ b/src/faebryk/library/TXS0102DCUR.py @@ -29,7 +29,7 @@ def can_bridge(self): voltage_b_power: F.ElectricPower n_oe: F.ElectricLogic - shifters = L.node_list(2, _BidirectionalLevelShifter) + shifters = L.list_field(2, _BidirectionalLevelShifter) def __preinit__(self): gnd = self.voltage_a_power.lv diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 966b3195..6dd50c6a 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -26,7 +26,7 @@ class InterfaceConfiguration(Enum): VBUS_DET: F.Electrical - usb_downstream = L.node_list(4, F.DifferentialPair) + usb_downstream = L.list_field(4, F.DifferentialPair) usb_upstream = F.DifferentialPair XTALIN: F.Electrical @@ -36,18 +36,18 @@ class InterfaceConfiguration(Enum): SUSP_IND: F.ElectricLogic RESET_N: F.Electrical RBIAS: F.Electrical - NON_REM = L.node_list(2, F.ElectricLogic) + NON_REM = L.list_field(2, F.ElectricLogic) LOCAL_PWR: F.Electrical CLKIN: F.Electrical - CFG_SEL = L.node_list(2, F.ElectricLogic) + CFG_SEL = L.list_field(2, F.ElectricLogic) HS_IND: F.ElectricLogic - PRTPWR = L.node_list(4, F.ElectricLogic) - PRT_DIS_P = L.node_list(4, F.ElectricLogic) - PRT_DIS_M = L.node_list(4, F.ElectricLogic) - OCS_N = L.node_list(4, F.ElectricLogic) - BC_EN = L.node_list(4, F.ElectricLogic) + PRTPWR = L.list_field(4, F.ElectricLogic) + PRT_DIS_P = L.list_field(4, F.ElectricLogic) + PRT_DIS_M = L.list_field(4, F.ElectricLogic) + OCS_N = L.list_field(4, F.ElectricLogic) + BC_EN = L.list_field(4, F.ElectricLogic) i2c: F.I2C gnd: F.Electrical diff --git a/src/faebryk/library/USB2_0_ESD_Protection.py b/src/faebryk/library/USB2_0_ESD_Protection.py index 436b171a..295c2c02 100644 --- a/src/faebryk/library/USB2_0_ESD_Protection.py +++ b/src/faebryk/library/USB2_0_ESD_Protection.py @@ -12,7 +12,7 @@ class USB2_0_ESD_Protection(Module): - usb = L.node_list(2, F.USB2_0) + usb = L.list_field(2, F.USB2_0) vbus_esd_protection: F.TBD[bool] data_esd_protection: F.TBD[bool] diff --git a/src/faebryk/library/USB_C_5V_PSU.py b/src/faebryk/library/USB_C_5V_PSU.py index 265fcd3d..f4b91241 100644 --- a/src/faebryk/library/USB_C_5V_PSU.py +++ b/src/faebryk/library/USB_C_5V_PSU.py @@ -13,7 +13,7 @@ class USB_C_5V_PSU(Module): usb: F.USB_C # components - configuration_resistors = L.node_list( + configuration_resistors = L.list_field( 2, lambda: F.Resistor().builder( lambda r: r.resistance.merge(F.Constant(5.1 * P.kohm)) diff --git a/src/faebryk/library/USB_C_PSU_Vertical.py b/src/faebryk/library/USB_C_PSU_Vertical.py index e0f688ce..02626e07 100644 --- a/src/faebryk/library/USB_C_PSU_Vertical.py +++ b/src/faebryk/library/USB_C_PSU_Vertical.py @@ -15,7 +15,7 @@ class USB_C_PSU_Vertical(Module): # components usb_connector: F.USB_Type_C_Receptacle_14_pin_Vertical # TODO: make generic - configuration_resistors = L.node_list(2, F.Resistor) + configuration_resistors = L.list_field(2, F.Resistor) gnd_resistor: F.Resistor gnd_capacitor: F.Capacitor esd: F.USB2_0_ESD_Protection diff --git a/src/faebryk/library/USB_RS485.py b/src/faebryk/library/USB_RS485.py index ae98f0f1..3c5cb885 100644 --- a/src/faebryk/library/USB_RS485.py +++ b/src/faebryk/library/USB_RS485.py @@ -15,7 +15,7 @@ class USB_RS485(Module): usb_uart: F.CH340x uart_rs485: F.UART_RS485 termination: F.Resistor - polarization = L.node_list(2, F.Resistor) + polarization = L.list_field(2, F.Resistor) usb: F.USB2_0 rs485: F.RS485 diff --git a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py index 92192bbd..a0b0774d 100644 --- a/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py +++ b/src/faebryk/library/USB_Type_C_Receptacle_24_pin.py @@ -16,8 +16,8 @@ class USB_Type_C_Receptacle_24_pin(Module): sbu2: F.Electrical shield: F.Electrical # power - gnd = L.node_list(4, F.Electrical) - vbus = L.node_list(4, F.Electrical) + gnd = L.list_field(4, F.Electrical) + vbus = L.list_field(4, F.Electrical) # diffpairs: p, n rx1: F.DifferentialPair rx2: F.DifferentialPair diff --git a/src/faebryk/library/pf_533984002.py b/src/faebryk/library/pf_533984002.py index 42c6bfbb..df90b1ff 100644 --- a/src/faebryk/library/pf_533984002.py +++ b/src/faebryk/library/pf_533984002.py @@ -8,8 +8,8 @@ class pf_533984002(Module): # interfaces - pin = L.node_list(2, F.Electrical) - mount = L.node_list(2, F.Electrical) + pin = L.list_field(2, F.Electrical) + mount = L.list_field(2, F.Electrical) @L.rt_field def attach_to_footprint(self): diff --git a/src/faebryk/libs/library/L.py b/src/faebryk/libs/library/L.py index 452f080e..bc331c4e 100644 --- a/src/faebryk/libs/library/L.py +++ b/src/faebryk/libs/library/L.py @@ -8,7 +8,7 @@ Node, d_field, f_field, - node_list, + list_field, rt_field, ) diff --git a/test/core/test_core.py b/test/core/test_core.py index a7aadd6b..c7bb67be 100644 --- a/test/core/test_core.py +++ b/test/core/test_core.py @@ -216,7 +216,7 @@ def test_fab_ll_simple_hierarchy(self): class N(Node): SN1: Node SN2: Node - SN3 = L.node_list(2, Node) + SN3 = L.list_field(2, Node) @L.rt_field def SN4(self): diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index 9ddef5b1..4784b0bb 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -85,11 +85,11 @@ def test_bridge(self): # R -------- R ----- R -------- R class Buffer(Module): - ins = L.node_list(2, F.Electrical) - outs = L.node_list(2, F.Electrical) + ins = L.list_field(2, F.Electrical) + outs = L.list_field(2, F.Electrical) - ins_l = L.node_list(2, F.ElectricLogic) - outs_l = L.node_list(2, F.ElectricLogic) + ins_l = L.list_field(2, F.ElectricLogic) + outs_l = L.list_field(2, F.ElectricLogic) def __preinit__(self) -> None: self_.assertIs( diff --git a/test/core/test_performance.py b/test/core/test_performance.py index 90612ce8..e380aed1 100644 --- a/test/core/test_performance.py +++ b/test/core/test_performance.py @@ -47,7 +47,7 @@ class TestPerformance(unittest.TestCase): def test_get_all(self): def _factory_simple_resistors(count: int): class App(Module): - resistors = L.node_list(count, F.Resistor) + resistors = L.list_field(count, F.Resistor) def __init__(self, timings: Times) -> None: super().__init__() @@ -60,7 +60,7 @@ def __preinit__(self): def _factory_interconnected_resistors(count: int): class App(Module): - resistors = L.node_list(count, F.Resistor) + resistors = L.list_field(count, F.Resistor) def __init__(self, timings: Times) -> None: super().__init__() From 60c63fc9af0e28c4b643e703ae731e215f2d4403 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 07:01:30 +0200 Subject: [PATCH 40/63] Fix route example --- examples/route.py | 6 ++---- src/faebryk/exporters/pcb/layout/typehierarchy.py | 15 +++++++++++---- .../library/has_pcb_routing_strategy_manual.py | 3 ++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/route.py b/examples/route.py index 862f5efe..0488ac0b 100644 --- a/examples/route.py +++ b/examples/route.py @@ -14,9 +14,7 @@ from faebryk.exporters.pcb.layout.extrude import LayoutExtrude from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy from faebryk.exporters.pcb.routing.util import Path -from faebryk.libs.examples.buildutil import ( - apply_design_to_pcb, -) +from faebryk.libs.examples.buildutil import apply_design_to_pcb from faebryk.libs.library import L from faebryk.libs.logging import setup_basic_logging from faebryk.libs.units import P @@ -41,7 +39,7 @@ def __preinit__(self): @L.rt_field def pcb_layout(self): - F.has_pcb_layout_defined( + return F.has_pcb_layout_defined( LayoutTypeHierarchy( layouts=[ LayoutTypeHierarchy.Level( diff --git a/src/faebryk/exporters/pcb/layout/typehierarchy.py b/src/faebryk/exporters/pcb/layout/typehierarchy.py index 3eb1f6e3..1389de43 100644 --- a/src/faebryk/exporters/pcb/layout/typehierarchy.py +++ b/src/faebryk/exporters/pcb/layout/typehierarchy.py @@ -5,9 +5,10 @@ from dataclasses import dataclass from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node from faebryk.exporters.pcb.layout.layout import Layout -from faebryk.libs.util import NotNone, find_or, flatten, groupby +from faebryk.libs.util import NotNone, find_or, groupby logger = logging.getLogger(__name__) @@ -26,9 +27,8 @@ def apply(self, *node: Node): """ Tip: Make sure at least one parent of node has an absolute position defined """ - from faebryk.core.util import get_node_direct_children - # Find the layout for each node and group by matched level + # Find the layout for each node (isinstance mod_type) and group by matched level levels = groupby( { n: find_or( @@ -46,12 +46,19 @@ def apply(self, *node: Node): for level, nodes_tuple in levels.items(): nodes = [n for n, _ in nodes_tuple] - direct_children = flatten(get_node_direct_children(n) for n in nodes) + direct_children = { + c + for n in nodes + for c in n.get_children( + direct_only=True, types=(Module, ModuleInterface) + ) + } logger.debug( f"Level: {level.mod_type if level else None}," f" Children: {direct_children}" ) + # No type match, search for children instead if level is None: self.apply(*direct_children) continue diff --git a/src/faebryk/library/has_pcb_routing_strategy_manual.py b/src/faebryk/library/has_pcb_routing_strategy_manual.py index 8bf6794e..317706f6 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_manual.py +++ b/src/faebryk/library/has_pcb_routing_strategy_manual.py @@ -2,6 +2,7 @@ # SPDX-License-Identifier: MIT import logging +from typing import Sequence import faebryk.library._F as F from faebryk.core.node import Node @@ -19,7 +20,7 @@ class has_pcb_routing_strategy_manual(F.has_pcb_routing_strategy.impl()): def __init__( self, - paths: list[tuple[F.Net | list[F.Electrical], Path]], + paths: Sequence[tuple[F.Net | Sequence[F.Electrical], Path]], relative_to: Node | None = None, absolute: bool = False, ): From 42b68b29b44bed2135a73c1965a46297650c46df Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 07:14:00 +0200 Subject: [PATCH 41/63] update libadd.py to new fab ll --- src/faebryk/tools/libadd.py | 44 ++++++++++--------------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/src/faebryk/tools/libadd.py b/src/faebryk/tools/libadd.py index 34277b0b..aeda945a 100644 --- a/src/faebryk/tools/libadd.py +++ b/src/faebryk/tools/libadd.py @@ -90,45 +90,23 @@ def module(ctx: typer.Context, interface: bool = False): import logging - from faebryk.core.core import {base} + import faebryk.library._F as F # noqa: F401 + from faebryk.core.{base.lower()} import {base} + from faebryk.libs.library import L # noqa: F401 + from faebryk.libs.units import P # noqa: F401 logger = logging.getLogger(__name__) class {get_name(ctx)}({base}): - @classmethod - def NODES(cls): - # submodules - class _NODES(super().NODES()): - pass - - return _NODES - - @classmethod - def PARAMS(cls): - # parameters - class _PARAMS(super().PARAMS()): - pass - - return _PARAMS - - @classmethod - def IFS(cls): - # interfaces - class _IFS(super().IFS()): - pass - - return _IFS - - def __init__(self): - # boilerplate - super().__init__() - self = self.IFS()(self) - self.PARAMs = self.PARAMS()(self) - self.NODEs = self.NODES()(self) + # subnodes + # interfaces + # params + # traits + def __preinit__(self): + pass # connections - - # traits + # parametrization """) write(ctx, out) From 9f3fa5d98c0af92870709c49b5e8115fd5789523 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 07:37:28 +0200 Subject: [PATCH 42/63] small timing print fix --- test/core/test_performance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/test_performance.py b/test/core/test_performance.py index e380aed1..e4883167 100644 --- a/test/core/test_performance.py +++ b/test/core/test_performance.py @@ -72,7 +72,7 @@ def __preinit__(self): core_util.connect_all_interfaces( r.unnamed[0] for r in self.resistors ) - timings.add("connect") + self._timings.add("connect") return App From 4016aa480e524b77070ab0be71f8fe2e2c4af844 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 07:46:45 +0200 Subject: [PATCH 43/63] removed inconsistent defined traits --- src/faebryk/exporters/netlist/graph.py | 6 +++--- src/faebryk/library/TI_CD4011BE.py | 2 +- src/faebryk/library/_F.py | 15 ++++++--------- src/faebryk/library/has_defined_capacitance.py | 14 -------------- src/faebryk/library/has_defined_kicad_ref.py | 13 ------------- src/faebryk/library/has_defined_resistance.py | 14 -------------- ...s.py => has_descriptive_properties_defined.py} | 2 +- src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 2 +- src/faebryk/libs/picker/lcsc.py | 8 ++++---- test/libs/picker/test_jlcpcb.py | 4 ++-- 10 files changed, 18 insertions(+), 62 deletions(-) delete mode 100644 src/faebryk/library/has_defined_capacitance.py delete mode 100644 src/faebryk/library/has_defined_kicad_ref.py delete mode 100644 src/faebryk/library/has_defined_resistance.py rename src/faebryk/library/{has_defined_descriptive_properties.py => has_descriptive_properties_defined.py} (92%) diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index 7c88dcca..1f777400 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -11,8 +11,8 @@ from faebryk.exporters.netlist.netlist import T2Netlist from faebryk.library.Electrical import Electrical from faebryk.library.Footprint import Footprint -from faebryk.library.has_defined_descriptive_properties import ( - has_defined_descriptive_properties, +from faebryk.library.has_descriptive_properties_defined import ( + has_descriptive_properties_defined, ) from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_footprint import has_footprint @@ -59,7 +59,7 @@ def get_or_set_name_and_value_of_node(c: Module): ) ) - has_defined_descriptive_properties.add_properties_to( + has_descriptive_properties_defined.add_properties_to( c, {"faebryk_name": c.get_full_name()} ) diff --git a/src/faebryk/library/TI_CD4011BE.py b/src/faebryk/library/TI_CD4011BE.py index 9e5d7371..c75462da 100644 --- a/src/faebryk/library/TI_CD4011BE.py +++ b/src/faebryk/library/TI_CD4011BE.py @@ -33,7 +33,7 @@ def __preinit__(self): } ) - F.has_defined_descriptive_properties.add_properties_to( + F.has_descriptive_properties_defined.add_properties_to( self, { DescriptiveProperties.manufacturer: "Texas Instruments", diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 634431b9..05907fb0 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -16,24 +16,23 @@ # flake8: noqa: E501 from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.Operation import Operation from faebryk.library.Range import Range -from faebryk.library.TBD import TBD from faebryk.library.Constant import Constant +from faebryk.library.Operation import Operation +from faebryk.library.TBD import TBD from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_capacitance import has_capacitance from faebryk.library.has_footprint import has_footprint from faebryk.library.has_datasheet import has_datasheet from faebryk.library.has_esphome_config import has_esphome_config from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_single_electric_reference import has_single_electric_reference from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.has_kicad_ref import has_kicad_ref from faebryk.library.has_simple_value_representation import has_simple_value_representation from faebryk.library.has_pcb_layout import has_pcb_layout from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.Power import Power from faebryk.library.has_resistance import has_resistance +from faebryk.library.has_capacitance import has_capacitance from faebryk.library.has_single_connection import has_single_connection from faebryk.library.has_designator import has_designator from faebryk.library.has_linked_pad import has_linked_pad @@ -43,28 +42,26 @@ from faebryk.library.has_picker import has_picker from faebryk.library.Mechanical import Mechanical from faebryk.library.is_representable_by_single_value import is_representable_by_single_value +from faebryk.library.has_kicad_ref import has_kicad_ref from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative from faebryk.library.has_pcb_position_defined import has_pcb_position_defined from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent from faebryk.library.Logic import Logic +from faebryk.library.Set import Set from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY -from faebryk.library.Set import Set from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.has_defined_capacitance import has_defined_capacitance from faebryk.library.Footprint import Footprint from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -from faebryk.library.has_defined_descriptive_properties import has_defined_descriptive_properties +from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -from faebryk.library.has_defined_kicad_ref import has_defined_kicad_ref from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_defined_resistance import has_defined_resistance from faebryk.library.has_single_connection_impl import has_single_connection_impl from faebryk.library.has_designator_defined import has_designator_defined from faebryk.library.has_linked_pad_defined import has_linked_pad_defined diff --git a/src/faebryk/library/has_defined_capacitance.py b/src/faebryk/library/has_defined_capacitance.py deleted file mode 100644 index 9114638f..00000000 --- a/src/faebryk/library/has_defined_capacitance.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is part of the faebryk project -# SPDX-License-Identifier: MIT - -import faebryk.library._F as F -from faebryk.core.parameter import Parameter - - -class has_defined_capacitance(F.has_capacitance.impl()): - def __init__(self, capacitance: Parameter) -> None: - super().__init__() - self.component_capacitance = capacitance - - def get_capacitance(self): - return self.component_capacitance diff --git a/src/faebryk/library/has_defined_kicad_ref.py b/src/faebryk/library/has_defined_kicad_ref.py deleted file mode 100644 index 58450289..00000000 --- a/src/faebryk/library/has_defined_kicad_ref.py +++ /dev/null @@ -1,13 +0,0 @@ -# This file is part of the faebryk project -# SPDX-License-Identifier: MIT - -import faebryk.library._F as F - - -class has_defined_kicad_ref(F.has_kicad_ref.impl()): - def __init__(self, ref: str) -> None: - super().__init__() - self.ref = ref - - def get_ref(self) -> str: - return self.ref diff --git a/src/faebryk/library/has_defined_resistance.py b/src/faebryk/library/has_defined_resistance.py deleted file mode 100644 index 6f3bfb99..00000000 --- a/src/faebryk/library/has_defined_resistance.py +++ /dev/null @@ -1,14 +0,0 @@ -# This file is part of the faebryk project -# SPDX-License-Identifier: MIT - -import faebryk.library._F as F -from faebryk.core.parameter import Parameter - - -class has_defined_resistance(F.has_resistance.impl()): - def __init__(self, resistance: Parameter) -> None: - super().__init__() - self.component_resistance = resistance - - def get_resistance(self): - return self.component_resistance diff --git a/src/faebryk/library/has_defined_descriptive_properties.py b/src/faebryk/library/has_descriptive_properties_defined.py similarity index 92% rename from src/faebryk/library/has_defined_descriptive_properties.py rename to src/faebryk/library/has_descriptive_properties_defined.py index 70dac756..cab8aafe 100644 --- a/src/faebryk/library/has_defined_descriptive_properties.py +++ b/src/faebryk/library/has_descriptive_properties_defined.py @@ -6,7 +6,7 @@ from faebryk.core.module import Module -class has_defined_descriptive_properties(F.has_descriptive_properties.impl()): +class has_descriptive_properties_defined(F.has_descriptive_properties.impl()): def __init__(self, properties: dict[str, str]) -> None: super().__init__() self.properties = properties diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index d18f1543..34a489f8 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -340,7 +340,7 @@ def attach( for name, value in zip([m.param_name for m in mapping], params): getattr(module, name).override(value) - F.has_defined_descriptive_properties.add_properties_to( + F.has_descriptive_properties_defined.add_properties_to( module, { DescriptiveProperties.partno: self.mfr, diff --git a/src/faebryk/libs/picker/lcsc.py b/src/faebryk/libs/picker/lcsc.py index 2e89c9af..a6b5afbd 100644 --- a/src/faebryk/libs/picker/lcsc.py +++ b/src/faebryk/libs/picker/lcsc.py @@ -19,8 +19,8 @@ from faebryk.library.can_attach_to_footprint_via_pinmap import ( can_attach_to_footprint_via_pinmap, ) -from faebryk.library.has_defined_descriptive_properties import ( - has_defined_descriptive_properties, +from faebryk.library.has_descriptive_properties_defined import ( + has_descriptive_properties_defined, ) from faebryk.library.has_footprint import has_footprint from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic @@ -210,7 +210,7 @@ def attach(component: Module, partno: str, get_model: bool = True): ) component.get_trait(can_attach_to_footprint).attach(fp) - has_defined_descriptive_properties.add_properties_to(component, {"LCSC": partno}) + has_descriptive_properties_defined.add_properties_to(component, {"LCSC": partno}) # model done by kicad (in fp) @@ -220,7 +220,7 @@ def attach(self, module: Module, part: PickerOption): assert isinstance(part.part, LCSC_Part) attach(component=module, partno=part.part.partno) if part.info is not None: - has_defined_descriptive_properties.add_properties_to(module, part.info) + has_descriptive_properties_defined.add_properties_to(module, part.info) class LCSC_Part(Part): diff --git a/test/libs/picker/test_jlcpcb.py b/test/libs/picker/test_jlcpcb.py index 10ab7aaf..44b77bf9 100644 --- a/test/libs/picker/test_jlcpcb.py +++ b/test/libs/picker/test_jlcpcb.py @@ -171,7 +171,7 @@ def test_find_manufacturer_partnumber(self): ) ) requirement.add_trait( - F.has_defined_descriptive_properties( + F.has_descriptive_properties_defined( { DescriptiveProperties.partno: "LMV321IDBVR", DescriptiveProperties.manufacturer: "Texas Instruments", @@ -199,7 +199,7 @@ def test_find_lcsc_partnumber(self): ) ) requirement.add_trait( - F.has_defined_descriptive_properties( + F.has_descriptive_properties_defined( { "LCSC": "C7972", } From 757a04accdcd57721646b2717f191680135e1dd1 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 08:07:19 +0200 Subject: [PATCH 44/63] replace TypeVar & Generic where single use --- .../exporters/pcb/kicad/transformer.py | 13 ++--- src/faebryk/exporters/pcb/routing/grid.py | 11 ++-- src/faebryk/library/ElectricLogicGate.py | 4 -- src/faebryk/library/ElectricLogicGates.py | 4 -- src/faebryk/library/LogicGates.py | 4 -- src/faebryk/library/LogicOps.py | 3 -- src/faebryk/library/TBD.py | 5 +- src/faebryk/libs/sexp/dataclass_sexp.py | 11 ++-- src/faebryk/libs/util.py | 50 +++++-------------- test/core/test_parameters.py | 9 +--- 10 files changed, 27 insertions(+), 87 deletions(-) diff --git a/src/faebryk/exporters/pcb/kicad/transformer.py b/src/faebryk/exporters/pcb/kicad/transformer.py index 65fedc49..6ac0e658 100644 --- a/src/faebryk/exporters/pcb/kicad/transformer.py +++ b/src/faebryk/exporters/pcb/kicad/transformer.py @@ -131,10 +131,7 @@ def abs_pos2d(origin: T, vector: T2) -> Point2D: ) -R = TypeVar("R") - - -def per_point( +def per_point[R]( line: tuple[Point2D, Point2D], func: Callable[[Point2D], R] ) -> tuple[R, R]: return func(line[0]), func(line[1]) @@ -284,10 +281,8 @@ def cleanup(self): elif isinstance(holder, dict): del holder[get_key(obj, holder)] - T = TypeVar("T") - @staticmethod - def flipped(input_list: list[tuple[T, int]]) -> list[tuple[T, int]]: + def flipped[T](input_list: list[tuple[T, int]]) -> list[tuple[T, int]]: return [(x, (y + 180) % 360) for x, y in reversed(input_list)] @staticmethod @@ -506,7 +501,7 @@ def get_layer_name(self, layer_id: int) -> str: # Insert --------------------------------------------------------------------------- @staticmethod - def mark(node: R) -> R: + def mark[R](node: R) -> R: if hasattr(node, "uuid"): node.uuid = PCB_Transformer.gen_uuid(mark=True) # type: ignore @@ -516,7 +511,7 @@ def mark(node: R) -> R: def insert(self, obj: Any): self._insert(obj) - def _get_pcb_list_field(self, node: R, prefix: str = "") -> list[R]: + def _get_pcb_list_field[R](self, node: R, prefix: str = "") -> list[R]: root = self.pcb key = prefix + type(node).__name__.removeprefix("C_") + "s" diff --git a/src/faebryk/exporters/pcb/routing/grid.py b/src/faebryk/exporters/pcb/routing/grid.py index e7b10bd7..93cfe3f3 100644 --- a/src/faebryk/exporters/pcb/routing/grid.py +++ b/src/faebryk/exporters/pcb/routing/grid.py @@ -6,7 +6,7 @@ import math import re from abc import ABC, abstractmethod -from typing import Generic, Self, TypeVar +from typing import Self import graph_tool.all as gt import networkx as nx @@ -19,8 +19,6 @@ DIAGONALS = True WEIGHTS = (10, 15, 10000) -T = TypeVar("T", int, float) - class GridException(Exception): ... @@ -35,7 +33,7 @@ def get_coord(self, grid: "Grid"): return grid._project_out(self.vertex_index) -class Coord(Generic[T], np.ndarray): +class Coord[T: int, float](np.ndarray): EPS = 0.05 def __new__(cls, x: T, y: T, z: T): @@ -130,10 +128,7 @@ def eq(c1: intCoord, c2: intCoord): return all([_c1 == _c2 for _c1, _c2 in zip(c1, c2)]) -T = TypeVar("T") - - -class Graph(Generic[T], ABC): +class Graph[T](ABC): def __init__(self, G: T, steps): self.G = G self.steps = steps diff --git a/src/faebryk/library/ElectricLogicGate.py b/src/faebryk/library/ElectricLogicGate.py index a27f0ef4..8a46be26 100644 --- a/src/faebryk/library/ElectricLogicGate.py +++ b/src/faebryk/library/ElectricLogicGate.py @@ -1,15 +1,11 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from typing import TypeVar - import faebryk.library._F as F from faebryk.core.trait import TraitImpl from faebryk.libs.library import L from faebryk.libs.util import times -T = TypeVar("T", bound=F.Logic) - class ElectricLogicGate(F.LogicGate): def __init__( diff --git a/src/faebryk/library/ElectricLogicGates.py b/src/faebryk/library/ElectricLogicGates.py index e2cf9217..9fe253b4 100644 --- a/src/faebryk/library/ElectricLogicGates.py +++ b/src/faebryk/library/ElectricLogicGates.py @@ -1,12 +1,8 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from typing import TypeVar - import faebryk.library._F as F -T = TypeVar("T", bound=F.Logic) - class ElectricLogicGates: class OR(F.ElectricLogicGate): diff --git a/src/faebryk/library/LogicGates.py b/src/faebryk/library/LogicGates.py index 309de0fc..61e25bfd 100644 --- a/src/faebryk/library/LogicGates.py +++ b/src/faebryk/library/LogicGates.py @@ -1,12 +1,8 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from typing import TypeVar - import faebryk.library._F as F -T = TypeVar("T", bound=F.Logic) - class LogicGates: class OR(F.LogicGate): diff --git a/src/faebryk/library/LogicOps.py b/src/faebryk/library/LogicOps.py index 6617264e..8be95ece 100644 --- a/src/faebryk/library/LogicOps.py +++ b/src/faebryk/library/LogicOps.py @@ -2,13 +2,10 @@ # SPDX-License-Identifier: MIT from abc import abstractmethod -from typing import TypeVar import faebryk.library._F as F from faebryk.core.trait import Trait -T = TypeVar("T", bound=F.Logic) - class LogicOps: class can_logic(Trait): diff --git a/src/faebryk/library/TBD.py b/src/faebryk/library/TBD.py index b5b89035..56139ffd 100644 --- a/src/faebryk/library/TBD.py +++ b/src/faebryk/library/TBD.py @@ -2,14 +2,11 @@ # SPDX-License-Identifier: MIT from textwrap import indent -from typing import Generic, TypeVar from faebryk.core.parameter import Parameter -PV = TypeVar("PV") - -class TBD(Generic[PV], Parameter[PV]): +class TBD[PV](Parameter[PV]): def __eq__(self, __value: object) -> bool: if isinstance(__value, TBD): return True diff --git a/src/faebryk/libs/sexp/dataclass_sexp.py b/src/faebryk/libs/sexp/dataclass_sexp.py index 7ce714c3..343d3ea5 100644 --- a/src/faebryk/libs/sexp/dataclass_sexp.py +++ b/src/faebryk/libs/sexp/dataclass_sexp.py @@ -3,7 +3,7 @@ from enum import Enum, IntEnum, StrEnum from pathlib import Path from types import UnionType -from typing import Any, Callable, Iterator, TypeVar, Union, get_args, get_origin +from typing import Any, Callable, Iterator, Union, get_args, get_origin import sexpdata from sexpdata import Symbol @@ -61,9 +61,6 @@ def from_field(cls, f: Field): class SymEnum(StrEnum): ... -T = TypeVar("T") - - def _convert(val, t): # Recurse (GenericAlias e.g list[]) if (origin := get_origin(t)) is not None: @@ -100,7 +97,7 @@ def _convert(val, t): netlist_type = list[netlist_obj] -def _decode(sexp: netlist_type, t: type[T]) -> T: +def _decode[T](sexp: netlist_type, t: type[T]) -> T: if logger.isEnabledFor(logging.DEBUG): logger.debug(f"parse into: {t.__name__} {'-'*40}") logger.debug(f"sexp: {sexp}") @@ -310,7 +307,7 @@ def _append_kv(name, v): return sexp -def loads(s: str | Path | list, t: type[T]) -> T: +def loads[T](s: str | Path | list, t: type[T]) -> T: text = s sexp = s if isinstance(s, Path): @@ -342,7 +339,7 @@ def dumps(self, path: Path | None = None): # TODO move class JSON_File: @classmethod - def loads(cls: type[T], path: Path | str) -> T: + def loads[T](cls: type[T], path: Path | str) -> T: text = path if isinstance(path, Path): text = path.read_text() diff --git a/src/faebryk/libs/util.py b/src/faebryk/libs/util.py index 10266b89..c82cd782 100644 --- a/src/faebryk/libs/util.py +++ b/src/faebryk/libs/util.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import asyncio -import functools import inspect import logging from abc import abstractmethod @@ -14,7 +13,6 @@ from typing import ( Any, Callable, - Generic, Iterable, Iterator, List, @@ -23,7 +21,6 @@ SupportsFloat, SupportsInt, Type, - TypeVar, get_origin, ) @@ -97,11 +94,7 @@ def flatten(obj: Iterable, depth=1) -> List: return [nested for top in obj for nested in flatten(top, depth=depth - 1)] -T = TypeVar("T") -U = TypeVar("U") - - -def get_key(haystack: dict[T, U], needle: U) -> T: +def get_key[T, U](haystack: dict[T, U], needle: U) -> T: return find(haystack.items(), lambda x: x[1] == needle)[0] @@ -114,7 +107,7 @@ def __init__(self, duplicates: list, *args: object) -> None: self.duplicates = duplicates -def find(haystack: Iterable[T], needle: Callable[[T], bool]) -> T: +def find[T](haystack: Iterable[T], needle: Callable[[T], bool]) -> T: results = list(filter(needle, haystack)) if not results: raise KeyErrorNotFound() @@ -123,14 +116,14 @@ def find(haystack: Iterable[T], needle: Callable[[T], bool]) -> T: return results[0] -def find_or(haystack: Iterable[T], needle: Callable[[T], bool], default: T) -> T: +def find_or[T](haystack: Iterable[T], needle: Callable[[T], bool], default: T) -> T: try: return find(haystack, needle) except KeyErrorNotFound: return default -def groupby(it: Iterable[T], key: Callable[[T], U]) -> dict[U, list[T]]: +def groupby[T, U](it: Iterable[T], key: Callable[[T], U]) -> dict[U, list[T]]: out = defaultdict(list) for i in it: out[key(i)].append(i) @@ -165,11 +158,7 @@ def __setattr__(self, __name, __value) -> None: self._callback(__name, __value) -T = TypeVar("T") -P = TypeVar("P") - - -class _wrapper(NotifiesOnPropertyChange, Generic[T, P]): +class _wrapper[T, P](NotifiesOnPropertyChange): @abstractmethod def __init__(self, parent: P) -> None: raise NotImplementedError @@ -191,11 +180,8 @@ def extend_list(self, list_name: str, *objs: T) -> None: raise NotImplementedError -def Holder(_type: Type[T], _ptype: Type[P]) -> Type[_wrapper[T, P]]: - _T = TypeVar("_T") - _P = TypeVar("_P") - - class __wrapper(_wrapper[_T, _P]): +def Holder[T, P](_type: Type[T], _ptype: Type[P]) -> Type[_wrapper[T, P]]: + class __wrapper[_T, _P](_wrapper[_T, _P]): def __init__(self, parent: P) -> None: self._list: list[T] = [] self._type = _type @@ -279,24 +265,17 @@ def NotNone(x): return x -T = TypeVar("T") - - -def cast_assert(t: type[T], obj) -> T: +def cast_assert[T](t: type[T], obj) -> T: assert isinstance(obj, t) return obj -def times(cnt: SupportsInt, lamb: Callable[[], T]) -> list[T]: +def times[T](cnt: SupportsInt, lamb: Callable[[], T]) -> list[T]: return [lamb() for _ in range(int(cnt))] -T = TypeVar("T") -U = TypeVar("U") - - @staticmethod -def is_type_pair( +def is_type_pair[T, U]( param1: Any, param2: Any, type1: type[T], type2: type[U] ) -> Optional[tuple[T, U]]: o1 = get_origin(type1) or type1 @@ -485,14 +464,11 @@ def _f_no_rec(*args, **kwargs): return _f_no_rec -def zip_non_locked(left: Iterable[T], right: Iterable[U]): - TS = TypeVar("TS") - US = TypeVar("US") - +def zip_non_locked[T, U](left: Iterable[T], right: Iterable[U]): # Theoretically supports any amount of iters, # but for type hinting limit to two for now - class _Iter(Iterator[tuple[TS, US]]): + class _Iter[TS, US](Iterator[tuple[TS, US]]): class _NONDEFAULT: ... def __init__(self, args: list[Iterable]): @@ -534,7 +510,7 @@ def __next__(self): return _Iter[T, U]([left, right]) -def try_or( +def try_or[T]( func: Callable[..., T], default: T | None = None, default_f: Callable[[Exception], T] | None = None, diff --git a/test/core/test_parameters.py b/test/core/test_parameters.py index ce6c79b0..f7bf74bf 100644 --- a/test/core/test_parameters.py +++ b/test/core/test_parameters.py @@ -4,7 +4,6 @@ import logging import unittest from operator import add -from typing import TypeVar from faebryk.core.core import logger as core_logger from faebryk.core.module import Module @@ -135,9 +134,7 @@ def assertIsInstance[T: Parameter](obj: Parameter, cls: type[T]) -> T: self.assertEqual(Set([1, 2]) * P.baud, Set([1 * P.baud, 2 * P.baud])) def test_resolution(self): - T = TypeVar("T") - - def assertIsInstance(obj, cls: type[T]) -> T: + def assertIsInstance[T](obj, cls: type[T]) -> T: self.assertIsInstance(obj, cls) assert isinstance(obj, cls) return obj @@ -252,9 +249,7 @@ def test_comp( test_comp(Constant(Set([Range(Range(1))])), 1) def test_modules(self): - T = TypeVar("T") - - def assertIsInstance(obj, cls: type[T]) -> T: + def assertIsInstance[T](obj, cls: type[T]) -> T: self.assertIsInstance(obj, cls) assert isinstance(obj, cls) return obj From 03728620b811f278dd233beaecbc0d2a66e766b4 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 08:08:09 +0200 Subject: [PATCH 45/63] Run ruff --- src/faebryk/exporters/netlist/graph.py | 2 +- src/faebryk/library/Constant.py | 2 -- src/faebryk/library/has_single_electric_reference.py | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index 1f777400..01e897a1 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -11,10 +11,10 @@ from faebryk.exporters.netlist.netlist import T2Netlist from faebryk.library.Electrical import Electrical from faebryk.library.Footprint import Footprint +from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_descriptive_properties_defined import ( has_descriptive_properties_defined, ) -from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_footprint import has_footprint from faebryk.library.has_kicad_footprint import has_kicad_footprint from faebryk.library.has_overriden_name import has_overriden_name diff --git a/src/faebryk/library/Constant.py b/src/faebryk/library/Constant.py index 3bb09406..ea6cbc27 100644 --- a/src/faebryk/library/Constant.py +++ b/src/faebryk/library/Constant.py @@ -3,9 +3,7 @@ from typing import Self, SupportsAbs -import faebryk.library._F as F from faebryk.core.parameter import Parameter, _resolved -from faebryk.libs.library import L from faebryk.libs.units import Quantity diff --git a/src/faebryk/library/has_single_electric_reference.py b/src/faebryk/library/has_single_electric_reference.py index a8f6481a..1f6aefcc 100644 --- a/src/faebryk/library/has_single_electric_reference.py +++ b/src/faebryk/library/has_single_electric_reference.py @@ -5,7 +5,6 @@ from abc import abstractmethod from typing import TYPE_CHECKING -import faebryk.library._F as F from faebryk.core.trait import Trait if TYPE_CHECKING: From a6c268e78c4a7baac949e9809072412befe91bcc Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 08:18:33 +0200 Subject: [PATCH 46/63] prettier libadd --- src/faebryk/tools/libadd.py | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/faebryk/tools/libadd.py b/src/faebryk/tools/libadd.py index aeda945a..937b5ded 100644 --- a/src/faebryk/tools/libadd.py +++ b/src/faebryk/tools/libadd.py @@ -98,15 +98,27 @@ def module(ctx: typer.Context, interface: bool = False): logger = logging.getLogger(__name__) class {get_name(ctx)}({base}): - # subnodes - # interfaces - # params - # traits + \"\"\" + Docstring describing your module + \"\"\" + + # ---------------------------------------- + # modules, interfaces, parameters + # ---------------------------------------- + + # ---------------------------------------- + # traits + # ---------------------------------------- def __preinit__(self): + # ------------------------------------ + # connections + # ------------------------------------ + + # ------------------------------------ + # parametrization + # ------------------------------------ pass - # connections - # parametrization """) write(ctx, out) @@ -127,8 +139,16 @@ def trait(ctx: typer.Context, defined: bool = False): logger = logging.getLogger(__name__) class {traitname}(Trait): + \"\"\" + Docstring describing your module + \"\"\" + @abstractmethod - def DO_SOMETHING(self) -> None: ... + def DO_SOMETHING(self) -> None: + \"\"\" + Docstring describing the function + \"\"\" + pass """) write(ctx, out) From f98968d085ba0cc38c4b52517506fedbb93b7db0 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 13:08:26 +0200 Subject: [PATCH 47/63] Add refactor libTof & run it --- src/faebryk/exporters/bom/jlcpcb.py | 33 +++--- src/faebryk/exporters/esphome/esphome.py | 9 +- src/faebryk/exporters/netlist/graph.py | 54 ++++----- src/faebryk/exporters/netlist/netlist.py | 7 +- src/faebryk/exporters/pcb/routing/routing.py | 12 +- src/faebryk/exporters/pcb/routing/util.py | 24 ++-- src/faebryk/library/KicadFootprint.py | 3 +- src/faebryk/library/_F.py | 50 ++++----- ...pcb_routing_strategy_greedy_direct_line.py | 17 +-- src/faebryk/libs/app/designators.py | 37 +++---- src/faebryk/libs/app/erc.py | 4 +- src/faebryk/libs/app/parameters.py | 15 ++- src/faebryk/libs/app/pcb.py | 21 ++-- src/faebryk/libs/brightness.py | 103 +++++++++--------- src/faebryk/libs/examples/pickers.py | 7 +- src/faebryk/libs/picker/jlcpcb/jlcpcb.py | 3 +- src/faebryk/libs/picker/lcsc.py | 35 +++--- src/faebryk/tools/main.py | 2 + src/faebryk/tools/refactor.py | 90 +++++++++++++++ 19 files changed, 290 insertions(+), 236 deletions(-) create mode 100644 src/faebryk/tools/refactor.py diff --git a/src/faebryk/exporters/bom/jlcpcb.py b/src/faebryk/exporters/bom/jlcpcb.py index 2d23f06e..9e6b8b8d 100644 --- a/src/faebryk/exporters/bom/jlcpcb.py +++ b/src/faebryk/exporters/bom/jlcpcb.py @@ -1,3 +1,6 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT + import csv import logging import os @@ -5,14 +8,8 @@ from dataclasses import dataclass from pathlib import Path +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.has_descriptive_properties import has_descriptive_properties -from faebryk.library.has_designator import has_designator -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_kicad_footprint import has_kicad_footprint -from faebryk.library.has_simple_value_representation import ( - has_simple_value_representation, -) from faebryk.libs.picker.picker import DescriptiveProperties logger = logging.getLogger(__name__) @@ -104,30 +101,30 @@ def _compact_bomlines(bomlines: list[BOMLine]) -> list[BOMLine]: def _get_bomline(cmp: Module) -> BOMLine | None: - if not cmp.has_trait(has_footprint): + if not cmp.has_trait(F.has_footprint): return if not all( cmp.has_trait(t) for t in ( - has_descriptive_properties, - has_designator, + F.has_descriptive_properties, + F.has_designator, ) ): logger.warning(f"Missing fields on component {cmp}") return - properties = cmp.get_trait(has_descriptive_properties).get_properties() - footprint = cmp.get_trait(has_footprint).get_footprint() + properties = cmp.get_trait(F.has_descriptive_properties).get_properties() + footprint = cmp.get_trait(F.has_footprint).get_footprint() value = ( - cmp.get_trait(has_simple_value_representation).get_value() - if cmp.has_trait(has_simple_value_representation) + cmp.get_trait(F.has_simple_value_representation).get_value() + if cmp.has_trait(F.has_simple_value_representation) else "" ) - designator = cmp.get_trait(has_designator).get_designator() + designator = cmp.get_trait(F.has_designator).get_designator() - if not footprint.has_trait(has_kicad_footprint): + if not footprint.has_trait(F.has_kicad_footprint): logger.warning(f"Missing kicad footprint on component {cmp}") return @@ -145,7 +142,9 @@ def _get_bomline(cmp: Module) -> BOMLine | None: else "" ) - footprint_name = footprint.get_trait(has_kicad_footprint).get_kicad_footprint_name() + footprint_name = footprint.get_trait( + F.has_kicad_footprint + ).get_kicad_footprint_name() return BOMLine( Designator=designator, diff --git a/src/faebryk/exporters/esphome/esphome.py b/src/faebryk/exporters/esphome/esphome.py index 11b8dac2..4496f9f4 100644 --- a/src/faebryk/exporters/esphome/esphome.py +++ b/src/faebryk/exporters/esphome/esphome.py @@ -6,10 +6,9 @@ import yaml +import faebryk.library._F as F from faebryk.core.graphinterface import Graph from faebryk.core.parameter import Parameter -from faebryk.library.Constant import Constant -from faebryk.library.has_esphome_config import has_esphome_config logger = logging.getLogger(__name__) @@ -56,7 +55,7 @@ def merge_dicts(*dicts: dict) -> dict: def make_esphome_config(G: Graph) -> dict: from faebryk.core.util import get_all_nodes_with_trait - esphome_components = get_all_nodes_with_trait(G, has_esphome_config) + esphome_components = get_all_nodes_with_trait(G, F.has_esphome_config) esphome_config = merge_dicts(*[t.get_config() for _, t in esphome_components]) @@ -64,9 +63,9 @@ def instantiate_param(param: Parameter | Any): if not isinstance(param, Parameter): return param - if not isinstance(param, Constant): + if not isinstance(param, F.Constant): raise Exception( - f"Parameter {param} is not a Constant, but {type(param)}" + f"Parameter {param} is not a F.Constant, but {type(param)}" f"Config: {esphome_config}" ) return param.value diff --git a/src/faebryk/exporters/netlist/graph.py b/src/faebryk/exporters/netlist/graph.py index 01e897a1..a18f01f8 100644 --- a/src/faebryk/exporters/netlist/graph.py +++ b/src/faebryk/exporters/netlist/graph.py @@ -6,29 +6,15 @@ import networkx as nx +import faebryk.library._F as F from faebryk.core.graphinterface import Graph from faebryk.core.module import Module from faebryk.exporters.netlist.netlist import T2Netlist -from faebryk.library.Electrical import Electrical -from faebryk.library.Footprint import Footprint -from faebryk.library.has_descriptive_properties import has_descriptive_properties -from faebryk.library.has_descriptive_properties_defined import ( - has_descriptive_properties_defined, -) -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_kicad_footprint import has_kicad_footprint -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.has_simple_value_representation import ( - has_simple_value_representation, -) -from faebryk.library.Net import Net -from faebryk.library.Pad import Pad logger = logging.getLogger(__name__) -class can_represent_kicad_footprint(Footprint.TraitT): +class can_represent_kicad_footprint(F.Footprint.TraitT): kicad_footprint = T2Netlist.Component @abstractmethod @@ -38,19 +24,19 @@ def get_name_and_value(self) -> tuple[str, str]: ... def get_kicad_obj(self) -> kicad_footprint: ... @abstractmethod - def get_pin_name(self, pin: Pad) -> str: ... + def get_pin_name(self, pin: F.Pad) -> str: ... def get_or_set_name_and_value_of_node(c: Module): value = ( - c.get_trait(has_simple_value_representation).get_value() - if c.has_trait(has_simple_value_representation) + c.get_trait(F.has_simple_value_representation).get_value() + if c.has_trait(F.has_simple_value_representation) else type(c).__name__ ) - if not c.has_trait(has_overriden_name): + if not c.has_trait(F.has_overriden_name): c.add_trait( - has_overriden_name_defined( + F.has_overriden_name_defined( "{}[{}:{}]".format( c.get_full_name(), type(c).__name__, @@ -59,11 +45,11 @@ def get_or_set_name_and_value_of_node(c: Module): ) ) - has_descriptive_properties_defined.add_properties_to( + F.has_descriptive_properties_defined.add_properties_to( c, {"faebryk_name": c.get_full_name()} ) - return c.get_trait(has_overriden_name).get_name(), value + return c.get_trait(F.has_overriden_name).get_name(), value class can_represent_kicad_footprint_via_attached_component( @@ -81,20 +67,20 @@ def __init__(self, component: Module, graph: nx.Graph) -> None: def get_name_and_value(self): return get_or_set_name_and_value_of_node(self.component) - def get_pin_name(self, pin: Pad): - return self.obj.get_trait(has_kicad_footprint).get_pin_names()[pin] + def get_pin_name(self, pin: F.Pad): + return self.obj.get_trait(F.has_kicad_footprint).get_pin_names()[pin] def get_kicad_obj(self): - fp = self.get_obj(Footprint) + fp = self.get_obj(F.Footprint) properties = { - "footprint": fp.get_trait(has_kicad_footprint).get_kicad_footprint() + "footprint": fp.get_trait(F.has_kicad_footprint).get_kicad_footprint() } for c in [fp, self.component]: - if c.has_trait(has_descriptive_properties): + if c.has_trait(F.has_descriptive_properties): properties.update( - c.get_trait(has_descriptive_properties).get_properties() + c.get_trait(F.has_descriptive_properties).get_properties() ) name, value = self.get_name_and_value() @@ -106,17 +92,17 @@ def get_kicad_obj(self): ) -def add_or_get_net(interface: Electrical): +def add_or_get_net(interface: F.Electrical): from faebryk.core.util import get_connected_mifs mifs = get_connected_mifs(interface.connected) nets = { p[0] for mif in mifs - if (p := mif.get_parent()) is not None and isinstance(p[0], Net) + if (p := mif.get_parent()) is not None and isinstance(p[0], F.Net) } if not nets: - net = Net() + net = F.Net() net.part_of.connect(interface) return net if len(nets) > 1: @@ -135,7 +121,7 @@ def attach_nets_and_kicad_info(g: Graph): n: t.get_footprint() # TODO maybe nicer to just look for footprints # and get their respective components instead - for n, t in get_all_nodes_with_trait(Gclosed, has_footprint) + for n, t in get_all_nodes_with_trait(Gclosed, F.has_footprint) if isinstance(n, Module) } @@ -151,5 +137,5 @@ def attach_nets_and_kicad_info(g: Graph): for fp in node_fps.values(): # TODO use graph - for mif in fp.get_children(direct_only=True, types=Pad): + for mif in fp.get_children(direct_only=True, types=F.Pad): add_or_get_net(mif.net) diff --git a/src/faebryk/exporters/netlist/netlist.py b/src/faebryk/exporters/netlist/netlist.py index cd8cb571..0e7d77cd 100644 --- a/src/faebryk/exporters/netlist/netlist.py +++ b/src/faebryk/exporters/netlist/netlist.py @@ -4,9 +4,8 @@ import logging from dataclasses import dataclass +import faebryk.library._F as F from faebryk.core.graphinterface import Graph -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_overriden_name import has_overriden_name logger = logging.getLogger(__name__) @@ -45,7 +44,7 @@ def make_t2_netlist_from_graph(G: Graph) -> T2Netlist: t2_nets = [ T2Netlist.Net( - properties={"name": net.get_trait(has_overriden_name).get_name()}, + properties={"name": net.get_trait(F.has_overriden_name).get_name()}, vertices=sorted( [ T2Netlist.Net.Vertex( @@ -63,7 +62,7 @@ def make_t2_netlist_from_graph(G: Graph) -> T2Netlist: comps = { t.get_footprint().get_trait(can_represent_kicad_footprint).get_kicad_obj() - for _, t in get_all_nodes_with_trait(G, has_footprint) + for _, t in get_all_nodes_with_trait(G, F.has_footprint) } not_found = [ diff --git a/src/faebryk/exporters/pcb/routing/routing.py b/src/faebryk/exporters/pcb/routing/routing.py index 177f72b4..92cbb30c 100644 --- a/src/faebryk/exporters/pcb/routing/routing.py +++ b/src/faebryk/exporters/pcb/routing/routing.py @@ -10,6 +10,7 @@ import networkx as nx +import faebryk.library._F as F from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.grid import ( Coord, @@ -18,8 +19,6 @@ GridInvalidVertexException, OutCoord, ) -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.Net import Net from faebryk.libs.geometry.basic import Geometry from faebryk.libs.kicad.pcb import Footprint, GR_Circle, GR_Line, GR_Rect, Pad @@ -126,13 +125,12 @@ def draw_circle(self, coord: OutCoord, size=0.5, layer="User.9"): def route_all(self): from faebryk.core.util import get_all_nodes_of_type - from faebryk.library.Net import Net as FNet - nets = get_all_nodes_of_type(self.transformer.graph, FNet) + nets = get_all_nodes_of_type(self.transformer.graph, F.Net) # TODO add net picking heuristic for net in nets: - netname = net.get_trait(has_overriden_name).get_name() + netname = net.get_trait(F.has_overriden_name).get_name() try: self.route_net(net) except GridInvalidVertexException as e: @@ -158,12 +156,12 @@ def layer(p): return [layer(p) for p in pad.pos] - def route_net(self, net: Net): + def route_net(self, net: F.Net): transformer = self.transformer assert net is not None pcb_net = transformer.get_net(net) - net_name = net.get_trait(has_overriden_name).get_name() + net_name = net.get_trait(F.has_overriden_name).get_name() mifs = net.get_connected_interfaces() # get pads diff --git a/src/faebryk/exporters/pcb/routing/util.py b/src/faebryk/exporters/pcb/routing/util.py index 3e395df6..5bef9acb 100644 --- a/src/faebryk/exporters/pcb/routing/util.py +++ b/src/faebryk/exporters/pcb/routing/util.py @@ -5,12 +5,10 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Iterable, Sequence +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node -from faebryk.library.Electrical import Electrical -from faebryk.library.Net import Net -from faebryk.library.Pad import Pad from faebryk.libs.geometry.basic import Geometry if TYPE_CHECKING: @@ -89,12 +87,12 @@ def __add__(self, other: "Path"): class Route(Module): - net_: Electrical + net_: F.Electrical pcb: ModuleInterface def __init__( self, - pads: Iterable[Pad], + pads: Iterable[F.Pad], path: Path | None = None, ): super().__init__() @@ -172,7 +170,7 @@ def apply_route_in_pcb(route: Route, transformer: "PCB_Transformer"): def get_internal_nets_of_node( node: Node, -) -> dict[Net | None, Iterable[ModuleInterface]]: +) -> dict[F.Net | None, Iterable[ModuleInterface]]: """ Returns all Nets occuring (at least partially) within Node and returns for each of those the corresponding mifs @@ -186,16 +184,16 @@ def get_internal_nets_of_node( ) from faebryk.libs.util import groupby - if isinstance(node, Net): + if isinstance(node, F.Net): return {node: get_connected_mifs(node.part_of.connected)} - mifs = {n for n in get_all_nodes(node) + [node] if isinstance(n, Electrical)} + mifs = {n for n in get_all_nodes(node) + [node] if isinstance(n, F.Electrical)} nets = groupby(mifs, lambda mif: get_net(mif)) return nets -def get_pads_pos_of_mifs(mifs: Sequence[Electrical]): +def get_pads_pos_of_mifs(mifs: Sequence[F.Electrical]): from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer return { @@ -206,9 +204,9 @@ def get_pads_pos_of_mifs(mifs: Sequence[Electrical]): def group_pads_that_are_connected_already( - pads: Iterable[Pad], -) -> list[set[Pad]]: - out: list[set[Pad]] = [] + pads: Iterable[F.Pad], +) -> list[set[F.Pad]]: + out: list[set[F.Pad]] = [] for pad in pads: for group in out: # Only need to check first, because transitively connected @@ -220,7 +218,7 @@ def group_pads_that_are_connected_already( return out -def get_routes_of_pad(pad: Pad): +def get_routes_of_pad(pad: F.Pad): from faebryk.core.util import get_parent_of_type return { diff --git a/src/faebryk/library/KicadFootprint.py b/src/faebryk/library/KicadFootprint.py index a9c91080..9026c68f 100644 --- a/src/faebryk/library/KicadFootprint.py +++ b/src/faebryk/library/KicadFootprint.py @@ -2,12 +2,11 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.library.Footprint import Footprint from faebryk.libs.library import L from faebryk.libs.util import times -class KicadFootprint(Footprint): +class KicadFootprint(F.Footprint): def __init__(self, kicad_identifier: str, pin_names: list[str]) -> None: super().__init__() diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 05907fb0..5ca758bc 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,19 +15,19 @@ # flake8: noqa: I001 # flake8: noqa: E501 -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.Range import Range +from faebryk.library.has_simple_value_representation import has_simple_value_representation +from faebryk.library.has_footprint import has_footprint +from faebryk.library.has_overriden_name import has_overriden_name +from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.Constant import Constant +from faebryk.library.Range import Range +from faebryk.library.has_pcb_position import has_pcb_position from faebryk.library.Operation import Operation from faebryk.library.TBD import TBD -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_footprint import has_footprint from faebryk.library.has_datasheet import has_datasheet from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_single_electric_reference import has_single_electric_reference from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.has_simple_value_representation import has_simple_value_representation from faebryk.library.has_pcb_layout import has_pcb_layout from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.Power import Power @@ -43,23 +43,23 @@ from faebryk.library.Mechanical import Mechanical from faebryk.library.is_representable_by_single_value import is_representable_by_single_value from faebryk.library.has_kicad_ref import has_kicad_ref +from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined +from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params +from faebryk.library.Footprint import Footprint +from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined +from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param +from faebryk.library.Logic import Logic +from faebryk.library.Set import Set from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative from faebryk.library.has_pcb_position_defined import has_pcb_position_defined from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent -from faebryk.library.Logic import Logic -from faebryk.library.Set import Set from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.Footprint import Footprint from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined -from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.has_single_connection_impl import has_single_connection_impl @@ -70,13 +70,13 @@ from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined from faebryk.library.has_multi_picker import has_multi_picker from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined +from faebryk.library.has_footprint_impl import has_footprint_impl +from faebryk.library.can_attach_to_footprint import can_attach_to_footprint +from faebryk.library.has_kicad_footprint import has_kicad_footprint from faebryk.library.LogicOps import LogicOps from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic from faebryk.library.SPI import SPI from faebryk.library.DifferentialPair import DifferentialPair -from faebryk.library.has_footprint_impl import has_footprint_impl -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.has_kicad_footprint import has_kicad_footprint from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap from faebryk.library.PJ398SM import PJ398SM from faebryk.library.Common_Mode_Filter import Common_Mode_Filter @@ -87,28 +87,27 @@ from faebryk.library.Pad import Pad from faebryk.library.GDT import GDT from faebryk.library.Button import Button +from faebryk.library.has_footprint_defined import has_footprint_defined from faebryk.library.LogicGate import LogicGate from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table from faebryk.library.RS485 import RS485 from faebryk.library.Ethernet import Ethernet -from faebryk.library.has_footprint_defined import has_footprint_defined from faebryk.library.Net import Net from faebryk.library.has_equal_pins import has_equal_pins from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist +from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap +from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically from faebryk.library.LogicGates import LogicGates from faebryk.library.MOSFET import MOSFET from faebryk.library.Diode import Diode from faebryk.library.BJT import BJT -from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap -from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs from faebryk.library.KicadFootprint import KicadFootprint -from faebryk.library.TVS import TVS from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF from faebryk.library.pf_533984002 import pf_533984002 from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin @@ -117,22 +116,23 @@ from faebryk.library.Resistor import Resistor from faebryk.library.Inductor import Inductor from faebryk.library.Capacitor import Capacitor +from faebryk.library.TVS import TVS from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined from faebryk.library.DIP import DIP from faebryk.library.SMDTwoPin import SMDTwoPin from faebryk.library.QFN import QFN from faebryk.library.SOIC import SOIC from faebryk.library.Mounting_Hole import Mounting_Hole -from faebryk.library.can_be_surge_protected import can_be_surge_protected -from faebryk.library.is_surge_protected import is_surge_protected from faebryk.library.Potentiometer import Potentiometer from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider from faebryk.library.is_decoupled import is_decoupled from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.is_surge_protected_defined import is_surge_protected_defined +from faebryk.library.can_be_surge_protected import can_be_surge_protected +from faebryk.library.is_surge_protected import is_surge_protected from faebryk.library.is_decoupled_nodes import is_decoupled_nodes -from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined +from faebryk.library.is_surge_protected_defined import is_surge_protected_defined from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined +from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined from faebryk.library.ElectricPower import ElectricPower from faebryk.library.Comparator import Comparator from faebryk.library.ElectricLogic import ElectricLogic diff --git a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py index 2cbefa53..031ff73b 100644 --- a/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py +++ b/src/faebryk/library/has_pcb_routing_strategy_greedy_direct_line.py @@ -6,14 +6,6 @@ from typing import TYPE_CHECKING import faebryk.library._F as F -from faebryk.exporters.pcb.routing.util import ( - DEFAULT_TRACE_WIDTH, - Path, - Route, - get_internal_nets_of_node, - get_pads_pos_of_mifs, - group_pads_that_are_connected_already, -) from faebryk.libs.geometry.basic import Geometry if TYPE_CHECKING: @@ -33,6 +25,15 @@ def __init__(self, topology: Topology = Topology.DIRECT, priority: float = 0.0): self.topology = topology def calculate(self, transformer: "PCB_Transformer"): + from faebryk.exporters.pcb.routing.util import ( + DEFAULT_TRACE_WIDTH, + Path, + Route, + get_internal_nets_of_node, + get_pads_pos_of_mifs, + group_pads_that_are_connected_already, + ) + node = self.obj nets = get_internal_nets_of_node(node) diff --git a/src/faebryk/libs/app/designators.py b/src/faebryk/libs/app/designators.py index dc199154..02026e5e 100644 --- a/src/faebryk/libs/app/designators.py +++ b/src/faebryk/libs/app/designators.py @@ -8,18 +8,13 @@ from pathlib import Path from typing import cast +import faebryk.library._F as F from faebryk.core.graphinterface import Graph from faebryk.core.util import ( get_all_nodes_by_names, get_all_nodes_with_trait, ) from faebryk.exporters.netlist.netlist import T2Netlist -from faebryk.library.has_designator import has_designator -from faebryk.library.has_designator_defined import has_designator_defined -from faebryk.library.has_designator_prefix import has_designator_prefix -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined from faebryk.libs.kicad.fileformats import C_kicad_pcb_file from faebryk.libs.util import duplicates, get_key, groupby @@ -31,12 +26,12 @@ def attach_random_designators(graph: Graph): sorts nodes by path and then sequentially assigns designators """ - nodes = {n for n, _ in get_all_nodes_with_trait(graph, has_footprint)} + nodes = {n for n, _ in get_all_nodes_with_trait(graph, F.has_footprint)} in_use = { - n.get_trait(has_designator).get_designator() + n.get_trait(F.has_designator).get_designator() for n in nodes - if n.has_trait(has_designator) + if n.has_trait(F.has_designator) } pattern = re.compile(r"([A-Z]+)([0-9]+)") @@ -60,35 +55,35 @@ def _get_first_hole(used: list[int]): nodes_sorted = sorted(nodes, key=lambda x: x.get_full_name()) for n in nodes_sorted: - if n.has_trait(has_designator): + if n.has_trait(F.has_designator): continue - if not n.has_trait(has_designator_prefix): + if not n.has_trait(F.has_designator_prefix): prefix = type(n).__name__ logger.warning(f"Node {prefix} has no designator prefix") - prefix = n.get_trait(has_designator_prefix).get_prefix() + prefix = n.get_trait(F.has_designator_prefix).get_prefix() next_num = _get_first_hole(assigned[prefix]) designator = f"{prefix}{next_num}" - n.add_trait(has_designator_defined(designator)) + n.add_trait(F.has_designator_defined(designator)) assigned[prefix].append(next_num) - no_designator = {n for n in nodes if not n.has_trait(has_designator)} + no_designator = {n for n in nodes if not n.has_trait(F.has_designator)} assert not no_designator - dupes = duplicates(nodes, lambda n: n.get_trait(has_designator).get_designator()) + dupes = duplicates(nodes, lambda n: n.get_trait(F.has_designator).get_designator()) assert not dupes, f"Duplcicate designators: {dupes}" def override_names_with_designators(graph: Graph): - for n, t in get_all_nodes_with_trait(graph, has_designator): + for n, t in get_all_nodes_with_trait(graph, F.has_designator): name = t.get_designator() - if n.has_trait(has_overriden_name): + if n.has_trait(F.has_overriden_name): logger.warning( - f"Renaming: {n.get_trait(has_overriden_name).get_name()} -> {name}" + f"Renaming: {n.get_trait(F.has_overriden_name).get_name()} -> {name}" ) - n.add_trait(has_overriden_name_defined(name)) + n.add_trait(F.has_overriden_name_defined(name)) def attach_hierarchical_designators(graph: Graph): @@ -112,7 +107,7 @@ def load_designators_from_netlist( for _, (n, designator) in matched_nodes.items(): logger.debug(f"Matched {n} to {designator}") - n.add_trait(has_designator_defined(designator)) + n.add_trait(F.has_designator_defined(designator)) logger.info(f"Matched {len(matched_nodes)}/{len(designators)} designators") nomatch = { @@ -131,7 +126,7 @@ def replace_faebryk_names_with_designators_in_kicad_pcb(graph: Graph, pcbfile: P pattern = re.compile(r"^(.*)\[[^\]]*\]$") translation = { n.get_full_name(): t.get_name() - for n, t in get_all_nodes_with_trait(graph, has_overriden_name) + for n, t in get_all_nodes_with_trait(graph, F.has_overriden_name) } for fp in pcb.kicad_pcb.footprints: diff --git a/src/faebryk/libs/app/erc.py b/src/faebryk/libs/app/erc.py index b33bac5c..c182e9d1 100644 --- a/src/faebryk/libs/app/erc.py +++ b/src/faebryk/libs/app/erc.py @@ -5,6 +5,7 @@ import logging from typing import Callable, Iterable, Sequence +import faebryk.library._F as F from faebryk.core.graphinterface import Graph from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface @@ -12,7 +13,6 @@ get_all_nodes_of_type, get_all_nodes_of_types, ) -from faebryk.library.has_overriden_name import has_overriden_name from faebryk.libs.picker.picker import has_part_picked from faebryk.libs.util import groupby, print_stack @@ -91,7 +91,7 @@ def simple_erc(G: Graph): net_name_collisions = { k: v for k, v in groupby( - nets, lambda n: n.get_trait(has_overriden_name).get_name() + nets, lambda n: n.get_trait(F.has_overriden_name).get_name() ).items() if len(v) > 1 } diff --git a/src/faebryk/libs/app/parameters.py b/src/faebryk/libs/app/parameters.py index 66c5f5af..4af45c73 100644 --- a/src/faebryk/libs/app/parameters.py +++ b/src/faebryk/libs/app/parameters.py @@ -3,20 +3,19 @@ import logging +import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.parameter import Parameter -from faebryk.library.ANY import ANY -from faebryk.library.TBD import TBD logger = logging.getLogger(__name__) def replace_tbd_with_any(module: Module, recursive: bool, loglvl: int | None = None): """ - Replace all TBD instances with ANY instances in the given module. + Replace all F.TBD instances with F.ANY instances in the given module. - :param module: The module to replace TBD instances in. - :param recursive: If True, replace TBD instances in submodules as well. + :param module: The module to replace F.TBD instances in. + :param recursive: If True, replace F.TBD instances in submodules as well. """ from faebryk.core.util import get_all_modules @@ -27,9 +26,9 @@ def replace_tbd_with_any(module: Module, recursive: bool, loglvl: int | None = N module = module.get_most_special() for param in module.get_children(direct_only=True, types=Parameter): - if isinstance(param.get_most_narrow(), TBD): - logger.debug(f"Replacing in {module}: {param} with ANY") - param.merge(ANY()) + if isinstance(param.get_most_narrow(), F.TBD): + logger.debug(f"Replacing in {module}: {param} with F.ANY") + param.merge(F.ANY()) logger.setLevel(lvl) diff --git a/src/faebryk/libs/app/pcb.py b/src/faebryk/libs/app/pcb.py index a90e7b44..8820d265 100644 --- a/src/faebryk/libs/app/pcb.py +++ b/src/faebryk/libs/app/pcb.py @@ -7,15 +7,12 @@ from pathlib import Path from typing import Any, Callable +import faebryk.library._F as F from faebryk.core.graph import Graph from faebryk.core.module import Module from faebryk.core.util import get_node_tree, iter_tree_by_depth from faebryk.exporters.pcb.kicad.transformer import PCB_Transformer from faebryk.exporters.pcb.routing.util import apply_route_in_pcb -from faebryk.library.has_pcb_layout import has_pcb_layout -from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy from faebryk.libs.app.kicad_netlist import write_netlist from faebryk.libs.kicad.fileformats import ( C_kicad_fp_lib_table_file, @@ -27,30 +24,30 @@ def apply_layouts(app: Module): - if not app.has_trait(has_pcb_position): + if not app.has_trait(F.has_pcb_position): app.add_trait( - has_pcb_position_defined( - has_pcb_position.Point((0, 0, 0, has_pcb_position.layer_type.NONE)) + F.has_pcb_position_defined( + F.has_pcb_position.Point((0, 0, 0, F.has_pcb_position.layer_type.NONE)) ) ) tree = get_node_tree(app) for level in iter_tree_by_depth(tree): for n in level: - if n.has_trait(has_pcb_layout): - n.get_trait(has_pcb_layout).apply() + if n.has_trait(F.has_pcb_layout): + n.get_trait(F.has_pcb_layout).apply() def apply_routing(app: Module, transformer: PCB_Transformer): - strategies: list[tuple[has_pcb_routing_strategy, int]] = [] + strategies: list[tuple[F.has_pcb_routing_strategy, int]] = [] tree = get_node_tree(app) for i, level in enumerate(list(iter_tree_by_depth(tree))): for n in level: - if not n.has_trait(has_pcb_routing_strategy): + if not n.has_trait(F.has_pcb_routing_strategy): continue - strategies.append((n.get_trait(has_pcb_routing_strategy), i)) + strategies.append((n.get_trait(F.has_pcb_routing_strategy), i)) logger.info("Applying routes") diff --git a/src/faebryk/libs/brightness.py b/src/faebryk/libs/brightness.py index 6c3a016c..678e31b4 100644 --- a/src/faebryk/libs/brightness.py +++ b/src/faebryk/libs/brightness.py @@ -4,9 +4,8 @@ from copy import copy from enum import Enum +import faebryk.library._F as F from faebryk.core.parameter import Parameter -from faebryk.library.Constant import Constant -from faebryk.library.Range import Range from faebryk.libs.units import P, Quantity """ @@ -80,50 +79,50 @@ class TypicalLuminousIntensity(Enum): Well known luminous intensities in candela. """ - CANDLE = LuminousFlux(Constant(1 * P.candela)) + CANDLE = LuminousFlux(F.Constant(1 * P.candela)) - CREE_SMD_LED_EXTREMELY_DIM = LuminousFlux(Constant(10 * P.millicandela)) - CREE_SMD_LED_VERY_DIM = LuminousFlux(Constant(25 * P.millicandela)) - CREE_SMD_LED_DIM = LuminousFlux(Constant(50 * P.millicandela)) - CREE_SMD_LED_NORMAL = LuminousFlux(Constant(100 * P.millicandela)) - CREE_SMD_LED_BRIGHT = LuminousFlux(Constant(250 * P.millicandela)) - CREE_SMD_LED_VERY_BRIGHT = LuminousFlux(Constant(2 * P.candela)) - CREE_SMD_LED_EXTREMELY_BRIGHT = LuminousFlux(Constant(14 * P.candela)) + CREE_SMD_LED_EXTREMELY_DIM = LuminousFlux(F.Constant(10 * P.millicandela)) + CREE_SMD_LED_VERY_DIM = LuminousFlux(F.Constant(25 * P.millicandela)) + CREE_SMD_LED_DIM = LuminousFlux(F.Constant(50 * P.millicandela)) + CREE_SMD_LED_NORMAL = LuminousFlux(F.Constant(100 * P.millicandela)) + CREE_SMD_LED_BRIGHT = LuminousFlux(F.Constant(250 * P.millicandela)) + CREE_SMD_LED_VERY_BRIGHT = LuminousFlux(F.Constant(2 * P.candela)) + CREE_SMD_LED_EXTREMELY_BRIGHT = LuminousFlux(F.Constant(14 * P.candela)) TYPICAL_SMD_LED_MAX_BRIGHTNESS = LuminousFlux( - Range(60 * P.millicandela, 800 * P.mcandela) + F.Range(60 * P.millicandela, 800 * P.mcandela) ) - WS2812B_LED_RED = LuminousFlux(Constant(420 * P.millicandela)) - WS2812B_LED_GREEN = LuminousFlux(Constant(720 * P.millicandela)) - WS2812B_LED_BLUE = LuminousFlux(Constant(200 * P.millicandela)) + WS2812B_LED_RED = LuminousFlux(F.Constant(420 * P.millicandela)) + WS2812B_LED_GREEN = LuminousFlux(F.Constant(720 * P.millicandela)) + WS2812B_LED_BLUE = LuminousFlux(F.Constant(200 * P.millicandela)) APPLICATION_CAR_HEADLIGHTS_HALOGEN_LOW_BEAM_MEDIUM = LuminousFlux( - Constant(20 * P.kcandela) + F.Constant(20 * P.kcandela) ) APPLICATION_CAR_HEADLIGHTS_HALOGEN_HIGH_BEAM_MEDIUM = LuminousFlux( - Constant(40 * P.kcandela) + F.Constant(40 * P.kcandela) ) - APPLICATION_CAR_TURN_INDICATOR_DIM = LuminousFlux(Constant(1 * P.kcandela)) - APPLICATION_CAR_TURN_INDICATOR_BRIGHT = LuminousFlux(Constant(10 * P.kcandela)) - APPLICATION_CAR_BREAK_LIGHT_DIM = LuminousFlux(Constant(5 * P.kcandela)) - APPLICATION_CAR_BREAK_LIGHT_BRIGHT = LuminousFlux(Constant(50 * P.kcandela)) + APPLICATION_CAR_TURN_INDICATOR_DIM = LuminousFlux(F.Constant(1 * P.kcandela)) + APPLICATION_CAR_TURN_INDICATOR_BRIGHT = LuminousFlux(F.Constant(10 * P.kcandela)) + APPLICATION_CAR_BREAK_LIGHT_DIM = LuminousFlux(F.Constant(5 * P.kcandela)) + APPLICATION_CAR_BREAK_LIGHT_BRIGHT = LuminousFlux(F.Constant(50 * P.kcandela)) # not sure about these values - APPLICATION_LED_STANDBY = LuminousFlux(Range(1 * P.millicandela, 10 * P.mcandela)) + APPLICATION_LED_STANDBY = LuminousFlux(F.Range(1 * P.millicandela, 10 * P.mcandela)) APPLICATION_LED_INDICATOR_INSIDE = LuminousFlux( - Range(10 * P.millicandela, 100 * P.mcandela) + F.Range(10 * P.millicandela, 100 * P.mcandela) ) APPLICATION_LED_KEYBOARD_BACKLIGHT = LuminousFlux( - Range(50 * P.millicandela, 500 * P.mcandela) + F.Range(50 * P.millicandela, 500 * P.mcandela) ) APPLICATION_LED_INDICATOR_OUTSIDE = LuminousFlux( - Range(100 * P.millicandela, 1 * P.candela) + F.Range(100 * P.millicandela, 1 * P.candela) ) APPLICATION_LED_DECORATIVE_LIGHTING = LuminousFlux( - Range(100 * P.millicandela, 1 * P.candela) + F.Range(100 * P.millicandela, 1 * P.candela) ) - APPLICATION_LED_FLASHLIGHT = LuminousFlux(Range(10 * P.candela, 1 * P.kcandela)) + APPLICATION_LED_FLASHLIGHT = LuminousFlux(F.Range(10 * P.candela, 1 * P.kcandela)) class TypicalLuminousFlux(Enum): @@ -131,21 +130,21 @@ class TypicalLuminousFlux(Enum): Well known luminous flux in lumen. """ - IKEA_E14_BULB_LED_DIM = LuminousFlux(Constant(100 * P.lm)) - IKEA_E14_BULB_LED_MEDIUM = LuminousFlux(Constant(250 * P.lm)) - IKEA_E14_BULB_LED_BRIGHT = LuminousFlux(Constant(470 * P.lm)) - IKEA_GU10_BULB_LED_DIM = LuminousFlux(Constant(230 * P.lm)) - IKEA_GU10_BULB_LED_MEDIUM = LuminousFlux(Constant(345 * P.lm)) - IKEA_E27_BULB_LED_DIM = LuminousFlux(Constant(470 * P.lm)) - IKEA_E27_BULB_LED_MEDIUM = LuminousFlux(Constant(806 * P.lm)) - IKEA_E27_BULB_LED_BRIGHT = LuminousFlux(Constant(1500 * P.lm)) + IKEA_E14_BULB_LED_DIM = LuminousFlux(F.Constant(100 * P.lm)) + IKEA_E14_BULB_LED_MEDIUM = LuminousFlux(F.Constant(250 * P.lm)) + IKEA_E14_BULB_LED_BRIGHT = LuminousFlux(F.Constant(470 * P.lm)) + IKEA_GU10_BULB_LED_DIM = LuminousFlux(F.Constant(230 * P.lm)) + IKEA_GU10_BULB_LED_MEDIUM = LuminousFlux(F.Constant(345 * P.lm)) + IKEA_E27_BULB_LED_DIM = LuminousFlux(F.Constant(470 * P.lm)) + IKEA_E27_BULB_LED_MEDIUM = LuminousFlux(F.Constant(806 * P.lm)) + IKEA_E27_BULB_LED_BRIGHT = LuminousFlux(F.Constant(1500 * P.lm)) - CREE_SMD_LED_VERY_BRIGHT = LuminousFlux(Constant(6000 * P.lm)) + CREE_SMD_LED_VERY_BRIGHT = LuminousFlux(F.Constant(6000 * P.lm)) - LASER_POINTER_GREEN_5MW = LuminousFlux(Constant(3.4 * P.lm)) + LASER_POINTER_GREEN_5MW = LuminousFlux(F.Constant(3.4 * P.lm)) - CAR_HEADLIGHTS_HALOGEN_LOW_BEAM_MEDIUM = LuminousFlux(Constant(1000 * P.lm)) - CAR_HEADLIGHTS_HALOGEN_HIGH_BEAM_MEDIUM = LuminousFlux(Constant(1300 * P.lm)) + CAR_HEADLIGHTS_HALOGEN_LOW_BEAM_MEDIUM = LuminousFlux(F.Constant(1000 * P.lm)) + CAR_HEADLIGHTS_HALOGEN_HIGH_BEAM_MEDIUM = LuminousFlux(F.Constant(1300 * P.lm)) class TypicalIlluminance(Enum): @@ -154,17 +153,17 @@ class TypicalIlluminance(Enum): """ # https://en.wikipedia.org/wiki/Lux - MOONLESS_OVERCAST_NIGHT_SKY_STARLIGHT = Illuminance(Constant(0.0001 * P.lx)) - MOONLESS_CLEAR_NIGHT_SKY_WITH_AIRGLOW = Illuminance(Constant(0.002 * P.lx)) - FULL_MOON_ON_A_CLEAR_NIGHT = Illuminance(Constant(0.05 * P.lx)) - DARK_LIMIT_OF_CIVIL_TWILIGHT_UNDER_A_CLEAR_SKY = Illuminance(Constant(3.4 * P.lx)) - PUBLIC_AREAS_WITH_DARK_SURROUNDINGS = Illuminance(Constant(20 * P.lx)) - FAMILY_LIVING_ROOM_LIGHTS = Illuminance(Constant(50 * P.lx)) - OFFICE_BUILDING_HALLWAY_TOILET_LIGHTING = Illuminance(Constant(80 * P.lx)) - VERY_DARK_OVERCAST_DAY = Illuminance(Constant(100 * P.lx)) - TRAIN_STATION_PLATFORMS = Illuminance(Constant(150 * P.lx)) - OFFICE_LIGHTING = Illuminance(Constant(320 * P.lx)) - SUNRISE_OR_SUNSET_ON_A_CLEAR_DAY = Illuminance(Constant(400 * P.lx)) - OVERCAST_DAY = Illuminance(Constant(1000 * P.lx)) - FULL_DAYLIGHT = Illuminance(Constant(25000 * P.lx)) - DIRECT_SUNLIGHT = Illuminance(Constant(100000 * P.lx)) + MOONLESS_OVERCAST_NIGHT_SKY_STARLIGHT = Illuminance(F.Constant(0.0001 * P.lx)) + MOONLESS_CLEAR_NIGHT_SKY_WITH_AIRGLOW = Illuminance(F.Constant(0.002 * P.lx)) + FULL_MOON_ON_A_CLEAR_NIGHT = Illuminance(F.Constant(0.05 * P.lx)) + DARK_LIMIT_OF_CIVIL_TWILIGHT_UNDER_A_CLEAR_SKY = Illuminance(F.Constant(3.4 * P.lx)) + PUBLIC_AREAS_WITH_DARK_SURROUNDINGS = Illuminance(F.Constant(20 * P.lx)) + FAMILY_LIVING_ROOM_LIGHTS = Illuminance(F.Constant(50 * P.lx)) + OFFICE_BUILDING_HALLWAY_TOILET_LIGHTING = Illuminance(F.Constant(80 * P.lx)) + VERY_DARK_OVERCAST_DAY = Illuminance(F.Constant(100 * P.lx)) + TRAIN_STATION_PLATFORMS = Illuminance(F.Constant(150 * P.lx)) + OFFICE_LIGHTING = Illuminance(F.Constant(320 * P.lx)) + SUNRISE_OR_SUNSET_ON_A_CLEAR_DAY = Illuminance(F.Constant(400 * P.lx)) + OVERCAST_DAY = Illuminance(F.Constant(1000 * P.lx)) + FULL_DAYLIGHT = Illuminance(F.Constant(25000 * P.lx)) + DIRECT_SUNLIGHT = Illuminance(F.Constant(100000 * P.lx)) diff --git a/src/faebryk/libs/examples/pickers.py b/src/faebryk/libs/examples/pickers.py index 50f3e1a9..f30b10d1 100644 --- a/src/faebryk/libs/examples/pickers.py +++ b/src/faebryk/libs/examples/pickers.py @@ -6,17 +6,20 @@ """ import logging +from typing import TYPE_CHECKING import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.util import specialize_module from faebryk.library._F import Constant, Range -from faebryk.library.Switch import _TSwitch from faebryk.libs.app.parameters import replace_tbd_with_any from faebryk.libs.picker.lcsc import LCSC_Part from faebryk.libs.picker.picker import PickerOption, pick_module_by_params from faebryk.libs.units import P +if TYPE_CHECKING: + from faebryk.library.Switch import _TSwitch + logger = logging.getLogger(__name__) @@ -264,7 +267,7 @@ def pick_battery(module: F.Battery): ) -def pick_switch(module: _TSwitch[F.Electrical]): +def pick_switch(module: "_TSwitch[F.Electrical]"): module.add_trait(F.can_attach_to_footprint_symmetrically()) pick_module_by_params( module, diff --git a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py index 34a489f8..6120d2e6 100644 --- a/src/faebryk/libs/picker/jlcpcb/jlcpcb.py +++ b/src/faebryk/libs/picker/jlcpcb/jlcpcb.py @@ -24,7 +24,6 @@ from faebryk.core.module import Module from faebryk.core.parameter import Parameter from faebryk.core.util import pretty_param_tree, pretty_params -from faebryk.library.Set import Set from faebryk.libs.e_series import ( E_SERIES_VALUES, ParamNotResolvedError, @@ -418,7 +417,7 @@ def filter_by_value( assert not self.results value_query = Q() try: - intersection = Set( + intersection = F.Set( [e_series_intersect(value, e_series or E_SERIES_VALUES.E_ALL)] ).params except ParamNotResolvedError as e: diff --git a/src/faebryk/libs/picker/lcsc.py b/src/faebryk/libs/picker/lcsc.py index a6b5afbd..9e29e921 100644 --- a/src/faebryk/libs/picker/lcsc.py +++ b/src/faebryk/libs/picker/lcsc.py @@ -14,17 +14,8 @@ from easyeda2kicad.kicad.export_kicad_3d_model import Exporter3dModelKicad from easyeda2kicad.kicad.export_kicad_footprint import ExporterFootprintKicad +import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.can_attach_to_footprint_via_pinmap import ( - can_attach_to_footprint_via_pinmap, -) -from faebryk.library.has_descriptive_properties_defined import ( - has_descriptive_properties_defined, -) -from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic -from faebryk.library.KicadFootprint import KicadFootprint from faebryk.libs.picker.picker import ( Part, PickerOption, @@ -180,13 +171,13 @@ def attach(component: Module, partno: str, get_model: bool = True): ) # symbol - if not component.has_trait(has_footprint): - if not component.has_trait(can_attach_to_footprint): - if not component.has_trait(has_pin_association_heuristic): + if not component.has_trait(F.has_footprint): + if not component.has_trait(F.can_attach_to_footprint): + if not component.has_trait(F.has_pin_association_heuristic): raise LCSCException( partno, - f"Need either can_attach_to_footprint or " - "has_pin_association_heuristic" + f"Need either F.can_attach_to_footprint or " + "F.has_pin_association_heuristic" f" for {component} with partno {partno}", ) @@ -196,21 +187,21 @@ def attach(component: Module, partno: str, get_model: bool = True): for pin in easyeda_symbol.pins ] try: - pinmap = component.get_trait(has_pin_association_heuristic).get_pins( + pinmap = component.get_trait(F.has_pin_association_heuristic).get_pins( pins ) - except has_pin_association_heuristic.PinMatchException as e: + except F.has_pin_association_heuristic.PinMatchException as e: raise LCSC_PinmapException(partno, f"Failed to get pinmap: {e}") from e - component.add_trait(can_attach_to_footprint_via_pinmap(pinmap)) + component.add_trait(F.can_attach_to_footprint_via_pinmap(pinmap)) # footprint - fp = KicadFootprint( + fp = F.KicadFootprint( f"lcsc:{easyeda_footprint.info.name}", [p.number for p in easyeda_footprint.pads], ) - component.get_trait(can_attach_to_footprint).attach(fp) + component.get_trait(F.can_attach_to_footprint).attach(fp) - has_descriptive_properties_defined.add_properties_to(component, {"LCSC": partno}) + F.has_descriptive_properties_defined.add_properties_to(component, {"LCSC": partno}) # model done by kicad (in fp) @@ -220,7 +211,7 @@ def attach(self, module: Module, part: PickerOption): assert isinstance(part.part, LCSC_Part) attach(component=module, partno=part.part.partno) if part.info is not None: - has_descriptive_properties_defined.add_properties_to(module, part.info) + F.has_descriptive_properties_defined.add_properties_to(module, part.info) class LCSC_Part(Part): diff --git a/src/faebryk/tools/main.py b/src/faebryk/tools/main.py index 4e70677a..d824741b 100644 --- a/src/faebryk/tools/main.py +++ b/src/faebryk/tools/main.py @@ -1,6 +1,7 @@ from faebryk.libs.tools.typer import typer_callback from faebryk.tools.libadd import main as libadd_main from faebryk.tools.project import main as project_main +from faebryk.tools.refactor import main as refactor_main @typer_callback(None) @@ -12,6 +13,7 @@ def main(): def __main__(): main.add_typer(libadd_main, name="libadd") main.add_typer(project_main, name="project") + main.add_typer(refactor_main, name="refactor") main() diff --git a/src/faebryk/tools/refactor.py b/src/faebryk/tools/refactor.py new file mode 100644 index 00000000..aa4e7eb2 --- /dev/null +++ b/src/faebryk/tools/refactor.py @@ -0,0 +1,90 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT + +import re +import subprocess +from dataclasses import dataclass +from pathlib import Path + +import typer + +from faebryk.libs.tools.typer import typer_callback + + +@dataclass +class CTX: ... + + +def get_ctx(ctx: typer.Context) -> "CTX": + return ctx.obj + + +@typer_callback(None) +def main(ctx: typer.Context): + """ + Can be called like this: > faebryk refactor + """ + pass + + +@main.command() +def libtof(ctx: typer.Context, root: Path): + file_paths = list(root.rglob("**/*.py")) + print(f"Found {len(file_paths)} files in path.") + + detection_pattern = re.compile(r"^from faebryk.library.[^_]") + + refactor_files = [ + path + for path in file_paths + if not path.stem.startswith("_") + and any(detection_pattern.match(line) for line in path.read_text().splitlines()) + ] + + print(f"Found {len(refactor_files)} files to refactor.") + + # TO match: + # from faebryk.library.has_kicad_footprint import has_kicad_footprint + # from faebryk.library.has_simple_value_representation import ( + # has_simple_value_representation, + # ) + + pyname = r"[_a-zA-Z][_a-zA-Z0-9]*" + import_pattern = re.compile( + r"^from faebryk.library.([^_][^ ]*) import (" + f"{pyname}$" + "|" + f"\\([\n ]*{pyname},[\n ]*\\)$" # multiline import + r")", + re.MULTILINE, + ) + + def refactor_file(path: Path): + text = path.read_text() + import_symbols = [m[0] for m in import_pattern.findall(text)] + text = import_pattern.subn("import faebryk.library._F as F", text, count=1)[0] + text = import_pattern.sub("", text) + + for sym in import_symbols: + if re.search(rf"from faebryk.library.{sym} import {sym} as", text): + print(f"Warning: skipping {sym} in {path}") + continue + + text = re.sub(rf"^\s*from faebryk.library.{sym} import {sym}$", "", text) + text = re.sub( + rf"^\s*from faebryk.library.{sym} import \(\n\s*{sym},\n\)$", "", text + ) + text = re.sub(rf"([^F][^.])\b{sym}\b", f"\1F.{sym}", text) + + # print(path, import_symbols) + path.write_text(text) + + for path in refactor_files: + refactor_file(path) + + # Run ruff + subprocess.check_call(["ruff", "check", "--fix", root]) + + +if __name__ == "__main__": + main() From ba5b5daf4d051a88afd129fe5917b194cf1dd339 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 13:33:41 +0200 Subject: [PATCH 48/63] fix lookahead refactor --- src/faebryk/tools/refactor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/faebryk/tools/refactor.py b/src/faebryk/tools/refactor.py index aa4e7eb2..80e005b0 100644 --- a/src/faebryk/tools/refactor.py +++ b/src/faebryk/tools/refactor.py @@ -74,7 +74,7 @@ def refactor_file(path: Path): text = re.sub( rf"^\s*from faebryk.library.{sym} import \(\n\s*{sym},\n\)$", "", text ) - text = re.sub(rf"([^F][^.])\b{sym}\b", f"\1F.{sym}", text) + text = re.sub(rf"(? Date: Thu, 29 Aug 2024 14:48:01 +0200 Subject: [PATCH 49/63] Add library instance test --- src/faebryk/core/core.py | 6 + src/faebryk/core/node.py | 6 +- src/faebryk/core/util.py | 2 +- src/faebryk/library/BH1750FVI_TR.py | 15 +- src/faebryk/library/Crystal_Oscillator.py | 14 +- src/faebryk/library/ESP32.py | 412 ------------------ .../ESP32_C3_MINI_1_Reference_Design.py | 2 +- src/faebryk/library/ElectricLogicGates.py | 3 +- src/faebryk/library/HLK_LD2410B_P.py | 11 +- src/faebryk/library/I2C.py | 3 + src/faebryk/library/LogicGates.py | 3 +- src/faebryk/library/LogicOps.py | 3 +- src/faebryk/library/PM1006.py | 14 +- src/faebryk/library/Powered_Relay.py | 2 +- .../library/RP2040_Reference_Design.py | 2 + src/faebryk/library/SCD40.py | 12 +- src/faebryk/library/SPIFlash.py | 2 +- src/faebryk/library/Switch.py | 4 +- src/faebryk/library/USB2_0.py | 3 +- src/faebryk/library/USB2_0_IF.py | 7 + src/faebryk/library/USB3.py | 7 + src/faebryk/library/USB3_IF.py | 7 + src/faebryk/library/XL_3528RGBW_WS2812B.py | 9 +- src/faebryk/library/_F.py | 5 +- test/library/test_basic.py | 48 ++ 25 files changed, 124 insertions(+), 478 deletions(-) delete mode 100644 src/faebryk/library/ESP32.py create mode 100644 test/library/test_basic.py diff --git a/src/faebryk/core/core.py b/src/faebryk/core/core.py index 0afb85fe..4249d283 100644 --- a/src/faebryk/core/core.py +++ b/src/faebryk/core/core.py @@ -24,3 +24,9 @@ def __init__(self) -> None: ... def builder(self, op: Callable[[Self], Any]) -> Self: op(self) return self + + +class Namespace: + """Marker class for namespace objects.""" + + pass diff --git a/src/faebryk/core/node.py b/src/faebryk/core/node.py index bcb87660..7d35c825 100644 --- a/src/faebryk/core/node.py +++ b/src/faebryk/core/node.py @@ -338,7 +338,11 @@ def _setup(self) -> None: # print(f"Called Node init {cls.__qualname__:<20} {'-' * 80}") # check if accidentally added a node instance instead of field - node_instances = [f for f in vars(cls).values() if isinstance(f, Node)] + node_instances = [ + (name, f) + for name, f in vars(cls).items() + if isinstance(f, Node) and not name.startswith("_") + ] if node_instances: raise FieldError(f"Node instances not allowed: {node_instances}") diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 03691a67..114f1317 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -367,7 +367,7 @@ def connect_module_mifs_by_name( ).items(): if src_m is None or dst_m is None: if not allow_partial: - raise Exception(f"Node with name {k} mot present in both") + raise Exception(f"Node with name {k} not present in both") continue src_m.connect(dst_m) diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 05750080..87d7685c 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -2,11 +2,9 @@ # SPDX-License-Identifier: MIT import logging -from dataclasses import dataclass, field import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.parameter import Parameter from faebryk.libs.library import L from faebryk.libs.units import P @@ -14,17 +12,12 @@ class BH1750FVI_TR(Module): - @dataclass class _bh1750_esphome_config(F.has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=F.TBD) - - def __post_init__(self) -> None: - super().__init__() + update_interval_s: F.TBD def get_config(self) -> dict: - assert isinstance( - self.update_interval_s, F.Constant - ), "No update interval set!" + val = self.update_interval_s.get_most_narrow() + assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj assert isinstance(obj, BH1750FVI_TR) @@ -38,7 +31,7 @@ def get_config(self) -> dict: "name": "BH1750 Illuminance", "address": "0x23", "i2c_id": i2c.get_trait(F.is_esphome_bus).get_bus_id(), - "update_interval": f"{self.update_interval_s.value}s", + "update_interval": f"{val.value}s", } ] } diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index bf5b3023..00af31f8 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -7,7 +7,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L -from faebryk.libs.units import P +from faebryk.libs.units import P, Quantity class Crystal_Oscillator(Module): @@ -21,26 +21,24 @@ class Crystal_Oscillator(Module): p: F.Electrical n: F.Electrical + load_capacitance: F.TBD[Quantity] + # ---------------------------------------- # parameters # ---------------------------------------- # https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ _STRAY_CAPACITANCE = F.Range(1 * P.nF, 5 * P.nF) - @L.rt_field - def load_capacitance(self): - return self.crystal.load_impedance - @L.rt_field def capacitance(self): - return F.Constant(2 * P.dimesionless) * ( - self.load_capacitance - copy(self._STRAY_CAPACITANCE) - ) + return (self.load_capacitance - copy(self._STRAY_CAPACITANCE)) * 2 def __preinit__(self): for cap in self.capacitors: cap.capacitance.merge(self.capacitance) + self.load_capacitance.merge(self.crystal.load_impedance) + # ---------------------------------------- # traits # ---------------------------------------- diff --git a/src/faebryk/library/ESP32.py b/src/faebryk/library/ESP32.py deleted file mode 100644 index a9f5c7a2..00000000 --- a/src/faebryk/library/ESP32.py +++ /dev/null @@ -1,412 +0,0 @@ -# This file is part of the faebryk project -# SPDX-License-Identifier: MIT - -import logging -import typing -from dataclasses import dataclass - -import faebryk.library._F as F -from faebryk.core.module import Module -from faebryk.core.moduleinterface import ModuleInterface -from faebryk.libs.library import L -from faebryk.libs.units import P -from faebryk.libs.util import times - -logger = logging.getLogger(__name__) - - -# TODO -class _ESP_ADC(ModuleInterface): - def __init__(self, channel_count: int) -> None: - super().__init__() - self.channel_count = channel_count - - @L.rt_field - def CHANNELS(self): - return times(self.channel_count, F.Electrical) - - -class _ESP_SDIO(ModuleInterface): - DATA = L.list_field(4, F.Electrical) - CLK: F.Electrical - CMD: F.Electrical - GND: F.Electrical - - -class _ESP32_EMAC(ModuleInterface): - TXD = L.list_field(4, F.Electrical) - RXD = L.list_field(4, F.Electrical) - TX_CLK: F.Electrical - RX_CLK: F.Electrical - TX_EN: F.Electrical - RX_ER: F.Electrical - RX_DV: F.Electrical - CLK_OUT: F.Electrical - CLK_OUT_180: F.Electrical - TX_ER: F.Electrical - MDC_out: F.Electrical - MDI_in: F.Electrical - MDO_out: F.Electrical - CRS_out: F.Electrical - COL_out: F.Electrical - - -class _ESP32_SPI(ModuleInterface): - D: F.Electrical - Q: F.Electrical - WP: F.Electrical - HD: F.Electrical - CS: F.Electrical - CLK: F.Electrical - GND: F.Electrical - - -class ESP32(Module): - simple_value_representation = L.f_field(F.has_simple_value_representation_defined)( - "ESP32" - ) - designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") - - # Analog - VDDA0: F.Electrical - LNA_IN: F.Electrical - VDD3P30: F.Electrical - VDD3P31: F.Electrical - SENSOR_VP: F.Electrical - # VDD3P3_RTC - SENSOR_CAPP: F.Electrical - SENSOR_CAPN: F.Electrical - SENSOR_VN: F.Electrical - CHIP_PU: F.Electrical - VDET_1: F.Electrical - VDET_2: F.Electrical - _32K_XP: F.Electrical - _32K_XN: F.Electrical - GPIO25: F.Electrical - GPIO26: F.Electrical - GPIO27: F.Electrical - MTMS: F.Electrical - MTDI: F.Electrical - VDD3P3_RTC: F.Electrical - MTCK: F.Electrical - MTDO: F.Electrical - GPIO2: F.Electrical - GPIO0: F.Electrical - GPIO4: F.Electrical - # VDD_SDIO - GPIO16: F.Electrical - VDD_SDIO: F.Electrical - GPIO17: F.Electrical - SD_DATA_2: F.Electrical - SD_DATA_3: F.Electrical - SD_CMD: F.Electrical - SD_CLK: F.Electrical - SD_DATA_0: F.Electrical - SD_DATA_1: F.Electrical - # VDD3P3_CPU - GPIO5: F.Electrical - GPIO18: F.Electrical - GPIO23: F.Electrical - VDD3P3_CPU: F.Electrical - GPIO19: F.Electrical - GPIO22: F.Electrical - U0RXD: F.Electrical - U0TXD: F.Electrical - GPIO21: F.Electrical - # Analog - VDDA1: F.Electrical - XTAL_N: F.Electrical - XTAL_P: F.Electrical - VDDA2: F.Electrical - CAP2: F.Electrical - CAP1: F.Electrical - GND: F.Electrical - - # High Level Functions - F.I2C = L.list_field(2, F.I2C) - SDIO_SLAVE: _ESP_SDIO - SDIO_HOST = L.list_field(2, _ESP_SDIO) - UART: F.UART_Base - JTAG: F.JTAG - TOUCH = L.list_field(10, F.Electrical) - GPIO = L.list_field(40 - 6, F.Electrical) - RTC_GPIO = L.list_field(18, F.Electrical) - ADC = L.d_field( - lambda: ( - None, - _ESP_ADC(channel_count=8), - _ESP_ADC(channel_count=10), - ) - ) - SPI = L.list_field(4, _ESP32_SPI) - EMAC: _ESP32_EMAC - - # Power - POWER_RTC: F.ElectricPower - POWER_CPU: F.ElectricPower - POWER_SDIO: F.ElectricPower - POWER_ANALOG: F.ElectricPower - - @L.rt_field - def attach_to_footprint(self): - x = self - self.pinmap = { - # Analog - "1": x.VDDA0, - "2": x.LNA_IN, - "3": x.VDD3P30, - "4": x.SENSOR_VP, - # VDD"3"P3_RTC - "5": x.SENSOR_CAPP, - "6": x.SENSOR_CAPN, - "7": x.SENSOR_VN, - "8": x.CHIP_PU, - "9": x.VDET_1, - "10": x.VDET_2, - "11": x._32K_XP, - "12": x._32K_XN, - "13": x.GPIO25, - "14": x.GPIO26, - "15": x.GPIO27, - "16": x.MTMS, - "17": x.MTDI, - "18": x.VDD3P3_RTC, - "19": x.MTCK, - "20": x.MTDO, - "21": x.GPIO2, - "22": x.GPIO0, - "23": x.GPIO4, - # VDD_SDIO - "24": x.GPIO16, - "25": x.VDD_SDIO, - "26": x.GPIO17, - "27": x.SD_DATA_2, - "28": x.SD_DATA_3, - "29": x.SD_CMD, - "30": x.SD_CLK, - "31": x.SD_DATA_0, - "32": x.SD_DATA_1, - # VDD"3"P3_CPU - "33": x.GPIO5, - "34": x.GPIO18, - "35": x.GPIO23, - "36": x.VDD3P3_CPU, - "37": x.GPIO19, - "38": x.GPIO22, - "39": x.U0RXD, - "40": x.U0TXD, - "41": x.GPIO21, - # Analog - "42": x.VDDA1, - "43": x.XTAL_N, - "44": x.XTAL_P, - "45": x.VDDA2, - "46": x.CAP2, - "47": x.CAP1, - "48": x.GND, - } - - return F.can_attach_to_footprint_via_pinmap(self.pinmap) - - def __preinit__(self): - x = self - - # SPI0 is connected to SPI1 (Arbiter) - x.SPI[0].Q.connect(x.SPI[1].Q) - x.SPI[0].D.connect(x.SPI[1].D) - x.SPI[0].HD.connect(x.SPI[1].HD) - x.SPI[0].WP.connect(x.SPI[1].WP) - x.SPI[0].CLK.connect(x.SPI[1].CLK) - x.SPI[0].CS.connect(x.SPI[1].CS) - - x.POWER_RTC.hv.connect(x.VDD3P3_RTC) - x.POWER_RTC.lv.connect(x.GND) - x.POWER_CPU.hv.connect(x.VDD3P3_CPU) - x.POWER_CPU.lv.connect(x.GND) - x.POWER_SDIO.hv.connect(x.VDD_SDIO) - x.POWER_SDIO.lv.connect(x.GND) - x.POWER_ANALOG.hv.connect(x.VDDA0) - x.POWER_ANALOG.hv.connect(x.VDDA1) - x.POWER_ANALOG.hv.connect(x.VDDA2) - x.POWER_ANALOG.lv.connect(x.GND) - - self.pinmux = _ESP32_Pinmux(self) - - def get_gpio(self, idx: int): - filtered = [20, 24, 28, 29, 30, 31] - # count of elements in filtered that are smaller than idx: - offset = len([x for x in filtered if x < idx]) - return self.GPIO[idx - offset] - - -class _ESP32_D0WD(ESP32): - footprint = L.f_field(F.has_footprint_defined)( - F.QFN( - pin_cnt=48, - size_xy=(5 * P.mm, 5 * P.mm), - pitch=0.350 * P.mm, - exposed_thermal_pad_cnt=1, - exposed_thermal_pad_dimensions=(3.700 * P.mm, 3.700 * P.mm), - has_thermal_vias=True, - ) - ) - - -class _ESP32_D0WD_V3(_ESP32_D0WD): - # Dual core - No embedded flash/PSRAM - ... - - -class _ESP32_D0WDR2_V3(_ESP32_D0WD): - # Dual core - 2 MB PSRAM - ... - - -@dataclass(frozen=True) -class _Function: - interface: F.Electrical - name: str - type: "typing.Any" - - -@dataclass(frozen=False) -class _Pad: - no: int - name: str - interface: ModuleInterface - power_domain: "typing.Any" - # - at_reset: "typing.Any" - after_reset: "typing.Any" - drive_strenght: "typing.Any" - # - functions: dict[int, _Function] - # - current_function: _Function | None = None - - -class _Mux(Module): - IN: F.Electrical - - @L.rt_field - def OUT(self): - return times(len(self.outputs), F.Electrical) - - def __init__(self, input: F.Electrical, *outputs: F.Electrical) -> None: - super().__init__() - self.input = input - self.outputs = outputs - - def __preinit__(self): - self.input.connect(self.IN) - self.map = dict(zip(self.outputs, self.OUT)) - for o1, o2 in self.map.items(): - o1.connect(o2) - - def select(self, output: F.Electrical): - self.IN.connect(self.map[output]) - - -def _matrix(esp32: ESP32): - x = esp32 - - # fmt: off - return [ - # Power - _Pad(1, "VDDA", x.VDDA0, "VDDA supply in", None, None, None, {}), # noqa: E501 - _Pad(43, "VDDA", x.VDDA1, "VDDA supply in", None, None, None, {}), # noqa: E501 - _Pad(46, "VDDA", x.VDDA2, "VDDA supply in", None, None, None, {}), # noqa: E501 - _Pad(2, "LNA_IN", x.LNA_IN, "VDD3P3", None, None, None, {}), # noqa: E501 - _Pad(3, "VDD3P3", x.VDD3P30, "VDD3P3 supply in", None, None, None, {}), # noqa: E501 - _Pad(4, "VDD3P3", x.VDD3P31, "VDD3P3 supply in", None, None, None, {}), # noqa: E501 - _Pad(19, "VDD3P3_RTC", x.VDD3P3_RTC, "VDD3P3_RTC supply in", None, None, None, {}), # noqa: E501 - _Pad(26, "VDD_SDIO", x.VDD_SDIO, "VDD_SDIO supply out/in", None, None, None, {}), # noqa: E501 - _Pad(37, "VDD3P3_CPU", x.VDD3P3_CPU, "VDD3P3_CPU supply in", None, None, None, {}), # noqa: E501 - _Pad(5, "SENSOR_VP", x.SENSOR_VP, "VDD3P3_RTC", "oe=0,ie=0", "oe=0,ie=0", None, { # noqa: E501 - 1 : _Function(x.ADC[1].CHANNELS[0], "ADC1_CH0", None), # noqa: E501 - 3 : _Function(x.RTC_GPIO[0], "RTC_GPIO0", None), # noqa: E501 - 5 : _Function(esp32.get_gpio(36), "GPIO36", "I"), # noqa: E501 - }), # noqa: E501 - _Pad(6, "SENSOR_CAPP", x.SENSOR_CAPP, "VDD3P3_RTC", "oe=0,ie=0", "oe=0,ie=0", None, { # noqa: E501 - 1 : _Function(x.ADC[1].CHANNELS[1], "ADC1_CH1", None), # noqa: E501 - 3 : _Function(x.RTC_GPIO[1], "RTC_GPIO1", None), # noqa: E501 - 5 : _Function(esp32.get_gpio(37), "GPIO37", "I"), # noqa: E501 - }), # noqa: E501 - _Pad(7, "SENSOR_CAPN", x.SENSOR_CAPN, "VDD3P3_RTC", "oe=0,ie=0", "oe=0,ie=0", None, { # noqa: E501 - 1 : _Function(x.ADC[1].CHANNELS[2], "ADC1_CH2", None), # noqa: E501 - 3 : _Function(x.RTC_GPIO[2], "RTC_GPIO2", None), # noqa: E501 - 5 : _Function(esp32.get_gpio(38), "GPIO38", "I"), # noqa: E501 - }), # noqa: E501 - _Pad(18, "MTDI", x.MTDI, "VDD3P3_RTC", "oe=0,ie=1,wpd", "oe=0,ie=1,wpd", "2'd2", { # noqa: E501 - 1 : _Function(x.ADC[2].CHANNELS[5], "ADC2_CH5", None), # noqa: E501 - 2 : _Function(x.TOUCH[5], "TOUCH5", None), # noqa: E501 - 3 : _Function(x.RTC_GPIO[15], "RTC_GPIO15", None), # noqa: E501 - 5 : _Function(x.JTAG.tdi.signal, "MTDI", "I1"), # noqa: E501 - 6 : _Function(x.SPI[2].Q, "HSPIQ", "I/O/T"), # noqa: E501 - 7 : _Function(esp32.get_gpio(12), "GPIO12", "I/O/T"), # noqa: E501 - 8 : _Function(x.SDIO_HOST[1].DATA[2], "HS2_DATA2", "I1/O/T"), # noqa: E501 - 9 : _Function(x.SDIO_SLAVE.DATA[2], "SD_DATA2", "I1/O/T"), # noqa: E501 - 10: _Function(x.EMAC.TXD[3], "EMAC_TXD3", "O") # noqa: E501 - }), # noqa: E501 - ] - # fmt: on - - -class _ESP32_Pinmux(Module): - @L.rt_field - def MUXES(self): - return [ - _Mux( - self.esp32.pinmap[str(pad.interface)], - *[f.interface for f in pad.functions.values()], - ) - for pad in self.matrix - ] - - def __init__(self, esp32: ESP32) -> None: - default_function = 5 - self.matrix = _matrix(esp32) - self.esp32 = esp32 - - for pad in self.matrix: - if len(pad.functions.items()) == 0: - continue - self._mux(pad.functions[default_function], pad) - - def _mux(self, function: _Function, pad: _Pad): - if pad.current_function == function: - return - - # Check if already set - # TODO remove, and make sure that reconnection is legal or spit warning or so - # assert (pad.current_function == None), "Already set" - - pad.current_function = function - self.MUXES[self.matrix.index(pad)].select(function.interface) - - def mux(self, internal: ModuleInterface, pad: ModuleInterface): - # Check if combination legal - row = [pin for pin in self.matrix if pin.interface == pad][0] - col = [ - function - for function in row.functions.values() - if function.interface == internal - ][0] - - self._mux(col, row) - - def mux_if(self, internal: ModuleInterface): - for pad in self.matrix: - for function in pad.functions.values(): - if function.interface == internal: - self._mux(function, pad) - return - assert False, "Not a pinmux interface" - - def mux_peripheral(self, peripheral: ModuleInterface): - ... - # ifs = peripheral.get_trait(can_list_interfaces).get_interfaces() - # for interface in ifs: - # self.mux_if(interface) - # TODO - # is this not ambiguous? diff --git a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py index 1e8fe8fd..bacbbc34 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py +++ b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py @@ -16,7 +16,7 @@ class ESP32_C3_MINI_1_Reference_Design(Module): # TODO make switch debounced boot_switch: F.Button # TODO: this cannot be picked Switch(F.Electrical) reset_switch: F.Button # TODO: this cannot be picked Switch(F.Electrical) - low_speed_crystal_clock = F.Crystal_Oscillator + low_speed_crystal_clock: F.Crystal_Oscillator vdd3v3: F.ElectricPower uart: F.UART_Base diff --git a/src/faebryk/library/ElectricLogicGates.py b/src/faebryk/library/ElectricLogicGates.py index 9fe253b4..dc3d78fe 100644 --- a/src/faebryk/library/ElectricLogicGates.py +++ b/src/faebryk/library/ElectricLogicGates.py @@ -2,9 +2,10 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F +from faebryk.core.core import Namespace -class ElectricLogicGates: +class ElectricLogicGates(Namespace): class OR(F.ElectricLogicGate): def __init__(self, input_cnt: F.Constant[int]): super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_or_gate()) diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index 017d93af..3e1eb596 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -1,22 +1,19 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from dataclasses import dataclass, field - import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.parameter import Parameter from faebryk.libs.library import L from faebryk.libs.units import P class HLK_LD2410B_P(Module): - @dataclass class _ld2410b_esphome_config(F.has_esphome_config.impl()): - throttle_ms: Parameter = field(default_factory=F.TBD) + throttle_ms: F.TBD def get_config(self) -> dict: - assert isinstance(self.throttle_ms, F.Constant), "No update interval set!" + val = self.throttle_ms.get_most_narrow() + assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj assert isinstance(obj, HLK_LD2410B_P), "This is not an HLK_LD2410B_P!" @@ -37,7 +34,7 @@ def get_config(self) -> dict: return { "ld2410": { - "throttle": f"{self.throttle_ms.value}ms", + "throttle": f"{val.value}ms", "uart_id": uart_cfg["id"], }, "binary_sensor": [ diff --git a/src/faebryk/library/I2C.py b/src/faebryk/library/I2C.py index 7db966d9..1af1c0b8 100644 --- a/src/faebryk/library/I2C.py +++ b/src/faebryk/library/I2C.py @@ -43,3 +43,6 @@ class SpeedMode(Enum): @staticmethod def define_max_frequency_capability(mode: SpeedMode): return F.Range(I2C.SpeedMode.low_speed, mode) + + +print(I2C, type(I2C)) diff --git a/src/faebryk/library/LogicGates.py b/src/faebryk/library/LogicGates.py index 61e25bfd..16c0ef08 100644 --- a/src/faebryk/library/LogicGates.py +++ b/src/faebryk/library/LogicGates.py @@ -2,9 +2,10 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F +from faebryk.core.core import Namespace -class LogicGates: +class LogicGates(Namespace): class OR(F.LogicGate): def __init__(self, input_cnt: F.Constant[int]): super().__init__(input_cnt, F.Constant(1), F.LogicGate.can_logic_or_gate()) diff --git a/src/faebryk/library/LogicOps.py b/src/faebryk/library/LogicOps.py index 8be95ece..ca141d30 100644 --- a/src/faebryk/library/LogicOps.py +++ b/src/faebryk/library/LogicOps.py @@ -4,10 +4,11 @@ from abc import abstractmethod import faebryk.library._F as F +from faebryk.core.core import Namespace from faebryk.core.trait import Trait -class LogicOps: +class LogicOps(Namespace): class can_logic(Trait): @abstractmethod def op(self, *ins: F.Logic) -> F.Logic: ... diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index 1c85ec01..560035e4 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -1,7 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from dataclasses import dataclass, field import faebryk.library._F as F from faebryk.core.module import Module @@ -27,17 +26,12 @@ class PM1006(Module): or UART signal. """ - @dataclass class _pm1006_esphome_config(F.has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=F.TBD) - - def __post_init__(self) -> None: - super().__init__() + update_interval_s: F.TBD def get_config(self) -> dict: - assert isinstance( - self.update_interval_s, F.Constant - ), "No update interval set!" + val = self.update_interval_s.get_most_narrow() + assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj assert isinstance(obj, PM1006), "This is not an PM1006!" @@ -48,7 +42,7 @@ def get_config(self) -> dict: "sensor": [ { "platform": "pm1006", - "update_interval": f"{self.update_interval_s.value}s", + "update_interval": f"{val.value}s", "uart_id": uart.get_trait(F.is_esphome_bus).get_bus_id(), } ] diff --git a/src/faebryk/library/Powered_Relay.py b/src/faebryk/library/Powered_Relay.py index 02f12fad..70aef98a 100644 --- a/src/faebryk/library/Powered_Relay.py +++ b/src/faebryk/library/Powered_Relay.py @@ -28,7 +28,7 @@ class Powered_Relay(Module): def __preinit__(self): from faebryk.core.util import connect_module_mifs_by_name - connect_module_mifs_by_name(self, self.relay) + connect_module_mifs_by_name(self, self.relay, allow_partial=True) self.relay_driver.power_in.connect(self.power) self.relay_driver.logic_in.connect(self.enable) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index fa1b0145..b544762c 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -34,6 +34,8 @@ class RP2040_Reference_Design(Module): # TODO: add optional LM4040 voltage reference or voltage divider def __preinit__(self): + # TODO + return # ---------------------------------------- # aliasess # ---------------------------------------- diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index dc261384..80ca4f9b 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -1,11 +1,9 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from dataclasses import dataclass, field import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.parameter import Parameter from faebryk.libs.library import L from faebryk.libs.units import P @@ -15,14 +13,12 @@ class SCD40(Module): Sensirion SCD4x NIR CO2 sensor """ - @dataclass class _scd4x_esphome_config(F.has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=F.TBD) + update_interval_s: F.TBD def get_config(self) -> dict: - assert isinstance( - self.update_interval_s, F.Constant - ), "No update interval set!" + val = self.update_interval_s.get_most_narrow() + assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj assert isinstance(obj, SCD40) @@ -44,7 +40,7 @@ def get_config(self) -> dict: }, "address": 0x62, "i2c_id": i2c.get_trait(F.is_esphome_bus).get_bus_id(), - "update_interval": f"{self.update_interval_s.value}s", + "update_interval": f"{val.value}s", } ] } diff --git a/src/faebryk/library/SPIFlash.py b/src/faebryk/library/SPIFlash.py index 88491710..8c8a1dc4 100644 --- a/src/faebryk/library/SPIFlash.py +++ b/src/faebryk/library/SPIFlash.py @@ -9,7 +9,7 @@ class SPIFlash(Module): power: F.ElectricPower - spi: F.MultiSPI + spi = L.f_field(F.MultiSPI)(4) memory_size: F.TBD[Quantity] designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/Switch.py b/src/faebryk/library/Switch.py index a18eda04..bc461bdc 100644 --- a/src/faebryk/library/Switch.py +++ b/src/faebryk/library/Switch.py @@ -1,13 +1,13 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from functools import cache from typing import TypeGuard import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.libs.library import L +from faebryk.libs.util import once class _TSwitch[T: ModuleInterface](Module): @@ -20,7 +20,7 @@ def is_instance(obj: Module, t: type[T]) -> bool: return isinstance(obj, _TSwitch) and issubclass(obj.t, t) -@cache # This means we can use a normal "isinstance" to test for them +@once # This means we can use a normal "isinstance" to test for them def Switch[T: ModuleInterface](interface_type: type[T]): class _Switch(_TSwitch[interface_type]): def __init__(self) -> None: diff --git a/src/faebryk/library/USB2_0.py b/src/faebryk/library/USB2_0.py index 8db61d36..36048ff2 100644 --- a/src/faebryk/library/USB2_0.py +++ b/src/faebryk/library/USB2_0.py @@ -3,10 +3,11 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.units import P class USB2_0(ModuleInterface): usb_if: F.USB2_0_IF def __preinit__(self): - self.usb_if.buspower.voltage.merge(F.Range.from_center(5, 0.25)) + self.usb_if.buspower.voltage.merge(F.Range.from_center(5 * P.V, 0.25 * P.V)) diff --git a/src/faebryk/library/USB2_0_IF.py b/src/faebryk/library/USB2_0_IF.py index f5895481..222124bf 100644 --- a/src/faebryk/library/USB2_0_IF.py +++ b/src/faebryk/library/USB2_0_IF.py @@ -3,8 +3,15 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L class USB2_0_IF(ModuleInterface): d: F.DifferentialPair buspower: F.ElectricPower + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/USB3.py b/src/faebryk/library/USB3.py index 09be9d81..7626ca2a 100644 --- a/src/faebryk/library/USB3.py +++ b/src/faebryk/library/USB3.py @@ -3,6 +3,7 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L from faebryk.libs.units import P @@ -12,3 +13,9 @@ class USB3(ModuleInterface): def __preinit__(self): self.usb3_if.gnd_drain.connect(self.usb3_if.usb_if.buspower.lv) self.usb3_if.usb_if.buspower.voltage.merge(F.Range(4.75 * P.V, 5.5 * P.V)) + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/USB3_IF.py b/src/faebryk/library/USB3_IF.py index ef2c7e20..13421a96 100644 --- a/src/faebryk/library/USB3_IF.py +++ b/src/faebryk/library/USB3_IF.py @@ -3,6 +3,7 @@ import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface +from faebryk.libs.library import L class USB3_IF(ModuleInterface): @@ -10,3 +11,9 @@ class USB3_IF(ModuleInterface): rx: F.DifferentialPair tx: F.DifferentialPair gnd_drain: F.Electrical + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self) + ) diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index 615b16b2..ed3b7e7d 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -1,21 +1,14 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from dataclasses import dataclass, field - import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.parameter import Parameter from faebryk.libs.library import L class XL_3528RGBW_WS2812B(Module): - @dataclass class _ws2812b_esphome_config(F.has_esphome_config.impl()): - update_interval_s: Parameter = field(default_factory=F.TBD) - - def __post_init__(self) -> None: - super().__init__() + update_interval_s: F.TBD def get_config(self) -> dict: assert isinstance( diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 5ca758bc..e741cc4b 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,8 +15,8 @@ # flake8: noqa: I001 # flake8: noqa: E501 -from faebryk.library.has_simple_value_representation import has_simple_value_representation from faebryk.library.has_footprint import has_footprint +from faebryk.library.has_simple_value_representation import has_simple_value_representation from faebryk.library.has_overriden_name import has_overriden_name from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.Constant import Constant @@ -43,9 +43,9 @@ from faebryk.library.Mechanical import Mechanical from faebryk.library.is_representable_by_single_value import is_representable_by_single_value from faebryk.library.has_kicad_ref import has_kicad_ref +from faebryk.library.Footprint import Footprint from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params -from faebryk.library.Footprint import Footprint from faebryk.library.has_overriden_name_defined import has_overriden_name_defined from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param @@ -179,7 +179,6 @@ from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP from faebryk.library.SWDConnector import SWDConnector from faebryk.library.UART import UART -from faebryk.library.ESP32 import ESP32 from faebryk.library.UART_RS485 import UART_RS485 from faebryk.library.TD541S485H import TD541S485H from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART diff --git a/test/library/test_basic.py b/test/library/test_basic.py new file mode 100644 index 00000000..56516a57 --- /dev/null +++ b/test/library/test_basic.py @@ -0,0 +1,48 @@ +# This file is part of the faebryk project +# SPDX-License-Identifier: MIT + +import unittest + +from faebryk.core.core import Namespace +from faebryk.core.node import Node + + +class TestBasicLibrary(unittest.TestCase): + def test_load_library(self): + import faebryk.library._F # noqa: F401 + + def test_symbol_types(self): + import faebryk.library._F as F + + symbols = { + k: v + for k, v in vars(F).items() + if not k.startswith("_") + and (not isinstance(v, type) or not issubclass(v, (Node, Namespace))) + and not type(v).__name__ == "_once" + } + self.assertFalse(symbols, f"Found unexpected symbols: {symbols}") + + def test_imports(self): + import faebryk.library._F as F + + # get all symbols in F + symbols = { + k: v + for k, v in vars(F).items() + if not k.startswith("_") + and isinstance(v, type) + and issubclass(v, Node) + # check if constructor has no args + and v.__init__.__code__.co_argcount == 1 + } + + for k, v in symbols.items(): + try: + v() + except Exception as e: + self.fail(f"Failed to instantiate {k}: {e}") + + +if __name__ == "__main__": + unittest.main() From b72f3ab6cf3cb0cae913d2951d25f706bd012c83 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 17:30:16 +0200 Subject: [PATCH 50/63] Make more refactor stuff --- src/faebryk/library/HLK_LD2410B_P.py | 6 +- src/faebryk/tools/refactor.py | 135 ++++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 4 deletions(-) diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index 3e1eb596..c8a3a361 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -9,10 +9,10 @@ class HLK_LD2410B_P(Module): class _ld2410b_esphome_config(F.has_esphome_config.impl()): - throttle_ms: F.TBD + throttle: F.TBD def get_config(self) -> dict: - val = self.throttle_ms.get_most_narrow() + val = self.throttle.get_most_narrow() assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj @@ -34,7 +34,7 @@ def get_config(self) -> dict: return { "ld2410": { - "throttle": f"{val.value}ms", + "throttle": f"{val.value.to('ms')}", "uart_id": uart_cfg["id"], }, "binary_sensor": [ diff --git a/src/faebryk/tools/refactor.py b/src/faebryk/tools/refactor.py index 80e005b0..b5741377 100644 --- a/src/faebryk/tools/refactor.py +++ b/src/faebryk/tools/refactor.py @@ -1,10 +1,12 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT +from lib2to3 import refactor import re import subprocess from dataclasses import dataclass from pathlib import Path +from textwrap import dedent, indent import typer @@ -27,6 +29,9 @@ def main(ctx: typer.Context): pass +pyname = r"[_a-zA-Z][_a-zA-Z0-9]*" + + @main.command() def libtof(ctx: typer.Context, root: Path): file_paths = list(root.rglob("**/*.py")) @@ -49,7 +54,6 @@ def libtof(ctx: typer.Context, root: Path): # has_simple_value_representation, # ) - pyname = r"[_a-zA-Z][_a-zA-Z0-9]*" import_pattern = re.compile( r"^from faebryk.library.([^_][^ ]*) import (" f"{pyname}$" @@ -86,5 +90,134 @@ def refactor_file(path: Path): subprocess.check_call(["ruff", "check", "--fix", root]) +maybe_f = r"(?:F\.)?" + + +@main.command() +def fabll(ctx: typer.Context, root: Path): + file_paths = list(root.rglob("**/*.py")) + print(f"Found {len(file_paths)} files in path.") + + types = r"(?:IF|NODE|PARAM)" + ano_class = rf"class _{types}s\(" + detection_pattern = re.compile(ano_class) + + refactor_files = file_paths + # refactor_files = [ + # path + # for path in file_paths + # if not path.stem.startswith("_") and detection_pattern.search(path.read_text()) + # ] + + print(f"Found {len(refactor_files)} files to refactor.") + + holder_header = rf"[ ]*{ano_class}.*?\):\n" + holder_pattern = re.compile( + rf"({holder_header})(.*?)\n\n", re.MULTILINE | re.DOTALL + ) + + instance_holder = re.compile(rf"self.{types}s = _{types}s\(self\)", re.MULTILINE) + holder_attr = re.compile(rf"\.{types}s\.") + + def refactor_file(path: Path): + text = path.read_text() + + print(path, "=" * 40) + + def process(m: re.Match) -> str: + # print("Block", "|||") + header, fields = m.groups() + fields: str = fields + "\n" + out = [] + for f in fields.split(")\n"): + if not f: + continue + f += ")" + # print(f) + # print(indent("|\nv", " " * 12)) + + if "times" in f: + f = re.sub(r"\n\s*", "", f) + f = f.replace(",)", ")") + + # case 3: screw_holes = times(3, lambda: F.Mounting_Hole()) + f = re.sub(r"times\((\d+),", r"L.list_field(\1,", f) + + # case 5: leds = times(\n self.pixels.value, \n ...,\n) + f = re.sub( + rf"\s*({pyname}) = (times\(.*\))", + r"@L.rt_field\ndef \1(self):\n return \2", + f, + ) + + # case 1: uart_in = F.UART_Base() + # case 4: if buffered:\n power_data = F.ElectricPower() + f = re.sub(rf" = ({maybe_f}{pyname})\(\)", r": \1", f) + + # case 2: fan_power_switch = F.PowerSwitchMOSFET(lowside=True, ...) + f = re.sub( + rf" = ({maybe_f}{pyname})\((.*)\)", r" = L.f_field(\1)(\2)", f + ) + + # print(f) + # print("--") + out.append(dedent(f)) + + outstr = indent("\n".join(out), " " * 4) + # print(outstr) + return outstr + + # Holders ------------------------------------- + text = holder_pattern.sub(process, text) + text = instance_holder.sub("", text) + text = holder_attr.sub(".", text) + + # Init ---------------------------------------- + # convert empty constructor to __preinit__ + text = re.sub( + r"def __init__\(self\).*?:(.*?)super\(\).__init__\(\)", + r"def __preinit__(self):\1pass", + text, + flags=re.DOTALL | re.MULTILINE, + ) + + # remove -> None from init + text = re.sub( + r"(def __init__\(self.*?\)).*?:", + r"\1:", + text, + ) + + def process_constructor(m: re.Match) -> str: + str_: str = m.group(0) + args = m.group(1) + out = str_ + prefix = re.match(r"^\s*", str_).group(0) + + # find names of args + arg_names = re.findall(rf",\s*({pyname})\s*(?:[:,]|$)", args) + for arg in arg_names: + out += indent(f"\n self._{arg} = {arg}", prefix) + + out += indent("\n\ndef __preinit__(self):\n pass", prefix) + return out + + # split args of constructor into init and pre_init + text = re.sub( + r"^[ ]*def __init__\(self(, .*?)\):.*?super\(\).__init__\(\)", + process_constructor, + text, + flags=re.DOTALL | re.MULTILINE, + ) + + # Done ---------------------------------------- + text = "\n".join(line.rstrip() for line in text.splitlines()) + text = text.strip() + "\n" + path.write_text(text) + + for path in refactor_files: + refactor_file(path) + + if __name__ == "__main__": main() From a4d2044c78eaa4355e1899d3cace851ac67c4391 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 19:51:25 +0200 Subject: [PATCH 51/63] Fixed esphome units --- new_holders_flat.py | 101 --------------------- src/faebryk/library/BH1750FVI_TR.py | 6 +- src/faebryk/library/PM1006.py | 6 +- src/faebryk/library/SCD40.py | 6 +- src/faebryk/library/XL_3528RGBW_WS2812B.py | 6 +- 5 files changed, 12 insertions(+), 113 deletions(-) delete mode 100644 new_holders_flat.py diff --git a/new_holders_flat.py b/new_holders_flat.py deleted file mode 100644 index 568ebc5c..00000000 --- a/new_holders_flat.py +++ /dev/null @@ -1,101 +0,0 @@ -from dataclasses import field - -import typer - -import faebryk.library._F as F -from faebryk.core.module import Module -from faebryk.core.parameter import Parameter -from faebryk.core.util import as_unit -from faebryk.libs.library import L -from faebryk.libs.units import P, Quantity -from faebryk.libs.util import times - -# ----------------------------------------------------------------------------- - - -class Diode2(Module): - forward_voltage: F.TBD[Quantity] - max_current: F.TBD[Quantity] - current: F.TBD[Quantity] - reverse_working_voltage: F.TBD[Quantity] - reverse_leakage_current: F.TBD[Quantity] - - # static param - bla_voltage: Parameter[Quantity] = L.d_field(lambda: 5 * P.V) - # bla_dep: Parameter[Quantity] = L.rt_field(lambda self: self.bla_voltage) - - anode: F.Electrical - cathode: F.Electrical - - # static trait - designator_prefix = L.f_field(F.has_designator_prefix_defined)("D") - - @L.rt_field - def bla_dep2(self): - return self.bla_voltage + (10 * P.V) - - # dynamic trait - @L.rt_field - def bridge(self): - return F.can_bridge_defined(self.anode, self.cathode) - - def __preinit__(self): - print("Called Diode __preinit__") - - # anonymous dynamic trait - self.add( - F.has_simple_value_representation_based_on_param( - self.forward_voltage, - lambda p: as_unit(p, "V"), - ) - ) - - def __init__(self): - super().__init__() - print("INIT DIODE") - - -class LED2(Diode2): - color: F.TBD[float] - - def __preinit__(self): - print("Called LED __preinit__") - - -class LED2_NOINT(LED2, init=False): - def __preinit__(self): - print("Called LED_NOINT __preinit__") - - -class LED2_WITHEXTRAT_IFS(LED2): - extra: list[F.Electrical] = field(default_factory=lambda: times(2, F.Electrical)) - extra2: list[F.Electrical] = L.list_field(2, F.Electrical) - - @L.rt_field - def bridge(self): - return F.can_bridge_defined(self.extra2[0], self.extra2[1]) - - def __preinit__(self): - print("Called LED_WITHEXTRAT_IFS __preinit__") - - -def main(): - print("Diode init ----") - _D = Diode2() - print("LED init ----") - _L = LED2() - print("LEDNOINIT init ----") - L2 = LED2_NOINT() - print("LEDEXTRA init ----") - L3 = LED2_WITHEXTRAT_IFS() - - L3.cathode.connect(L2.cathode) - - assert L3.cathode.is_connected_to(L2.cathode) - L3.forward_voltage.merge(5 * P.V) - L3.get_trait(F.has_simple_value_representation).get_value() - - assert L3.designator_prefix.prefix == "D" - - -typer.run(main) diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 87d7685c..894d1d00 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -13,10 +13,10 @@ class BH1750FVI_TR(Module): class _bh1750_esphome_config(F.has_esphome_config.impl()): - update_interval_s: F.TBD + update_interval: F.TBD def get_config(self) -> dict: - val = self.update_interval_s.get_most_narrow() + val = self.update_interval.get_most_narrow() assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj @@ -31,7 +31,7 @@ def get_config(self) -> dict: "name": "BH1750 Illuminance", "address": "0x23", "i2c_id": i2c.get_trait(F.is_esphome_bus).get_bus_id(), - "update_interval": f"{val.value}s", + "update_interval": f"{val.value.to('s')}", } ] } diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index 560035e4..df302730 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -27,10 +27,10 @@ class PM1006(Module): """ class _pm1006_esphome_config(F.has_esphome_config.impl()): - update_interval_s: F.TBD + update_interval: F.TBD def get_config(self) -> dict: - val = self.update_interval_s.get_most_narrow() + val = self.update_interval.get_most_narrow() assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj @@ -42,7 +42,7 @@ def get_config(self) -> dict: "sensor": [ { "platform": "pm1006", - "update_interval": f"{val.value}s", + "update_interval": f"{val.value.to('s')}", "uart_id": uart.get_trait(F.is_esphome_bus).get_bus_id(), } ] diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index 80ca4f9b..5a3076a1 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -14,10 +14,10 @@ class SCD40(Module): """ class _scd4x_esphome_config(F.has_esphome_config.impl()): - update_interval_s: F.TBD + update_interval: F.TBD def get_config(self) -> dict: - val = self.update_interval_s.get_most_narrow() + val = self.update_interval.get_most_narrow() assert isinstance(val, F.Constant), "No update interval set!" obj = self.obj @@ -40,7 +40,7 @@ def get_config(self) -> dict: }, "address": 0x62, "i2c_id": i2c.get_trait(F.is_esphome_bus).get_bus_id(), - "update_interval": f"{val.value}s", + "update_interval": f"{val.value.to('s')}", } ] } diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index ed3b7e7d..e80a8314 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -8,11 +8,11 @@ class XL_3528RGBW_WS2812B(Module): class _ws2812b_esphome_config(F.has_esphome_config.impl()): - update_interval_s: F.TBD + update_interval: F.TBD def get_config(self) -> dict: assert isinstance( - self.update_interval_s, F.Constant + self.update_interval, F.Constant ), "No update interval set!" obj = self.obj @@ -24,7 +24,7 @@ def get_config(self) -> dict: "light": [ { "platform": "esp32_rmt_led_strip", - "update_interval": f"{self.update_interval_s.value}s", + "update_interval": f"{self.update_interval.value.to('s')}", "num_leds": 1, # TODO: make dynamic "rmt_channel": 0, # TODO: make dynamic "chipset": "WS2812", From 4a15444555e88249bb2952da03981785b47a9eef Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 20:02:59 +0200 Subject: [PATCH 52/63] remove debug --- src/faebryk/library/I2C.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/faebryk/library/I2C.py b/src/faebryk/library/I2C.py index 1af1c0b8..7db966d9 100644 --- a/src/faebryk/library/I2C.py +++ b/src/faebryk/library/I2C.py @@ -43,6 +43,3 @@ class SpeedMode(Enum): @staticmethod def define_max_frequency_capability(mode: SpeedMode): return F.Range(I2C.SpeedMode.low_speed, mode) - - -print(I2C, type(I2C)) From 334d4f0f29e291aeabb5e9919edcc3a5517f0050 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 20:56:40 +0200 Subject: [PATCH 53/63] handpick ruben lib fixes --- src/faebryk/core/parameter.py | 4 +- src/faebryk/library/Button.py | 4 +- src/faebryk/library/CBM9002A_56ILG.py | 13 +- .../CBM9002A_56ILG_Reference_Design.py | 7 + src/faebryk/library/Crystal_Oscillator.py | 5 + src/faebryk/library/ElectricPower.py | 6 +- src/faebryk/library/LDO.py | 6 +- src/faebryk/library/OLED_Module.py | 17 ++- src/faebryk/library/Powered_Relay.py | 6 + src/faebryk/library/RP2040.py | 76 +++++++++- .../library/RP2040_Reference_Design.py | 142 ++++++++++++++++-- src/faebryk/library/RS485_Bus_Protection.py | 28 ++-- src/faebryk/library/SNx4LVC541A.py | 2 +- src/faebryk/library/TD541S485H.py | 14 +- src/faebryk/library/UART.py | 8 +- src/faebryk/library/UART_RS485.py | 4 +- src/faebryk/library/USB2514B.py | 39 ++++- src/faebryk/library/XL_3528RGBW_WS2812B.py | 3 + 18 files changed, 334 insertions(+), 50 deletions(-) diff --git a/src/faebryk/core/parameter.py b/src/faebryk/core/parameter.py index 9137b42c..587d11e4 100644 --- a/src/faebryk/core/parameter.py +++ b/src/faebryk/core/parameter.py @@ -101,7 +101,9 @@ def _is_pair[T, U](type1: type[T], type2: type[U]) -> Optional[tuple[T, U]]: if isinstance(out, Operation): raise self.MergeException("not resolvable") if out == Set([]) and not pair[0] == pair[1] == Set([]): - raise self.MergeException("conflicting sets/ranges") + raise self.MergeException( + f"conflicting sets/ranges: {self!r} {other!r}" + ) return out raise NotImplementedError diff --git a/src/faebryk/library/Button.py b/src/faebryk/library/Button.py index 0a47e77c..122451e9 100644 --- a/src/faebryk/library/Button.py +++ b/src/faebryk/library/Button.py @@ -6,14 +6,16 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L +from faebryk.libs.units import Quantity logger = logging.getLogger(__name__) class Button(Module): unnamed = L.list_field(2, F.Electrical) + height: F.TBD[Quantity] - designator_prefix = L.f_field(F.has_designator_prefix_defined)("S") + designator_prefix = L.f_field(F.has_designator_prefix_defined)("SW") @L.rt_field def can_bridge(self): diff --git a/src/faebryk/library/CBM9002A_56ILG.py b/src/faebryk/library/CBM9002A_56ILG.py index 438dbbe4..df840126 100644 --- a/src/faebryk/library/CBM9002A_56ILG.py +++ b/src/faebryk/library/CBM9002A_56ILG.py @@ -3,6 +3,7 @@ import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface from faebryk.libs.library import L @@ -43,15 +44,15 @@ class CBM9002A_56ILG(Module): "https://corebai.com/Data/corebai/upload/file/20240201/CBM9002A.pdf" ) - @L.rt_field - def single_electric_reference(self): - return F.has_single_electric_reference_defined( - F.ElectricLogic.connect_all_module_references(self) - ) - # ---------------------------------------- # connections # ---------------------------------------- def __preinit__(self): self.avcc.decoupled.decouple() # TODO: decouple all pins self.vcc.decoupled.decouple() # TODO: decouple all pins + + F.ElectricLogic.connect_all_node_references( + self.get_children(direct_only=True, types=ModuleInterface).difference( + {self.avcc} + ) + ) diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index cfe0694f..e295a9b1 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -70,3 +70,10 @@ def __preinit__(self): self.oscillator.crystal.frequency.merge(F.Constant(24 * P.Mhertz)) self.oscillator.crystal.load_impedance.merge(F.Constant(12 * P.pohm)) + + self.oscillator.crystal.frequency_temperature_tolerance.merge(20 * P.ppm) + # TODO: just set to a 1N4148 + self.reset_diode.forward_voltage.merge(715 * P.mV) + self.reset_diode.reverse_leakage_current.merge(1 * P.uA) + self.reset_diode.current.merge(300 * P.mA) + self.reset_diode.max_current.merge(1 * P.A) diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 00af31f8..1a48b495 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -27,6 +27,7 @@ class Crystal_Oscillator(Module): # parameters # ---------------------------------------- # https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ + # http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00221665.pdf _STRAY_CAPACITANCE = F.Range(1 * P.nF, 5 * P.nF) @L.rt_field @@ -57,3 +58,7 @@ def __preinit__(self): self.crystal.unnamed[0].connect(self.n) self.crystal.unnamed[1].connect(self.p) + + @L.rt_field + def can_bridge(self): + return F.can_bridge_defined(self.p, self.n) diff --git a/src/faebryk/library/ElectricPower.py b/src/faebryk/library/ElectricPower.py index a0cb2e59..8cd5f6e9 100644 --- a/src/faebryk/library/ElectricPower.py +++ b/src/faebryk/library/ElectricPower.py @@ -2,6 +2,8 @@ # SPDX-License-Identifier: MIT +import math + import faebryk.library._F as F from faebryk.core.moduleinterface import ModuleInterface from faebryk.libs.library import L @@ -22,7 +24,9 @@ def decouple(self): super() .decouple() .builder( - lambda c: c.rated_voltage.merge(F.Range(0 * P.V, obj.voltage * 2.0)) + lambda c: c.rated_voltage.merge( + F.Range(obj.voltage * 2.0, math.inf * P.V) + ) ) ) diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index 422d007e..eb1d046b 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -39,10 +39,10 @@ def __preinit__(self): self.power_out.decoupled.decouple() self.enable.reference.connect(self.power_in) - if self.output_polarity == self.OutputPolarity.POSITIVE: - self.power_in.lv.connect(self.power_out.lv) - else: + if self.output_polarity == self.OutputPolarity.NEGATIVE: self.power_in.hv.connect(self.power_out.hv) + else: + self.power_in.lv.connect(self.power_out.lv) @L.rt_field def can_bridge(self): diff --git a/src/faebryk/library/OLED_Module.py b/src/faebryk/library/OLED_Module.py index 53ffe0f4..ca5a3fd7 100644 --- a/src/faebryk/library/OLED_Module.py +++ b/src/faebryk/library/OLED_Module.py @@ -13,21 +13,34 @@ class OLED_Module(Module): - class Resolution(Enum): + class DisplayResolution(Enum): H64xV32 = auto() H128xV32 = auto() H128xV64 = auto() H256xV64 = auto() + class DisplaySize(Enum): + INCH_0_96 = auto() + INCH_1_12 = auto() + INCH_1_27 = auto() + INCH_1_3 = auto() + INCH_1_5 = auto() + INCH_2_23 = auto() + INCH_2_3 = auto() + INCH_2_42 = auto() + INCH_2_7 = auto() + class DisplayController(Enum): SSD1315 = auto() SSD1306 = auto() + SSD1309 = auto() power: F.ElectricPower i2c: F.I2C - resolution: F.TBD[Resolution] + display_resolution: F.TBD[DisplayResolution] display_controller: F.TBD[DisplayController] + display_size: F.TBD[DisplaySize] def __preinit__(self): self.power.voltage.merge(F.Range(3.0 * P.V, 5 * P.V)) diff --git a/src/faebryk/library/Powered_Relay.py b/src/faebryk/library/Powered_Relay.py index 70aef98a..91dca3fe 100644 --- a/src/faebryk/library/Powered_Relay.py +++ b/src/faebryk/library/Powered_Relay.py @@ -37,3 +37,9 @@ def __preinit__(self): self.relay.coil_n.connect_via(self.flyback_diode, self.relay.coil_p) self.indicator.power.connect(self.relay_driver.switched_power_out) + + @L.rt_field + def single_electric_reference(self): + return F.has_single_electric_reference_defined( + F.ElectricLogic.connect_all_module_references(self, gnd_only=True) + ) diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index be8d03ce..4eeca64d 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -5,7 +5,9 @@ import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.core.moduleinterface import ModuleInterface from faebryk.libs.library import L +from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -30,6 +32,7 @@ class RP2040(Module): uart: F.UART_Base def __preinit__(self): + return # decouple power rails and connect GNDs toghether gnd = self.io_vdd.lv for pwrrail in [ @@ -44,9 +47,80 @@ def __preinit__(self): pwrrail.decoupled.decouple() # set parameters - # self.io_vdd.voltage.merge(F.Range(1.8*P.V, 3.63*P.V)) + self.vreg_out.voltage.merge(1.1 * P.V) + self.io_vdd.voltage.merge(3.3 * P.V) + + F.ElectricLogic.connect_all_node_references( + self.get_children(direct_only=True, types=ModuleInterface).difference( + {self.adc_vdd, self.core_vdd} + ) + ) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") datasheet = L.f_field(F.has_datasheet_defined)( "https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf" ) + + @L.rt_field + def attach_to_footprint(self): + return F.can_attach_to_footprint_via_pinmap( + { + "1": self.io_vdd.hv, + "2": self.gpio[0], + "3": self.gpio[1], + "4": self.gpio[2], + "5": self.gpio[3], + "6": self.gpio[4], + "7": self.gpio[5], + "8": self.gpio[6], + "9": self.gpio[7], + "10": self.io_vdd.hv, + "11": self.gpio[8], + "12": self.gpio[9], + "13": self.gpio[10], + "14": self.gpio[11], + "15": self.gpio[12], + "16": self.gpio[13], + "17": self.gpio[14], + "18": self.gpio[15], + "19": self.xin, + "20": self.xout, + "21": self.test, + "22": self.io_vdd.hv, + "23": self.core_vdd.hv, + "24": self.swd.clk.signal, + "25": self.swd.dio.signal, + "26": self.run.signal, + "27": self.gpio[16], + "28": self.gpio[17], + "29": self.gpio[18], + "30": self.gpio[19], + "31": self.gpio[20], + "32": self.gpio[21], + "33": self.io_vdd.hv, + "34": self.gpio[22], + "35": self.gpio[23], + "36": self.gpio[24], + "37": self.gpio[25], + "38": self.gpio[26], + "39": self.gpio[27], + "40": self.gpio[28], + "41": self.gpio[29], + "42": self.io_vdd.hv, + "43": self.adc_vdd.hv, + "44": self.vreg_in.hv, + "45": self.vreg_out.hv, + "46": self.usb.usb_if.d.n, + "47": self.usb.usb_if.d.p, + "48": self.usb.usb_if.buspower.hv, + "49": self.io_vdd.hv, + "50": self.core_vdd.hv, + "51": self.qspi.data[3].signal, + "52": self.qspi.clk.signal, + "53": self.qspi.data[0].signal, + "54": self.qspi.data[2].signal, + "55": self.qspi.data[1].signal, + "56": self.qspi.cs.signal, + "57": self.io_vdd.lv, + } + ) diff --git a/src/faebryk/library/RP2040_Reference_Design.py b/src/faebryk/library/RP2040_Reference_Design.py index b544762c..7873e96c 100644 --- a/src/faebryk/library/RP2040_Reference_Design.py +++ b/src/faebryk/library/RP2040_Reference_Design.py @@ -20,17 +20,20 @@ class RP2040_Reference_Design(Module): # modules, interfaces, parameters # ---------------------------------------- - power: F.ElectricPower usb: F.USB2_0 rp2040: F.RP2040 flash: F.SPIFlash led: F.PoweredLED usb_current_limit_resistor = L.list_field(2, F.Resistor) - # TODO: add crystal oscillator + reset_button: F.Button + boot_button: F.Button + boot_resistor: F.Resistor + ldo: F.LDO + crystal_oscillator: F.Crystal_Oscillator + oscillator_resistor: F.Resistor + # TODO: add voltage divider with switch - # TODO: add boot button - # TODO: add reset button # TODO: add optional LM4040 voltage reference or voltage divider def __preinit__(self): @@ -39,11 +42,22 @@ def __preinit__(self): # ---------------------------------------- # aliasess # ---------------------------------------- - gnd = self.power.lv + power_3v3 = self.ldo.power_out + power_5v = self.ldo.power_in + power_vbus = self.usb.usb_if.buspower + gnd = power_vbus.lv # ---------------------------------------- # parametrization # ---------------------------------------- - self.power.voltage.merge(F.Constant(3.3 * P.V)) + self.ldo.output_voltage.merge(3.3 * P.V) + self.ldo.output_current.merge(600 * P.mA) + self.crystal_oscillator.crystal.frequency.merge(12 * P.MHz) + self.crystal_oscillator.crystal.load_impedance.merge(10 * P.pF) + + # for cap in self.crystal_oscillator.capacitors: + # cap.capacitance.merge(15 * P.pF) # TODO: remove? + + self.oscillator_resistor.resistance.merge(F.Constant(1 * P.kohm)) self.flash.memory_size.merge(F.Constant(16 * P.Mbit)) @@ -51,6 +65,8 @@ def __preinit__(self): self.led.led.brightness.merge( TypicalLuminousIntensity.APPLICATION_LED_INDICATOR_INSIDE.value.value ) + # TODO: remove: #poweredled voltage merge issue + self.led.power.voltage.merge(power_3v3.voltage) self.usb_current_limit_resistor[0].resistance.merge(F.Constant(27 * P.ohm)) self.usb_current_limit_resistor[1].resistance.merge(F.Constant(27 * P.ohm)) @@ -59,24 +75,40 @@ def __preinit__(self): # connections # ---------------------------------------- # connect power rails - main_power_rail = self.power + power_vbus.connect(power_5v) + + # connect rp2040 power rails for pwrrail in [ self.rp2040.io_vdd, self.rp2040.adc_vdd, self.rp2040.vreg_in, self.rp2040.usb.usb_if.buspower, ]: - pwrrail.connect(main_power_rail) + pwrrail.connect(power_3v3) self.rp2040.vreg_out.connect(self.rp2040.core_vdd) # connect flash self.flash.spi.connect(self.rp2040.qspi) - self.flash.power.connect(main_power_rail) + self.flash.power.connect(power_3v3) # connect led self.rp2040.gpio[25].connect_via(self.led, gnd) + # crystal oscillator + self.rp2040.xin.connect_via( + [self.crystal_oscillator, self.oscillator_resistor], + self.rp2040.xout, + ) + gnd.connect(self.crystal_oscillator.power.lv) + + # buttons + self.rp2040.qspi.cs.signal.connect_via( + [self.boot_resistor, self.boot_button], gnd + ) + self.boot_resistor.resistance.merge(F.Constant(1 * P.kohm)) + self.rp2040.run.signal.connect_via(self.reset_button, gnd) + # connect usb self.usb.usb_if.d.p.connect_via( self.usb_current_limit_resistor[0], @@ -90,3 +122,95 @@ def __preinit__(self): datasheet = L.f_field(F.has_datasheet_defined)( "https://datasheets.raspberrypi.com/rp2040/hardware-design-with-rp2040.pdf" ) + + @L.rt_field + def pcb_layout(self): + from faebryk.exporters.pcb.layout.absolute import LayoutAbsolute + from faebryk.exporters.pcb.layout.extrude import LayoutExtrude + from faebryk.exporters.pcb.layout.typehierarchy import LayoutTypeHierarchy + + Point = F.has_pcb_position.Point + L = F.has_pcb_position.layer_type + + return F.has_pcb_layout_defined( + layout=LayoutTypeHierarchy( + layouts=[ + LayoutTypeHierarchy.Level( + mod_type=F.RP2040, + layout=LayoutAbsolute( + Point((0, 0, 0, L.NONE)), + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.LDO, + layout=LayoutAbsolute(Point((0, 14, 0, L.NONE))), + ), + LayoutTypeHierarchy.Level( + mod_type=F.Button, + layout=LayoutExtrude( + base=Point((-1.75, -11.5, 0, L.NONE)), + vector=(3.5, 0, 90), + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.SPIFlash, + layout=LayoutAbsolute( + Point((-1.95, -6.5, 0, L.NONE)), + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.PoweredLED, + layout=LayoutAbsolute( + Point((6.5, -1.5, 270, L.NONE)), + ), + children_layout=LayoutTypeHierarchy( + layouts=[ + LayoutTypeHierarchy.Level( + mod_type=F.LED, + layout=LayoutAbsolute( + Point((0, 0, 0, L.NONE)), + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.Resistor, + layout=LayoutAbsolute( + Point((-2.75, 0, 180, L.NONE)) + ), + ), + ] + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.Crystal_Oscillator, + layout=LayoutAbsolute( + Point((0, 7, 0, L.NONE)), + ), + children_layout=LayoutTypeHierarchy( + layouts=[ + LayoutTypeHierarchy.Level( + mod_type=F.Crystal, + layout=LayoutAbsolute( + Point((0, 0, 0, L.NONE)), + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.Capacitor, + layout=LayoutExtrude( + base=Point((-3, 0, 90, L.NONE)), + vector=(0, 6, 180), + dynamic_rotation=True, + ), + ), + ] + ), + ), + LayoutTypeHierarchy.Level( + mod_type=F.Resistor, + layout=LayoutExtrude( + base=Point((0.75, -6, 0, L.NONE)), + vector=(1.25, 0, 270), + ), + ), + ] + ) + ) diff --git a/src/faebryk/library/RS485_Bus_Protection.py b/src/faebryk/library/RS485_Bus_Protection.py index 7f9f5216..70c2a01c 100644 --- a/src/faebryk/library/RS485_Bus_Protection.py +++ b/src/faebryk/library/RS485_Bus_Protection.py @@ -74,7 +74,7 @@ def __preinit__(self): self.gnd_couple_resistor.resistance.merge(F.Constant(1 * P.Mohm)) self.gnd_couple_capacitor.capacitance.merge(F.Constant(1 * P.uF)) - self.gnd_couple_capacitor.rated_voltage.merge(F.Constant(2 * P.kV)) + self.gnd_couple_capacitor.rated_voltage.merge(F.Range.lower_bound(2 * P.kV)) self.tvs.reverse_working_voltage.merge(F.Constant(8.5 * P.V)) # self.tvs.max_current.merge(F.Constant(41.7*P.A)) @@ -92,17 +92,17 @@ def __preinit__(self): self.gdt.common.connect(self.earth) # rs485_in connections - self.rs485_in.diff_pair.p.connect(self.common_mode_filter.c_a[0]) - self.rs485_in.diff_pair.n.connect(self.common_mode_filter.c_b[0]) + self.rs485_in.diff_pair.n.connect(self.common_mode_filter.c_a[0]) + self.rs485_in.diff_pair.p.connect(self.common_mode_filter.c_b[0]) # rs485_out connections self.common_mode_filter.c_a[1].connect_via( self.current_limmiter_resistors[0], - self.rs485_out.diff_pair.p, + self.rs485_out.diff_pair.n, ) self.common_mode_filter.c_b[1].connect_via( self.current_limmiter_resistors[1], - self.rs485_out.diff_pair.n, + self.rs485_out.diff_pair.p, ) self.rs485_out.diff_pair.n.connect_via(self.gdt, self.rs485_out.diff_pair.p) @@ -150,29 +150,29 @@ def __preinit__(self): LayoutTypeHierarchy.Level( mod_type=F.Common_Mode_Filter, layout=LayoutAbsolute( - Point((0, 25.5, 90, L.NONE)), + Point((0, 19, 90, L.NONE)), ), ), LayoutTypeHierarchy.Level( mod_type=F.Diode, layout=LayoutExtrude( - base=Point((0, 14.5, 0, L.NONE)), + base=Point((-3.5, 14.5, 90, L.NONE)), vector=(0, 3.5, 0), ), ), LayoutTypeHierarchy.Level( mod_type=F.Resistor, layout=LayoutExtrude( - base=Point((-2, 8, 90, L.NONE)), + base=Point((-2, 7, 90, L.NONE)), vector=(0, 4, 0), ), ), - LayoutTypeHierarchy.Level( - mod_type=F.Capacitor, - layout=LayoutAbsolute( - Point((10, 0, 90, L.NONE)), - ), - ), + # LayoutTypeHierarchy.Level( + # mod_type=F.Capacitor, + # layout=LayoutAbsolute( + # Point((10, 0, 90, L.NONE)), + # ), + # ), ] ), ) diff --git a/src/faebryk/library/SNx4LVC541A.py b/src/faebryk/library/SNx4LVC541A.py index 3cbf9df2..a561eda6 100644 --- a/src/faebryk/library/SNx4LVC541A.py +++ b/src/faebryk/library/SNx4LVC541A.py @@ -45,7 +45,7 @@ def __preinit__(self): # ---------------------------------------- # connections # ---------------------------------------- - self.power.get_trait(F.can_be_decoupled).decouple() + self.power.decoupled.decouple() @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/TD541S485H.py b/src/faebryk/library/TD541S485H.py index c4a6cc72..a6c203b6 100644 --- a/src/faebryk/library/TD541S485H.py +++ b/src/faebryk/library/TD541S485H.py @@ -6,6 +6,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L +from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -16,8 +17,8 @@ class TD541S485H(Module): power_iso_out: F.ElectricPower uart: F.UART_Base rs485: F.RS485 - read_enable: F.Electrical - write_enable: F.Electrical + read_enable: F.ElectricLogic + write_enable: F.ElectricLogic designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") @@ -27,6 +28,7 @@ def __preinit__(self): self.power_iso_out.decoupled.decouple() self.power_iso_in.lv.connect(self.power_iso_out.lv) + self.power_iso_out.voltage.merge(5 * P.V) @L.rt_field def attach_to_footprint(self): @@ -36,8 +38,8 @@ def attach_to_footprint(self): "1": x.power.lv, "2": x.power.hv, "3": x.uart.rx.signal, - "4": x.read_enable, - "5": x.write_enable, + "4": x.read_enable.signal, + "5": x.write_enable.signal, "6": x.uart.tx.signal, "7": x.power.hv, "8": x.power.lv, @@ -49,3 +51,7 @@ def attach_to_footprint(self): "16": x.power_iso_in.lv, } ) + + datasheet = L.f_field(F.has_datasheet_defined)( + "https://www.mornsun-power.com/public/uploads/pdf/TD(H)541S485H.pdf" + ) diff --git a/src/faebryk/library/UART.py b/src/faebryk/library/UART.py index e8013ff4..8d7975c2 100644 --- a/src/faebryk/library/UART.py +++ b/src/faebryk/library/UART.py @@ -7,7 +7,7 @@ class UART(ModuleInterface): base_uart: F.UART_Base - rts: F.Electrical - cts: F.Electrical - dtr: F.Electrical - dsr: F.Electrical + rts: F.ElectricLogic + cts: F.ElectricLogic + dtr: F.ElectricLogic + dsr: F.ElectricLogic diff --git a/src/faebryk/library/UART_RS485.py b/src/faebryk/library/UART_RS485.py index af6da5ea..312dc6fc 100644 --- a/src/faebryk/library/UART_RS485.py +++ b/src/faebryk/library/UART_RS485.py @@ -15,8 +15,8 @@ class UART_RS485(Module): power: F.ElectricPower uart: F.UART_Base rs485: F.RS485 - read_enable: F.Electrical - write_enable: F.Electrical + read_enable: F.ElectricLogic + write_enable: F.ElectricLogic max_data_rate: F.TBD[Quantity] gpio_voltage: F.TBD[Quantity] diff --git a/src/faebryk/library/USB2514B.py b/src/faebryk/library/USB2514B.py index 6dd50c6a..ab68fa63 100644 --- a/src/faebryk/library/USB2514B.py +++ b/src/faebryk/library/USB2514B.py @@ -7,6 +7,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L +from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -18,6 +19,12 @@ class InterfaceConfiguration(Enum): BUS_POWERED = auto() EEPROM = auto() + class NonRemovablePortConfiguration(Enum): + ALL_PORTS_REMOVABLE = auto() + PORT_1_NOT_REMOVABLE = auto() + PORT_1_2_NOT_REMOVABLE = auto() + PORT_1_2_3_NOT_REMOVABLE = auto() + VDD33: F.ElectricPower VDDA33: F.ElectricPower @@ -53,6 +60,8 @@ class InterfaceConfiguration(Enum): gnd: F.Electrical interface_configuration: F.TBD[InterfaceConfiguration] + non_removable_port_configuration: F.TBD[NonRemovablePortConfiguration] + designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") def __preinit__(self): @@ -86,6 +95,34 @@ def __preinit__(self): x.RESET_N.connect(self.gnd) + self.PLLFILT.voltage.merge(1.8 * P.V) + self.CRFILT.voltage.merge(1.8 * P.V) + + if ( + self.non_removable_port_configuration + == USB2514B.NonRemovablePortConfiguration.ALL_PORTS_REMOVABLE + ): + self.NON_REM[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + self.NON_REM[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + elif ( + self.non_removable_port_configuration + == USB2514B.NonRemovablePortConfiguration.PORT_1_NOT_REMOVABLE + ): + self.NON_REM[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.NON_REM[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + elif ( + self.non_removable_port_configuration + == USB2514B.NonRemovablePortConfiguration.PORT_1_2_NOT_REMOVABLE + ): + self.NON_REM[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=False) + self.NON_REM[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + elif ( + self.non_removable_port_configuration + == USB2514B.NonRemovablePortConfiguration.PORT_1_2_3_NOT_REMOVABLE + ): + self.NON_REM[0].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + self.NON_REM[1].get_trait(F.ElectricLogic.can_be_pulled).pull(up=True) + datasheet = L.f_field(F.has_datasheet_defined)( - "https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/00001692C.pdf" + "https://ww1.microchip.com/downloads/aemDocuments/documents/UNG/ProductDocuments/DataSheets/USB251xB-xBi-Data-Sheet-DS00001692.pdf" ) diff --git a/src/faebryk/library/XL_3528RGBW_WS2812B.py b/src/faebryk/library/XL_3528RGBW_WS2812B.py index e80a8314..4a0d4ad9 100644 --- a/src/faebryk/library/XL_3528RGBW_WS2812B.py +++ b/src/faebryk/library/XL_3528RGBW_WS2812B.py @@ -70,3 +70,6 @@ def attach_to_footprint(self): ) esphome_config: _ws2812b_esphome_config + + def __preinit__(self): + self.power.decoupled.decouple() From 4cee3a280e512c622e867e11028a0c475ceeab6a Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Thu, 29 Aug 2024 20:57:50 +0200 Subject: [PATCH 54/63] Add todo to RP2040 --- src/faebryk/library/RP2040.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/faebryk/library/RP2040.py b/src/faebryk/library/RP2040.py index 4eeca64d..de4f6323 100644 --- a/src/faebryk/library/RP2040.py +++ b/src/faebryk/library/RP2040.py @@ -32,6 +32,7 @@ class RP2040(Module): uart: F.UART_Base def __preinit__(self): + # TODO return # decouple power rails and connect GNDs toghether gnd = self.io_vdd.lv From 717c5a78666f9498101e4c665f99f2198296bc0c Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:29:18 +0200 Subject: [PATCH 55/63] Add: Only generate _F.py when staged library files are detected --- tools/library/gen_F.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index 7194033f..d9b7c96f 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -6,6 +6,7 @@ import logging import re +import subprocess from graphlib import TopologicalSorter from pathlib import Path from typing import Iterable @@ -16,6 +17,17 @@ OUT = DIR / "_F.py" +def check_for_file_changes() -> bool: + """Check if any library files have been changed using git diff""" + git_command = f"git diff --name-only --cached {DIR} ':!*_F.py'" + + result = subprocess.run(git_command, shell=True, capture_output=True, text=True) + changed_files = result.stdout.splitlines() + logger.debug(f"Staged and changed library files: {changed_files}") + + return bool(changed_files) + + def try_(stmt: str, exc: str | type[Exception] | Iterable[type[Exception]]): if isinstance(exc, type): exc = exc.__name__ @@ -79,6 +91,11 @@ def main(): logger.info(f"Found {len(module_files)} modules") + if not check_for_file_changes(): + logger.info("No changes in staged files detected, exiting") + return + logger.info("Changes detected, regenerating _F.py") + modules_out: dict[str, tuple[Path, str]] = {} # Import each module and add its class to the current namespace From c32e089e00838609dbd97b04319a3c523dc8c48a Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:46:03 +0200 Subject: [PATCH 56/63] Skip gen_F when _F.py is already staged --- tools/library/gen_F.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index d9b7c96f..fb5e39a8 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -19,12 +19,16 @@ def check_for_file_changes() -> bool: """Check if any library files have been changed using git diff""" - git_command = f"git diff --name-only --cached {DIR} ':!*_F.py'" + git_command = f"git diff --name-only --cached {DIR}" result = subprocess.run(git_command, shell=True, capture_output=True, text=True) changed_files = result.stdout.splitlines() logger.debug(f"Staged and changed library files: {changed_files}") + if any(re.match(r".*\/_F\.py", f) for f in changed_files): + logger.info("_F.py is staged, no need to regenerate") + return False + return bool(changed_files) From 4f2fa39bac26a53ee9ac29e7d4c0f4d75d2c50ea Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:46:49 +0200 Subject: [PATCH 57/63] Fix some more components - Add: ESP32C3: bootmode set function - Add: BH1750FVI dvi components - Fix: crystal osc load impedance - Fix: Quantity --- src/faebryk/library/BH1750FVI_TR.py | 9 +- src/faebryk/library/Crystal.py | 12 +- src/faebryk/library/Crystal_Oscillator.py | 8 +- src/faebryk/library/ESP32_C3.py | 17 +- .../ESP32_C3_MINI_1_Reference_Design.py | 21 ++- src/faebryk/library/HLK_LD2410B_P.py | 4 +- src/faebryk/library/PM1006.py | 1 - src/faebryk/library/SCD40.py | 4 +- src/faebryk/library/_F.py | 178 +++++++++--------- 9 files changed, 132 insertions(+), 122 deletions(-) diff --git a/src/faebryk/library/BH1750FVI_TR.py b/src/faebryk/library/BH1750FVI_TR.py index 894d1d00..5f723613 100644 --- a/src/faebryk/library/BH1750FVI_TR.py +++ b/src/faebryk/library/BH1750FVI_TR.py @@ -6,14 +6,14 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L -from faebryk.libs.units import P +from faebryk.libs.units import P, Quantity logger = logging.getLogger(__name__) class BH1750FVI_TR(Module): class _bh1750_esphome_config(F.has_esphome_config.impl()): - update_interval: F.TBD + update_interval: F.TBD[Quantity] def get_config(self) -> dict: val = self.update_interval.get_most_narrow() @@ -47,6 +47,7 @@ def get_config(self) -> dict: def set_address(self, addr: int): raise NotImplementedError() + # TODO: Implement set_address # ADDR = ‘H’ ( ADDR ≧ 0.7VCC ) “1011100“ # ADDR = 'L' ( ADDR ≦ 0.3VCC ) “0100011“ ... @@ -70,8 +71,10 @@ def __preinit__(self): # set constraints self.power.voltage.merge(F.Range(2.4 * P.V, 3.6 * P.V)) - self.power.decoupled.decouple().capacitance.merge(0.1 * P.uF) + self.power.decoupled.decouple().capacitance.merge(100 * P.nF) # TODO: self.dvi.low_pass(self.dvi_capacitor, self.dvi_resistor) + self.dvi.signal.connect_via(self.dvi_capacitor, self.power.lv) + self.dvi.signal.connect_via(self.dvi_resistor, self.power.hv) @L.rt_field def single_electric_reference(self): diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index 3a43b905..006a66db 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -11,7 +11,12 @@ class Crystal(Module): # ---------------------------------------- # modules, interfaces, parameters # ---------------------------------------- + gnd: F.Electrical + unnamed = L.list_field(2, F.Electrical) + # ---------------------------------------- + # parameters + # ---------------------------------------- frequency: F.TBD[Quantity] frequency_tolerance: F.TBD[F.Range] frequency_temperature_tolerance: F.TBD[F.Range] @@ -20,13 +25,6 @@ class Crystal(Module): shunt_capacitance: F.TBD[Quantity] load_impedance: F.TBD[Quantity] - gnd: F.Electrical - unnamed = L.list_field(2, F.Electrical) - - # ---------------------------------------- - # parameters - # ---------------------------------------- - # ---------------------------------------- # traits # ---------------------------------------- diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index 1a48b495..e1f9646b 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -7,7 +7,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L -from faebryk.libs.units import P, Quantity +from faebryk.libs.units import P class Crystal_Oscillator(Module): @@ -21,8 +21,6 @@ class Crystal_Oscillator(Module): p: F.Electrical n: F.Electrical - load_capacitance: F.TBD[Quantity] - # ---------------------------------------- # parameters # ---------------------------------------- @@ -32,14 +30,12 @@ class Crystal_Oscillator(Module): @L.rt_field def capacitance(self): - return (self.load_capacitance - copy(self._STRAY_CAPACITANCE)) * 2 + return (self.crystal.load_impedance - copy(self._STRAY_CAPACITANCE)) * 2 def __preinit__(self): for cap in self.capacitors: cap.capacitance.merge(self.capacitance) - self.load_capacitance.merge(self.crystal.load_impedance) - # ---------------------------------------- # traits # ---------------------------------------- diff --git a/src/faebryk/library/ESP32_C3.py b/src/faebryk/library/ESP32_C3.py index 3942495d..6f50f65c 100644 --- a/src/faebryk/library/ESP32_C3.py +++ b/src/faebryk/library/ESP32_C3.py @@ -85,13 +85,6 @@ def __preinit__(self): # ) self.enable.pulled.pull(up=True) # TODO: combine with lowpass filter - # set default boot mode to "SPI Boot mode" (gpio = N.C. or HIGH) - # https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf page 25 # noqa E501 - # TODO: make configurable - self.gpio[8].pulled.pull(up=True) # boot_resistors[0] - self.gpio[2].pulled.pull(up=True) # boot_resistors[1] - # TODO: gpio[9] has an internal pull-up at boot = SPI-Boot - # TODO: Fix this # # set mux states # # UART 1 @@ -216,3 +209,13 @@ def __preinit__(self): # i for i, g in enumerate(self.gpio) if g.signal == gpio # ][0] # return pin, gpio_index + + def set_default_boot_mode(self, default_boot_to_spi_flash: bool = True): + # set default boot mode to "SPI Boot mode" + # https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf page 26 # noqa E501 + # TODO: make configurable + self.gpio[8].pulled.pull(up=True).resistance.merge(10 * P.kohm) + self.gpio[2].pulled.pull(up=True).resistance.merge(10 * P.kohm) + # gpio[9] has an internal pull-up at boot = SPI-Boot + if not default_boot_to_spi_flash: + self.gpio[9].pulled.pull(up=False).resistance.merge(10 * P.kohm) diff --git a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py index bacbbc34..ea312996 100644 --- a/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py +++ b/src/faebryk/library/ESP32_C3_MINI_1_Reference_Design.py @@ -5,6 +5,7 @@ import faebryk.library._F as F from faebryk.core.module import Module +from faebryk.libs.units import P logger = logging.getLogger(__name__) @@ -30,18 +31,17 @@ def __preinit__(self): self.vdd3v3.connect(self.esp32_c3_mini_1.vdd3v3) # TODO: set default boot mode (GPIO[8] pull up with 10k resistor) + (GPIO[2] pull up with 10k resistor) # noqa: E501 + self.esp32_c3_mini_1.esp32_c3 # boot and enable switches # TODO: Fix bridging of (boot and reset) switches - # self.esp32_c3_mini_1.chip_enable.connect_via( - # self.boot_switch, gnd - # ) + self.esp32_c3_mini_1.chip_enable.signal.connect_via(self.boot_switch, gnd) # TODO: lowpass chip_enable - # self.gpio[9].connect_via(self.reset_switch, gnd) + self.esp32_c3_mini_1.gpio[9].signal.connect_via(self.reset_switch, gnd) # connect low speed crystal oscillator self.low_speed_crystal_clock.n.connect(self.esp32_c3_mini_1.gpio[0].signal) self.low_speed_crystal_clock.p.connect(self.esp32_c3_mini_1.gpio[1].signal) - self.low_speed_crystal_clock.power.lv.connect(gnd) + self.low_speed_crystal_clock.power.connect(self.vdd3v3) # TODO: set the following in the pinmux # jtag gpio 4,5,6,7 @@ -52,3 +52,14 @@ def __preinit__(self): # connect UART[0] self.uart.connect(self.esp32_c3_mini_1.esp32_c3.uart[0]) + + # default to SPI flash boot mode + self.esp32_c3_mini_1.esp32_c3.set_default_boot_mode() + + # ------------------------------------ + # parametrization + # ------------------------------------ + self.low_speed_crystal_clock.crystal.frequency.merge(32.768 * P.kHz) + self.low_speed_crystal_clock.crystal.frequency_tolerance.merge( + F.Range.lower_bound(20 * P.ppm) + ) diff --git a/src/faebryk/library/HLK_LD2410B_P.py b/src/faebryk/library/HLK_LD2410B_P.py index c8a3a361..7fb8c522 100644 --- a/src/faebryk/library/HLK_LD2410B_P.py +++ b/src/faebryk/library/HLK_LD2410B_P.py @@ -4,12 +4,12 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L -from faebryk.libs.units import P +from faebryk.libs.units import P, Quantity class HLK_LD2410B_P(Module): class _ld2410b_esphome_config(F.has_esphome_config.impl()): - throttle: F.TBD + throttle: F.TBD[Quantity] def get_config(self) -> dict: val = self.throttle.get_most_narrow() diff --git a/src/faebryk/library/PM1006.py b/src/faebryk/library/PM1006.py index df302730..df12656c 100644 --- a/src/faebryk/library/PM1006.py +++ b/src/faebryk/library/PM1006.py @@ -4,7 +4,6 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.parameter import Parameter from faebryk.libs.library import L from faebryk.libs.units import P diff --git a/src/faebryk/library/SCD40.py b/src/faebryk/library/SCD40.py index 5a3076a1..40f82456 100644 --- a/src/faebryk/library/SCD40.py +++ b/src/faebryk/library/SCD40.py @@ -5,7 +5,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.libs.library import L -from faebryk.libs.units import P +from faebryk.libs.units import P, Quantity class SCD40(Module): @@ -14,7 +14,7 @@ class SCD40(Module): """ class _scd4x_esphome_config(F.has_esphome_config.impl()): - update_interval: F.TBD + update_interval: F.TBD[Quantity] def get_config(self) -> dict: val = self.update_interval.get_most_narrow() diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index e741cc4b..b8e9a0eb 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,198 +15,198 @@ # flake8: noqa: I001 # flake8: noqa: E501 -from faebryk.library.has_footprint import has_footprint from faebryk.library.has_simple_value_representation import has_simple_value_representation -from faebryk.library.has_overriden_name import has_overriden_name from faebryk.library.has_descriptive_properties import has_descriptive_properties +from faebryk.library.has_overriden_name import has_overriden_name +from faebryk.library.has_footprint import has_footprint from faebryk.library.Constant import Constant from faebryk.library.Range import Range -from faebryk.library.has_pcb_position import has_pcb_position from faebryk.library.Operation import Operation from faebryk.library.TBD import TBD +from faebryk.library.has_pcb_position import has_pcb_position +from faebryk.library.has_picker import has_picker +from faebryk.library.has_footprint_requirement import has_footprint_requirement +from faebryk.library.has_single_electric_reference import has_single_electric_reference +from faebryk.library.has_pcb_layout import has_pcb_layout from faebryk.library.has_datasheet import has_datasheet +from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.has_single_electric_reference import has_single_electric_reference from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.has_pcb_layout import has_pcb_layout -from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.Power import Power -from faebryk.library.has_resistance import has_resistance -from faebryk.library.has_capacitance import has_capacitance -from faebryk.library.has_single_connection import has_single_connection from faebryk.library.has_designator import has_designator -from faebryk.library.has_linked_pad import has_linked_pad +from faebryk.library.has_single_connection import has_single_connection +from faebryk.library.has_designator_prefix import has_designator_prefix +from faebryk.library.has_resistance import has_resistance from faebryk.library.can_bridge import can_bridge -from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.has_footprint_requirement import has_footprint_requirement -from faebryk.library.has_picker import has_picker +from faebryk.library.has_linked_pad import has_linked_pad +from faebryk.library.has_kicad_ref import has_kicad_ref from faebryk.library.Mechanical import Mechanical from faebryk.library.is_representable_by_single_value import is_representable_by_single_value -from faebryk.library.has_kicad_ref import has_kicad_ref -from faebryk.library.Footprint import Footprint -from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined +from faebryk.library.has_capacitance import has_capacitance from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined +from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +from faebryk.library.Footprint import Footprint from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.Logic import Logic from faebryk.library.Set import Set -from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative -from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent +from faebryk.library.Logic import Logic from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY +from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative +from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent +from faebryk.library.has_pcb_position_defined import has_pcb_position_defined +from faebryk.library.has_multi_picker import has_multi_picker +from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined +from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined +from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined from faebryk.library.has_datasheet_defined import has_datasheet_defined +from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.has_single_connection_impl import has_single_connection_impl from faebryk.library.has_designator_defined import has_designator_defined -from faebryk.library.has_linked_pad_defined import has_linked_pad_defined +from faebryk.library.has_single_connection_impl import has_single_connection_impl +from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined -from faebryk.library.has_multi_picker import has_multi_picker +from faebryk.library.has_linked_pad_defined import has_linked_pad_defined from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined from faebryk.library.has_footprint_impl import has_footprint_impl from faebryk.library.can_attach_to_footprint import can_attach_to_footprint from faebryk.library.has_kicad_footprint import has_kicad_footprint from faebryk.library.LogicOps import LogicOps -from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic -from faebryk.library.SPI import SPI from faebryk.library.DifferentialPair import DifferentialPair +from faebryk.library.SPI import SPI +from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.PJ398SM import PJ398SM -from faebryk.library.Common_Mode_Filter import Common_Mode_Filter +from faebryk.library.Relay import Relay from faebryk.library.RJ45_Receptacle import RJ45_Receptacle -from faebryk.library.Crystal import Crystal from faebryk.library.Header import Header -from faebryk.library.Relay import Relay -from faebryk.library.Pad import Pad -from faebryk.library.GDT import GDT +from faebryk.library.PJ398SM import PJ398SM +from faebryk.library.Crystal import Crystal +from faebryk.library.Common_Mode_Filter import Common_Mode_Filter from faebryk.library.Button import Button +from faebryk.library.GDT import GDT +from faebryk.library.Pad import Pad from faebryk.library.has_footprint_defined import has_footprint_defined from faebryk.library.LogicGate import LogicGate -from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table from faebryk.library.RS485 import RS485 from faebryk.library.Ethernet import Ethernet -from faebryk.library.Net import Net +from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table from faebryk.library.has_equal_pins import has_equal_pins -from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist +from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint +from faebryk.library.Net import Net from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically from faebryk.library.LogicGates import LogicGates from faebryk.library.MOSFET import MOSFET from faebryk.library.Diode import Diode from faebryk.library.BJT import BJT -from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer -from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal -from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs +from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs from faebryk.library.KicadFootprint import KicadFootprint -from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF +from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer +from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual from faebryk.library.pf_533984002 import pf_533984002 from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin +from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF from faebryk.library.Fuse import Fuse +from faebryk.library.Inductor import Inductor from faebryk.library.Switch import Switch from faebryk.library.Resistor import Resistor -from faebryk.library.Inductor import Inductor from faebryk.library.Capacitor import Capacitor from faebryk.library.TVS import TVS -from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined +from faebryk.library.QFN import QFN from faebryk.library.DIP import DIP from faebryk.library.SMDTwoPin import SMDTwoPin -from faebryk.library.QFN import QFN from faebryk.library.SOIC import SOIC +from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined from faebryk.library.Mounting_Hole import Mounting_Hole from faebryk.library.Potentiometer import Potentiometer from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider from faebryk.library.is_decoupled import is_decoupled from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.can_be_surge_protected import can_be_surge_protected from faebryk.library.is_surge_protected import is_surge_protected +from faebryk.library.can_be_surge_protected import can_be_surge_protected from faebryk.library.is_decoupled_nodes import is_decoupled_nodes from faebryk.library.is_surge_protected_defined import is_surge_protected_defined from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.Comparator import Comparator -from faebryk.library.ElectricLogic import ElectricLogic -from faebryk.library.OpAmp import OpAmp from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection +from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N +from faebryk.library.Battery import Battery +from faebryk.library.Fan import Fan from faebryk.library.LED import LED -from faebryk.library.USB2_0_IF import USB2_0_IF from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin -from faebryk.library.Fan import Fan +from faebryk.library.ElectricLogic import ElectricLogic +from faebryk.library.Comparator import Comparator from faebryk.library.Crystal_Oscillator import Crystal_Oscillator -from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N -from faebryk.library.Battery import Battery -from faebryk.library.Sercom import Sercom +from faebryk.library.OpAmp import OpAmp +from faebryk.library.ButtonCell import ButtonCell +from faebryk.library.PoweredLED import PoweredLED from faebryk.library.SNx4LVC541A import SNx4LVC541A +from faebryk.library.RS232 import RS232 +from faebryk.library.SK9822_EC20 import SK9822_EC20 +from faebryk.library.USB2_0_IF import USB2_0_IF from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B -from faebryk.library.ElectricLogicGate import ElectricLogicGate from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 -from faebryk.library.LDO import LDO +from faebryk.library.SWD import SWD from faebryk.library.can_switch_power import can_switch_power -from faebryk.library.SK9822_EC20 import SK9822_EC20 -from faebryk.library.RS232 import RS232 -from faebryk.library.MultiSPI import MultiSPI -from faebryk.library.GenericBusProtection import GenericBusProtection -from faebryk.library.JTAG import JTAG from faebryk.library.I2C import I2C -from faebryk.library.SWD import SWD +from faebryk.library.ElectricLogicGate import ElectricLogicGate +from faebryk.library.LDO import LDO +from faebryk.library.Sercom import Sercom +from faebryk.library.GenericBusProtection import GenericBusProtection +from faebryk.library.MultiSPI import MultiSPI from faebryk.library.TXS0102DCUR import TXS0102DCUR +from faebryk.library.JTAG import JTAG from faebryk.library.UART_Base import UART_Base -from faebryk.library.PoweredLED import PoweredLED -from faebryk.library.USB2_0 import USB2_0 from faebryk.library.USB3_IF import USB3_IF -from faebryk.library.ButtonCell import ButtonCell -from faebryk.library.ElectricLogicGates import ElectricLogicGates -from faebryk.library.Logic74xx import Logic74xx +from faebryk.library.USB2_0 import USB2_0 +from faebryk.library.SWDConnector import SWDConnector from faebryk.library.can_switch_power_defined import can_switch_power_defined -from faebryk.library.SPIFlash import SPIFlash +from faebryk.library.USB2514B import USB2514B +from faebryk.library.QWIIC import QWIIC +from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP from faebryk.library.OLED_Module import OLED_Module -from faebryk.library.SCD40 import SCD40 -from faebryk.library.QWIIC_Connector import QWIIC_Connector from faebryk.library.BH1750FVI_TR import BH1750FVI_TR from faebryk.library.EEPROM import EEPROM -from faebryk.library.QWIIC import QWIIC -from faebryk.library.USB2514B import USB2514B -from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP -from faebryk.library.SWDConnector import SWDConnector +from faebryk.library.QWIIC_Connector import QWIIC_Connector +from faebryk.library.SCD40 import SCD40 +from faebryk.library.Logic74xx import Logic74xx +from faebryk.library.ElectricLogicGates import ElectricLogicGates +from faebryk.library.SPIFlash import SPIFlash from faebryk.library.UART import UART from faebryk.library.UART_RS485 import UART_RS485 +from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P from faebryk.library.TD541S485H import TD541S485H from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART -from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P from faebryk.library.PM1006 import PM1006 +from faebryk.library.USB3 import USB3 +from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical +from faebryk.library.RP2040 import RP2040 +from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection +from faebryk.library.MCP2221A import MCP2221A from faebryk.library.USBLC6_2P6 import USBLC6_2P6 -from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG from faebryk.library.ESP32_C3 import ESP32_C3 -from faebryk.library.RP2040 import RP2040 -from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical -from faebryk.library.MCP2221A import MCP2221A -from faebryk.library.USB3 import USB3 -from faebryk.library.CD4011 import CD4011 from faebryk.library.PowerSwitch import PowerSwitch +from faebryk.library.CD4011 import CD4011 from faebryk.library.CH340x import CH340x -from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design -from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 -from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design -from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical from faebryk.library.USB_C import USB_C from faebryk.library.USB3_connector import USB3_connector -from faebryk.library.TI_CD4011BE import TI_CD4011BE +from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design +from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design +from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical +from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 from faebryk.library.PowerSwitchStatic import PowerSwitchStatic from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET +from faebryk.library.TI_CD4011BE import TI_CD4011BE from faebryk.library.USB_RS485 import USB_RS485 -from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU +from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design from faebryk.library.LEDIndicator import LEDIndicator from faebryk.library.Powered_Relay import Powered_Relay From 221dab21d03e7e6fa335e32b2dc015b6d9a610c5 Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 15:32:10 +0200 Subject: [PATCH 58/63] Add: IsPowerSource Add: LinkIsolatedReference --- src/faebryk/library/Crystal.py | 2 +- src/faebryk/library/Crystal_Oscillator.py | 4 +- src/faebryk/library/ElectricLogic.py | 8 ++++ src/faebryk/library/LDO.py | 2 +- src/faebryk/library/Power.py | 16 ++++++- src/faebryk/library/_F.py | 14 +++---- test/core/test_hierarchy_connect.py | 51 +++++++++++++++++++++++ 7 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/faebryk/library/Crystal.py b/src/faebryk/library/Crystal.py index 006a66db..07b66107 100644 --- a/src/faebryk/library/Crystal.py +++ b/src/faebryk/library/Crystal.py @@ -23,7 +23,7 @@ class Crystal(Module): frequency_ageing: F.TBD[F.Range] equivalent_series_resistance: F.TBD[Quantity] shunt_capacitance: F.TBD[Quantity] - load_impedance: F.TBD[Quantity] + load_capacitance: F.TBD[Quantity] # ---------------------------------------- # traits diff --git a/src/faebryk/library/Crystal_Oscillator.py b/src/faebryk/library/Crystal_Oscillator.py index e1f9646b..8571f20c 100644 --- a/src/faebryk/library/Crystal_Oscillator.py +++ b/src/faebryk/library/Crystal_Oscillator.py @@ -26,11 +26,11 @@ class Crystal_Oscillator(Module): # ---------------------------------------- # https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ # http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00221665.pdf - _STRAY_CAPACITANCE = F.Range(1 * P.nF, 5 * P.nF) + _STRAY_CAPACITANCE = F.Range(1 * P.pF, 5 * P.pF) @L.rt_field def capacitance(self): - return (self.crystal.load_impedance - copy(self._STRAY_CAPACITANCE)) * 2 + return (self.crystal.load_capacitance - copy(self._STRAY_CAPACITANCE)) * 2 def __preinit__(self): for cap in self.capacitors: diff --git a/src/faebryk/library/ElectricLogic.py b/src/faebryk/library/ElectricLogic.py index 5e573ea6..759e7a82 100644 --- a/src/faebryk/library/ElectricLogic.py +++ b/src/faebryk/library/ElectricLogic.py @@ -6,6 +6,8 @@ from typing import Iterable, Self import faebryk.library._F as F +from faebryk.core.graphinterface import GraphInterface +from faebryk.core.link import LinkFilteredException, _TLinkDirectShallow from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface from faebryk.core.node import Node @@ -61,6 +63,12 @@ def pull(self, up: bool): obj.add_trait(ElectricLogic.has_pulls_defined(up_r, down_r)) return resistor + class LinkIsolatedReference(_TLinkDirectShallow): + def __init__(self, interfaces: list[GraphInterface]) -> None: + if any(isinstance(gif.node, F.ElectricPower) for gif in interfaces): + raise LinkFilteredException("All nodes are ElectricPower") + super().__init__(interfaces) + # class can_be_buffered(Trait): # @abstractmethod # def buffer(self): diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index eb1d046b..bd5c10ec 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -29,7 +29,7 @@ class OutputPolarity(Enum): enable: F.ElectricLogic power_in: F.ElectricPower - power_out: F.ElectricPower + power_out = L.d_field(lambda: F.ElectricPower().make_source()) def __preinit__(self): self.power_in.voltage.merge(self.max_input_voltage) diff --git a/src/faebryk/library/Power.py b/src/faebryk/library/Power.py index dc973407..02474593 100644 --- a/src/faebryk/library/Power.py +++ b/src/faebryk/library/Power.py @@ -4,4 +4,18 @@ from faebryk.core.moduleinterface import ModuleInterface -class Power(ModuleInterface): ... +class Power(ModuleInterface): + class PowerSourcesShortedError(Exception): ... + + class IsPowerSource(ModuleInterface.TraitT): ... + + class IsPowerSourceDefined(IsPowerSource.impl()): ... + + def make_source(self): + self.add(self.IsPowerSourceDefined()) + return self + + def _on_connect(self, other: "Power"): + print(f"Power._on_connect({self}, {other})") # TODO remove + if self.has_trait(self.IsPowerSource) and other.has_trait(self.IsPowerSource): + raise self.PowerSourcesShortedError(self, other) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index b8e9a0eb..1947cc37 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,12 +15,12 @@ # flake8: noqa: I001 # flake8: noqa: E501 +from faebryk.library.has_footprint import has_footprint from faebryk.library.has_simple_value_representation import has_simple_value_representation from faebryk.library.has_descriptive_properties import has_descriptive_properties from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.has_footprint import has_footprint -from faebryk.library.Constant import Constant from faebryk.library.Range import Range +from faebryk.library.Constant import Constant from faebryk.library.Operation import Operation from faebryk.library.TBD import TBD from faebryk.library.has_pcb_position import has_pcb_position @@ -30,8 +30,8 @@ from faebryk.library.has_pcb_layout import has_pcb_layout from faebryk.library.has_datasheet import has_datasheet from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.has_esphome_config import has_esphome_config from faebryk.library.is_esphome_bus import is_esphome_bus +from faebryk.library.has_esphome_config import has_esphome_config from faebryk.library.Power import Power from faebryk.library.has_designator import has_designator from faebryk.library.has_single_connection import has_single_connection @@ -43,14 +43,14 @@ from faebryk.library.Mechanical import Mechanical from faebryk.library.is_representable_by_single_value import is_representable_by_single_value from faebryk.library.has_capacitance import has_capacitance +from faebryk.library.Footprint import Footprint from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined from faebryk.library.has_overriden_name_defined import has_overriden_name_defined -from faebryk.library.Footprint import Footprint -from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.Set import Set from faebryk.library.Logic import Logic +from faebryk.library.Set import Set +from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param from faebryk.library.Electrical import Electrical from faebryk.library.ANY import ANY from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative @@ -62,8 +62,8 @@ from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -from faebryk.library.has_esphome_config_defined import has_esphome_config_defined from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined +from faebryk.library.has_esphome_config_defined import has_esphome_config_defined from faebryk.library.has_designator_defined import has_designator_defined from faebryk.library.has_single_connection_impl import has_single_connection_impl from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined diff --git a/test/core/test_hierarchy_connect.py b/test/core/test_hierarchy_connect.py index 4784b0bb..3df37346 100644 --- a/test/core/test_hierarchy_connect.py +++ b/test/core/test_hierarchy_connect.py @@ -231,6 +231,57 @@ class _Link(LinkDirectShallow(lambda link, gif: True)): ... self.assertIsInstance(mifs_special[0].is_connected_to(mifs_special[2]), _Link) + def test_isolated_connect(self): + x1 = F.ElectricLogic() + x2 = F.ElectricLogic() + x1.connect(x2, linkcls=F.ElectricLogic.LinkIsolatedReference) + self.assertIsInstance( + x1.is_connected_to(x2), F.ElectricLogic.LinkIsolatedReference + ) + + self.assertIsInstance( + x1.signal.is_connected_to(x2.signal), + F.ElectricLogic.LinkIsolatedReference, + ) + + self.assertIsNone(x1.reference.is_connected_to(x2.reference)) + + self.assertIsNone(x1.reference.hv.is_connected_to(x2.reference.hv)) + + y1 = F.ElectricPower() + y2 = F.ElectricPower() + + y1.make_source() + y2.make_source() + + with self.assertRaises(F.Power.PowerSourcesShortedError): + y1.connect(y2) + + ldo1 = F.LDO() + ldo2 = F.LDO() + + with self.assertRaises(F.Power.PowerSourcesShortedError): + ldo1.power_out.connect(ldo2.power_out) + + a1 = F.I2C() + b1 = F.I2C() + + a1.connect(b1, linkcls=F.ElectricLogic.LinkIsolatedReference) + self.assertIsInstance( + a1.is_connected_to(b1), F.ElectricLogic.LinkIsolatedReference + ) + self.assertIsInstance( + a1.scl.signal.is_connected_to(b1.scl.signal), + F.ElectricLogic.LinkIsolatedReference, + ) + self.assertIsInstance( + a1.sda.signal.is_connected_to(b1.sda.signal), + F.ElectricLogic.LinkIsolatedReference, + ) + + self.assertIsNone(a1.scl.reference.is_connected_to(b1.scl.reference)) + self.assertIsNone(a1.sda.reference.is_connected_to(b1.sda.reference)) + if __name__ == "__main__": unittest.main() From 4f7f37340aa7139d394ef19c3c067c110b904c1c Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 30 Aug 2024 16:00:12 +0200 Subject: [PATCH 59/63] gen_F deterministc, fix ldo subclass --- src/faebryk/library/ME6211C33M5G_N.py | 23 +-- src/faebryk/library/Power.py | 11 +- src/faebryk/library/_F.py | 240 +++++++++++++------------- tools/library/gen_F.py | 26 +-- 4 files changed, 135 insertions(+), 165 deletions(-) diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index 679077af..2ed6eb25 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -2,22 +2,15 @@ # SPDX-License-Identifier: MIT import faebryk.library._F as F -from faebryk.core.module import Module from faebryk.libs.library import L from faebryk.libs.units import P -class ME6211C33M5G_N(Module): +class ME6211C33M5G_N(F.LDO): """ 3.3V 600mA LDO """ - # interfaces - - power_in: F.ElectricPower - power_out: F.ElectricPower - enable: F.Electrical - # components def __init__(self, default_enabled: bool = True) -> None: @@ -25,22 +18,16 @@ def __init__(self, default_enabled: bool = True) -> None: self._default_enabled = default_enabled def __preinit__(self): - from faebryk.core.util import connect_to_all_interfaces - # set constraints self.power_out.voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) - # connect decouple capacitor - self.power_in.decoupled.decouple() - self.power_out.decoupled.decouple() - # LDO in & out share gnd reference - self.power_in.lv.connect(self.power_out.lv) + F.ElectricLogic.connect_all_node_references( + [self.power_in, self.power_out], gnd_only=True + ) if self._default_enabled: - self.enable.connect(self.power_in.hv) - - connect_to_all_interfaces(self.power_in.lv, [self.power_out.lv]) + self.enable.set(True) designator_prefix = L.f_field(F.has_designator_prefix_defined)("U") diff --git a/src/faebryk/library/Power.py b/src/faebryk/library/Power.py index 02474593..abf48d0a 100644 --- a/src/faebryk/library/Power.py +++ b/src/faebryk/library/Power.py @@ -7,15 +7,16 @@ class Power(ModuleInterface): class PowerSourcesShortedError(Exception): ... - class IsPowerSource(ModuleInterface.TraitT): ... + class is_power_source(ModuleInterface.TraitT): ... - class IsPowerSourceDefined(IsPowerSource.impl()): ... + class is_power_source_defined(is_power_source.impl()): ... def make_source(self): - self.add(self.IsPowerSourceDefined()) + self.add(self.is_power_source_defined()) return self def _on_connect(self, other: "Power"): - print(f"Power._on_connect({self}, {other})") # TODO remove - if self.has_trait(self.IsPowerSource) and other.has_trait(self.IsPowerSource): + if self.has_trait(self.is_power_source) and other.has_trait( + self.is_power_source + ): raise self.PowerSourcesShortedError(self, other) diff --git a/src/faebryk/library/_F.py b/src/faebryk/library/_F.py index 1947cc37..e2727a32 100644 --- a/src/faebryk/library/_F.py +++ b/src/faebryk/library/_F.py @@ -15,198 +15,198 @@ # flake8: noqa: I001 # flake8: noqa: E501 +from faebryk.library.TBD import TBD +from faebryk.library.Constant import Constant +from faebryk.library.Range import Range +from faebryk.library.has_esphome_config import has_esphome_config +from faebryk.library.is_esphome_bus import is_esphome_bus +from faebryk.library.has_single_electric_reference import has_single_electric_reference +from faebryk.library.Power import Power from faebryk.library.has_footprint import has_footprint -from faebryk.library.has_simple_value_representation import has_simple_value_representation -from faebryk.library.has_descriptive_properties import has_descriptive_properties +from faebryk.library.Mechanical import Mechanical from faebryk.library.has_overriden_name import has_overriden_name -from faebryk.library.Range import Range -from faebryk.library.Constant import Constant from faebryk.library.Operation import Operation -from faebryk.library.TBD import TBD +from faebryk.library.has_linked_pad import has_linked_pad from faebryk.library.has_pcb_position import has_pcb_position -from faebryk.library.has_picker import has_picker +from faebryk.library.can_bridge import can_bridge +from faebryk.library.has_designator import has_designator +from faebryk.library.has_designator_prefix import has_designator_prefix +from faebryk.library.has_descriptive_properties import has_descriptive_properties +from faebryk.library.has_simple_value_representation import has_simple_value_representation +from faebryk.library.has_capacitance import has_capacitance +from faebryk.library.has_datasheet import has_datasheet from faebryk.library.has_footprint_requirement import has_footprint_requirement -from faebryk.library.has_single_electric_reference import has_single_electric_reference +from faebryk.library.has_kicad_ref import has_kicad_ref +from faebryk.library.has_picker import has_picker from faebryk.library.has_pcb_layout import has_pcb_layout -from faebryk.library.has_datasheet import has_datasheet from faebryk.library.has_pcb_routing_strategy import has_pcb_routing_strategy -from faebryk.library.is_esphome_bus import is_esphome_bus -from faebryk.library.has_esphome_config import has_esphome_config -from faebryk.library.Power import Power -from faebryk.library.has_designator import has_designator -from faebryk.library.has_single_connection import has_single_connection -from faebryk.library.has_designator_prefix import has_designator_prefix from faebryk.library.has_resistance import has_resistance -from faebryk.library.can_bridge import can_bridge -from faebryk.library.has_linked_pad import has_linked_pad -from faebryk.library.has_kicad_ref import has_kicad_ref -from faebryk.library.Mechanical import Mechanical +from faebryk.library.has_single_connection import has_single_connection from faebryk.library.is_representable_by_single_value import is_representable_by_single_value -from faebryk.library.has_capacitance import has_capacitance -from faebryk.library.Footprint import Footprint -from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params -from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined -from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined -from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +from faebryk.library.ANY import ANY +from faebryk.library.Electrical import Electrical from faebryk.library.Logic import Logic from faebryk.library.Set import Set -from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param -from faebryk.library.Electrical import Electrical -from faebryk.library.ANY import ANY +from faebryk.library.has_esphome_config_defined import has_esphome_config_defined +from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined +from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined +from faebryk.library.Footprint import Footprint +from faebryk.library.has_overriden_name_defined import has_overriden_name_defined +from faebryk.library.has_linked_pad_defined import has_linked_pad_defined +from faebryk.library.has_pcb_position_defined import has_pcb_position_defined from faebryk.library.has_pcb_position_defined_relative import has_pcb_position_defined_relative from faebryk.library.has_pcb_position_defined_relative_to_parent import has_pcb_position_defined_relative_to_parent -from faebryk.library.has_pcb_position_defined import has_pcb_position_defined -from faebryk.library.has_multi_picker import has_multi_picker +from faebryk.library.can_bridge_defined import can_bridge_defined +from faebryk.library.has_designator_defined import has_designator_defined +from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined +from faebryk.library.has_descriptive_properties_defined import has_descriptive_properties_defined +from faebryk.library.has_simple_value_representation_based_on_param import has_simple_value_representation_based_on_param +from faebryk.library.has_simple_value_representation_based_on_params import has_simple_value_representation_based_on_params +from faebryk.library.has_simple_value_representation_defined import has_simple_value_representation_defined +from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_footprint_requirement_defined import has_footprint_requirement_defined -from faebryk.library.has_single_electric_reference_defined import has_single_electric_reference_defined +from faebryk.library.has_multi_picker import has_multi_picker from faebryk.library.has_pcb_layout_defined import has_pcb_layout_defined -from faebryk.library.has_datasheet_defined import has_datasheet_defined from faebryk.library.has_pcb_routing_strategy_greedy_direct_line import has_pcb_routing_strategy_greedy_direct_line -from faebryk.library.is_esphome_bus_defined import is_esphome_bus_defined -from faebryk.library.has_esphome_config_defined import has_esphome_config_defined -from faebryk.library.has_designator_defined import has_designator_defined from faebryk.library.has_single_connection_impl import has_single_connection_impl -from faebryk.library.has_designator_prefix_defined import has_designator_prefix_defined -from faebryk.library.can_bridge_defined import can_bridge_defined -from faebryk.library.has_linked_pad_defined import has_linked_pad_defined from faebryk.library.is_representable_by_single_value_defined import is_representable_by_single_value_defined -from faebryk.library.has_footprint_impl import has_footprint_impl -from faebryk.library.can_attach_to_footprint import can_attach_to_footprint -from faebryk.library.has_kicad_footprint import has_kicad_footprint -from faebryk.library.LogicOps import LogicOps from faebryk.library.DifferentialPair import DifferentialPair from faebryk.library.SPI import SPI from faebryk.library.has_pin_association_heuristic import has_pin_association_heuristic +from faebryk.library.LogicOps import LogicOps +from faebryk.library.can_attach_to_footprint import can_attach_to_footprint from faebryk.library.can_attach_via_pinmap import can_attach_via_pinmap -from faebryk.library.Relay import Relay -from faebryk.library.RJ45_Receptacle import RJ45_Receptacle -from faebryk.library.Header import Header -from faebryk.library.PJ398SM import PJ398SM -from faebryk.library.Crystal import Crystal -from faebryk.library.Common_Mode_Filter import Common_Mode_Filter +from faebryk.library.has_footprint_impl import has_footprint_impl +from faebryk.library.has_kicad_footprint import has_kicad_footprint +from faebryk.library.Pad import Pad from faebryk.library.Button import Button +from faebryk.library.Common_Mode_Filter import Common_Mode_Filter +from faebryk.library.Crystal import Crystal from faebryk.library.GDT import GDT -from faebryk.library.Pad import Pad -from faebryk.library.has_footprint_defined import has_footprint_defined -from faebryk.library.LogicGate import LogicGate -from faebryk.library.RS485 import RS485 +from faebryk.library.Header import Header +from faebryk.library.PJ398SM import PJ398SM +from faebryk.library.RJ45_Receptacle import RJ45_Receptacle +from faebryk.library.Relay import Relay from faebryk.library.Ethernet import Ethernet +from faebryk.library.RS485 import RS485 from faebryk.library.has_pin_association_heuristic_lookup_table import has_pin_association_heuristic_lookup_table -from faebryk.library.has_equal_pins import has_equal_pins +from faebryk.library.LogicGate import LogicGate +from faebryk.library.has_footprint_defined import has_footprint_defined +from faebryk.library.Net import Net from faebryk.library.can_attach_via_pinmap_pinlist import can_attach_via_pinmap_pinlist +from faebryk.library.has_equal_pins import has_equal_pins from faebryk.library.has_kicad_manual_footprint import has_kicad_manual_footprint -from faebryk.library.Net import Net -from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap -from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically -from faebryk.library.LogicGates import LogicGates -from faebryk.library.MOSFET import MOSFET -from faebryk.library.Diode import Diode from faebryk.library.BJT import BJT +from faebryk.library.Diode import Diode +from faebryk.library.MOSFET import MOSFET +from faebryk.library.LogicGates import LogicGates +from faebryk.library.can_attach_to_footprint_symmetrically import can_attach_to_footprint_symmetrically +from faebryk.library.can_attach_to_footprint_via_pinmap import can_attach_to_footprint_via_pinmap +from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual +from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer from faebryk.library.can_attach_via_pinmap_equal import can_attach_via_pinmap_equal from faebryk.library.has_equal_pins_in_ifs import has_equal_pins_in_ifs from faebryk.library.has_kicad_footprint_equal_ifs import has_kicad_footprint_equal_ifs from faebryk.library.KicadFootprint import KicadFootprint -from faebryk.library.has_pcb_routing_strategy_via_to_layer import has_pcb_routing_strategy_via_to_layer -from faebryk.library.has_pcb_routing_strategy_manual import has_pcb_routing_strategy_manual -from faebryk.library.pf_533984002 import pf_533984002 -from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin -from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF +from faebryk.library.TVS import TVS +from faebryk.library.Capacitor import Capacitor from faebryk.library.Fuse import Fuse from faebryk.library.Inductor import Inductor -from faebryk.library.Switch import Switch from faebryk.library.Resistor import Resistor -from faebryk.library.Capacitor import Capacitor -from faebryk.library.TVS import TVS -from faebryk.library.QFN import QFN +from faebryk.library.Switch import Switch +from faebryk.library.B4B_ZR_SM4_TF import B4B_ZR_SM4_TF +from faebryk.library.USB_Type_C_Receptacle_24_pin import USB_Type_C_Receptacle_24_pin +from faebryk.library.pf_533984002 import pf_533984002 from faebryk.library.DIP import DIP +from faebryk.library.QFN import QFN from faebryk.library.SMDTwoPin import SMDTwoPin from faebryk.library.SOIC import SOIC from faebryk.library.has_kicad_footprint_equal_ifs_defined import has_kicad_footprint_equal_ifs_defined from faebryk.library.Mounting_Hole import Mounting_Hole +from faebryk.library.can_be_surge_protected import can_be_surge_protected +from faebryk.library.is_surge_protected import is_surge_protected +from faebryk.library.can_be_decoupled import can_be_decoupled +from faebryk.library.is_decoupled import is_decoupled from faebryk.library.Potentiometer import Potentiometer from faebryk.library.Resistor_Voltage_Divider import Resistor_Voltage_Divider -from faebryk.library.is_decoupled import is_decoupled -from faebryk.library.can_be_decoupled import can_be_decoupled -from faebryk.library.is_surge_protected import is_surge_protected -from faebryk.library.can_be_surge_protected import can_be_surge_protected -from faebryk.library.is_decoupled_nodes import is_decoupled_nodes from faebryk.library.is_surge_protected_defined import is_surge_protected_defined -from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined +from faebryk.library.is_decoupled_nodes import is_decoupled_nodes from faebryk.library.can_be_surge_protected_defined import can_be_surge_protected_defined +from faebryk.library.can_be_decoupled_defined import can_be_decoupled_defined from faebryk.library.ElectricPower import ElectricPower -from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection -from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N from faebryk.library.Battery import Battery -from faebryk.library.Fan import Fan -from faebryk.library.LED import LED -from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin -from faebryk.library.ElectricLogic import ElectricLogic from faebryk.library.Comparator import Comparator from faebryk.library.Crystal_Oscillator import Crystal_Oscillator +from faebryk.library.ElectricLogic import ElectricLogic +from faebryk.library.Fan import Fan +from faebryk.library.LED import LED from faebryk.library.OpAmp import OpAmp +from faebryk.library.RS485_Bus_Protection import RS485_Bus_Protection +from faebryk.library.USB_Type_C_Receptacle_16_pin import USB_Type_C_Receptacle_16_pin from faebryk.library.ButtonCell import ButtonCell -from faebryk.library.PoweredLED import PoweredLED -from faebryk.library.SNx4LVC541A import SNx4LVC541A +from faebryk.library.ElectricLogicGate import ElectricLogicGate +from faebryk.library.GenericBusProtection import GenericBusProtection +from faebryk.library.I2C import I2C +from faebryk.library.JTAG import JTAG +from faebryk.library.LDO import LDO +from faebryk.library.MultiSPI import MultiSPI from faebryk.library.RS232 import RS232 from faebryk.library.SK9822_EC20 import SK9822_EC20 -from faebryk.library.USB2_0_IF import USB2_0_IF -from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B -from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 +from faebryk.library.SNx4LVC541A import SNx4LVC541A from faebryk.library.SWD import SWD -from faebryk.library.can_switch_power import can_switch_power -from faebryk.library.I2C import I2C -from faebryk.library.ElectricLogicGate import ElectricLogicGate -from faebryk.library.LDO import LDO from faebryk.library.Sercom import Sercom -from faebryk.library.GenericBusProtection import GenericBusProtection -from faebryk.library.MultiSPI import MultiSPI from faebryk.library.TXS0102DCUR import TXS0102DCUR -from faebryk.library.JTAG import JTAG from faebryk.library.UART_Base import UART_Base -from faebryk.library.USB3_IF import USB3_IF -from faebryk.library.USB2_0 import USB2_0 -from faebryk.library.SWDConnector import SWDConnector -from faebryk.library.can_switch_power_defined import can_switch_power_defined -from faebryk.library.USB2514B import USB2514B -from faebryk.library.QWIIC import QWIIC -from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP -from faebryk.library.OLED_Module import OLED_Module +from faebryk.library.USB2_0_IF import USB2_0_IF +from faebryk.library.XL_3528RGBW_WS2812B import XL_3528RGBW_WS2812B +from faebryk.library.can_switch_power import can_switch_power +from faebryk.library.pf_74AHCT2G125 import pf_74AHCT2G125 +from faebryk.library.PoweredLED import PoweredLED +from faebryk.library.ElectricLogicGates import ElectricLogicGates +from faebryk.library.Logic74xx import Logic74xx from faebryk.library.BH1750FVI_TR import BH1750FVI_TR from faebryk.library.EEPROM import EEPROM +from faebryk.library.M24C08_FMN6TP import M24C08_FMN6TP +from faebryk.library.OLED_Module import OLED_Module +from faebryk.library.QWIIC import QWIIC from faebryk.library.QWIIC_Connector import QWIIC_Connector from faebryk.library.SCD40 import SCD40 -from faebryk.library.Logic74xx import Logic74xx -from faebryk.library.ElectricLogicGates import ElectricLogicGates +from faebryk.library.USB2514B import USB2514B +from faebryk.library.ME6211C33M5G_N import ME6211C33M5G_N from faebryk.library.SPIFlash import SPIFlash -from faebryk.library.UART import UART -from faebryk.library.UART_RS485 import UART_RS485 +from faebryk.library.SWDConnector import SWDConnector from faebryk.library.HLK_LD2410B_P import HLK_LD2410B_P +from faebryk.library.PM1006 import PM1006 from faebryk.library.TD541S485H import TD541S485H from faebryk.library.TXS0102DCUR_UART import TXS0102DCUR_UART -from faebryk.library.PM1006 import PM1006 -from faebryk.library.USB3 import USB3 -from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical -from faebryk.library.RP2040 import RP2040 +from faebryk.library.UART import UART +from faebryk.library.UART_RS485 import UART_RS485 +from faebryk.library.USB2_0 import USB2_0 +from faebryk.library.USB3_IF import USB3_IF +from faebryk.library.can_switch_power_defined import can_switch_power_defined +from faebryk.library.CD4011 import CD4011 from faebryk.library.CBM9002A_56ILG import CBM9002A_56ILG -from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection +from faebryk.library.CH340x import CH340x +from faebryk.library.ESP32_C3 import ESP32_C3 from faebryk.library.MCP2221A import MCP2221A +from faebryk.library.RP2040 import RP2040 +from faebryk.library.USB2_0_ESD_Protection import USB2_0_ESD_Protection from faebryk.library.USBLC6_2P6 import USBLC6_2P6 -from faebryk.library.ESP32_C3 import ESP32_C3 +from faebryk.library.USB_Type_C_Receptacle_14_pin_Vertical import USB_Type_C_Receptacle_14_pin_Vertical +from faebryk.library.USB3 import USB3 from faebryk.library.PowerSwitch import PowerSwitch -from faebryk.library.CD4011 import CD4011 -from faebryk.library.CH340x import CH340x -from faebryk.library.USB_C import USB_C -from faebryk.library.USB3_connector import USB3_connector -from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design +from faebryk.library.TI_CD4011BE import TI_CD4011BE from faebryk.library.CBM9002A_56ILG_Reference_Design import CBM9002A_56ILG_Reference_Design -from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical +from faebryk.library.USB_RS485 import USB_RS485 from faebryk.library.ESP32_C3_MINI_1 import ESP32_C3_MINI_1 -from faebryk.library.PowerSwitchStatic import PowerSwitchStatic +from faebryk.library.RP2040_Reference_Design import RP2040_Reference_Design +from faebryk.library.USB_C_PSU_Vertical import USB_C_PSU_Vertical +from faebryk.library.USB3_connector import USB3_connector +from faebryk.library.USB_C import USB_C from faebryk.library.PowerSwitchMOSFET import PowerSwitchMOSFET -from faebryk.library.TI_CD4011BE import TI_CD4011BE -from faebryk.library.USB_RS485 import USB_RS485 -from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly -from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU +from faebryk.library.PowerSwitchStatic import PowerSwitchStatic from faebryk.library.ESP32_C3_MINI_1_Reference_Design import ESP32_C3_MINI_1_Reference_Design +from faebryk.library.USB_C_5V_PSU import USB_C_5V_PSU +from faebryk.library.USB_C_PowerOnly import USB_C_PowerOnly from faebryk.library.LEDIndicator import LEDIndicator from faebryk.library.Powered_Relay import Powered_Relay diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index fb5e39a8..ba8cc994 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -17,21 +17,6 @@ OUT = DIR / "_F.py" -def check_for_file_changes() -> bool: - """Check if any library files have been changed using git diff""" - git_command = f"git diff --name-only --cached {DIR}" - - result = subprocess.run(git_command, shell=True, capture_output=True, text=True) - changed_files = result.stdout.splitlines() - logger.debug(f"Staged and changed library files: {changed_files}") - - if any(re.match(r".*\/_F\.py", f) for f in changed_files): - logger.info("_F.py is staged, no need to regenerate") - return False - - return bool(changed_files) - - def try_(stmt: str, exc: str | type[Exception] | Iterable[type[Exception]]): if isinstance(exc, type): exc = exc.__name__ @@ -65,8 +50,10 @@ def find_deps(module_path: Path) -> set[str]: topo_graph = { module_name: find_deps(module_path) for module_name, module_path in all_modules } - # for k, v in topo_graph.items(): - # print(k, v) + topo_graph = { + k: list(sorted(v)) + for k, v in sorted(topo_graph.items(), key=lambda item: item[0]) + } order = list(TopologicalSorter(topo_graph).static_order()) # TEST @@ -95,11 +82,6 @@ def main(): logger.info(f"Found {len(module_files)} modules") - if not check_for_file_changes(): - logger.info("No changes in staged files detected, exiting") - return - logger.info("Changes detected, regenerating _F.py") - modules_out: dict[str, tuple[Path, str]] = {} # Import each module and add its class to the current namespace From 46e9c83bdd05f7a623e2e36e6da58ce63c9171d9 Mon Sep 17 00:00:00 2001 From: iopapamanoglou Date: Fri, 30 Aug 2024 16:01:33 +0200 Subject: [PATCH 60/63] ruff --- src/faebryk/tools/refactor.py | 3 +-- tools/library/gen_F.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/faebryk/tools/refactor.py b/src/faebryk/tools/refactor.py index b5741377..c27af925 100644 --- a/src/faebryk/tools/refactor.py +++ b/src/faebryk/tools/refactor.py @@ -1,7 +1,6 @@ # This file is part of the faebryk project # SPDX-License-Identifier: MIT -from lib2to3 import refactor import re import subprocess from dataclasses import dataclass @@ -100,7 +99,7 @@ def fabll(ctx: typer.Context, root: Path): types = r"(?:IF|NODE|PARAM)" ano_class = rf"class _{types}s\(" - detection_pattern = re.compile(ano_class) + # detection_pattern = re.compile(ano_class) refactor_files = file_paths # refactor_files = [ diff --git a/tools/library/gen_F.py b/tools/library/gen_F.py index ba8cc994..77e08db0 100755 --- a/tools/library/gen_F.py +++ b/tools/library/gen_F.py @@ -6,7 +6,6 @@ import logging import re -import subprocess from graphlib import TopologicalSorter from pathlib import Path from typing import Iterable From 1915403fc601e4a59ed7e1abefcd95bdd21e52ac Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 23:23:44 +0200 Subject: [PATCH 61/63] Update: dependencies --- poetry.lock | 470 ++++++++++++++++++++++++++++++++----------------- pyproject.toml | 2 + 2 files changed, 308 insertions(+), 164 deletions(-) diff --git a/poetry.lock b/poetry.lock index 94ab7fe3..763050b6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -82,13 +82,13 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -228,66 +228,87 @@ files = [ [[package]] name = "contourpy" -version = "1.2.1" +version = "1.3.0" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false python-versions = ">=3.9" files = [ - {file = "contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040"}, - {file = "contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da"}, - {file = "contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd"}, - {file = "contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619"}, - {file = "contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8"}, - {file = "contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5"}, - {file = "contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2"}, - {file = "contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205"}, - {file = "contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8"}, - {file = "contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec"}, - {file = "contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc"}, - {file = "contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0"}, - {file = "contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce"}, - {file = "contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4"}, - {file = "contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f"}, - {file = "contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bb6834cbd983b19f06908b45bfc2dad6ac9479ae04abe923a275b5f48f1a186b"}, - {file = "contourpy-1.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1d59e739ab0e3520e62a26c60707cc3ab0365d2f8fecea74bfe4de72dc56388f"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd3db01f59fdcbce5b22afad19e390260d6d0222f35a1023d9adc5690a889364"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a12a813949e5066148712a0626895c26b2578874e4cc63160bb007e6df3436fe"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe0ccca550bb8e5abc22f530ec0466136379c01321fd94f30a22231e8a48d985"}, - {file = "contourpy-1.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1d59258c3c67c865435d8fbeb35f8c59b8bef3d6f46c1f29f6123556af28445"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f32c38afb74bd98ce26de7cc74a67b40afb7b05aae7b42924ea990d51e4dac02"}, - {file = "contourpy-1.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d31a63bc6e6d87f77d71e1abbd7387ab817a66733734883d1fc0021ed9bfa083"}, - {file = "contourpy-1.2.1-cp39-cp39-win32.whl", hash = "sha256:ddcb8581510311e13421b1f544403c16e901c4e8f09083c881fab2be80ee31ba"}, - {file = "contourpy-1.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:10a37ae557aabf2509c79715cd20b62e4c7c28b8cd62dd7d99e5ed3ce28c3fd9"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a31f94983fecbac95e58388210427d68cd30fe8a36927980fab9c20062645609"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef2b055471c0eb466033760a521efb9d8a32b99ab907fc8358481a1dd29e3bd3"}, - {file = "contourpy-1.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b33d2bc4f69caedcd0a275329eb2198f560b325605810895627be5d4b876bf7f"}, - {file = "contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"}, + {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"}, + {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"}, + {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"}, + {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"}, + {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"}, + {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"}, + {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"}, + {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"}, + {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"}, + {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"}, + {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"}, ] [package.dependencies] -numpy = ">=1.20" +numpy = ">=1.23" [package.extras] bokeh = ["bokeh", "selenium"] docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.8.0)", "types-Pillow"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] -test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] [[package]] name = "cycler" @@ -319,6 +340,23 @@ files = [ marshmallow = ">=3.18.0,<4.0.0" typing-inspect = ">=0.4.0,<1" +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + [[package]] name = "distlib" version = "0.3.8" @@ -465,18 +503,18 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "freetype-py" -version = "2.4.0" +version = "2.5.1" description = "Freetype python bindings" optional = false python-versions = ">=3.7" files = [ - {file = "freetype-py-2.4.0.zip", hash = "sha256:8ad81195d2f8f339aba61700cebfbd77defad149c51f59b75a2a5e37833ae12e"}, - {file = "freetype_py-2.4.0-py3-none-macosx_10_9_universal2.whl", hash = "sha256:3e0f5a91bc812f42d98a92137e86bac4ed037a29e43dafdb76d716d5732189e8"}, - {file = "freetype_py-2.4.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9a3abc277f5f6d21575c0093c0c6139c161bf05b91aa6258505ab27c5001c5e"}, - {file = "freetype_py-2.4.0-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ce931f581d5038c4fea1f3d314254e0264e92441a5fdaef6817fe77b7bb888d3"}, - {file = "freetype_py-2.4.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:c6276d92ac401c8ce02ea391fc854de413b01a8d835fb394ee5eb6f04fc947f5"}, - {file = "freetype_py-2.4.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:9614f68876e9c62e821dfa811dd6160e00279d9d98cf60118cb264be48da1472"}, - {file = "freetype_py-2.4.0-py3-none-win_amd64.whl", hash = "sha256:a2620788d4f0c00bd75fee2dfca61635ab0da856131598c96e2355d5257f70e5"}, + {file = "freetype-py-2.5.1.zip", hash = "sha256:cfe2686a174d0dd3d71a9d8ee9bf6a2c23f5872385cf8ce9f24af83d076e2fbd"}, + {file = "freetype_py-2.5.1-py3-none-macosx_10_9_universal2.whl", hash = "sha256:d01ded2557694f06aa0413f3400c0c0b2b5ebcaabeef7aaf3d756be44f51e90b"}, + {file = "freetype_py-2.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d2f6b3d68496797da23204b3b9c4e77e67559c80390fc0dc8b3f454ae1cd819"}, + {file = "freetype_py-2.5.1-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:289b443547e03a4f85302e3ac91376838e0d11636050166662a4f75e3087ed0b"}, + {file = "freetype_py-2.5.1-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:cd3bfdbb7e1a84818cfbc8025fca3096f4f2afcd5d4641184bf0a3a2e6f97bbf"}, + {file = "freetype_py-2.5.1-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:3c1aefc4f0d5b7425f014daccc5fdc7c6f914fb7d6a695cc684f1c09cd8c1660"}, + {file = "freetype_py-2.5.1-py3-none-win_amd64.whl", hash = "sha256:0b7f8e0342779f65ca13ef8bc103938366fecade23e6bb37cb671c2b8ad7f124"}, ] [[package]] @@ -506,13 +544,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -705,13 +743,13 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "marshmallow" -version = "3.21.3" +version = "3.22.0" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.8" files = [ - {file = "marshmallow-3.21.3-py3-none-any.whl", hash = "sha256:86ce7fb914aa865001a4b2092c4c2872d13bc347f3d42673272cabfdbad386f1"}, - {file = "marshmallow-3.21.3.tar.gz", hash = "sha256:4f57c5e050a54d66361e826f94fba213eb10b67b2fdb02c3e0343ce207ba1662"}, + {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, + {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, ] [package.dependencies] @@ -719,7 +757,7 @@ packaging = ">=17.0" [package.extras] dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] -docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.3.7)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] tests = ["pytest", "pytz", "simplejson"] [[package]] @@ -796,6 +834,17 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "more-itertools" +version = "10.4.0" +description = "More routines for operating on iterables, beyond itertools" +optional = false +python-versions = ">=3.8" +files = [ + {file = "more-itertools-10.4.0.tar.gz", hash = "sha256:fe0e63c4ab068eac62410ab05cccca2dc71ec44ba8ef29916a0090df061cf923"}, + {file = "more_itertools-10.4.0-py3-none-any.whl", hash = "sha256:0f7d9f83a0a8dcfa8a2694a770590d98a67ea943e3d9f5298309a484758c4e27"}, +] + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -932,13 +981,13 @@ files = [ [[package]] name = "patool" -version = "2.3.0" +version = "2.4.0" description = "portable archive file manager" optional = false python-versions = ">=3.10" files = [ - {file = "patool-2.3.0-py2.py3-none-any.whl", hash = "sha256:e91bcd067b3967eab38ac4c6d2673b834087fcd3e036affd7f64047d0c5546c9"}, - {file = "patool-2.3.0.tar.gz", hash = "sha256:498e294fd8c7d50889d65019d431c6867bf3fb1fec5ea2d39d1d39d1215002f8"}, + {file = "patool-2.4.0-py2.py3-none-any.whl", hash = "sha256:0ab5ab376b0f7838c495a8583fab2d73b43889820c7ef2e9300a7e5c952054f2"}, + {file = "patool-2.4.0.tar.gz", hash = "sha256:2c54bcd2b904bf37253fad4f5d04cec808056b15fa974fd36b2a84fc931f3c0f"}, ] [[package]] @@ -1329,13 +1378,13 @@ types = ["typing-extensions"] [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -1482,13 +1531,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.7.1" +version = "13.8.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, + {file = "rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc"}, + {file = "rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"}, ] [package.dependencies] @@ -1500,63 +1549,71 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.6.1" +version = "0.6.3" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, - {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, - {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, - {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, - {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, - {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, - {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, + {file = "ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3"}, + {file = "ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc"}, + {file = "ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8"}, + {file = "ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521"}, + {file = "ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb"}, + {file = "ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82"}, + {file = "ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983"}, ] [[package]] name = "scipy" -version = "1.14.0" +version = "1.14.1" description = "Fundamental algorithms for scientific computing in Python" optional = false python-versions = ">=3.10" files = [ - {file = "scipy-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484"}, - {file = "scipy-1.14.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6"}, - {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7"}, - {file = "scipy-1.14.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1"}, - {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0"}, - {file = "scipy-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0"}, - {file = "scipy-1.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d"}, - {file = "scipy-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359"}, - {file = "scipy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e"}, - {file = "scipy-1.14.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"}, - {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf"}, - {file = "scipy-1.14.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86"}, - {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8"}, - {file = "scipy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74"}, - {file = "scipy-1.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb"}, - {file = "scipy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc"}, - {file = "scipy-1.14.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9"}, - {file = "scipy-1.14.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4"}, - {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0"}, - {file = "scipy-1.14.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f"}, - {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209"}, - {file = "scipy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14"}, - {file = "scipy-1.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159"}, - {file = "scipy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20"}, - {file = "scipy-1.14.0.tar.gz", hash = "sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b"}, + {file = "scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389"}, + {file = "scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3"}, + {file = "scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0"}, + {file = "scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3"}, + {file = "scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d"}, + {file = "scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69"}, + {file = "scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad"}, + {file = "scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5"}, + {file = "scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675"}, + {file = "scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2"}, + {file = "scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617"}, + {file = "scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8"}, + {file = "scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37"}, + {file = "scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2"}, + {file = "scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2"}, + {file = "scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94"}, + {file = "scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d"}, + {file = "scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07"}, + {file = "scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5"}, + {file = "scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc"}, + {file = "scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310"}, + {file = "scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066"}, + {file = "scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1"}, + {file = "scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f"}, + {file = "scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79"}, + {file = "scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e"}, + {file = "scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73"}, + {file = "scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e"}, + {file = "scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d"}, + {file = "scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e"}, + {file = "scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06"}, + {file = "scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84"}, + {file = "scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417"}, ] [package.dependencies] @@ -1564,8 +1621,8 @@ numpy = ">=1.23.5,<2.3" [package.extras] dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodestyle", "pydevtool", "rich-click", "ruff (>=0.0.292)", "types-psutil", "typing_extensions"] -doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] -test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] +doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0,<=7.3.7)", "sphinx-design (>=0.4.0)"] +test = ["Cython", "array-api-strict (>=2.0)", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "sexpdata" @@ -1580,47 +1637,53 @@ files = [ [[package]] name = "shapely" -version = "2.0.5" +version = "2.0.6" description = "Manipulation and analysis of geometric objects" optional = false python-versions = ">=3.7" files = [ - {file = "shapely-2.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:89d34787c44f77a7d37d55ae821f3a784fa33592b9d217a45053a93ade899375"}, - {file = "shapely-2.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:798090b426142df2c5258779c1d8d5734ec6942f778dab6c6c30cfe7f3bf64ff"}, - {file = "shapely-2.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45211276900c4790d6bfc6105cbf1030742da67594ea4161a9ce6812a6721e68"}, - {file = "shapely-2.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e119444bc27ca33e786772b81760f2028d930ac55dafe9bc50ef538b794a8e1"}, - {file = "shapely-2.0.5-cp310-cp310-win32.whl", hash = "sha256:9a4492a2b2ccbeaebf181e7310d2dfff4fdd505aef59d6cb0f217607cb042fb3"}, - {file = "shapely-2.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:1e5cb5ee72f1bc7ace737c9ecd30dc174a5295fae412972d3879bac2e82c8fae"}, - {file = "shapely-2.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5bbfb048a74cf273db9091ff3155d373020852805a37dfc846ab71dde4be93ec"}, - {file = "shapely-2.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93be600cbe2fbaa86c8eb70656369f2f7104cd231f0d6585c7d0aa555d6878b8"}, - {file = "shapely-2.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f8e71bb9a46814019f6644c4e2560a09d44b80100e46e371578f35eaaa9da1c"}, - {file = "shapely-2.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5251c28a29012e92de01d2e84f11637eb1d48184ee8f22e2df6c8c578d26760"}, - {file = "shapely-2.0.5-cp311-cp311-win32.whl", hash = "sha256:35110e80070d664781ec7955c7de557456b25727a0257b354830abb759bf8311"}, - {file = "shapely-2.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:6c6b78c0007a34ce7144f98b7418800e0a6a5d9a762f2244b00ea560525290c9"}, - {file = "shapely-2.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:03bd7b5fa5deb44795cc0a503999d10ae9d8a22df54ae8d4a4cd2e8a93466195"}, - {file = "shapely-2.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ff9521991ed9e201c2e923da014e766c1aa04771bc93e6fe97c27dcf0d40ace"}, - {file = "shapely-2.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b65365cfbf657604e50d15161ffcc68de5cdb22a601bbf7823540ab4918a98d"}, - {file = "shapely-2.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21f64e647a025b61b19585d2247137b3a38a35314ea68c66aaf507a1c03ef6fe"}, - {file = "shapely-2.0.5-cp312-cp312-win32.whl", hash = "sha256:3ac7dc1350700c139c956b03d9c3df49a5b34aaf91d024d1510a09717ea39199"}, - {file = "shapely-2.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:30e8737983c9d954cd17feb49eb169f02f1da49e24e5171122cf2c2b62d65c95"}, - {file = "shapely-2.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ff7731fea5face9ec08a861ed351734a79475631b7540ceb0b66fb9732a5f529"}, - {file = "shapely-2.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff9e520af0c5a578e174bca3c18713cd47a6c6a15b6cf1f50ac17dc8bb8db6a2"}, - {file = "shapely-2.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b299b91557b04acb75e9732645428470825061f871a2edc36b9417d66c1fc5"}, - {file = "shapely-2.0.5-cp37-cp37m-win32.whl", hash = "sha256:b5870633f8e684bf6d1ae4df527ddcb6f3895f7b12bced5c13266ac04f47d231"}, - {file = "shapely-2.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:401cb794c5067598f50518e5a997e270cd7642c4992645479b915c503866abed"}, - {file = "shapely-2.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e91ee179af539100eb520281ba5394919067c6b51824e6ab132ad4b3b3e76dd0"}, - {file = "shapely-2.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8af6f7260f809c0862741ad08b1b89cb60c130ae30efab62320bbf4ee9cc71fa"}, - {file = "shapely-2.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5456dd522800306ba3faef77c5ba847ec30a0bd73ab087a25e0acdd4db2514f"}, - {file = "shapely-2.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b714a840402cde66fd7b663bb08cacb7211fa4412ea2a209688f671e0d0631fd"}, - {file = "shapely-2.0.5-cp38-cp38-win32.whl", hash = "sha256:7e8cf5c252fac1ea51b3162be2ec3faddedc82c256a1160fc0e8ddbec81b06d2"}, - {file = "shapely-2.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4461509afdb15051e73ab178fae79974387f39c47ab635a7330d7fee02c68a3f"}, - {file = "shapely-2.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7545a39c55cad1562be302d74c74586f79e07b592df8ada56b79a209731c0219"}, - {file = "shapely-2.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4c83a36f12ec8dee2066946d98d4d841ab6512a6ed7eb742e026a64854019b5f"}, - {file = "shapely-2.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89e640c2cd37378480caf2eeda9a51be64201f01f786d127e78eaeff091ec897"}, - {file = "shapely-2.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06efe39beafde3a18a21dde169d32f315c57da962826a6d7d22630025200c5e6"}, - {file = "shapely-2.0.5-cp39-cp39-win32.whl", hash = "sha256:8203a8b2d44dcb366becbc8c3d553670320e4acf0616c39e218c9561dd738d92"}, - {file = "shapely-2.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:7fed9dbfbcfec2682d9a047b9699db8dcc890dfca857ecba872c42185fc9e64e"}, - {file = "shapely-2.0.5.tar.gz", hash = "sha256:bff2366bc786bfa6cb353d6b47d0443c570c32776612e527ee47b6df63fcfe32"}, + {file = "shapely-2.0.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29a34e068da2d321e926b5073539fd2a1d4429a2c656bd63f0bd4c8f5b236d0b"}, + {file = "shapely-2.0.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c84c3f53144febf6af909d6b581bc05e8785d57e27f35ebaa5c1ab9baba13b"}, + {file = "shapely-2.0.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad2fae12dca8d2b727fa12b007e46fbc522148a584f5d6546c539f3464dccde"}, + {file = "shapely-2.0.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3304883bd82d44be1b27a9d17f1167fda8c7f5a02a897958d86c59ec69b705e"}, + {file = "shapely-2.0.6-cp310-cp310-win32.whl", hash = "sha256:3ec3a0eab496b5e04633a39fa3d5eb5454628228201fb24903d38174ee34565e"}, + {file = "shapely-2.0.6-cp310-cp310-win_amd64.whl", hash = "sha256:28f87cdf5308a514763a5c38de295544cb27429cfa655d50ed8431a4796090c4"}, + {file = "shapely-2.0.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5aeb0f51a9db176da9a30cb2f4329b6fbd1e26d359012bb0ac3d3c7781667a9e"}, + {file = "shapely-2.0.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9a7a78b0d51257a367ee115f4d41ca4d46edbd0dd280f697a8092dd3989867b2"}, + {file = "shapely-2.0.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f32c23d2f43d54029f986479f7c1f6e09c6b3a19353a3833c2ffb226fb63a855"}, + {file = "shapely-2.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3dc9fb0eb56498912025f5eb352b5126f04801ed0e8bdbd867d21bdbfd7cbd0"}, + {file = "shapely-2.0.6-cp311-cp311-win32.whl", hash = "sha256:d93b7e0e71c9f095e09454bf18dad5ea716fb6ced5df3cb044564a00723f339d"}, + {file = "shapely-2.0.6-cp311-cp311-win_amd64.whl", hash = "sha256:c02eb6bf4cfb9fe6568502e85bb2647921ee49171bcd2d4116c7b3109724ef9b"}, + {file = "shapely-2.0.6-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cec9193519940e9d1b86a3b4f5af9eb6910197d24af02f247afbfb47bcb3fab0"}, + {file = "shapely-2.0.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83b94a44ab04a90e88be69e7ddcc6f332da7c0a0ebb1156e1c4f568bbec983c3"}, + {file = "shapely-2.0.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:537c4b2716d22c92036d00b34aac9d3775e3691f80c7aa517c2c290351f42cd8"}, + {file = "shapely-2.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98fea108334be345c283ce74bf064fa00cfdd718048a8af7343c59eb40f59726"}, + {file = "shapely-2.0.6-cp312-cp312-win32.whl", hash = "sha256:42fd4cd4834747e4990227e4cbafb02242c0cffe9ce7ef9971f53ac52d80d55f"}, + {file = "shapely-2.0.6-cp312-cp312-win_amd64.whl", hash = "sha256:665990c84aece05efb68a21b3523a6b2057e84a1afbef426ad287f0796ef8a48"}, + {file = "shapely-2.0.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:42805ef90783ce689a4dde2b6b2f261e2c52609226a0438d882e3ced40bb3013"}, + {file = "shapely-2.0.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6d2cb146191a47bd0cee8ff5f90b47547b82b6345c0d02dd8b25b88b68af62d7"}, + {file = "shapely-2.0.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3fdef0a1794a8fe70dc1f514440aa34426cc0ae98d9a1027fb299d45741c381"}, + {file = "shapely-2.0.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c665a0301c645615a107ff7f52adafa2153beab51daf34587170d85e8ba6805"}, + {file = "shapely-2.0.6-cp313-cp313-win32.whl", hash = "sha256:0334bd51828f68cd54b87d80b3e7cee93f249d82ae55a0faf3ea21c9be7b323a"}, + {file = "shapely-2.0.6-cp313-cp313-win_amd64.whl", hash = "sha256:d37d070da9e0e0f0a530a621e17c0b8c3c9d04105655132a87cfff8bd77cc4c2"}, + {file = "shapely-2.0.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fa7468e4f5b92049c0f36d63c3e309f85f2775752e076378e36c6387245c5462"}, + {file = "shapely-2.0.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed5867e598a9e8ac3291da6cc9baa62ca25706eea186117034e8ec0ea4355653"}, + {file = "shapely-2.0.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81d9dfe155f371f78c8d895a7b7f323bb241fb148d848a2bf2244f79213123fe"}, + {file = "shapely-2.0.6-cp37-cp37m-win32.whl", hash = "sha256:fbb7bf02a7542dba55129062570211cfb0defa05386409b3e306c39612e7fbcc"}, + {file = "shapely-2.0.6-cp37-cp37m-win_amd64.whl", hash = "sha256:837d395fac58aa01aa544495b97940995211e3e25f9aaf87bc3ba5b3a8cd1ac7"}, + {file = "shapely-2.0.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c6d88ade96bf02f6bfd667ddd3626913098e243e419a0325ebef2bbd481d1eb6"}, + {file = "shapely-2.0.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8b3b818c4407eaa0b4cb376fd2305e20ff6df757bf1356651589eadc14aab41b"}, + {file = "shapely-2.0.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbc783529a21f2bd50c79cef90761f72d41c45622b3e57acf78d984c50a5d13"}, + {file = "shapely-2.0.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2423f6c0903ebe5df6d32e0066b3d94029aab18425ad4b07bf98c3972a6e25a1"}, + {file = "shapely-2.0.6-cp38-cp38-win32.whl", hash = "sha256:2de00c3bfa80d6750832bde1d9487e302a6dd21d90cb2f210515cefdb616e5f5"}, + {file = "shapely-2.0.6-cp38-cp38-win_amd64.whl", hash = "sha256:3a82d58a1134d5e975f19268710e53bddd9c473743356c90d97ce04b73e101ee"}, + {file = "shapely-2.0.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:392f66f458a0a2c706254f473290418236e52aa4c9b476a072539d63a2460595"}, + {file = "shapely-2.0.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eba5bae271d523c938274c61658ebc34de6c4b33fdf43ef7e938b5776388c1be"}, + {file = "shapely-2.0.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7060566bc4888b0c8ed14b5d57df8a0ead5c28f9b69fb6bed4476df31c51b0af"}, + {file = "shapely-2.0.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b02154b3e9d076a29a8513dffcb80f047a5ea63c897c0cd3d3679f29363cf7e5"}, + {file = "shapely-2.0.6-cp39-cp39-win32.whl", hash = "sha256:44246d30124a4f1a638a7d5419149959532b99dfa25b54393512e6acc9c211ac"}, + {file = "shapely-2.0.6-cp39-cp39-win_amd64.whl", hash = "sha256:2b542d7f1dbb89192d3512c52b679c822ba916f93479fa5d4fc2fe4fa0b3c9e8"}, + {file = "shapely-2.0.6.tar.gz", hash = "sha256:997f6159b1484059ec239cacaa53467fd8b5564dabe186cd84ac2944663b0bf6"}, ] [package.dependencies] @@ -1680,13 +1743,13 @@ psycopg = ["psycopg[binary,pool] (>=3.0.12,<4.0.0)"] [[package]] name = "typer" -version = "0.12.4" +version = "0.12.5" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false python-versions = ">=3.7" files = [ - {file = "typer-0.12.4-py3-none-any.whl", hash = "sha256:819aa03699f438397e876aa12b0d63766864ecba1b579092cc9fe35d886e34b6"}, - {file = "typer-0.12.4.tar.gz", hash = "sha256:c9c1613ed6a166162705b3347b8d10b661ccc5d95692654d0fb628118f2c34e6"}, + {file = "typer-0.12.5-py3-none-any.whl", hash = "sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b"}, + {file = "typer-0.12.5.tar.gz", hash = "sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722"}, ] [package.dependencies] @@ -1807,7 +1870,86 @@ objprint = ">0.1.3" [package.extras] full = ["orjson"] +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + [metadata] lock-version = "2.0" python-versions = "^3.12,<3.13" -content-hash = "7b96e458fbfc778cabc91bcaef7a38704a50297d91f0d436c55e283510e2fc62" +content-hash = "d0dafbd8caf6f0e106af5c970066ea0d66b884103c18bacfc788f0a41c03688b" diff --git a/pyproject.toml b/pyproject.toml index 76b55190..c3adaed5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,8 @@ typer = { version = ">=0.9,<0.13", extras = ["all"] } isort = "^5.6.4" ruff = ">=0.4.4,<0.7.0" pint = "^0.24.3" +deprecated = "^1.2.14" +more-itertools = "^10.4.0" [tool.poetry.group.dev.dependencies] pre-commit = ">=2.20,<4.0" From 7464e3ce56f3be7d7cf3a82a258021df18cf09cf Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 23:31:52 +0200 Subject: [PATCH 62/63] Fix: ME6211C33M5G_N Fix: LDO gnd connect Fix: CBM9002A oscillator params --- .../library/CBM9002A_56ILG_Reference_Design.py | 5 +++-- src/faebryk/library/LDO.py | 14 ++++++++++---- src/faebryk/library/ME6211C33M5G_N.py | 7 +------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py index e295a9b1..eeabab69 100644 --- a/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py +++ b/src/faebryk/library/CBM9002A_56ILG_Reference_Design.py @@ -69,9 +69,10 @@ def __preinit__(self): self.reset_lowpass_cap.capacitance.merge(F.Constant(1 * P.uF)) self.oscillator.crystal.frequency.merge(F.Constant(24 * P.Mhertz)) - self.oscillator.crystal.load_impedance.merge(F.Constant(12 * P.pohm)) + self.oscillator.crystal.frequency_tolerance.merge( + F.Range.upper_bound(20 * P.ppm) + ) - self.oscillator.crystal.frequency_temperature_tolerance.merge(20 * P.ppm) # TODO: just set to a 1N4148 self.reset_diode.forward_voltage.merge(715 * P.mV) self.reset_diode.reverse_leakage_current.merge(1 * P.uA) diff --git a/src/faebryk/library/LDO.py b/src/faebryk/library/LDO.py index bd5c10ec..2e98fbd0 100644 --- a/src/faebryk/library/LDO.py +++ b/src/faebryk/library/LDO.py @@ -39,10 +39,16 @@ def __preinit__(self): self.power_out.decoupled.decouple() self.enable.reference.connect(self.power_in) - if self.output_polarity == self.OutputPolarity.NEGATIVE: - self.power_in.hv.connect(self.power_out.hv) - else: - self.power_in.lv.connect(self.power_out.lv) + # TODO: should be implemented differently (see below) + # if self.output_polarity == self.OutputPolarity.NEGATIVE: + # self.power_in.hv.connect(self.power_out.hv) + # else: + # self.power_in.lv.connect(self.power_out.lv) + + # LDO in & out share gnd reference + F.ElectricLogic.connect_all_node_references( + [self.power_in, self.power_out], gnd_only=True + ) @L.rt_field def can_bridge(self): diff --git a/src/faebryk/library/ME6211C33M5G_N.py b/src/faebryk/library/ME6211C33M5G_N.py index 2ed6eb25..8d81ebd0 100644 --- a/src/faebryk/library/ME6211C33M5G_N.py +++ b/src/faebryk/library/ME6211C33M5G_N.py @@ -19,12 +19,7 @@ def __init__(self, default_enabled: bool = True) -> None: def __preinit__(self): # set constraints - self.power_out.voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) - - # LDO in & out share gnd reference - F.ElectricLogic.connect_all_node_references( - [self.power_in, self.power_out], gnd_only=True - ) + self.output_voltage.merge(F.Range(3.3 * 0.98 * P.V, 3.3 * 1.02 * P.V)) if self._default_enabled: self.enable.set(True) From 1b4fa76cad02d590859373e1ed7946f23264b80e Mon Sep 17 00:00:00 2001 From: ruben-iteng <94007802+ruben-iteng@users.noreply.github.com> Date: Fri, 30 Aug 2024 23:37:03 +0200 Subject: [PATCH 63/63] Pass through linkcls in connect functions --- src/faebryk/core/util.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/faebryk/core/util.py b/src/faebryk/core/util.py index 114f1317..1b33ce72 100644 --- a/src/faebryk/core/util.py +++ b/src/faebryk/core/util.py @@ -321,22 +321,24 @@ def get_param_tree(param: Parameter) -> list[tuple[Parameter, list]]: def connect_interfaces_via_chain( - start: ModuleInterface, bridges: Iterable[Node], end: ModuleInterface + start: ModuleInterface, bridges: Iterable[Node], end: ModuleInterface, linkcls=None ): from faebryk.library.can_bridge import can_bridge last = start for bridge in bridges: - last.connect(bridge.get_trait(can_bridge).get_in()) + last.connect(bridge.get_trait(can_bridge).get_in(), linkcls=linkcls) last = bridge.get_trait(can_bridge).get_out() - last.connect(end) + last.connect(end, linkcls=linkcls) -def connect_all_interfaces[MIF: ModuleInterface](interfaces: Iterable[MIF]): +def connect_all_interfaces[MIF: ModuleInterface]( + interfaces: Iterable[MIF], linkcls=None +): interfaces = list(interfaces) if not interfaces: return - return connect_to_all_interfaces(interfaces[0], interfaces[1:]) + return connect_to_all_interfaces(interfaces[0], interfaces[1:], linkcls=linkcls) # not needed with current connection implementation # for i in interfaces: # for j in interfaces: @@ -344,10 +346,10 @@ def connect_all_interfaces[MIF: ModuleInterface](interfaces: Iterable[MIF]): def connect_to_all_interfaces[MIF: ModuleInterface]( - source: MIF, targets: Iterable[MIF] + source: MIF, targets: Iterable[MIF], linkcls=None ): for i in targets: - source.connect(i) + source.connect(i, linkcls=linkcls) return source