Skip to content
Merged
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions blinky_skeleton.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from typing_extensions import override

from edg import *


class BlinkyExample(SimpleBoardTop):
@override
def contents(self) -> None:
super().contents()
# your implementation here
Expand Down
8 changes: 8 additions & 0 deletions edg/BoardTop.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing_extensions import override

from .parts import *


Expand All @@ -8,6 +10,7 @@ def __init__(self) -> None:
self.refdes_prefix = self.Parameter(StringExpr())
self.assign(self.refdes_prefix, "") # override with refinements

@override
def refinements(self) -> Refinements:
return super().refinements() + Refinements(
class_refinements=[
Expand Down Expand Up @@ -52,6 +55,7 @@ class BoardTop(BaseBoardTop):


class JlcToolingHole(InternalSubcircuit, FootprintBlock):
@override
def contents(self) -> None:
super().contents()
self.footprint(
Expand All @@ -62,6 +66,7 @@ def contents(self) -> None:


class JlcToolingHoles(InternalSubcircuit, Block):
@override
def contents(self) -> None:
super().contents()
self.th1 = self.Block(JlcToolingHole())
Expand All @@ -71,6 +76,7 @@ def contents(self) -> None:

class JlcTopRefinements(BaseBoardTop):
"""Design top with refinements to use parts from JLC's assembly service"""
@override
def refinements(self) -> Refinements:
return super().refinements() + Refinements(
class_refinements=[
Expand Down Expand Up @@ -111,13 +117,15 @@ def refinements(self) -> Refinements:

class JlcBoardTop(JlcTopRefinements):
"""Design top with refinements to use parts from JLC's assembly service and including the tooling holes"""
@override
def contents(self) -> None:
super().contents()
self.jlc_th = self.Block(JlcToolingHoles())


class SimpleBoardTop(JlcTopRefinements):
"""A BoardTop with refinements that make getting started easier but may not be desirable everywhere."""
@override
def refinements(self) -> Refinements:
return super().refinements() + Refinements(
class_refinements=[
Expand Down
7 changes: 7 additions & 0 deletions edg/abstract_parts/AbstractAnalogSwitch.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from typing import List, cast, Optional, Dict

from typing_extensions import override

from ..electronics_model import *
from .Categories import Interface


@abstract_block
class AnalogSwitch(Interface, KiCadImportableBlock, Block):
"""Base class for a n-ported analog switch with passive-typed ports."""
@override
def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
assert symbol_name.startswith('edg_importable:Mux') # can be any Mux
count = int(symbol_name.removeprefix('edg_importable:Mux'))
Expand Down Expand Up @@ -43,6 +46,7 @@ def __init__(self, switch_size: IntLike = 0):
self.switch_size = self.ArgParameter(switch_size)
self.generator_param(self.switch_size, self.inputs.requested(), self.control_gnd.is_connected())

@override
def generate(self) -> None:
import math
super().generate()
Expand Down Expand Up @@ -104,6 +108,7 @@ def generate(self) -> None:
class AnalogMuxer(Interface, KiCadImportableBlock, GeneratorBlock):
"""Wrapper around AnalogSwitch that provides muxing functionality - multiple sink ports, one source port.
"""
@override
def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
assert symbol_name.startswith('edg_importable:Mux') # can be any Mux
count = int(symbol_name.removeprefix('edg_importable:Mux'))
Expand Down Expand Up @@ -132,6 +137,7 @@ def __init__(self) -> None:

self.generator_param(self.inputs.requested(), self.control_gnd.is_connected())

@override
def generate(self) -> None:
super().generate()
self.inputs.defined()
Expand Down Expand Up @@ -175,6 +181,7 @@ def __init__(self) -> None:

self.generator_param(self.outputs.requested())

@override
def generate(self) -> None:
super().generate()
self.outputs.defined()
Expand Down
2 changes: 2 additions & 0 deletions edg/abstract_parts/AbstractAntenna.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.generator_param(self.frequency, self.power, self.impedance)

@override
def _row_filter(self, row: PartsTableRow) -> bool:
return super()._row_filter(row) and \
self.get(self.frequency).fuzzy_in(row[self.FREQUENCY_RATING]) and \
row[self.IMPEDANCE].fuzzy_in(self.get(self.impedance)) and\
self.get(self.power).fuzzy_in(row[self.POWER_RATING])

@override
def _row_generate(self, row: PartsTableRow) -> None:
super()._row_generate(row)
self.assign(self.actual_frequency_rating, row[self.FREQUENCY_RATING])
Expand Down
4 changes: 4 additions & 0 deletions edg/abstract_parts/AbstractBjt.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Bjt(KiCadImportableBlock, DiscreteSemiconductor, HasStandardFootprint):
"""
_STANDARD_FOOTPRINT = lambda: BjtStandardFootprint

@override
def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
# TODO actually check that the device channel corresponds with the schematic?
assert symbol_name.startswith('Device:Q_NPN_') or symbol_name.startswith('Device:Q_PNP_')
Expand Down Expand Up @@ -48,6 +49,7 @@ def __init__(self, collector_voltage: RangeLike, collector_current: RangeLike, *
self.actual_power_rating = self.Parameter(RangeExpr())
self.actual_gain = self.Parameter(RangeExpr())

@override
def contents(self) -> None:
super().contents()

Expand Down Expand Up @@ -94,6 +96,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.generator_param(self.collector_voltage, self.collector_current, self.gain, self.power, self.channel)

@override
def _row_filter(self, row: PartsTableRow) -> bool:
return super()._row_filter(row) and \
row[self.CHANNEL] == self.get(self.channel) and \
Expand All @@ -102,6 +105,7 @@ def _row_filter(self, row: PartsTableRow) -> bool:
row[self.GAIN].fuzzy_in(self.get(self.gain)) and \
self.get(self.power).fuzzy_in(row[self.POWER_RATING])

@override
def _row_generate(self, row: PartsTableRow) -> None:
super()._row_generate(row)
self.assign(self.actual_collector_voltage_rating, row[self.VCE_RATING])
Expand Down
15 changes: 15 additions & 0 deletions edg/abstract_parts/AbstractCapacitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import Optional, cast, Dict, Any, Tuple, Mapping
import math

from typing_extensions import override

from ..electronics_model import *
from .ESeriesUtil import ESeriesUtil
from .PartsTable import PartsTableColumn, PartsTableRow, PartsTable
Expand Down Expand Up @@ -35,6 +37,7 @@ def __init__(self, capacitance: RangeLike, voltage: RangeLike, *,
self.actual_capacitance = self.Parameter(RangeExpr())
self.actual_voltage_rating = self.Parameter(RangeExpr())

@override
def contents(self) -> None:
super().contents()

Expand All @@ -55,6 +58,7 @@ class Capacitor(UnpolarizedCapacitor, KiCadInstantiableBlock, HasStandardFootpri
"\s*" + f"([\d.{PartParserUtil.SI_PREFIXES}]+\s*V)" + "$")
CAPACITOR_DEFAULT_TOL = 0.20 # TODO this should be unified elsewhere

@override
def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
assert symbol_name in ('Device:C', 'Device:C_Small', 'Device:C_Polarized', 'Device:C_Polarized_Small')
return {'1': self.pos, '2': self.neg}
Expand All @@ -75,6 +79,7 @@ def parse_capacitor(cls, value: str) -> Tuple[Range, Range]:
return (capacitance, Range.zero_to_upper(voltage))

@classmethod
@override
def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Capacitor':
return Capacitor(*cls.parse_capacitor(properties['Value']))

Expand Down Expand Up @@ -180,11 +185,13 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.generator_param(self.capacitance, self.voltage, self.voltage_rating_derating, self.exact_capacitance)

@override
def _row_generate(self, row: PartsTableRow) -> None:
super()._row_generate(row)
self.assign(self.actual_voltage_rating, row[self.VOLTAGE_RATING])
self.assign(self.actual_capacitance, row[self.CAPACITANCE])

@override
def _row_filter(self, row: PartsTableRow) -> bool:
derated_voltage = self.get(self.voltage) / self.get(self.voltage_rating_derating)
return super()._row_filter(row) and \
Expand All @@ -195,6 +202,7 @@ def _row_filter_capacitance(self, row: PartsTableRow) -> bool:
return row[self.CAPACITANCE].fuzzy_in(self.get(self.capacitance))

@classmethod
@override
def _row_sort_by(cls, row: PartsTableRow) -> Any:
return (ESeriesUtil.series_of(row[cls.NOMINAL_CAPACITANCE], default=ESeriesUtil.SERIES_MAX + 1),
super()._row_sort_by(row))
Expand Down Expand Up @@ -224,10 +232,12 @@ def __init__(self, *args: Any, single_nominal_capacitance: RangeLike = (0, 22)*u

self.actual_derated_capacitance = self.Parameter(RangeExpr())

@override
def _row_filter_capacitance(self, row: PartsTableRow) -> bool:
# post-derating capacitance filtering is in _table_postprocess
return Range.exact(row[self.NOMINAL_CAPACITANCE]).fuzzy_in(self.get(self.single_nominal_capacitance))

@override
def _table_postprocess(self, table: PartsTable) -> PartsTable:
def add_derated_row(row: PartsTableRow) -> Optional[Dict[PartsTableColumn, Any]]:
if not self.get(self.exact_capacitance):
Expand Down Expand Up @@ -264,6 +274,7 @@ def add_derated_row(row: PartsTableRow) -> Optional[Dict[PartsTableColumn, Any]]
row[self.PARALLEL_DERATED_CAPACITANCE].fuzzy_in(self.get(self.capacitance))
))

@override
def _row_generate(self, row: PartsTableRow) -> None:
"""This one is weird. Because this is the last in the class order, this is called last.
So the top subclass needs explicit logic to handle parallel capacitors."""
Expand Down Expand Up @@ -307,6 +318,7 @@ def __init__(self, footprint: StringLike = "", manufacturer: StringLike = "", pa
class DecouplingCapacitor(DiscreteApplication, KiCadImportableBlock):
"""Optionally polarized capacitor used for DC decoupling, with VoltageSink connections with voltage inference.
Implemented as a shim block."""
@override
def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
assert symbol_name in ('Device:C', 'Device:C_Small', 'Device:C_Polarized', 'Device:C_Polarized_Small')
return {'1': self.pwr, '2': self.gnd}
Expand Down Expand Up @@ -339,6 +351,7 @@ def connected(self, gnd: Optional[Port[GroundLink]] = None, pwr: Optional[Port[V
class AnalogCapacitor(DiscreteApplication, KiCadImportableBlock):
"""Capacitor attached to an analog line, that presents as an open model-wise.
"""
@override
def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
assert symbol_name in ('Device:C', 'Device:C_Small', 'Device:C_Polarized', 'Device:C_Polarized_Small')
return {'1': self.io, '2': self.gnd}
Expand All @@ -363,6 +376,7 @@ def connected(self, gnd: Optional[Port[GroundLink]] = None, io: Optional[Port[An


class CombinedCapacitorElement(Capacitor): # to avoid an abstract part error
@override
def contents(self) -> None:
super().contents()
self.assign(self.actual_capacitance, self.capacitance) # fake it, since a combined capacitance is handwavey
Expand Down Expand Up @@ -391,6 +405,7 @@ def __init__(self, *, extend_upper: BoolLike = False) -> None:
self.generator_param(self.pos.requested(), self.neg.requested(), self.extend_upper)


@override
def generate(self) -> None:
super().generate()
capacitance = self.capacitances.sum()
Expand Down
5 changes: 5 additions & 0 deletions edg/abstract_parts/AbstractComparator.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
from typing import Mapping

from typing_extensions import override

from .ResistiveDivider import FeedbackVoltageDivider, VoltageDivider
from ..abstract_parts import Analog
from ..electronics_model import *


class Comparator(KiCadInstantiableBlock, Analog):
"""Abstract comparator interface, output goes high when inp > inn."""
@override
def symbol_pinning(self, symbol_name: str) -> Mapping[str, BasePort]:
assert symbol_name in ('Simulation_SPICE:OPAMP', 'edg_importable:Opamp')
return {'+': self.inp, '-': self.inn, '3': self.out, 'V+': self.pwr, 'V-': self.gnd}

@classmethod
@override
def block_from_symbol(cls, symbol_name: str, properties: Mapping[str, str]) -> 'Comparator':
return Comparator()

Expand Down Expand Up @@ -55,6 +59,7 @@ def __init__(self, trip_voltage: RangeLike, *, invert: BoolLike = False,

self.actual_trip_voltage = self.Parameter(RangeExpr())

@override
def generate(self) -> None:
super().generate()

Expand Down
6 changes: 6 additions & 0 deletions edg/abstract_parts/AbstractCrystal.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import Any

from typing_extensions import override

from ..electronics_model import *
from . import PartsTableSelector, PartsTableColumn, Capacitor, PartsTableRow
from .Categories import *
Expand All @@ -21,6 +23,7 @@ def __init__(self, frequency: RangeLike) -> None:
self.crystal = self.Port(CrystalPort(self.actual_frequency), [InOut]) # set by subclass
self.gnd = self.Port(Ground(), [Common])

@override
def contents(self) -> None:
super().contents()

Expand Down Expand Up @@ -66,10 +69,12 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.generator_param(self.frequency)

@override
def _row_filter(self, row: PartsTableRow) -> bool:
return super()._row_filter(row) and \
(row[self.FREQUENCY] in self.get(self.frequency))

@override
def _row_generate(self, row: PartsTableRow) -> None:
super()._row_generate(row)
self.assign(self.actual_frequency, row[self.FREQUENCY])
Expand Down Expand Up @@ -103,6 +108,7 @@ class OscillatorCrystal(OscillatorReference): # TODO rename to disambiguate fro
# TODO this should be formalized better.
CAPACITOR_TOLERANCE = 0.38

@override
def contents(self) -> None:
super().contents()

Expand Down
Loading
Loading