# Using a behavioral voltage source as a zero crossing detector for inductance current in LTSpice

I'm trying to simulate a buck converter IC in LTSpice (MP4569) based on the functional block diagram from the datasheet using behavioral voltage sources to represent the logic from the block diagram.

I have 2 switches in place of the high and low side mosfets and the switches are driven by behavioral voltage sources.

I'm trying to implement the zero current detection block (ZCD block on the diagram) with a behavioral voltage source with the condition comparing the current to a threshold (V=(I(L1)>1m), the number is arbitrary, just a small near-zero value, could be zero.

The LTSpice model is available here.

I end up having the output of the ZCD voltage source in the simulation to be always 0 (after the initial 1 in the very beginning), BUT the current in the inductance is oscillating (very small amplitude) just above the limit in the ZCD voltage source (whatever I set it to). Also the simulation slows down to a crawl at this point and never completes, I have to stop it.

It appears that it does trigger the voltage source, but very briefly and it's not visible on the output when plotted in the simulation, but it does affect the behavior of the switch.

Maybe some kind of hysteresis is needed around the zero current for this ZCD voltage source, but I cannot figure out how to add it. I tried adding a flip-flop with 2 behavioral voltage sources connected to Set and Reset but it didn't help and I'm still getting similar behavior

• Why on Earth would you use behavioural sources with discontinuous and convergent-unfriendly conditionals, when ou have the A-devices especially for that, not only guaranteed to converge, but also faster and a lot more flexible? Jul 1 '20 at 6:51
• @aconcernedcitizen, I don't have much experience with SPICE. Wanted a simplified model of the buck IC, A-devices? Analog? Existing models from manufacturers?
– axk
Jul 1 '20 at 8:11
• I mean the ones in [Digital]/*. Also see the help for LTspice > Circuit Elements > A. ..., or the ltwiki undocumented features. Jul 1 '20 at 14:48
• @aconcernedcitizen, thanks! after replacing the B-sources with a combination of diffschmitt, inv and and it all worked! You can post this as an answer if you want.
– axk
Jul 1 '20 at 19:19

Besides @Voltage Spike's answer, a warm recommendation would be to avoid conditionals in behavioural expressions like if(), buf(), etc (or other discontinuous functions like limit(), uramp(), etc), because the solver might get stuck with "timestep too small". They might work, they might not, they could be attempted to be "tamed" with some strategically placed small capacitors to help out the sharp transitions, but there already is a very convergent-friendly solution: A-devices.

For your case, you can replace these:

• the negation in B2 and the one for the second term in B3 with [Digital]/inv
• the AND for B3 and B7 with [Digital]/and
• all the conditionals in B4, B6, and B8 with either [Digital]/schmitt (or diffschmitt) with vt=<...> vh=0, or with [Digital]/buf with ref=<...>
• the conditional for the 2nd term in B7 with [Digital]/schmitt with vt=0 vh=0, or with buf1 with ref=0

For the cases where you need to use a voltage, it's simple, just add the respective node to the input of the logic gate. For currents, since you're only using I(L1), you can add an H-source with L1 1 as value (which might be a better choice than a B-source).

And, while we're at it:

• (important!) you named ZCD both the node for the Q output of A2 and the output of B4. Since you are using a behavioural voltage source, it can't be intentional
• you may also change B6 with a normal voltage source. I only see it used in B7, so you can just delete the source altogether and use an inv with ref=1
• delete the resistors R1 and R[6,7,8,9], they're not needed. The A-devices have a default output resistance of 1 Ω (one exception, not needed here), so adding a resistor will change the output levels
• C1 is useless there since voltage sources have zero internal resistance. You could add a seris resistance between the source and the cap, but you'd be better off adding Rser to the source, in which case C1 can be safely deleted and Cpar can be specified in the source.
• a bit of a "heads-up", you'll most probably need some dead-time for the drivers, so in that case you should add some anti-parallel diodes to the switches. Since you're on the theoretical or, at least, the ideal side, a .model d d ron=10m roff=10meg vfwd=0.7 epsilon=0.1 revepsilon=50m will do just fine.

On the bright side, the VCSW have their .model cards with a negative hysteresis and very acceptable range between the ON/OFF states, so that's a bravo from me.

With these, here's a quick remake:

And the .asc file, where I have only used td for the srflop; feel free to add tau and tripdt, they will only help:

Version 4
SHEET 1 1100 688
WIRE 320 -112 240 -112
WIRE 928 -112 320 -112
WIRE -112 -80 -160 -80
WIRE 0 -80 -48 -80
WIRE 144 -80 96 -80
WIRE 160 -80 144 -80
WIRE 240 -48 240 -112
WIRE 0 -32 -32 -32
WIRE 144 -32 112 -32
WIRE 192 -32 144 -32
WIRE 320 -32 320 -112
WIRE 928 -32 928 -112
WIRE -256 48 -304 48
WIRE -112 48 -192 48
WIRE -32 48 -32 -32
WIRE -32 48 -48 48
WIRE -112 80 -128 80
WIRE 240 112 240 32
WIRE 320 112 320 32
WIRE 320 112 240 112
WIRE 384 112 320 112
WIRE 512 112 464 112
WIRE 592 112 512 112
WIRE 672 112 592 112
WIRE 720 112 672 112
WIRE 832 112 800 112
WIRE 848 112 832 112
WIRE 240 144 240 112
WIRE 672 144 672 112
WIRE 176 160 128 160
WIRE 192 160 176 160
WIRE 320 160 320 112
WIRE 512 160 512 112
WIRE 848 160 848 112
WIRE 32 240 -16 240
WIRE 128 240 128 160
WIRE 128 240 96 240
WIRE 32 272 -16 272
WIRE 240 272 240 224
WIRE 320 272 320 224
WIRE 320 272 240 272
WIRE 384 272 320 272
WIRE 512 272 512 224
WIRE 512 272 384 272
WIRE 672 272 672 224
WIRE 672 272 512 272
WIRE 848 272 848 240
WIRE 848 272 672 272
WIRE 928 272 928 48
WIRE 928 272 848 272
WIRE 560 416 496 416
WIRE 608 416 560 416
WIRE 752 416 672 416
WIRE 768 416 752 416
WIRE -80 432 -128 432
WIRE -32 432 -80 432
WIRE 96 432 32 432
WIRE 224 432 192 432
WIRE 240 432 224 432
WIRE 96 480 48 480
WIRE 224 480 208 480
WIRE 240 480 224 480
WIRE -80 560 -80 432
WIRE -32 560 -80 560
WIRE 48 560 48 480
WIRE 48 560 32 560
FLAG 192 16 0
FLAG 192 208 0
FLAG 384 272 0
FLAG 592 112 out
FLAG 144 -32 _LQ
FLAG 176 160 x
FLAG 496 496 0
FLAG 560 416 i
FLAG 752 416 _i
FLAG -160 -80 i
FLAG 832 112 fb
FLAG -304 48 fb
FLAG -128 80 zcd
FLAG -128 432 i
FLAG 224 480 _zcd
FLAG 224 432 zcd
FLAG 144 -80 LQ
FLAG -16 240 LQ
FLAG -16 272 _zcd
SYMBOL voltage 928 -48 R0
WINDOW 123 24 118 Left 2
WINDOW 39 24 140 Left 2
SYMATTR InstName V1
SYMATTR Value pwl 0 0 1u 56
SYMATTR Value2 Rser=10m
SYMATTR SpiceLine Cpar=1m
SYMBOL ind 368 128 R270
WINDOW 0 32 56 VTop 2
WINDOW 3 5 56 VBottom 2
SYMATTR InstName L1
SYMATTR Value 33u
SYMBOL cap 496 160 R0
SYMATTR InstName C1
SYMATTR Value 22u rser=50m
SYMBOL sw 240 48 M180
SYMATTR InstName S1
SYMATTR Value up
SYMBOL sw 240 240 M180
SYMATTR InstName S2
SYMATTR Value dn
SYMBOL diode 304 32 M180
WINDOW 0 24 64 Left 2
WINDOW 3 24 0 Left 2
SYMATTR InstName D1
SYMBOL diode 304 224 M180
WINDOW 0 24 64 Left 2
WINDOW 3 24 0 Left 2
SYMATTR InstName D2
SYMBOL res 656 128 R0
SYMATTR InstName R1
SYMATTR Value 33
SYMBOL Digital\\srflop 48 -128 R0
WINDOW 3 -40 34 Left 2
SYMATTR InstName A1
SYMATTR Value td=10n
SYMBOL h 496 400 R0
WINDOW 0 33 68 Left 2
SYMATTR InstName H1
SYMATTR Value L1 1
SYMBOL Digital\\inv 608 352 R0
SYMATTR InstName A2
SYMBOL Digital\\buf1 -112 -144 R0
WINDOW 3 -2 94 Left 2
SYMATTR InstName A3
SYMATTR Value ref=0.7
SYMBOL Digital\\inv -256 -16 R0
WINDOW 3 -4 99 Left 2
SYMATTR InstName A4
SYMATTR Value ref=1
SYMBOL res 816 96 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R2
SYMATTR Value 1.2Meg
SYMBOL res 832 144 R0
SYMATTR InstName R3
SYMATTR Value 510k
SYMBOL Digital\\and -80 0 R0
SYMATTR InstName A5
SYMBOL Digital\\inv -32 368 R0
WINDOW 3 -4 99 Left 2
SYMATTR InstName A6
SYMATTR Value ref=10m
SYMBOL Digital\\buf1 -32 496 R0
WINDOW 3 -2 94 Left 2
SYMATTR InstName A8
SYMATTR Value ref=20m
SYMBOL Digital\\srflop 144 384 R0
WINDOW 3 -40 34 Left 2
SYMATTR InstName A7
SYMATTR Value td=10n
SYMBOL Digital\\and 64 192 R0
SYMATTR InstName A9
TEXT -80 -224 Left 2 !,model up sw ron=1.5 roff=0.1g vt=0.5 vh=-0.5\n.model dn sw ron=0.625 roff=0.1g vt=0.5 vh=-0.5\n.model d d ron=1 roff=100meg vfwd=0.7 epsilon=0.1 revepsilon=50m
TEXT 768 -232 Left 2 !.tran 1m
TEXT 760 -176 Left 2 ;V(ref) = 1 V
TEXT -288 104 Left 2 ;1 > V(fb)
TEXT -184 144 Left 2 ;V(zcd) & (1 > V(fb))
TEXT -168 -136 Left 2 ;I(L1) > 0.7
TEXT -80 368 Left 2 ;I(L1) < 10m
TEXT -64 624 Left 2 ;I(L1) > 20m
TEXT 96 16 Left 2 ;!V(LQ)
TEXT 104 304 Left 2 ;V(LQ) & !V(zcd)

• I usually pepper my designs with appropriately placed passives to help the solver. Alot of this can be done by using real physical parasitics in the design (ie making sure that there are no superconducting wires, inductors, capacitors). Also throwing in some small caps (and one should really use cshunt of at least 1e-13, because on a real PCB everything is about 1e-14 or grater farads away from the ground plane. Jul 2 '20 at 23:52
• +1 You are correct, I also usually use conditionals, but place reasonably valued low pass filters on my b-sources. Jul 2 '20 at 23:54
• @VoltageSpike Those are reflexes to be praised. Still, inside the subcircuits, I try to keep things as simple as possible, sometimes even at the cost of minor realism (within sensible limits), because if things get stuck or crawling, I'd like the subcircuits to be the last place I need to search for problems. Outside, "apres nous, le diluge". Jul 3 '20 at 7:49

I couldn't get the switches to turn on until I set vref to 0.1V, after that it started switching, so either change Vref or check your VFB.

Generally speaking, you should never have a voltage source that can source infinite amounts of current. This creates problems for the solver.

So put a series resistor (like 0.1Ω) on B6,B7,B8,B4 and maybe B2 and B3

B2 and B3 need thresholds, they aren't producing voltage