1
\$\begingroup\$

I had been using these modeling technique for counting number of clock cycles.

Delay is created and inverted - to get small positive edge of the clock and count numbers is charged based on the number of pulses. But this needs to change value of R2 and C2 and counts are sometimes greater or less than integers. Is there any other alternatives so that we can count number of clock cycles and reset it?

Schematic

Waveform

\$\endgroup\$
1
\$\begingroup\$

What you need is a resettable integrator. You have a nice approach, but you should really take time to read the manual, you'd find out that there are quite a few surprises in there.

For example, if an A-device is referenced directly to the ground, you don't need to connect the unused inputs to the 8th pin, they can be left floating. Tying them up to the 8th pin is done internally (i.e. the gate does not act like a real-life case with floating inputs).

Another one is that behavioural if() expressions introduce discontinuities around the jump and may cause, more often than not, timestep too small errors, or similar. You could use a bi source, instead of a bv, which allows internal parasitics Rpar/Cpar, which give you a time constant which smooths out a bit the sharp transition. The better solution is to use an A-device, which is far superior both in terms of convergence and runtime (the builtin parameters allow for many tweaks).

These said, here is a version of a resettable integrator:

test

A1 and A2 form the integrator, driven by the complementary clocks generated by A4. The tau is neded to allow for smooth rise/fall times whose trigger points for the two S&Hs fall after the trigger point of the input signal. This can be done with setting ref in the S&H, but this way is clearer and also affects both S&Hs at once. A2 receives the output of A1 on its inverting input, so that the output can go back into A1's inverting input, creating the needed positive feedback for an integrator. A3 is a mota (multiplying OTA) that takes care of the reset function (active low). The reset signal should be strictly 0 V or 1 V, since A3 is a multiplier. If the external signal is not with these limits, it can be adjusted by either an A-device gate, or by the u(), or buf() (or inverting inv()) functions.

A few things to notice: LTspice's S&H has a default upper/lower limit of +/-10 V, which don't act as hard limits, rather they attenuate by a factor of 1000 (or so) everything going beyond the limits. This means that a 1001 V input and a limit of vhigh=1 will result in a 2 V output, not 1 V. The 2nd S&H has vlow set, because it's in an inverting configuration. A3 has the linear flag, which makes its output to vary linearly until vhigh/vlow, after which, similar to its S&H cousin (both A-devices), it does not hard-limit the output, rather it attenuates by a factor of around 2 (same link as for the S&H). Lastly, the output starts from 1, since it's considered that a trigger can only come after a pulse, but if this behaviour is not wanted, add a current source of 1 mA at the output, drawing current to the ground. This, combined with the default output resistance for the S&H A-devices of 1 kOhm (an exception to the rest of the A-devices, can be changed by setting rout), creates a -1 V voltage that is subtracted from the output.

\$\endgroup\$
2
  • \$\begingroup\$ Re-settable integrator approach is differently shown. It took some time for me to understand in and around this techniques. Query 1: If I use this as a counter block while modeling in other simulators Can this approach used or converted.(Eg: PSpice). Query 2:I tried drawing current from out net but it didn't help to start from 0 after reset. I may have wrongly understood. \$\endgroup\$
    – Pai
    May 13 '20 at 17:56
  • 1
    \$\begingroup\$ A-devices are unique to LTspice, so porting this to PSpice is not possible, I'm afraid. But it can be converted to a library with a symbol of your choice. Now that I re-read it, the the current source at the output is not really a solution, unless you're careful with how much current you draw, but that leads to different output levels. Instead, add a series voltage source of -1 V, or however much you want to subtract. That will work, for sure. \$\endgroup\$ May 13 '20 at 18:03
1
\$\begingroup\$

Building on top of your approach, you can use the following circuit. The only modification is the addition of an ideal diode to prevent the capacitor, which acts as memory, from discharging. The bevavioral voltage supply increments the voltage across the capacitor whenever there is a rising edge present at the CLK line.

Circuit

EDIT #1

In order to add an active high reset to the previous counter, it suffices to change the voltage behavioural statement to:

V=IF(V(RST), 0, IF(buf(ddt(V(CLK))),V(count)+Vstep,0))

and create a voltage source with an output voltage node named RST.

Here is a more compact version with only one voltage supply and the possibility of being reset.

Circuit_2

\$\endgroup\$
9
  • 2
    \$\begingroup\$ If you want to go with the Swiss army knife of the SPICE world (behavioural expressions), you can improve your version with itd(x, y, reset). You should know (if you don't, already), that putting too much burden on the behavioural sources will need tinkering with tripdv/tripdt and, occasionally, helpful parasitics and timesteps. Behavioural sources are exceptional when complicated functions come into play, but that is also their Achilles' heel. \$\endgroup\$ May 9 '20 at 9:00
  • \$\begingroup\$ Since the OP was already using it, I wanted to keep it as simple as possible. \$\endgroup\$
    – vtolentino
    May 9 '20 at 9:09
  • \$\begingroup\$ Call me blind, but I don't see idt() anywhere in the OP. What I meant was that you can avoid the D and C as the integrator (which would make resetting a bit difficult), and simply use idt() together with its third argument, reset, which resets to zero instantly. \$\endgroup\$ May 9 '20 at 9:18
  • \$\begingroup\$ The function is actually called sdt(). \$\endgroup\$
    – vtolentino
    May 9 '20 at 9:53
  • \$\begingroup\$ If you look in the help at behavioural sources, you'll see that sdt() is an alternate name for idt(), which should make sense considering that ddt() has d from derivative, and idt() has i for integral, while s in sdt() is a would-be integral sign in ASCII. But since both do the exact same thing, it doesn't matter, so I don't understand the purpose of your comment. \$\endgroup\$ May 9 '20 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.