[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnucap-devel] bug in pulse
From: |
al davis |
Subject: |
Re: [Gnucap-devel] bug in pulse |
Date: |
Sat, 11 Jan 2014 15:41:00 -0500 |
User-agent: |
KMail/1.13.7 (Linux/3.2.0-4-amd64; KDE/4.8.4; x86_64; ; ) |
On Saturday 30 November 2013, Felix Salfelder wrote:
> this example only demonstrates the problem, other examples
> just don't converge at all or do other fancy things they
> clearly shouldnt. which is bad.
Finally getting to this.
I have another project that is urgent and has been taking all of
my time.
The needed bug-fix is a one liner:
diff -r26.138 bm_pulse.cc
191c191
< double time_offset = raw_time - time;
---
> double time_offset = raw_time - time - d->_sim->_dtmin*1.5;
and now I know the real reason for changing > to >= in
EVAL_BM_PULSE::tr_eval.
First .. the fix and the problem:
The problem:
Event timing on discrete events ..
In the real world the concept of exact time does not exist.
Pick a time, there is time before that and after that.
In the case of an instantaneous change, such as pulse with zero
rise time, the value at that instant is indeterminant, but the
value just before and just after is relavant and can be known.
The time step control for such an event should try not to
schedule an evaluation at that exact time, but rather just
before or just after.
Oh wait .. I mean just before AND just after. .. and that's the
problem.
In the example presented here (look back in the thread) there
was an evaluation at that exact time due to strobing, not due to
the event mechanism.
The problem was that it scheduled a single event, which
sometimes would be just after, with no event just before. Then
the check mechanism caught it and rescheduled time steps based
on curve fit or truncation error before, each time with a step
rejection. Since each one was scheduled at a midpoint, it took
several of these rejections to home in.
The fix is to shove the event time a little earlier
(- d->_sim->_dtmin*1.5) to guarantee a step just before the
state change. Then some other mechanism can schedule a step
just after.
The amount before (dtmin*1.5) has to be enough to survive small
time shifts that may occur elsewhere.
Now, regarding ">" vs ">=". While I was testing this I was
reminded of the real reason for this change. It has to do with
roundoff error in the line:
if (time > _delay) {
time = fmod(time - _delay, _period) + _delay;
that would occasionally cause a glitch in the output.
So line 154 is ">" ... Equals goes with the lower time band,
not wrapping.
and line 168 is ">=" .. equals goes with the upper time band.
The reverse would make a glitch on occasion when a pulse is
periodic with a delay, where the initial value appears later
when it is no longer initial.
Line 166 must be ">=" to avoid a divide by zero in line 169.
Likewise line 161 must be ">=" to avoid a divide by zero in line
164.
Spice compatibility isn't the issue here. Spice does not allow
0 rise or fall time. It substitutes the user time step from the
tran command.
- Re: [Gnucap-devel] bug in pulse,
al davis <=