Menu

#35 transient noise extension

v1.0 (example)
open
nobody
None
5
2019-01-24
2019-01-03
No

Hi,

I tested the transient noise in ngspice-29, and I like it: nice work. I see from the manual (Chapter 15.3.10) that you may need some help at various points. I can offer help, as I implemented a similar function in matlab some time ago.

First the implementation as it is now:
- The first parameter in the trnoise statement cannot be parameterised; why not? The second parameter can be parameterised. I did not check the other parameters.
- The spectral density is rms_noise/sqrt(fs) where rms_noise is the rms-noise-value and fs is the sample frequency (or the frequency that is used by the noise source). In the netlist the simulation stops at 100us, so the frequency resolution or bin-width is 1/100us=10 kHz. So a 1Vrms noise voltage sampled at 1 MHz, viewed in a 10 kHz bandwidth gives: 1V*sqrt(10kHz/1MHz)=0.1 Vrms or -20 dBVrms/10kHz. The simulation gives (average over 101 runs) -14dBVp=-17dBVrms in a 10 kHz bandwidth (obtained by averaging from DC to 0.1 MHz), see the plot. The simulated noise is 3 dB higher than the calculated noise. When I did this in octave the simulated noise was 2 dB higher than the calculated noise. In cadence transient analysis, the simulated noise is 2 dB lower than the calculated noise.
- As the noise function is 'clocked' at 1 MHz with a random function, it has 'zeros' at multiples of the clock frequency, as visible in the graph. Up to fs/4 the spectrum is acceptably flat. Pending simulation requirement you should increase the sample frequency of the noise source.

I would like to have the functionality of ngspice extended such that resistors and active devices generate noise:
- The resistor noise can be implemented by adding a noise current of sqrt(4kT/R) in parallel to each resistor in the ciruit (I expect that the voltage equivalent is less appropriate as it adds nodes to the circuit, increases the matrix size and thus increases simulation time). The current-trnoise function should have a rms-amplitude of sqrt(4ktemperaturefs/R) to generate the correct noise level. The parameter fs should be given as input to the simulator.
- The noise in the active devices is either resistive (so solved in the resistor noise part) or current-noise (sqrt(2
q*I) as proposed in Chapter 15.3.10 of the ngspicd-29 manual).

I can help testing functionality. Let me know what you think of this.

regards,
Paul

3 Attachments

