@@ -325,7 +325,7 @@ def _ilim_expr(inductor_ilim: RangeExpr, sw_ilim: RangeExpr, inductor_iripple: R
325325 iout_limit_inductor = inductor_ilim - (inductor_iripple .upper () / 2 )
326326 iout_limit_sw = (sw_ilim .upper () > 0 ).then_else (
327327 sw_ilim - (inductor_iripple .upper () / 2 ), Range .all ())
328- return iout_limit_inductor .intersect (iout_limit_sw )
328+ return iout_limit_inductor .intersect (iout_limit_sw ). intersect ( Range . from_lower ( 0 ))
329329
330330 @init_in_parent
331331 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
337337 ripple_ratio : RangeLike = Range .all ()):
338338 super ().__init__ ()
339339
340- self .pwr_in = self .Port (VoltageSink .empty (), [Power ]) # models the input cap only
341- self .pwr_out = self .Port (VoltageSource .empty ()) # models the output cap and inductor power source
342- self .switch = self .Port (VoltageSink .empty ()) # current draw defined as average
340+ self .pwr_in = self .Port (VoltageSink .empty (), [Power ]) # no modeling, input cap only
341+ self .pwr_out = self .Port (VoltageSource .empty ()) # models max output avg. current
342+ # technically VoltageSink is the wrong model, but this is used to pass the current draw to the chip
343+ # (and its input pin) without need the top-level to explicitly pass a parameter to the chip
344+ self .switch = self .Port (VoltageSink .empty ()) # models input / inductor avg. current draw
343345 self .gnd = self .Port (Ground .empty (), [Common ])
344346
345347 self .input_voltage = self .ArgParameter (input_voltage )
@@ -360,6 +362,7 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc
360362
361363 self .actual_dutycycle = self .Parameter (RangeExpr ())
362364 self .actual_inductor_current_ripple = self .Parameter (RangeExpr ())
365+ self .actual_inductor_current_peak = self .Parameter (RangeExpr ())
363366
364367 def contents (self ):
365368 super ().contents ()
@@ -390,14 +393,16 @@ def generate(self) -> None:
390393 self ._buck_inductor_filter , values .inductor_avg_current .upper , values .ripple_scale , values .min_ripple )
391394 ))
392395 self .assign (self .actual_inductor_current_ripple , values .ripple_scale / self .inductor .actual_inductance )
396+ self .assign (self .actual_inductor_current_peak ,
397+ values .inductor_avg_current + self .actual_inductor_current_ripple / 2 )
393398
394399 self .connect (self .switch , self .inductor .a .adapt_to (VoltageSink (
395- current_draw = self .pwr_out . link (). current_drawn * values .dutycycle
400+ current_draw = self .output_current * values .effective_dutycycle
396401 )))
397402 self .connect (self .pwr_out , self .inductor .b .adapt_to (VoltageSource (
398403 voltage_out = self .output_voltage ,
399404 current_limits = self ._ilim_expr (self .inductor .actual_current_rating , self .sw_current_limits ,
400- self .actual_inductor_current_ripple )
405+ self .actual_inductor_current_ripple ) * self . efficiency
401406 )))
402407
403408 self .in_cap = self .Block (DecouplingCapacitor (
@@ -521,16 +526,16 @@ def _calculate_parameters(cls, input_voltage: Range, output_voltage: Range, freq
521526 @init_in_parent
522527 def __init__ (self , input_voltage : RangeLike , output_voltage : RangeLike , frequency : RangeLike ,
523528 output_current : RangeLike , sw_current_limits : RangeLike , * ,
524- input_voltage_ripple : FloatLike = 75 * mVolt ,
525- output_voltage_ripple : FloatLike = 25 * mVolt ,
529+ input_voltage_ripple : FloatLike ,
530+ output_voltage_ripple : FloatLike ,
526531 efficiency : RangeLike = (0.8 , 1.0 ), # from TI reference
527532 dutycycle_limit : RangeLike = (0.1 , 0.9 ), # arbitrary
528533 ripple_ratio : RangeLike = Range .all ()):
529534 super ().__init__ ()
530535
531- self .pwr_in = self .Port (VoltageSink .empty (), [Power ]) # models input cap and inductor power draw
532- self .pwr_out = self .Port (VoltageSink .empty ()) # only used for the output cap
533- self .switch = self .Port (VoltageSource .empty ()) # current draw defined as average
536+ self .pwr_in = self .Port (VoltageSink .empty (), [Power ]) # models input / inductor avg. current draw
537+ self .pwr_out = self .Port (VoltageSink .empty ()) # no modeling, output cap only
538+ self .switch = self .Port (VoltageSource .empty ()) # models maximum output avg. current
534539 self .gnd = self .Port (Ground .empty (), [Common ])
535540
536541 self .input_voltage = self .ArgParameter (input_voltage )
@@ -551,6 +556,7 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc
551556
552557 self .actual_dutycycle = self .Parameter (RangeExpr ())
553558 self .actual_inductor_current_ripple = self .Parameter (RangeExpr ())
559+ self .actual_inductor_current_peak = self .Parameter (RangeExpr ())
554560
555561 def contents (self ):
556562 super ().contents ()
@@ -582,15 +588,17 @@ def generate(self) -> None:
582588 values .inductor_avg_current .upper , values .ripple_scale , values .min_ripple )
583589 ))
584590 self .assign (self .actual_inductor_current_ripple , values .ripple_scale / self .inductor .actual_inductance )
591+ self .assign (self .actual_inductor_current_peak ,
592+ values .inductor_avg_current + self .actual_inductor_current_ripple / 2 )
585593
586594 self .connect (self .pwr_in , self .inductor .a .adapt_to (VoltageSink (
587- current_draw = self . pwr_out . link (). current_drawn / ( 1 - values .dutycycle )
595+ current_draw = values .inductor_avg_current
588596 )))
589597 self .connect (self .switch , self .inductor .b .adapt_to (VoltageSource (
590598 voltage_out = self .output_voltage ,
591599 current_limits = BuckConverterPowerPath ._ilim_expr (self .inductor .actual_current_rating , self .sw_current_limits ,
592600 self .actual_inductor_current_ripple )
593- * self . input_voltage / self . output_voltage
601+ * ( 1 - values . effective_dutycycle . upper )
594602 )))
595603
596604 self .in_cap = self .Block (DecouplingCapacitor (
@@ -647,10 +655,10 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc
647655 ripple_ratio : RangeLike = Range .all ()):
648656 super ().__init__ ()
649657
650- self .pwr_in = self .Port (VoltageSink .empty (), [Power ]) # connected to the input cap, models input current
651- self .switch_in = self .Port (Passive .empty ()) # models input high and low switch current draws
652- self .switch_out = self .Port (Passive .empty ()) # models output high and low switch current draws
653- self .pwr_out = self .Port (VoltageSink .empty ()) # only used for the output cap
658+ self .pwr_in = self .Port (VoltageSink .empty (), [Power ]) # no modeling, input cap only
659+ self .switch_in = self .Port (VoltageSink .empty ()) # models input / inductor avg. current draw
660+ self .switch_out = self .Port (VoltageSource .empty ()) # models maximum output avg. current
661+ self .pwr_out = self .Port (VoltageSink .empty ()) # no modeling, output cap only
654662 self .gnd = self .Port (Ground .empty (), [Common ])
655663
656664 self .input_voltage = self .ArgParameter (input_voltage )
@@ -671,8 +679,7 @@ def __init__(self, input_voltage: RangeLike, output_voltage: RangeLike, frequenc
671679 self .actual_buck_dutycycle = self .Parameter (RangeExpr ()) # possible actual duty cycle in buck mode
672680 self .actual_boost_dutycycle = self .Parameter (RangeExpr ()) # possible actual duty cycle in boost mode
673681 self .actual_inductor_current_ripple = self .Parameter (RangeExpr ())
674- self .actual_inductor_current = self .Parameter (RangeExpr ()) # inductor current accounting for ripple (upper is peak)
675- self .actual_avg_current_rating = self .Parameter (RangeExpr ()) # determined by inductor rating excl. ripple
682+ self .actual_inductor_current_peak = self .Parameter (RangeExpr ()) # inductor current accounting for ripple (upper is peak)
676683
677684 def contents (self ):
678685 super ().contents ()
@@ -713,13 +720,18 @@ def generate(self) -> None:
713720 BuckConverterPowerPath ._buck_inductor_filter ,
714721 combined_inductor_avg_current .upper , combined_ripple_scale , combined_min_ripple )
715722 ))
716- self .connect (self .switch_in , self .inductor .a )
717- self .connect (self .switch_out , self .inductor .b )
723+ self .connect (self .switch_in , self .inductor .a .adapt_to (VoltageSink (
724+ current_draw = combined_inductor_avg_current
725+ )))
726+ self .connect (self .switch_out , self .inductor .b .adapt_to (VoltageSource (
727+ voltage_out = self .output_voltage ,
728+ current_limits = BuckConverterPowerPath ._ilim_expr (self .inductor .actual_current_rating , self .sw_current_limits ,
729+ self .actual_inductor_current_ripple )
730+ * (1 - boost_values .effective_dutycycle .upper )
731+ )))
718732 self .assign (self .actual_inductor_current_ripple , combined_ripple_scale / self .inductor .actual_inductance )
719- self .assign (self .actual_avg_current_rating ,
720- BuckConverterPowerPath ._ilim_expr (self .inductor .actual_current_rating , self .sw_current_limits ,
721- self .actual_inductor_current_ripple ))
722- self .assign (self .actual_inductor_current , combined_inductor_avg_current + self .actual_inductor_current_ripple / 2 )
733+ self .assign (self .actual_inductor_current_peak ,
734+ combined_inductor_avg_current + self .actual_inductor_current_ripple / 2 )
723735
724736 self .in_cap = self .Block (DecouplingCapacitor (
725737 capacitance = buck_values .input_capacitance .intersect (boost_values .input_capacitance ) * Farad ,
0 commit comments