diff --git a/edg/abstract_parts/AbstractPowerConverters.py b/edg/abstract_parts/AbstractPowerConverters.py index f78ad53a6..bbb67d20a 100644 --- a/edg/abstract_parts/AbstractPowerConverters.py +++ b/edg/abstract_parts/AbstractPowerConverters.py @@ -325,7 +325,7 @@ def _ilim_expr(inductor_ilim: RangeExpr, sw_ilim: RangeExpr, inductor_iripple: R iout_limit_inductor = inductor_ilim - (inductor_iripple.upper() / 2) iout_limit_sw = (sw_ilim.upper() > 0).then_else( sw_ilim - (inductor_iripple.upper() / 2), Range.all()) - return iout_limit_inductor.intersect(iout_limit_sw) + return iout_limit_inductor.intersect(iout_limit_sw).intersect(Range.from_lower(0)) @init_in_parent def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequency: RangeLike, @@ -337,9 +337,11 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc ripple_ratio: RangeLike = Range.all()): super().__init__() - self.pwr_in = self.Port(VoltageSink.empty(), [Power]) # models the input cap only - self.pwr_out = self.Port(VoltageSource.empty()) # models the output cap and inductor power source - self.switch = self.Port(VoltageSink.empty()) # current draw defined as average + self.pwr_in = self.Port(VoltageSink.empty(), [Power]) # no modeling, input cap only + self.pwr_out = self.Port(VoltageSource.empty()) # models max output avg. current + # technically VoltageSink is the wrong model, but this is used to pass the current draw to the chip + # (and its input pin) without need the top-level to explicitly pass a parameter to the chip + self.switch = self.Port(VoltageSink.empty()) # models input / inductor avg. current draw self.gnd = self.Port(Ground.empty(), [Common]) self.input_voltage = self.ArgParameter(input_voltage) @@ -360,6 +362,7 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc self.actual_dutycycle = self.Parameter(RangeExpr()) self.actual_inductor_current_ripple = self.Parameter(RangeExpr()) + self.actual_inductor_current_peak = self.Parameter(RangeExpr()) def contents(self): super().contents() @@ -390,14 +393,16 @@ def generate(self) -> None: self._buck_inductor_filter, values.inductor_avg_current.upper, values.ripple_scale, values.min_ripple) )) self.assign(self.actual_inductor_current_ripple, values.ripple_scale / self.inductor.actual_inductance) + self.assign(self.actual_inductor_current_peak, + values.inductor_avg_current + self.actual_inductor_current_ripple / 2) self.connect(self.switch, self.inductor.a.adapt_to(VoltageSink( - current_draw=self.pwr_out.link().current_drawn * values.dutycycle + current_draw=self.output_current * values.effective_dutycycle ))) self.connect(self.pwr_out, self.inductor.b.adapt_to(VoltageSource( voltage_out=self.output_voltage, current_limits=self._ilim_expr(self.inductor.actual_current_rating, self.sw_current_limits, - self.actual_inductor_current_ripple) + self.actual_inductor_current_ripple) * self.efficiency ))) self.in_cap = self.Block(DecouplingCapacitor( @@ -521,16 +526,16 @@ def _calculate_parameters(cls, input_voltage: Range, output_voltage: Range, freq @init_in_parent def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequency: RangeLike, output_current: RangeLike, sw_current_limits: RangeLike, *, - input_voltage_ripple: FloatLike = 75*mVolt, - output_voltage_ripple: FloatLike = 25*mVolt, + input_voltage_ripple: FloatLike, + output_voltage_ripple: FloatLike, efficiency: RangeLike = (0.8, 1.0), # from TI reference dutycycle_limit: RangeLike = (0.1, 0.9), # arbitrary ripple_ratio: RangeLike = Range.all()): super().__init__() - self.pwr_in = self.Port(VoltageSink.empty(), [Power]) # models input cap and inductor power draw - self.pwr_out = self.Port(VoltageSink.empty()) # only used for the output cap - self.switch = self.Port(VoltageSource.empty()) # current draw defined as average + self.pwr_in = self.Port(VoltageSink.empty(), [Power]) # models input / inductor avg. current draw + self.pwr_out = self.Port(VoltageSink.empty()) # no modeling, output cap only + self.switch = self.Port(VoltageSource.empty()) # models maximum output avg. current self.gnd = self.Port(Ground.empty(), [Common]) self.input_voltage = self.ArgParameter(input_voltage) @@ -551,6 +556,7 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc self.actual_dutycycle = self.Parameter(RangeExpr()) self.actual_inductor_current_ripple = self.Parameter(RangeExpr()) + self.actual_inductor_current_peak = self.Parameter(RangeExpr()) def contents(self): super().contents() @@ -582,15 +588,17 @@ def generate(self) -> None: values.inductor_avg_current.upper, values.ripple_scale, values.min_ripple) )) self.assign(self.actual_inductor_current_ripple, values.ripple_scale / self.inductor.actual_inductance) + self.assign(self.actual_inductor_current_peak, + values.inductor_avg_current + self.actual_inductor_current_ripple / 2) self.connect(self.pwr_in, self.inductor.a.adapt_to(VoltageSink( - current_draw=self.pwr_out.link().current_drawn / (1 - values.dutycycle) + current_draw=values.inductor_avg_current ))) self.connect(self.switch, self.inductor.b.adapt_to(VoltageSource( voltage_out=self.output_voltage, current_limits=BuckConverterPowerPath._ilim_expr(self.inductor.actual_current_rating, self.sw_current_limits, self.actual_inductor_current_ripple) - * self.input_voltage / self.output_voltage + * (1 - values.effective_dutycycle.upper) ))) self.in_cap = self.Block(DecouplingCapacitor( @@ -647,10 +655,10 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc ripple_ratio: RangeLike = Range.all()): super().__init__() - self.pwr_in = self.Port(VoltageSink.empty(), [Power]) # connected to the input cap, models input current - self.switch_in = self.Port(Passive.empty()) # models input high and low switch current draws - self.switch_out = self.Port(Passive.empty()) # models output high and low switch current draws - self.pwr_out = self.Port(VoltageSink.empty()) # only used for the output cap + self.pwr_in = self.Port(VoltageSink.empty(), [Power]) # no modeling, input cap only + self.switch_in = self.Port(VoltageSink.empty()) # models input / inductor avg. current draw + self.switch_out = self.Port(VoltageSource.empty()) # models maximum output avg. current + self.pwr_out = self.Port(VoltageSink.empty()) # no modeling, output cap only self.gnd = self.Port(Ground.empty(), [Common]) self.input_voltage = self.ArgParameter(input_voltage) @@ -671,8 +679,7 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc self.actual_buck_dutycycle = self.Parameter(RangeExpr()) # possible actual duty cycle in buck mode self.actual_boost_dutycycle = self.Parameter(RangeExpr()) # possible actual duty cycle in boost mode self.actual_inductor_current_ripple = self.Parameter(RangeExpr()) - self.actual_inductor_current = self.Parameter(RangeExpr()) # inductor current accounting for ripple (upper is peak) - self.actual_avg_current_rating = self.Parameter(RangeExpr()) # determined by inductor rating excl. ripple + self.actual_inductor_current_peak = self.Parameter(RangeExpr()) # inductor current accounting for ripple (upper is peak) def contents(self): super().contents() @@ -713,13 +720,18 @@ def generate(self) -> None: BuckConverterPowerPath._buck_inductor_filter, combined_inductor_avg_current.upper, combined_ripple_scale, combined_min_ripple) )) - self.connect(self.switch_in, self.inductor.a) - self.connect(self.switch_out, self.inductor.b) + self.connect(self.switch_in, self.inductor.a.adapt_to(VoltageSink( + current_draw=combined_inductor_avg_current + ))) + self.connect(self.switch_out, self.inductor.b.adapt_to(VoltageSource( + voltage_out=self.output_voltage, + current_limits=BuckConverterPowerPath._ilim_expr(self.inductor.actual_current_rating, self.sw_current_limits, + self.actual_inductor_current_ripple) + * (1 - boost_values.effective_dutycycle.upper) + ))) self.assign(self.actual_inductor_current_ripple, combined_ripple_scale / self.inductor.actual_inductance) - self.assign(self.actual_avg_current_rating, - BuckConverterPowerPath._ilim_expr(self.inductor.actual_current_rating, self.sw_current_limits, - self.actual_inductor_current_ripple)) - self.assign(self.actual_inductor_current, combined_inductor_avg_current + self.actual_inductor_current_ripple / 2) + self.assign(self.actual_inductor_current_peak, + combined_inductor_avg_current + self.actual_inductor_current_ripple / 2) self.in_cap = self.Block(DecouplingCapacitor( capacitance=buck_values.input_capacitance.intersect(boost_values.input_capacitance) * Farad, diff --git a/edg/abstract_parts/DummyDevices.py b/edg/abstract_parts/DummyDevices.py index 45d5ae932..4f0531611 100644 --- a/edg/abstract_parts/DummyDevices.py +++ b/edg/abstract_parts/DummyDevices.py @@ -106,6 +106,25 @@ def __init__(self, forced_current_draw: RangeLike) -> None: ), [Output]) +class ForcedVoltageCurrentLimit(DummyDevice, NetBlock): + """Forces some output current limit, which should be tighter than the input's actual current draw.""" + @init_in_parent + def __init__(self, forced_current_limit: RangeLike) -> None: + super().__init__() + + self.pwr_in = self.Port(VoltageSink( + current_draw=RangeExpr(), + voltage_limits=RangeExpr.ALL + ), [Input]) + + self.pwr_out = self.Port(VoltageSource( + voltage_out=self.pwr_in.link().voltage, + current_limits=forced_current_limit + ), [Output]) + + self.assign(self.pwr_in.current_draw, self.pwr_out.link().current_drawn) + + class ForcedVoltage(DummyDevice, NetBlock): """Forces some voltage on the output regardless of the input's actual voltage. Current draw is passed through unchanged.""" diff --git a/edg/abstract_parts/PowerCircuits.py b/edg/abstract_parts/PowerCircuits.py index 313ca048c..3fddbed61 100644 --- a/edg/abstract_parts/PowerCircuits.py +++ b/edg/abstract_parts/PowerCircuits.py @@ -46,6 +46,8 @@ def __init__(self, frequency: RangeLike, fet_rds: RangeLike = (0, 1)*Ohm, self.fet_rds = self.ArgParameter(fet_rds) self.gate_res = self.ArgParameter(gate_res) + self.actual_current_limits = self.Parameter(RangeExpr()) + def contents(self): super().contents() self.driver = self.Block(HalfBridgeDriver(has_boot_diode=True)) @@ -94,6 +96,9 @@ def contents(self): self.out) self.connect(self.out.as_ground((0, 0)*Amp), self.driver.high_gnd) # TODO model driver current + self.assign(self.actual_current_limits, self.low_fet.actual_drain_current_rating.intersect( + self.high_fet.actual_drain_current_rating)) + class FetHalfBridgeIndependent(FetHalfBridge, HalfBridgeIndependent): def contents(self): diff --git a/edg/abstract_parts/__init__.py b/edg/abstract_parts/__init__.py index 961ace175..33453070d 100644 --- a/edg/abstract_parts/__init__.py +++ b/edg/abstract_parts/__init__.py @@ -107,8 +107,8 @@ from .DummyDevices import DummyPassive, DummyGround, DummyVoltageSource, DummyVoltageSink, DummyDigitalSink, \ DummyAnalogSource, DummyAnalogSink -from .DummyDevices import ForcedVoltageCurrentDraw, ForcedVoltage, ForcedVoltageCurrent, ForcedAnalogVoltage,\ - ForcedAnalogSignal, ForcedDigitalSinkCurrentDraw +from .DummyDevices import ForcedVoltageCurrentDraw, ForcedVoltageCurrentLimit, ForcedVoltage, ForcedVoltageCurrent, \ + ForcedAnalogVoltage, ForcedAnalogSignal, ForcedDigitalSinkCurrentDraw from .MergedBlocks import MergedVoltageSource, MergedDigitalSource, MergedAnalogSource, MergedSpiController from .Nonstrict3v3Compatible import Nonstrict3v3Compatible diff --git a/edg/abstract_parts/test_switching_converters.py b/edg/abstract_parts/test_switching_converters.py index a399f7802..f974d6f9d 100644 --- a/edg/abstract_parts/test_switching_converters.py +++ b/edg/abstract_parts/test_switching_converters.py @@ -1,7 +1,10 @@ import unittest from .AbstractPowerConverters import BuckConverterPowerPath, BoostConverterPowerPath -from ..core import Range +from ..electronics_model import * +from .AbstractInductor import Inductor +from .AbstractCapacitor import Capacitor +from .DummyDevices import DummyVoltageSource, DummyVoltageSink, DummyGround class SwitchingConverterCalculationTest(unittest.TestCase): @@ -87,3 +90,88 @@ def test_boost_converter_example(self): self.assertAlmostEqual(values.inductor_peak_currents.upper, 1.44, places=2) # the example calculation output is wrong, this is the correct result of the formula self.assertAlmostEqual(values.output_capacitance.lower, 9.95e-6, places=7) + + +class TestCapacitor(Capacitor): + def contents(self): + super().contents() + self.assign(self.actual_capacitance, self.capacitance) + self.assign(self.actual_voltage_rating, Range.all()) + + +class TestInductor(Inductor): + def contents(self): + super().contents() + self.assign(self.actual_inductance, self.inductance) + self.assign(self.actual_current_rating, (0, 1.5)*Amp) + self.assign(self.actual_frequency_rating, Range.all()) + + +class BuckPowerPathTestTop(DesignTop): + def __init__(self): + super().__init__() + self.dut = self.Block(BuckConverterPowerPath( + input_voltage=Range(4, 6), output_voltage=(2, 3), + frequency= Range.exact(100e3), output_current=Range(0.2, 1), + sw_current_limits=Range(0, 2), + input_voltage_ripple=75*mVolt, output_voltage_ripple=25*mVolt, + )) + (self.pwr_in, ), _ = self.chain(self.Block(DummyVoltageSource()), self.dut.pwr_in) + (self.switch, ), _ = self.chain(self.Block(DummyVoltageSource()), self.dut.switch) + (self.pwr_out, ), _ = self.chain(self.Block(DummyVoltageSink()), self.dut.pwr_out) + (self.gnd, ), _ = self.chain(self.Block(DummyGround()), self.dut.gnd) + + self.require(self.dut.actual_dutycycle.contains(Range(0.334, 0.832))) + self.require(self.dut.actual_inductor_current_ripple.contains(Range(0.433, 0.478))) + self.require(self.dut.pwr_out.current_limits.contains(Range(0.0, 1.260))) + self.require(self.dut.switch.current_draw.contains(Range(0.067, 0.832))) + + def refinements(self) -> Refinements: + return Refinements( + class_refinements=[ + (Capacitor, TestCapacitor), + (Inductor, TestInductor), + ], + instance_values=[ + (['dut', 'inductor', 'actual_inductance'], Range.from_tolerance(33e-6, 0.05)) + ] + ) + + +class BoostPowerPathTestTop(DesignTop): + def __init__(self): + super().__init__() + self.dut = self.Block(BoostConverterPowerPath( + input_voltage=Range(4, 6), output_voltage=(10, 14), + frequency=Range.exact(200e3), output_current=Range(0.2, 0.5), + sw_current_limits=Range(0, 2), + input_voltage_ripple=75*mVolt, output_voltage_ripple=25*mVolt, + )) + (self.pwr_in, ), _ = self.chain(self.Block(DummyVoltageSource()), self.dut.pwr_in) + (self.pwr_out, ), _ = self.chain(self.Block(DummyVoltageSource()), self.dut.pwr_out) + (self.switch, ), _ = self.chain(self.Block(DummyVoltageSink()), self.dut.switch) + (self.gnd, ), _ = self.chain(self.Block(DummyGround()), self.dut.gnd) + + self.require(self.dut.actual_dutycycle.contains(Range(0.4, 0.771))) + self.require(self.dut.actual_inductor_current_ripple.contains(Range(0.495, 0.546))) + self.require(self.dut.pwr_in.current_draw.contains(Range(0.334, 2.185))) + self.require(self.dut.switch.current_limits.contains(Range(0.0, 0.280))) + + def refinements(self) -> Refinements: + return Refinements( + class_refinements=[ + (Capacitor, TestCapacitor), + (Inductor, TestInductor), + ], + instance_values=[ + (['dut', 'inductor', 'actual_inductance'], Range.from_tolerance(33e-6, 0.05)) + ] + ) + + +class PowerPathBlockTest(unittest.TestCase): + def test_buck_power_path(self) -> None: + ScalaCompiler.compile(BuckPowerPathTestTop) + + def test_boost_power_path(self) -> None: + ScalaCompiler.compile(BoostPowerPathTestTop) diff --git a/edg/parts/BuckBoostConverter_Custom.py b/edg/parts/BuckBoostConverter_Custom.py index 306148ccd..09c8cddaa 100644 --- a/edg/parts/BuckBoostConverter_Custom.py +++ b/edg/parts/BuckBoostConverter_Custom.py @@ -18,6 +18,19 @@ def __init__(self, voltage_out: RangeLike, a_current_limits: RangeLike, b_curren ), [Output]) # exterior source: set output voltage + Ilim +class VoltageSourceConnector(DummyDevice, NetBlock): + """Connects two voltage sources together (inductor output to FET center 'source').""" + @init_in_parent + def __init__(self, a_current_draw: RangeLike, b_current_draw: RangeLike) -> None: + super().__init__() + self.a = self.Port(VoltageSink( + current_draw=a_current_draw + ), [Input]) # FET top: set output voltage, allow instantaneous current draw + self.b = self.Port(VoltageSink( + current_draw=b_current_draw + ), [Output]) # exterior source: set output voltage + Ilim + + class CustomSyncBuckBoostConverterPwm(DiscreteBoostConverter, Resettable): """Custom synchronous buck-boost with four PWMs for the switches. Because of the MOSFET body diode, will probably be fine-ish if the buck low-side FET and the boost high-side FET @@ -26,7 +39,7 @@ class CustomSyncBuckBoostConverterPwm(DiscreteBoostConverter, Resettable): def __init__(self, *args, frequency: RangeLike = (100, 1000)*kHertz, ripple_ratio: RangeLike = (0.2, 0.5), - voltage_drop: RangeLike = (0, 1)*Volt, rds_on: RangeLike = (0, 1.0)*Ohm, + rds_on: RangeLike = (0, 1.0)*Ohm, **kwargs): super().__init__(*args, **kwargs) @@ -36,7 +49,6 @@ def __init__(self, *args, self.frequency = self.ArgParameter(frequency) self.ripple_ratio = self.ArgParameter(ripple_ratio) - self.voltage_drop = self.ArgParameter(voltage_drop) self.rds_on = self.ArgParameter(rds_on) def contents(self): @@ -54,36 +66,40 @@ def contents(self): self.connect(self.power_path.pwr_out, self.pwr_out) self.connect(self.power_path.gnd, self.gnd) - self.buck_sw = self.Block(FetHalfBridge(frequency=self.frequency)) + self.buck_sw = self.Block(FetHalfBridge(frequency=self.frequency, fet_rds=self.rds_on)) self.connect(self.buck_sw.gnd, self.gnd) self.connect(self.buck_sw.pwr_logic, self.pwr_logic) self.connect(self.buck_sw.with_mixin(HalfBridgePwm()).pwm_ctl, self.buck_pwm) self.connect(self.buck_sw.with_mixin(Resettable()).reset, self.reset) - (self.pwr_in_forced, ), _ = self.chain( # use average draw instead of peak for external draw specs + (self.pwr_in_force, ), _ = self.chain( # use average draw for power input draw self.pwr_in, - self.Block(ForcedVoltageCurrentDraw(self.pwr_out.link().current_drawn * - self.output_voltage / self.pwr_in.link().voltage / - self.power_path.efficiency)), + self.Block(ForcedVoltageCurrentDraw(self.power_path.switch_in.current_draw)), self.buck_sw.pwr ) - self.connect( # current draw used to size FETs, size for peak current + (self.sw_in_force, ), _ = self.chain( # current draw used to size FETs, size for peak current self.buck_sw.out, - self.power_path.switch_in.adapt_to(VoltageSink(current_draw=self.power_path.actual_inductor_current)) + self.Block(ForcedVoltageCurrentDraw(self.power_path.actual_inductor_current_peak)), + self.power_path.switch_in ) - self.boost_sw = self.Block(FetHalfBridge(frequency=self.frequency)) + self.boost_sw = self.Block(FetHalfBridge(frequency=self.frequency, fet_rds=self.rds_on)) self.connect(self.boost_sw.gnd, self.gnd) self.connect(self.boost_sw.pwr_logic, self.pwr_logic) self.connect(self.boost_sw.with_mixin(HalfBridgePwm()).pwm_ctl, self.boost_pwm) self.connect(self.boost_sw.with_mixin(Resettable()).reset, self.reset) - (self.boost_pwr_conn, ), _ = self.chain( + sw_current_limits = self.buck_sw.actual_current_limits.intersect(self.boost_sw.actual_current_limits) + (self.pwr_out_force, ), _ = self.chain( # use average output limits for power out limits self.boost_sw.pwr, self.Block(VoltageSinkConnector(self.output_voltage, - self.power_path.actual_inductor_current, - self.power_path.actual_avg_current_rating)), + Range.all(), # unused, port actually in reverse + self.power_path.switch_out.current_limits.intersect( + sw_current_limits - self.power_path.actual_inductor_current_ripple.upper() / 2 + ).intersect(Range.from_lower(0)))), self.pwr_out ) - self.connect( # current draw used to size FETs, size for peak current - self.power_path.switch_out.adapt_to(VoltageSink(current_draw=self.power_path.actual_inductor_current)), + (self.sw_out_force, ), _ = self.chain( # current draw used to size FETs, size for peak current + self.power_path.switch_out, + self.Block(VoltageSourceConnector(Range.exact(0), + self.power_path.actual_inductor_current_peak)), self.boost_sw.out ) diff --git a/edg/parts/BuckConverter_Custom.py b/edg/parts/BuckConverter_Custom.py index 026153d01..a85b9c1a0 100644 --- a/edg/parts/BuckConverter_Custom.py +++ b/edg/parts/BuckConverter_Custom.py @@ -33,12 +33,11 @@ def contents(self): ripple_ratio=self.ripple_ratio )) self.connect(self.power_path.pwr_in, self.pwr_in) - self.connect(self.power_path.pwr_out, self.pwr_out) self.connect(self.power_path.gnd, self.gnd) - self.sw = self.Block(FetHalfBridge(frequency=self.frequency)) + self.sw = self.Block(FetHalfBridge(frequency=self.frequency, fet_rds=self.rds_on)) self.connect(self.sw.gnd, self.gnd) - (self.sw_in_force, ), _ = self.chain( # use average current draw for boundary ports + (self.pwr_in_force, ), _ = self.chain( # use average current draw for boundary ports self.pwr_in, self.Block(ForcedVoltageCurrentDraw(self.power_path.switch.link().current_drawn)), self.sw.pwr) @@ -46,8 +45,15 @@ def contents(self): sw_ctl = self.sw.with_mixin(HalfBridgeIndependent()) self.connect(sw_ctl.low_ctl, self.pwm_low) self.connect(sw_ctl.high_ctl, self.pwm_high) - (self.sw_force, ), _ = self.chain( + (self.sw_out_force, ), _ = self.chain( self.sw.out, # current draw used to size FETs, size for peak current - self.Block(ForcedVoltageCurrentDraw(self.power_path.output_current - + self.power_path.actual_inductor_current_ripple / 2)), + self.Block(ForcedVoltageCurrentDraw(self.power_path.actual_inductor_current_peak)), self.power_path.switch) + (self.pwr_out_force, ), _ = self.chain( + self.power_path.pwr_out, + self.Block(ForcedVoltageCurrentLimit(self.power_path.pwr_out.current_limits.intersect( + self.sw.actual_current_limits - self.power_path.actual_inductor_current_ripple.upper() / 2).intersect( + Range.from_lower(0) + ))), + self.pwr_out + ) diff --git a/edg/parts/FanConnector.py b/edg/parts/FanConnector.py index 7911934d0..e85bfffb9 100644 --- a/edg/parts/FanConnector.py +++ b/edg/parts/FanConnector.py @@ -9,7 +9,7 @@ def __init__(self): self.gnd = self.Port(Ground(), [Common]) self.pwr = self.Port(VoltageSink( voltage_limits=12*Volt(tol=0.05), - current_draw=(0, 2.2)*Amp, # section 2.1.2: 2.2A max for up to 2s during startup + current_draw=(0, 2.2)*Amp, # section 2.1.2: 2.2A max up to 1s during startup, steady-state 1.5A ), [Power]) self.sense = self.Port(DigitalSource.low_from_supply(self.gnd)) # tolerant up to 12v diff --git a/examples/IotIron/IotIron.net b/examples/IotIron/IotIron.net index 27f167d92..d9e6dad84 100644 --- a/examples/IotIron/IotIron.net +++ b/examples/IotIron/IotIron.net @@ -1366,7 +1366,7 @@ (net (code 54) (name "Iledr.res.a") (node (ref ledr.res) (pin 1)) (node (ref ledr.package) (pin 1))) -(net (code 55) (name "Iconv.sw_force") +(net (code 55) (name "Iconv.sw_out_force") (node (ref conv.sw.low_fet) (pin 5)) (node (ref conv.sw.low_fet) (pin 6)) (node (ref conv.sw.low_fet) (pin 7)) diff --git a/examples/IotIron/IotIron.ref.net b/examples/IotIron/IotIron.ref.net index 00156dea4..f3001a861 100644 --- a/examples/IotIron/IotIron.ref.net +++ b/examples/IotIron/IotIron.ref.net @@ -1366,7 +1366,7 @@ (net (code 54) (name "Iledr.res.a") (node (ref IR10) (pin 1)) (node (ref ID2) (pin 1))) -(net (code 55) (name "Iconv.sw_force") +(net (code 55) (name "Iconv.sw_out_force") (node (ref IQ1) (pin 5)) (node (ref IQ1) (pin 6)) (node (ref IQ1) (pin 7)) diff --git a/examples/UsbSourceMeasure/UsbSourceMeasure.net b/examples/UsbSourceMeasure/UsbSourceMeasure.net index 96474fd98..5ddf76517 100644 --- a/examples/UsbSourceMeasure/UsbSourceMeasure.net +++ b/examples/UsbSourceMeasure/UsbSourceMeasure.net @@ -3390,13 +3390,13 @@ (net (code 96) (name "reg_v5.en_res.b") (node (ref reg_v5.en_res) (pin 2)) (node (ref reg_v5.ic) (pin 5))) -(net (code 97) (name "conv.power_path.switch_in") - (node (ref conv.power_path.inductor) (pin 1)) +(net (code 97) (name "conv.sw_in_force") (node (ref conv.buck_sw.low_fet) (pin 2)) (node (ref conv.buck_sw.high_fet) (pin 3)) + (node (ref conv.power_path.inductor) (pin 1)) (node (ref conv.buck_sw.driver.ic) (pin 7)) (node (ref conv.buck_sw.driver.high_cap) (pin 2))) -(net (code 98) (name "conv.power_path.switch_out") +(net (code 98) (name "conv.sw_out_force") (node (ref conv.power_path.inductor) (pin 2)) (node (ref conv.boost_sw.low_fet) (pin 2)) (node (ref conv.boost_sw.high_fet) (pin 3)) diff --git a/examples/UsbSourceMeasure/UsbSourceMeasure.ref.net b/examples/UsbSourceMeasure/UsbSourceMeasure.ref.net index 4cba5aa24..954fc6bb6 100644 --- a/examples/UsbSourceMeasure/UsbSourceMeasure.ref.net +++ b/examples/UsbSourceMeasure/UsbSourceMeasure.ref.net @@ -3390,13 +3390,13 @@ (net (code 96) (name "reg_v5.en_res.b") (node (ref R3) (pin 2)) (node (ref U1) (pin 5))) -(net (code 97) (name "conv.power_path.switch_in") - (node (ref L2) (pin 1)) +(net (code 97) (name "conv.sw_in_force") (node (ref Q1) (pin 2)) (node (ref Q2) (pin 3)) + (node (ref L2) (pin 1)) (node (ref U3) (pin 7)) (node (ref C21) (pin 2))) -(net (code 98) (name "conv.power_path.switch_out") +(net (code 98) (name "conv.sw_out_force") (node (ref L2) (pin 2)) (node (ref Q3) (pin 2)) (node (ref Q4) (pin 3))