In response to Calcul of SNR in CADENCEWatch Full Movie Online Streaming Online and Download
I generally don’t like Cadence’s FFT command as it only computes a radix-2 FFT. This is great if your sampling frequency happens to be a power of two of your input frequency. Most of the time, this is the case (or close enough to be immaterial). That’s not the case with me.
I’ll save how I get a non-radix-2 FFT into Cadence for later (I use Matlab). However, here’s how I compute SNR/SNDR when I have an FFT already provided:
- I run the simulation for a time period of (kcyc+ncyc)/fS. fS is the sampling frequency. kcyc is the number of cycles to leave for startup transients.
- I do an FFT over the last ncyc samples. So, even though I run the ADC for (kcyc+ncyc)/fS, I exclude the first kcyc samples. I generally use a minimum 4-term Blackman-Harris window. In simulation, if you ahve the ability to pick your sample frequenciy and input frequency, you don’t need to window; your FFT frequencies will be right-on with the FFT bins. I window anyway.
- I sum up +/- 5 FFT bins around the nominal input frequency. This is because I use the BH4 window, which extends the main lobe of the signal out. I’ve found that +/- 5 bins definitely catches the signal. Any additional noise it catches if usually immaterial.
- For an SNR (versus an SNDR) measurement, I subtract out any distortion. I define distortion as any odd-order harmonics of the signal (odd multiples of the input frequency) that fall within the bandwidth of interest.
- After summing up signal power, noise power, and noise+distortion power, I comute the ratios to get SNR or SNDR.
Anyway. Here’s the code to do it. Once again, I relase it under the GNU Public License to encourage others to contribute back their improvements:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
; Compute SNR based on an FFT of the output
; Copyright (c) 2008 Poojan Wagh (poojanwagh {at} circuitdesign [dot] info)
; http://www.circuitdesign.info
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1
2
3
4
5
6
|
ncyc = 1024; % number of points for fft
kcyc = 512; % number of points for startup (excluded for fft)
simtime = (ncyc+kcyc)/fS % total simulation time
fbin = fS/ncyc; % FFT bin width (Hz)
fin = 13*fbin; % Input frequency (arbitrary)
bw = round(2E6/fbin)*fbin; % bandwidth (rounded to FFT bin)
|
1
2
3
4
5
6
7
|
procedure( sumpsd( psd fstart fend)
if(fstart < fend then
integ( clip(psd fstart fend) )
else
0.0
)
)
|
1
2
3
4
5
6
|
; get power of signal centered at fc
procedure( getpow( psd fc fbin )
let( list( (speclobew 5) )
sumpsd(psd fc–speclobew*fbin fc+speclobew*fbin)
)
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
; compute PSD of output (abs(FFT)^2)
; I‘m currently using Matlab to do this (procedure matpsd)
; However, Cadence/Ocean’s fft() function will do equally well:
psdoutput = matpsd( dumpfile fS ncs ncyc )
; PSig = sumpsd(psdoutput fin–5*fbin fin+5*fbin) ; Signal Power
PSig = getpow(psdoutput fin fbin) ; Signal Power
PND = sumpsd(psdoutput 0 min(bw fin–6*fbin)) + sumpsd(psdoutput fin+6*fbin bw) ; Noise Power
PN = PND;
exbw = 0;
; for SNR measurement, exclude odd–mode distortion
; from 3*fin to bw
for( k 1 floor(bw/2/fin)
fex1 = (2*k+1)*fin–5*fbin
fex2 = min(bw (2*k+1)*fin+5*fbin)
psdex = sumpsd(psdoutput fex1 fex2);
; printf(“k = %u Excluding distortion from %f kHz to %f kHz (%g – %g)\n” 2*k+1 fex1 fex2 PN psdex)
PN = PN – psdex;
exbw = exbw + (fex2–fex1);
; printf(“Excluding distortion from %f kHz to %f kHz (%f kHz)\n” fex1/1.0k fex2/1.0k (fex2–fex1)/1.0k);
)
PN = PN / (1 – exbw/bw) ;compensate for frequencies we have excluded
;(assuming white noise)
SNDR = PSig/PND;
SNR = PSig/PN;
SNDRdB = db10(SNDR);
SNRdB = db10(SNR);
printf(“SNDR [%s/%s/%s]= %.2f dB\n” library cell view SNDRdB);
printf(“SNR [%s/%s/%s]= %.2f dB\n” library cell view SNRdB);
sprintf(wintitle “PSD of Digitized PWM [%s/%s/%s] SNDR = %.0f dB NSR = %.0f dB” library cell view SNDRdB SNRdB)
plot(db10(clip(psdoutput, fin–5*fbin, fin+5*fbin)) db10(psdoutput) ?expr list(“Desired Signal” wintitle))
xLimit(list(0 bw))
|
Hi, I am doing project on a similar topic of this, which is to design a DEM circuit for feedback DAC of delta-sigma modulator. And I found the post here is useful for me. many thanks for your work.