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)