From 19cac3ad0cec9aecae4865552621c8c83f1ab6cb Mon Sep 17 00:00:00 2001 From: napowderly Date: Wed, 13 Mar 2024 16:38:39 -0700 Subject: [PATCH 1/3] inital commit --- sandbox/test.ato | 61 +++++++++++++++++++ sandbox/typing_sandbox.py | 122 ++++++++++++++++++++++++++++++++++++++ src/atopile/typing.py | 0 3 files changed, 183 insertions(+) create mode 100644 sandbox/test.ato create mode 100644 sandbox/typing_sandbox.py create mode 100644 src/atopile/typing.py diff --git a/sandbox/test.ato b/sandbox/test.ato new file mode 100644 index 00000000..38f5342e --- /dev/null +++ b/sandbox/test.ato @@ -0,0 +1,61 @@ + +module ESP32S3: + power = new Power + + power.voltage = 3.3V + assert power.voltage within 2.8V to 3.3V + +module ESP32S3: + power = new PowerIn + + power.voltage = 3.1V to 3.2V + + +module BuckConverter: + power = new PowerOut + + +module PowerSupply: + power_out = new Power + power_out.voltage = 3.1V to 3.2V + + assert power_out.current within 0.5A to 1A + assert power_out.voltage within 1.8V to 12V + + +interface Power: + signal vcc + signal gnd + + maximum_voltage: Voltage + voltage: Voltage + current: Current # need to go sum up the current draws of connected devices + + +interface PowerIn from Power: + # power sink + # multiple allowed on each bus + # currents should be summed together + + +interface PowerOut from Power: + # power source + # only one allowed on each bus + + +interface I2C: + signal sda + signal scl + signal gnd + + # address = new Hex + address = 0x68 + +# Defined behind the scenes? +type Voltage: + series: false + +type Current: + series: true + +type MyPowerInterface from PowerSourceInterface: diff --git a/sandbox/typing_sandbox.py b/sandbox/typing_sandbox.py new file mode 100644 index 00000000..4f090672 --- /dev/null +++ b/sandbox/typing_sandbox.py @@ -0,0 +1,122 @@ +from typing import List, Tuple + + +class RangedValue: + def __init__(self, name: str, min_value: float, max_value: float, expanding: bool, series: bool): + self.name = name + self.min_value = min_value + self.max_value = max_value + self.expanding = expanding # supply vs demand? + self.series = series # do we sum these values or not? + +""" +eg. +power_supply.power_out.voltage = 2.8V to 3.2V + +""" + +example_interfaces = [ + RangedValue("power_supply.power_out.voltage", 2.8, 3.2, True, False), + RangedValue("power_supply.power_out.max_voltage", 1.8, 12, False, False), + RangedValue("micro", 2.2, 3.4, False, False), + RangedValue("imu", 1.8, 3.5, False, False), +] + +""" +eg. +micro.sda.vol = 0V to 0.8V +micro.sda.vil = 0V to 1.2V +""" + +example_interfaces = [ + RangedValue("micro-sda-vol", 0, 0.8, True, False), + RangedValue("micro-sda-vil", 0, 1.2, False, False), + RangedValue("imu-sda-vol", 0, 0.7, True, False), + RangedValue("imu-sda-vil", 0, 0.9, False, False), + RangedValue("temp-sda-vol", 0, 0.85, True, False), + RangedValue("temp-sda-vol", 0, 1.1, False, False), +] + +example_interfaces = [ + RangedValue("micro-sda-voh", 2.2, 3.3, True, False), + RangedValue("micro-sda-vih", 2, 3.3, False, False), + RangedValue("imu-sda-voh", 2.4, 3.3, True, False), + RangedValue("imu-sda-vih", 1.9, 3.3, False, False), + RangedValue("temp-sda-voh", 2.8, 3.3, True, False), + RangedValue("temp-sda-vih", 1.8, 3.3, False, False), +] + + +def find_union_of_ranged_values(ranged_values: List[RangedValue]) -> RangedValue: + #if they are series, we sum them + if all([ranged_value.series for ranged_value in ranged_values]): + # Calculate the sum of min and max values + min_union = sum([ranged_value.min_value for ranged_value in ranged_values]) + max_union = sum([ranged_value.max_value for ranged_value in ranged_values]) + + elif not any([ranged_value.series for ranged_value in ranged_values]): + # Initialize min and max with the first RangedValue's min and max values + min_union, max_union = ranged_values[0].min_value, ranged_values[0].max_value + + for ranged_value in ranged_values[1:]: + # Update min and max values if the current RangedValue extends beyond the current union's bounds + min_union = min(min_union, ranged_value.min_value) + max_union = max(max_union, ranged_value.max_value) + + # Return a new RangedValue representing the union of all provided RangedValues + return RangedValue("union", min_union, max_union, True, ranged_values[0].series) + +def find_intersection_of_ranged_values(ranged_values: List[RangedValue]) -> RangedValue: + # Initialize min and max with the first RangedValue's min and max values + min_intersection, max_intersection = ranged_values[0].min_value, ranged_values[0].max_value + + for ranged_value in ranged_values[1:]: + # Update min and max values to find the intersection + min_intersection = max(min_intersection, ranged_value.min_value) + max_intersection = min(max_intersection, ranged_value.max_value) + # If there is no intersection + if min_intersection > max_intersection: + return RangedValue("no_intersection", 0.0, 0.0, False, False) # or any indication that there's no intersection + + return RangedValue("intersection", min_intersection, max_intersection, False, False) + + +#1. find the union of all the expanding ranged values +#2. find the intersection of all the non-expanding ranged values + +# do this for non summing ranges eg voltage: +# Expanding ranges are those that assert something will be true, eg a power supply +expanding_attributes = [ranged_value for ranged_value in example_interfaces if ranged_value.expanding] +expanding_range = find_union_of_ranged_values(expanding_attributes) + +# Contracting ranges are those that assert something will not be true, eg an abs max rating on a microcontroller +contracting_attributes = [ranged_value for ranged_value in example_interfaces if not ranged_value.expanding] +contracting_range = find_intersection_of_ranged_values(contracting_attributes) + +# Check if the intersection of the contracting ranges is within the union of the expanding ranges +intersection = find_intersection_of_ranged_values([expanding_range, contracting_range]) +# print out the result nicely (min val, max val and a pass if the intersection is within the union) +print(f"intersection: {intersection.min_value}, {intersection.max_value}, {intersection.min_value <= expanding_range.min_value and intersection.max_value >= expanding_range.max_value}") + + + +example_interfaces_summing = [ + RangedValue("power_supply.power_out.current", 0.02, 4, False, True), + RangedValue("micro.power.max_current", 0.05, 0.5, True, True), + RangedValue("imu.power.max_current", 0.15, 0.3, True, True), + RangedValue("motor_driver.power.max_current", 0.1, 2.5, True, True), +] + + +# do this for summing ranges eg current: +expanding_attributes = [ranged_value for ranged_value in example_interfaces_summing if ranged_value.expanding] +expanding_range = find_union_of_ranged_values(expanding_attributes) +print(round(expanding_range.min_value, 2), round(expanding_range.max_value, 2)) + +contracting_attributes = [ranged_value for ranged_value in example_interfaces_summing if not ranged_value.expanding] +contracting_range = find_intersection_of_ranged_values(contracting_attributes) +print(round(contracting_range.min_value, 2), round(contracting_range.max_value, 2)) + +intersection = find_intersection_of_ranged_values([expanding_range, contracting_range]) +print(f"intersection: {intersection.min_value}, {intersection.max_value}, {intersection.min_value <= expanding_range.min_value and intersection.max_value >= expanding_range.max_value}") + diff --git a/src/atopile/typing.py b/src/atopile/typing.py new file mode 100644 index 00000000..e69de29b From 2b54420b32130c229cbe986aa25e0ec759c80d21 Mon Sep 17 00:00:00 2001 From: Matthew Wildoer Date: Wed, 13 Mar 2024 16:52:02 -0700 Subject: [PATCH 2/3] Demo of how to import instance tree in jupyter notebook --- sandbox/typing.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 sandbox/typing.py diff --git a/sandbox/typing.py b/sandbox/typing.py new file mode 100644 index 00000000..0a31efe7 --- /dev/null +++ b/sandbox/typing.py @@ -0,0 +1,20 @@ +# %% +import atopile.front_end +import atopile.config +import atopile.address +from pathlib import Path + +PROJECT_PATH = "/Users/mattwildoer/Projects/atopile-workspace/logic-card/elec/src/logic-card.ato" +config = atopile.config.get_project_config_from_path(Path(PROJECT_PATH)) +project_ctx = atopile.config.ProjectContext.from_config(config) +atopile.config.set_project_context(project_ctx) + +root = atopile.front_end.lofty.get_instance(PROJECT_PATH + ":LogicCard") + +# %% + +import atopile.instance_methods + +list(atopile.instance_methods.all_descendants(root.addr)) + +# %% From 2a2c62f04a0359b15fdd37bd6ae43313fb6a8037 Mon Sep 17 00:00:00 2001 From: Matthew Wildoer Date: Fri, 15 Mar 2024 23:13:45 -0700 Subject: [PATCH 3/3] Late-night future-syntax experiments --- sandbox/matt.ato | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 sandbox/matt.ato diff --git a/sandbox/matt.ato b/sandbox/matt.ato new file mode 100644 index 00000000..cbcb56a8 --- /dev/null +++ b/sandbox/matt.ato @@ -0,0 +1,42 @@ +""" +This file containers +""" + +module TopLevel: # we should consider transitioning from module + component -> class + some_var = 3.3V +/- 100mV # maybe this comment should be considered a long-name for some_var + top_signal = Signal() # do we want the new signal + + module_a = new Module: # this is defining and instantiating an anonymous module + a = new Signal + b = new Signal + + top_signal ~ .a + + +module TopLevel: + signal vcc + signal gnd + + v_div = module: + signal v_in + signal v_out + + vcc ~ (r1 = new Resistor) ~ v_out ~ (r2 = new Resistor) ~ gnd + + +module TopLevel: + signal vcc + signal gnd + + v_in = 3.3V +/- 100mV + v_out = 1.65V +/- 100mV + + v_div = module: + signal v_in + signal v_out + + vcc ~ (r1: Resistor) ~ v_out ~ (r2: Resistor) ~ gnd + + assert v_in * r2 / (r1 + r2) within v_out + + \ No newline at end of file