Discussion

  • Dietmar Warning

    Dietmar Warning - 2019-01-04

    Hello Paul,
    any help is appreciated.
    I am afraid that my knowledge is not sufficient to follow you. Perhaps Holger and Marcel can answer. (BTW - it looks that some statements are missing in your test case, at least the end card.)
    But to your statement regarding the parametrization of amplitude in trnoise statement I can agree: If I put NoiseVoltage direct into a crash follows. If I enclose it with braces {} it runs fine.
    I will open a bug ticket.
    Thank you,
    Dietmar

     
  • marcel hendrix

    marcel hendrix - 2019-01-04

    Let me know what you think of this.

    I had a look at the manual, and my first impression was that I needed to read the referenced paper. Furthermore, I think it is very important to exactly define what is meant by "the Gaussian noise rms voltage amplitude", let's call it 'a'. Is 'a' the value that produces 1 Vrms of noise, or is 'a' 1V to produce 1Vrms? I assumed the former in my experiment with your test circuit, modified to get 1Vrms from node 2, using 1MHz sampling frequency:

    V2 2 0 dc=0 trnoise({sqrt(2)}, 1e-6, 0, 0, 0, 0, 0)
    .TRAN 1u 10ms
    

    Note that I could parameterize NA just fine (using the braces). Note also that I simulate for 10ms, not 100us. I noticed that in the time domain the signal, at least by eye, is very random, i.e. integrating it will give a large variation depending on the random number seed. I am too busy to look it up now, but what is the expected deviation for your reported measurement? I integrated over 10ms, and also over 1s, and the RMS amplitude starts at about 802mV and seems to go very, very slowly to 707 mV (really slowly, I have to look up how long to integrate to get an error < 1%). It takes only six points to plot an acceptable Gaussian, but many more to get a reasonably low error for each individual point 1].

    On a practical note, and I really do not want to offend: did you resample the time waveform at 1MHz before computing the RMS value? The manual mentions that breakpoints are used to makes sure there is a timepoint every NT seconds, but NGSPICE makes many additional non-homogeneous steps inbetween.

    Before looking any further there could be an error of about 1dB here, but I'd need to read the original paper what the claims, limitations, and testcases are.

    -marcel

    1] To quantify the statement:

    * define sample frequency fs and voltage density vn
    .param fs=1u
    .param vn=1
    .param NoiseVoltage=vn*sqrt(fs)
    *The first parameter in the trnoise statement cannot be parametrized. Why not?
    
    * simple test circuit
    * See ngspice-manual v29, section 15.3.10.
    V1 1 0 DC 0 trnoise(1e-5 fs 0 0 0 0 0 )
    V2 2 0 dc=0 trnoise({sqrt(2)}, 1e-6, 0, 0, 0, 0, 0)
    
    .TRAN 1u 1s
    .meas tran rmsnoise100u  RMS V(2) from=0 to=100u
    .meas tran rmsnoise1ms   RMS V(2) from=0 to=1ms
    .meas tran rmsnoise10ms  RMS V(2) from=0 to=10ms
    .meas tran rmsnoise100ms RMS V(2) from=0 to=100ms
    .meas tran rmsnoise1s    RMS V(2) from=0 to=1
    
    .end
    

    Output of spice -b noise_bug.cir seems to converge but it takes too long for my patience (not unlike trying to get a perfect Gaussian out of a Monte Carlo simulation) :

    rmsnoise100u  = 1.265608e+00 RMS from 0.000000e+00 to 1.000000e-04
    rmsnoise1ms   = 1.221538e+00 RMS from 0.000000e+00 to 1.000000e-03
    rmsnoise10ms  = 1.186752e+00 RMS from 0.000000e+00 to 1.000000e-02
    rmsnoise100ms = 1.186903e+00 RMS from 0.000000e+00 to 1.000000e-01
    rmsnoise1s    = 1.184066e+00 RMS from 0.000000e+00 to 1.000000e+00
    
     

    Last edit: marcel hendrix 2019-01-04
    • marcel hendrix

      marcel hendrix - 2019-01-06

      To investigate this some more, I wrote a "moving RMS" filter and applied it to both the tran noise and a new perfect 1 kHz sine signal with an amplitude of sqrt(2) Volt.

      Noise_bug reported by Paul van Zeijl
      
      * *************************************************************************** *
      * Analog Delay unit; V(out) is delay(V(in),Td)  Rout=0.1              *
      * Parameter: Td                                       *
      * *************************************************************************** *
      .subckt adelay in out Td=1ms Ttrip=0.1us Vtrip=0.1 ampl=1
      Rin  in  ind 50
      O1   ind 0   outd 0  dline
      .model dline LTRA R=0 G=0 L=td*50 C=td/50 rel=1 abs=0 len=1 $ Zo=50
      Rout outd 0 50
      *A1 %v[outd] vilimit
      *.model vilimit trip_dt(tripdt={Ttrip} trip=[{Vtrip}] warnings=false)
      Bo 0 out I=20*V(outd)*{ampl}    $ compensate for 6dB insertion loss
      Ro out 0 0.1
      .ends adelay
      
      * *******************
      * running RMS filter
      * Interval = Twindow
      * *******************
      .subckt movingrms x rmsx Twindow=100ms
      X1 x delayed adelay Td={Twindow} Ttrip=0.1us Vtrip=0.1 ampl=1
      Bi 0    rmsx I = 1u * (V(x)**2 - V(delayed)**2) / Twindow
      Ci rmsx    0 1uF ic=0
      .ends movingrms
      
      * simple test circuit
      
      V2 2 0 dc=0 trnoise({sqrt(2)}, 1e-6, 0, 0, 0, 0, 0)
      X1 2 3 movingrms Twindow=10ms
      V3 4 0 dc=0 sin(0 {sqrt(2)} 1k)
      X2 4 5 movingrms Twindow=10ms
      
      .TRAN 1u 20ms
      .meas tran rmsnoise100u  RMS V(2) from=0 to=100u
      .meas tran rmsnoise1ms   RMS V(2) from=0 to=1ms
      .meas tran rmsnoise10ms  RMS V(2) from=0 to=10ms
      .meas tran rmsnoise100ms RMS V(2) from=0 to=100ms
      .meas tran rmsnoise1s    RMS V(2) from=0 to=1
      
      .end
      

      As can be seen in the two attachments, the movingrms filter does its job on the 1 kHz sine and gives 1V rms exactly, after the 10ms startup of the delay line.
      The tran noise signal for both runs seems to converge to 1V rms also, but in the start up phase it is 5% off. The second run is without the 'tripdt' code model for the delay line and might be less accurate 1), so I can't say with confidence that the TRAN NOISE code is bugfree.

      -marcel

      1) My current hypothesis is that the accuracy of the simulator can not be neglected. The waveforms with the HF noise on them should be sampled such that their RMS value can be recovered perfectly. The tripdt code model increases the accuracy for discontinuous signals and it is my belief that therefore the RMS value is also nearer to the expected 1Vrms. In another experiment (not shown) I changed the sine frequency to 1MHz and got completely wrong RMS results (-20 dB or so).

       
  • Paul van Zeijl

    Paul van Zeijl - 2019-01-06

    Dietmar,
    I confirm that the {} brackets solves the problem. Indeed the .end statement was missing, but I did not get an error. Thanks for filing the ticket.
    regards,
    Paul

     
  • Paul van Zeijl

    Paul van Zeijl - 2019-01-06

    Marcel,
    I remember simulating without re-sampling using trnoise(1, 1e-6, ...) giving 0.85 as rms voltages, which corresponds to your trnoise(sqrt(2)=1.4, 1e-6 ..) giving 1.2.
    When I resample the output data at 1/fs=1us multiples (actually only taking the values at multiples of 1 us), I get an rms-values of 1.0 with deviations of +/-3% max (up to 100 runs averaged), also for repeated runs. So the generation of the random variable is ok.

    My interest is into mainly in frequency domain results, that's why I look at the spectral density. I did not explain my plots: freqDomain1.png is the spectral plot of 100 runs, with the black trace the average power over the 100 runs. freqDomain2.png is only the average data.
    regards,
    Paul

     
  • Paul van Zeijl

    Paul van Zeijl - 2019-01-10

    Marcel,
    you say "I can't say with confidence that the tran noise code is bugfree". I think you mean to say that " I can say ...", right? I agree with that the noise amplitude in the time-domain is correct. In the frequency domain I found that pending window function the (low-frequency) noise-amplitude (in dB/sqrt(Hz)) may vary some dB's. I will check the exact relation later.

    What do you think on extending the ngspice functionality with generation noise for all resistors and active devices?

    regards,
    Paul

     
    • marcel hendrix

      marcel hendrix - 2019-01-10

      I think you mean to say that " I can say ...", right?

      No, I indeed meant no guarantee, i.e. I am not fully convinced of the correctness yet. This is because the output of the "movingrms" filter rises slightly (~5%) too fast and that 'feels' wrong. That the output of the filter appears to fall away slowly is because of the perfect integrator: any dc offset or simulation inaccuracy will cause a slight up or down gradient that becomes visible sooner or later. Therefore the point where the delayline starts to contribute and the curve becomes flat is critical: there the error should be minimal. An experimental approach is to do many runs with different random seeds and see if / how much the amplitude at this breakpoint fluctuates. The theoretical approach is to check the original article, or to analyze the algorithm afresh.

      What do you think on extending the ngspice functionality with generation noise for all
      resistors and active devices?

      Can you give a motivating example? I guess you want the full analysis functionality of .NOISE transplanted on TRNOISE, i.e. do transient analysis with noise sources enabled. As far as I can see this will only bring new insights for decidedly non-linear circuits. Are you thinking about PLL's or such? At GHz frequencies transient analysis is unworkable slow, but at a few MHz it might still be somewhat usable...

       
  • Paul van Zeijl

    Paul van Zeijl - 2019-01-11

    Marcel,
    on the motivation: I prefer to have PSS, PAC, PNOISE analysis for analysing mixer/transmitter/receiver circuits. I have seen NGSPICE-PSS work work but only for oscillators. I would be nice to have it work at fixed frequencies (which I expect to be easier than non-fixed, not-know frequencies). But PSS-PAC-PNOISE cannot be used in PLLs, delta-sigma modulators and detecting PRBS sequences, as they don't have a steady-state solution.
    I expect the TRNOISE to be implemented easier, although simulator accuracy will become important. I am not so worried on the simulator becoming slow, sofar it is very fast. Suppose I want to simulate a signal up to 1 GHz, so I need a time step below 500 ps (nyquist), but I usually go for 100 ps. In the frequency domain the noise would remain more or less flat up to 2.5 GHz. I will see noise upconversion from low frequencies, but may miss downconversion from noise around signal harmonics. But this is a good first step.
    regards,
    Paul

     
    • marcel hendrix

      marcel hendrix - 2019-01-11

      On 2019-01-11 13:56, Paul van Zeijl wrote:

      Marcel,
      on the motivation: I prefer to have PSS, PAC, PNOISE analysis for

      I guess these (PAC and PNOISE) are features of Spectre-RF?
      ( http://www.designers-guide.org/Analysis/sc-filters.pdf )

      analysing mixer/transmitter/receiver circuits. I have seen NGSPICE-PSS
      work work but only for oscillators. I would be nice to have it work at
      fixed frequencies (which I expect to be easier than non-fixed,
      not-know frequencies). But PSS-PAC-PNOISE cannot be used in PLLs,
      delta-sigma modulators and detecting PRBS sequences, as they don't
      have a steady-state solution.

      You mean noise does not fit the stated limitations of PAC (Kundert
      in the above paper?)

      I expect the TRNOISE to be implemented easier, although simulator
      accuracy will become important. I am not so worried on the simulator
      becoming slow, sofar it is very fast. Suppose I want to simulate a
      signal up to 1 GHz, so I need a time step below 500 ps (nyquist), but
      I usually go for 100 ps. In the frequency domain the noise would
      remain more or less flat up to 2.5 GHz. I will see noise upconversion
      from low frequencies, but may miss downconversion from noise around
      signal harmonics. But this is a good first step.

      I can't say I follow this, but it might be worth the effort.

      BTW, there is an aspect of TRNOISE I hadn't realized yet: in some
      sense, adding noise to a component should be equivalent to compressing
      many Monte Carlo runs into a single simulation, as the shape of the
      resulting noise spectrum is related to what happens when the value
      of the component is statistically distributed like the noise type
      added to it. Then, adding TRNOISE to every component should give
      results in one run that are equivalent to MC's for every individual
      component done sequentially and post-added. This could be orders
      of magnitude faster than a simple MC...

      This said, at the moment there are (too) many interesting subjects
      competing for my (too) limited time, so I can't personally take it
      up immediately.

      -marcel

       
  • Paul van Zeijl

    Paul van Zeijl - 2019-01-24

    Marcel,

    Yes, there are limitation to pss-pac-pnoise (you need pnoise for pss).

    Paul

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.