Problem using the time variable in a C++ module

Hello,
I am trying to generate a ramp using the time variable in a C++ module. I use the following statements:

Ts= 5e-6;
Sawtooth= t/Ts - floor(t/Ts);

When the program is simple (only those statements) the ramp is good. But when I add more statements to the C++ program to do other things the ramp becomes distorted. Please, see attached figures (a) and (b) respectively.
Also, when I plot the time variable “t” versus time both values are not exactly the same, which seems very strange to me. I think this could be what creates the distortion of the ramp. Is “t” the right variable to access the simulation time?
Thanks in advance.

Hi, Marcos.

Just guessing but I’d suspect that you’re hitting the limits of numerical precision. Looks like (b) must be simulating significantly more timesteps. Are you perhaps using float types instead of doubles for the output port types? Are Sawtooth and Ts doubles?

–robert

Hi, Robert
Thanks for your help. Sawtooth pin is defined as “float (64 bit double)”. Ts is a constant defined as “const double”.
The simulation maximum timestep is selected to 10n (.tran 400µ 0 0.01µ uic)
What I do not understand is why in (b) V(t) is not a perfect straight line as in (a).
To plot “t” I send it to a pin defined as “float (64 bit double)”

Hmm. How odd. I assume that you’re using the QSpice fast math setting, right? (It shouldn’t matter but grasping at straws here.)

Could you share the code?

I have done this simple test comparing the “analog time” from the schematic and the “digital time” from the C++ module. There is a difference of 0.1 us between them. This seems to me a considerable difference and I think is the reason of the error when generating the ramp.
The difference is more or less the same using Fast math setting or not.


Time-test.qsch (2.1 KB)
mymodule.cpp (1.3 KB)

Well, that IS interesting… In a quick test, the t parameter passed into the evaluation function is running about 600ns behind B1, about 6 simulation timesteps.

Might be a question for @Engelhardt.

–robert

1 Like

I believe the software works correctly, but I don’t know what you’re simulation. Here is an example demonstrating that all is well:

Tnewton is the time in the analog Newton-Raphson interation. This is the exact time. The .DLL gets the time from the very last timestep, which for the 10ns earlier since I’ve stipulated that maximum timestep:

image

The inevitable error in mixed mode simulation is why the time tolerances can be specified, not that I’m using that here, just limited the maximum timestep size.

This is the C++ code for the .DLL:

2 Likes

Hi,

Are you prof Marcos from Uni Oviedo?

anyway, generally speaking, creating mixed mode simulation with purely in C-block doesnt yield a very good result.

I would suggest to separate the analog and digital function and implement the analog in native Qspice block and digital functions in C-block

I have 2 example:

  1. FRA analysis where all the math integration is done with native integration function and I just use C-block to control the sinewave freq/amp and to sample the integral output.
    QSPICE/FRA_project at main · physicboy/QSPICE · GitHub

  2. For controller, I did pure digital controller where I can compute the exact future switching event. Thus I dont even need to generate the COUNTER signal nor use an actual CMP > COUNTER
    QSPICE/PWM_example_SRbuck/Level4 SR-Buck Internal Cblock PWM with Deadtime at main · physicboy/QSPICE · GitHub

1 Like

Thanks for your detailed response. It has been very useful. I didn’t want to suggest that anything was wrong with the software. Sorry about that. That is far beyond my knowledge. I only wanted to better understand how it works.
I did a simulation using a maximum timestep of 10ns and instead of using “t” in the generation of the ramp I used “t + 10ns”, which is the difference in time between the simulation time and the dll time, as you showed. Now the ramp is perfect. I know that the time step is not always equal to the maximum time step because it changes along the simulation time but even so the ramp is OK. I am attaching an image of the ramp in the same situation as before but with the above-mentioned change.
Thank you very much!

Thanks, Mike.

FWIW, the simulation that I posted was from @marcos.uniovi’s code. The DLL eval func was simply “out0=t” same as yours. I ran it again today and it works as it should. I’ve no explanation why the prior simulation seemed to have the DLL t variable/output running six-ish timesteps behind the BV=time. Very strange. Gremlins, I guess.

Anyway, thanks for checking it out.

–robert

1 Like

Hello,
Yes, that’s me. Nice to meet you.
Your examples are amazing. You have a great knowledge of Qspice and C++.
I will study your examples. I am sure I will learn a lot from them.
Thank you very much for sharing the files.

Hi, I have the same problem and after a bit of debugging I found the reason:

  • the output of C++ code is delayed by one step.
    To be clear, in the plot I have these results for the function: " out = t "
    t1 ; out = 99.29us ; 98.31uV
    t2 ; out = 100,2us ; 99,29uV
    t3 ; out = 101,01us ; 100.2uV
    t4 ; out = 101.02us ; 101.01uV
    t5 ; out = 101.04us ; 101.02uV

Between t3 and t4 there are 10ns while in the output there is a jump of 1uV
Question: is it possible to avoid this delay?

Hi, Fabio.

You can use Trunc() to reduce the timestep around events that exceed some tolerance. If you are not familiar with Trunc(), see the C-Block Basics series on my GitHub QSpice repository.

Hope that helps.

–robert

Thanks RDunn, I’ll try it and other things…