0

I'm trying to make a custom square wave generator to drive high-side and low side MOSFETs.

I need a HIGH pulse, then a DEAD time then a LOW pulse. Pulses to be adjustable from 10 microseconds to 1 millisecond.

Initially, I drew two custom PWL to do that, which work perfectly (this is one of them:)

PWL repeat forever(0 0 {RISE} {GATE} {RISE+PULSE} {GATE} {RISE+PULSE+FALL} 0 {2*DEAD+2*RISE+2*PULSE+2*FALL} 0) endrepeat

The problem is when I tried to simulate 1k (or greater) seconds transient, LTSpice gets stuck forever in "Expanding repeating PWL" over the entire timeframe area.

Now I tried different approach to generate squares:

  • use a sawtooth voltage source
  • use a b-source as a comparator
  • or, use some Schmidt triggers with proper thresholds across sawtooth

This is working, but for some reason, both Schmidt and B-Source presents a 1usecond rise/fall on generated square wave. I don't understand where it comes from.

For Schmidt I tried to set Rise/Fall near zero (1 nanosecond) but has no effect, still I measure 1 microsecond on graph.

enter image description here

This is output of Schmidt trigger:

enter image description here

This is output of B-Source, the same story, 1 microsecond rise/fall:

enter image description here

Any clue from where this rise/falltime comes from and how to shorten it?

JRE
  • 67,678
  • 8
  • 104
  • 179
yo3hcv
  • 553
  • 1
  • 4
  • 18

3 Answers3

3

For the sake of completeness, I'll add some information about what you did, what you achieved, and what could be achieved (and maybe why).

When you made your PWL source, you made it, probably, with microseconds, or milliseconds in mind. Then you tried to use that for a 1k total simulation time (tst), but LTspice "got stuck". This is what happened: a PWL source is a Piece-Wise Linear function, in that it takes a set of time/value pairs and linearly interpolates between them. The thing to know about this is that all these points must be known prior to simulation start. If the keywords repeat <value> and endrepeat are used, it takes that sequence and concatenates it in time -- it literally recalculates all the points for all the concatenated segments so that they fit one after another, <value> times. If the keyword forever is used instead of <value>, it calculates the tst and divides that to the length of the sequence, to generate <value>. Now think of what happened: you specified tst=1k with repeat forever and us...ms length sequence. That results in <value>=1e3/1e-3=1e6, thus you forced LTspice to keep on calculating and adjusting the time/value pairs for all the segments a million times, or more. This is why you "got stuck".

For the future, if all you have is some pulsed waveform, it's better to use PULSE instead of PWL, because the handling is different. Try a PULSE(0 1 0 0 0 0 1u) for .tran 1k and you'll see that it simulates without hiccups. Also, it's not necessary to use a PULSE or PWL with an imposed timestep in order to view better edges, since, as I mentioned, these points are known prior to simulation time. In fact, it's a known trick to use a PULSE with sharp edges to force a relatively uniformly sampled waveform (used in FFT analysis, for example). The same would have been the case here.

Then you used a Schmitt trigger and a behavioural source as a comparator. The Schmitt trigger is part of the A-devices, which are the ones I would recommend over anything else when it comes to switching waveforms. This is why:

Behavioural sources are meant to be the Swiss knife of the SPICE world. They can take virtually any (real valued) function and use it in a simulation. The downside is that all this heavy math is a burden for computation. When the expressions are simple, they work very well, otherwise they need tweaking, and LTspice provides two temporal parameters that can help: tripdv and tripdt. What these do is they set a value for the voltage, current, or power (the ordinate) -- tripdv -- and one for the time (abscissa) -- tripdt -- which determine that any change lesser than tripdv in tripdt seconds forces the timestep to slow down and calculate the minutiae. If there is a change greater than tripdv/tripdt, the timestep is no longer constrained and the simulation runs as if there was no imposed timestep. If these two are not specified, then the simulation doesn't stop to "inquire" what happens when sharp changes occur, relative to the timestep, and the dynamic range is affected (though there are some default values for them, the result is the same in most of the cases). It translates into what you saw: microsecond edges, despite the apparent sharpness a boolean expression might imply.

So, while the above can help, using boolean expressions comes with a different problem: discontinuities. These are not simulator-friendly because the derivative has sudden jumps and these can cause the engine to stop with timestep too small errors.

There are various solutions, I won't go into details, but I'll say that the much better (in fact, the best in this case) alternative would be the A-devices. This is because they were built with switching in mind. And for this, they have a lot of temporal aids that can trully shine. They don't have tripdv, it's probably considered unity due to the default logic levels, [0,1] V, but they have tripdt, whith the same meaning as for the behavioural sources: any change that happens in less than tripdt seconds forces the simulator to slow down and show more details; elsewhere, no constraints. But, in addition to this, there is also tau, and tau plus tripdt are very powerful: tau causes a 1st order rise/fall, while tripdt ensures that this is smoothly calculated and displayed, resulting in a smooth variation of the output, thus convergent-friendly, and fast switching due to tripdt.

What you used are trise and tfall. These cause the output to linearly rise or fall, but without tripdt they are treated just like in the behavioural source's case, which is what you saw. If you aded tripdt=1n, for example, you would have seen 1 ns rise/fall edges. There is a choice that has to be made, though: only one of [tau], [rout, cout], [rhigh, rlow, cout], [trise, tfall] can be used at a time. The 2nd and 3rd are the equivalent of tau.


So, to end the novel, the conclusions to take are these:

  • PULSE and PWL don't need timestep imposed -- but you decide how they behave
  • A-devices are the best choice when it comes to switching, and using them with tau and tripdt should be the minimum for the best behaviour simulation-wise.

Here are two examples of having a 100 kHz switching waveform over 1 s. Since you didn't specify the pulse width, I just assumed it to be 0.5, so I used a single Schmitt inverter as an oscillator. Both run fast, preserve the resolution of the pulses, and have approximately the same shape (note: no imposed timestep):

no timestep

rise

fall

a concerned citizen
  • 21,167
  • 1
  • 20
  • 40
1

What's the maximum timestep value you have set up in LTSpice - it needs to be maybe 10 ns to get the response you want. If you leave any PSpice simulator to "do its own thing" it will take shortcuts in the analysis in order to render a quicker result.

Any clue from where this rise/falltime comes from and how to shorten it?

Well my best guess is what I've said above.

Andy aka
  • 434,556
  • 28
  • 351
  • 777
  • 1
    Andy.. you're the man! Thank you – yo3hcv Oct 09 '20 at 10:20
  • @orfruit you might also be interested in [this circuit](https://electronics.stackexchange.com/questions/503865/how-is-dead-time-in-a-half-bridge-implemented/503871#503871) that provides dead-band between pulses to prevent MOSFET shoot-through. This is suitable for a push-pull output that uses two N channel MOSFETs. – Andy aka Oct 09 '20 at 10:36
1

Well, Andy was right, I set "Maximum Timestep" to 100n and issue is gone.

However, after that, I realized that I can simplify even further PWM + deadtime generation like this (in case anyone needs). A million faster than my initial PWL approach.

  • UP_ON is for high side pulse
  • DWN_ON is for low side pulse
  • DEAD is after pulse
  • OFF is time after all together (so adjust overall duty)

enter image description here

yo3hcv
  • 553
  • 1
  • 4
  • 18