The Designer's Guide Community Forum
https://designers-guide.org/forum/YaBB.pl Measurements >> Other Measurements >> Query regarding DFT function in Spectre https://designers-guide.org/forum/YaBB.pl?num=1220511510 Message started by shaikh_sarfraz on Sep 3rd, 2008, 11:58pm |
Title: Query regarding DFT function in Spectre Post by shaikh_sarfraz on Sep 3rd, 2008, 11:58pm Hi, I need to simulate an ADC for SNR values. I am using coherent sampling technique. I am applying a sinusoidal wave at the input of ADC and generating a staircase at the output. Then I am using DFT (rectangular window) to get the frequency domain output. As the output of DFT is in complex form, I am converting it magnitude form by squaring and adding the real and imaginary part and then taking the square root. Now my query is: 1). How to find the RMS value of Noise? I am taking the square of each noise magnitude, then taking its mean and then taking the root. Is this the correct way, I mean do we simply need to add the square of noise components and take the root or should we take the mean of it. To cut it short: Is the magnitude form (which I am getting from the complex output ) of DFT output is the RMS value or not? Best Regards Sarfraz |
Title: Re: Query regarding DFT function in Spectre Post by als on Sep 4th, 2008, 4:44am Shaikh, If you have access to ViVA, SNR [SNHR] is now available in the calculator. The spectrum function allows designers to calculate all the standard parameters: SINAD, SFDR, SNR, THD, and ENOB. If you don't have access to ViVA, then you will need to write your OCEAN function to do the calculation. Best Regards, Sheldon |
Title: Re: Query regarding DFT function in Spectre Post by shaikh_sarfraz on Sep 4th, 2008, 7:09am Hi, Thanks for your inputs. But the problem is, I donnot have Viva. I am writing functions in Ocean. I am getting the staircase output. And from that I am getting the DFT plot (4096 point DFT with rectangular windowing). Can any body give some hint on how to proceed from here to get the SNR? (I will be using OCEAN) Best Regards Sarfraz |
Title: Re: Query regarding DFT function in Spectre Post by pancho_hideboo on Sep 4th, 2008, 11:32pm shaikh_sarfraz wrote on Sep 3rd, 2008, 11:58pm:
Answer is no. It is peak value. You should learn fourier series theory. shaikh_sarfraz wrote on Sep 4th, 2008, 7:09am:
Usually we use sinusoidal output for evaluating SINAD, SFDR, SNR, THD, and ENOB. Staircase output(Ramp Code) is for static DNL and INL evaluation. You might mean zero order hold output with " staircase output" ? shaikh_sarfraz wrote on Sep 4th, 2008, 7:09am:
Just do coding with following definition of SNR. Your question is Laguage issue when you write codes using Cadence Ocean ? or Just you don't understand mathematical definitions of SINAD, SFDR, SNR, THD, and ENOB ? If you can understand mathematical definitions of SINAD, SFDR, SNR, THD, and ENOB, coding tasks are very easy whatever language you use. For example, I wrote such code using C-language long long ago for actual measurement using logic analyzer(state analyzer). And long ago I rewrote this C code to Ocean and M-file of MATLAB easily. If you can access MATLAB, the following might be also useful a little. http://www.designers-guide.org/Forum/YaBB.pl?num=1213204643 |
Title: Re: Query regarding DFT function in Spectre Post by pancho_hideboo on Sep 4th, 2008, 11:52pm As simple reference, this is only SNR evaluation. If you apply this to ADC, you have to convert digital code to integer or real number. ============================================ base_dir = getWorkingDir() ; awvSetOptionValue('dateStamp t) awvSetOptionValue('displayGrids t) awvSetOptionValue("cursorPrecision" 9) awvSetOptionValue("displayAxesBy125" t) ;;; circuit_dir = "aho_boke_kasu_nasu" ;;; ;sim_data = "schematic" sim_data = "cnr_15db" result_dir = strcat(base_dir "/simulation/" circuit_dir "/spectre/" sim_data) openResults( strcat(result_dir "/psf") ) ; wid = newWindow() addTitle("SINAD/SNR Test of aho_boke_kasu_nasu") ; dump_file = "/tmp/aho.dat" myPort = outfile( dump_file ) ; f0 = 10.7MHz fin = 1.0kHz VCrms = 1.0 CNR = 15.0 fmax = 80kHz ;np = 10.0 VNrms = VCrms * 10**(-CNR/20.0) tstart = 0.5*(1.0/fin) ;tstop = tstart + np*(1.0/fin) ; pi = acos(-1.0) ; selectResult('tran) Vsignal = v("/Vsignal") Vnoise = v("/Vnoise") Vin = v("/Vin") Vin_clipped1 = v("/Vin_clipped1") Vout = v("/Vout") Vout1 = v("/Vout1") time_vec = drGetWaveformXVec( Vin ) tstop = drGetElem( time_vec, drVectorLength(time_vec)-1 ) printf("tstop = %g[msec]\n", tstop/1m) fnyquist = fmax finaltime = tstop - tstart delta_f = 1.0 / finaltime N = round(2*fnyquist * finaltime) ip = round(log(N)/log(2)) NN = 2**ip if( NN < N then NN=2**(ip+1) ) fnyquist = NN / (2.0*finaltime) printf("N = %d --> N = %d\n", N NN) ; Vout_freq = dft(Vout tstart tstop N "Rectangular" 1 1) Vout1_freq = dft(Vout1 tstart tstop N "Rectangular" 1 1) signal_pwr = 0.5 * mag(value(Vout_freq fin))**2 signal1_pwr = 0.5 * mag(value(Vout1_freq fin))**2 noise_pwr = 0.0 noise1_pwr = 0.0 dist_pwr = 0.0 dist1_pwr = 0.0 ipeak = round(fin/delta_f) printf("ipeak = %d\n", ipeak) nmax = round(fmax/delta_f) if( nmax * delta_f < fmax then ++nmax ) if( nmax > NN/2 then nmax = NN/2) printf("fmax = %g[kHz]\n", nmax * delta_f / 1k) for( i 1 ipeak-1 freq = i * delta_f noise_pwr = noise_pwr + 0.5*mag(value(Vout_freq freq))**2 noise1_pwr = noise1_pwr + 0.5*mag(value(Vout1_freq freq))**2 ) for( i ipeak+1 nmax freq = i * delta_f noise_pwr = noise_pwr + 0.5*mag(value(Vout_freq freq))**2 noise1_pwr = noise1_pwr + 0.5*mag(value(Vout1_freq freq))**2 if( mod(i ipeak) == 0 then dist_pwr = dist_pwr + 0.5*mag(value(Vout_freq freq))**2 dist1_pwr = dist1_pwr + 0.5*mag(value(Vout1_freq freq))**2 ) ) fprintf(myPort "Signal Voltage = %g [Vrms]\n", sqrt(signal_pwr)) fprintf(myPort "Signal Voltage1 = %g [Vrms]\n", sqrt(signal1_pwr)) fprintf(myPort "\n") fprintf(myPort "Noise+Distortion Voltage = %g [Vrms]\n", sqrt(noise_pwr)) fprintf(myPort "Noise+Distortion Voltage1 = %g [Vrms]\n", sqrt(noise1_pwr)) fprintf(myPort "\n") fprintf(myPort "Noise Voltage = %g [Vrms]\n", sqrt(noise_pwr-dist_pwr)) fprintf(myPort "Noise Voltage1 = %g [Vrms]\n", sqrt(noise1_pwr-dist1_pwr)) sinad = signal_pwr / noise_pwr sinad1 = signal1_pwr / noise1_pwr thd = dist_pwr / signal_pwr thd1 = dist1_pwr / signal1_pwr if( ipeak == 1 then snr = 10**(200.0/10.0) snr1 = 10**(200.0/10.0) else snr = 1.0 / (1.0 / sinad - thd) snr1 = 1.0 / (1.0 / sinad1 - thd1) ) fprintf(myPort "\n") fprintf(myPort "SINAD = %2.1f [dB]\n", 10.0*log10(sinad) ) fprintf(myPort "SINAD1 = %2.1f [dB]\n", 10.0*log10(sinad1) ) fprintf(myPort "\n") fprintf(myPort "SNR = %2.1f [dB]\n", 10.0*log10(snr) ) fprintf(myPort "SNR1 = %2.1f [dB]\n", 10.0*log10(snr1) ) fprintf(myPort "\n") fprintf(myPort "THD = %g [%%]\n", sqrt(thd)*100.0 ) fprintf(myPort "THD1 = %g [%%]\n", sqrt(thd1)*100.0 ) close( myPort ) edit( sprintf(nil "%s" dump_file) ) ;view(dump_file nil "Results of SINAD/SNR") bid = currentSubwindow(1) addSubwindowTitle( sprintf(nil "Carrier=%2.1f[Vrms]@%2.1fMHz , CNR=%2.1f[dB]" VCrms f0/1M CNR) ) t1 = tstop-3.0/f0 t2 = tstop dt = (1.0/f0)/500.0 plot( sample(Vsignal t1 t2 "linear" dt) ?expr '("Vsignal") ) plot( sample(Vnoise t1 t2 "linear" dt) ?expr '("Vnoise") ) plot( sample(Vin t1 t2 "linear" dt) ?expr '("Vin") ) plot( sample(Vin_clipped1 t1 t2 "linear" dt) ?expr '("Vin_clipped1") ) awvSetXAxisLabel(wid "time [sec]" ?subwindow bid) awvSetYAxisLabel(wid 1 "Amplitude [volt]" ?subwindow bid) displayMode("strip") yLimit( list(-1.5 1.5) ?stripNumber 1 ) yLimit( list(-1.5 1.5) ?stripNumber 2 ) yLimit( list(-1.5 1.5) ?stripNumber 3 ) yLimit( list(-1.5 1.5) ?stripNumber 4 ) addSubwindow() bid = currentSubwindow(2) addSubwindowTitle( sprintf(nil "fsignal=%2.1f[kHz]" fin/1k) ) t1 = tstop - 1.0*(1.0/fin) t2 = tstop dt = (1.0/fin)/500.0 plot( sample(Vout t1 t2 "linear" dt) ?expr '("Vout") ) plot( sample(Vout1 t1 t2 "linear" dt) ?expr '("Vout1") ) awvSetXAxisLabel(wid "time [sec]" ?subwindow bid) awvSetYAxisLabel(wid 1 "Amplitude [volt]" ?subwindow bid) ;plotStyle('joined) displayMode("strip") yLimit( list(-1.5 1.5) ?stripNumber 1 ) yLimit( list(-1.5 1.5) ?stripNumber 2 ) addSubwindow() bid = currentSubwindow(3) addSubwindowTitle( sprintf(nil "fnyquist=%2.1f[kHz] , delta_f=%2.1f[kHz]" fnyquist/1k delta_f/1k) ) plot( db20(Vout_freq) ?expr '("Vout_freq") ) plot( db20(Vout1_freq) ?expr '("Vout1_freq") ) ;plotStyle('joined) displayMode("strip") awvSetXAxisLabel(wid "frequency [Hz]" ?subwindow bid) awvSetYAxisLabel(wid 1 "Spectrum [dB]" ?subwindow bid) xLimit( list(0 15k) ) yLimit( list(-70 10) ?stripNumber 1 ) yLimit( list(-70 10) ?strip |
Title: Re: Query regarding DFT function in Spectre Post by shaikh_sarfraz on Sep 14th, 2008, 11:45pm Hi, Thanks for your response. It was of great help to me. Let me know if my understanding is correct: 1). From the FFT plot we can get Signal power (rms) = 0.5*Vsig**2 2). Noise power (rms) = 0.5*Vn1**2 + 0.5*Vn2**2 ......+0.5*Vnn**2 SNR = 10log(Signal(rms) / Noise(rms)) Best Regards Sarfraz |
Title: Re: Query regarding DFT function in Spectre Post by ywguo on Sep 23rd, 2008, 8:40pm Hi Sarfraz, You are correct except that is not rms value, but 2nd power of the rms value. Yawei |
Title: Re: Query regarding DFT function in Spectre Post by shaikh_sarfraz on Sep 25th, 2008, 7:25am Ok..that should be 2 nd power of RMS noise....... Thanks Yawei |
The Designer's Guide Community Forum » Powered by YaBB 2.2.2! YaBB © 2000-2008. All Rights Reserved. |