|  | 
 
| 
求大神指导:SAR ADC,10bit 240MHz  ADC输出,用理想DAC转换,然后导入matlab,去了64个点做FFT,下面是不同输入频率时的结果:
×
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册  
       仿真时没有考虑IO pad的寄生影响,主要疑问有:
 1、每次出来的ENOB都比10大,SNR值也比理想的要大
 2、为什么有的谐波几乎为0,在cadence中我做了DFT,结果也是这样,部分谐波非常小
 3、我用理想的8bit ADC做了实验,出来的结果部分谐波也是几乎为0。
 下面贴出FFT的程序和理想10bitDAC代码。中间我也尝试着把span、spanh、spandc取了不同的值,但结果几乎一样。
 第一次做,求大神指导。非常谢谢!
 %***********************************************************************%
 % The following program code plots the FFT spectrum of a desired test tone.
 % Test tone based on coherent sampling criteria, and computes SNR, SNDR, THD and SFDR.
 % This program is believed to be accurate and reliable.
 % This program may get altered without prior notification.;
 % Company: xxx Analog Mixed-signal Group
 % Author:
 % Date: 2016-01-09
 %***********************************************************************%
 
 
 
 
 %***********************************************************************%
 % 采样时钟240MHz,输入信号频率86.25MHz,FFT点数64,ADC分辨率10bit,仿真时间400ns。
 % 从cadence输出时间隔是4.16666667ns,共计97个点,从第20个点开始取64点做FFT。
 % cadence输出的是归一化的结果范围是0-1.6V,需除以1.6再乘以1024,转换为数字码。
 %***********************************************************************%
 
 
 
 
 clear all;
 clc;
 datafile='ADC_result8.csv'
 spectP_file='spec.csv';
 
 
 
 
 %***********************************************************************%
 % 输入采样时钟、样本点数、分辨率等变量
 %***********************************************************************%
 fs=240e6;        %采样时钟
 Data_Num=64;   %样本点数
 numbit=10;       %ADC分辨率
 data_start=20; %取点起始位置
 fclk=fs/1e6;     %x坐标轴数值显示
 numpt=Data_Num;
 fres=fclk/numpt; %Desired frequency resolution of FFT[MHz], fres=fclk/2^N
 
 
 %***********************************************************************%
 % 读取数据
 %***********************************************************************%
 d_in=csvread('ADC_result8.csv',1,1);
 d_in=d_in/1.6*1024;
 code=zeros(1,numpt);
 code(1:numpt)=d_in(data_start:data_start+numpt-1);
 
 
 %***********************************************************************%
 % Plot output code
 %***********************************************************************%
 figure;
 plot(code);
 title(sprintf('ADC Digital Output'));
 
 
 %***********************************************************************%
 % Recenter the digital sine wave, for 2's complement code
 %***********************************************************************%
 m_ean=mean(code);
 for hk=1:length(code)
 code(hk)=code(hk)-m_ean;
 end
 
 
 %***********************************************************************%
 % Display a warning, when the input generates a code greater than
 % full-scale, for 2's complement code
 %***********************************************************************%
 max_code=max(code)
 min_code=min(code)
 if (max(code)>2^(numbit-1)) | (min(code)<(0-2^(numbit-1)))
 %if (max(code)==2numbit -1) | (min(code)==0)
 disp('Warning: ADC may be clipping!');
 end
 
 
 %***********************************************************************%
 % Normalize input signal relative to full-scale
 %***********************************************************************%
 fin_dB=20*log10((max_code-min_code)/(2^numbit));
 
 
 %***********************************************************************%
 % 对数据样本加窗函数处理
 %***********************************************************************%
 % If no window function is used, the input tone must be chosen to be unique and with
 % regard to the sampling frequency. To achieve this prime numbers are introduced and the
 % input tone is determined by Fin = Fsample * (Prime Number / Data Record Size).
 % To relax this requirement, window functions such as HANNING and HAMING (see below) can
 % be introduced, however the fundamental in the resulting FFT spectrum appears 'sharper'
 %without the use of window functions.
 Dout=code';
 Doutw=Dout;
 % Doutw=Dout.*hanning(numpt);
 % Doutw=Dout.*hamming(numpt);
 % Doutw=Dout.*blackman(numpt);
 
 
 %***********************************************************************%
 % Performing the Fast Fourier Transform [FFT]
 %***********************************************************************%
 span=0; %Span of the input frequency on each side; span=max(round(numpt/200),5);
 spanh=0; %Approximate search span for harmonics on each side
 spandc=0; %Approximate search span for DC on right side
 Dout_spect=fft(Doutw);
 Dout_dB=20*log10(abs(Dout_spect)); %Recalculate to dB abs(Dout_spect)
 spectP=(abs(Dout_spect)).*(abs(Dout_spect)); %Determine power spectrum
 maxdB=max(Dout_dB(1+spandc:numpt/2));
 fin=find(Dout_dB(1:numpt/2)==maxdB); %Find the signal bin number, DC=bin1
 
 
 %***********************************************************************%
 % Calculate SNR, SNDR, THD and SFDR values.
 %***********************************************************************%
 fw=fopen(spectP_file,'w'); %write the power soectrum to file
 fprintf(fw,'%12.9e\n',spectP);
 fclose('all');
 %Find DC offset power
 Pdc=sum(spectP(1:span));
 %Extract overall signal power
 idx1=fin-span;
 idx2=fin+span;
 if(idx1<=0)
 idx1 = 1;
 end
 Ps=sum(spectP(idx1:idx2));
 %Vector/matrix to store both frequency and power of signal and harmonics
 Fh=[];
 %The 1st element in the vector/matrix represents the signal, the next element represents the 2nd harmonic
 Ph=[];
 %Vector/matrix to store the sampling points responding to the harmonics
 Nh=[];
 %Ah represents signal and harmonic amplitude
 Ah=[];
 %Find harmonic frequencies and power components in the FFT spectrum
 %For this procedure to work, ensure the folded back high order harmonics do not overlap
 %with DC or signal or lower order harmonics , so it should be modified according to the actual condition
 for har_num=1:5
 tone=rem((har_num*(fin-1)+1)/numpt,1); %Input tones greater than fSAMPLE are aliased back into the spectrum
 if tone>0.5
 tone=1-tone; %Input tones greater than 0.5*Fsample (after aliasing) are reflected
 end
 Fh=[Fh tone];
 %Check Nh to see the bin of the harmonics
 Nh=[Nh round(tone*numpt)];
 %For this procedure to work, ensure the folded back high order harmonics do not overlap
 %with DC or signal or lower order harmonics
 har_peak=max(spectP(round(tone*numpt)-spanh:round(tone*numpt)+spanh));
 har_bin=find(spectP(round(tone*numpt)-spanh:round(tone*numpt)+spanh)==har_peak);
 har_bin=har_bin+round(tone*numpt)-spanh-1;
 Ph=[Ph sum(spectP(har_bin-spanh:har_bin+spanh))];
 Ah=[Ah Dout_dB(har_bin)];
 end
 %Determine the total distortion power, it should be modified according to the actual condition.
 Pd=sum(Ph(2:5));
 %Determine the noise power
 Pn=sum(spectP(1:numpt/2))-Pdc-Ps-Pd;
 %Determine the next largest component
 spur_max=max(max(spectP(spandc+1:fin-span-1)),max(spectP(fin+span+1:numpt/2)));
 spur_bin=find(spectP(1:numpt/2)==spur_max)
 %**********************计算动态特性结果**********************%
 format; %设置输出格式
 SFDR = 10*log10(max(spectP(1:numpt/2))/spur_max); %-fin_dB
 THD = 10*log10(Pd/Ps); %+fin_dB
 SNR = 10*log10(Ps/Pn); %-fin_dB
 SNDR = 10*log10(Ps/(Pn+Pd)); %-fin_dB
 ENOB = (SNDR-1.76)/6.02;
 %disp('Note: THD is calculated from 2nd through 10th order harmonics.');
 %*********************标示信号和谐波位置*********************%
 %hold on;
 %plot((Nh(2:10)-1).*fres,Ah(2:10)-maxdB+fin_dB,'rs');
 % 标示信号
 bins=(Nh(1)-1)*fres;
 Ahs=Ah(1)-maxdB+fin_dB;
 % 标示2次谐波
 bin2=(Nh(2)-1)*fres;
 Ah2=Ah(2)-maxdB+fin_dB;
 % 标示3次谐波
 bin3=(Nh(3)-1)*fres;
 Ah3=Ah(3)-maxdB+fin_dB;
 % 标示4次谐波
 bin4=(Nh(4)-1)*fres;
 Ah4=Ah(4)-maxdB+fin_dB;
 % 标示5次谐波
 bin5=(Nh(5)-1)*fres;
 Ah5=Ah(5)-maxdB+fin_dB;
 % 在FFT频谱图中追加标示
 figure;
 plot(bins,Ahs,'rs',bin2,Ah2,'rd',bin3,Ah3,'r^',bin4,Ah4,'r*',bin5,Ah5,'rx');
 legend('SINGAL','HD2','HD3','HD4','HD5');
 %**********************图表显示**********************%
 ylabel('Full-Scale Normalized Magnitude[dB]')
 xlabel('Frequency [MHz]')
 title(sprintf('ADC FFT Spectrum (%g points)\nFs = %g MSps, Fin = %g MHz (%1.2gdBFS)', Data_Num,fs/1e6,(fin-1)*fres,fin_dB));
 grid on;
 box on;
 ylim([-110 10]);
 set(gca,'xgrid', 'off');
 set(gca, 'GridLineStyle' ,'-');
 set(gca,'yTick',[-110:10:10]);
 %****************************************************%
 %Display the results in the frequency domain with an FFT plot.
 for i=0:1
  numpt/2-1) hold on;
 line([i*fres,i*fres],[-110,Dout_dB(i+1)-maxdB+fin_dB],'LineWidth',2);
 hold off;
 end
 %***********************在图中打印结果***********************%
 hold on;
 s1=sprintf('SFDR = %4.1fdB\n',SFDR);
 s2=sprintf('THD = %4.1fdB\n',THD);
 s3=sprintf('SNR   = %4.1fdB\n',SNR);
 s4=sprintf('SNDR = %4.1fdB\n',SNDR);
 s5=sprintf('ENOB = %4.2fbit\n',ENOB);
 text(25,-10,s1);
 text(25,-20,s2);
 text(25,-30,s3);
 text(25,-40,s4);
 text(25,-50,s5);
 hold off;
 
 
 
 
 
 
 
 
 
 
 
 
 
 10bit DAC
 `include "discipline.h"
 `include "constants.h"
 
 
 // $Date: 1997/08/28 05:54:36 $
 // $Revision: 1.1 $
 //
 //
 
 
 
 
 
 
 //--------------------
 // dac_10bit_ideal
 //
 // -  10 bit digital analog converter
 //
 // vd0..vd9:
 data inputs [V,A]
 // vout:
 [V,A]
 //
 // INSTANCE parameters
 //    vref   = reference voltage that conversion is with respect to [V]
 //    vtrans = transition voltage between logic high and low [V]
 //    tdel,trise,tfall = {usual}
 //
 // MODEL parameters
 //    {none}
 
 
 module dac_10bit_ideal (vd9, vd8, vd7, vd6, vd5, vd4, vd3, vd2, vd1, vd0, vout);
 electrical vd9, vd8, vd7, vd6, vd5, vd4, vd3, vd2, vd1, vd0, vout;
 parameter real vref  = 1.6 from [0:inf);
 parameter real trise = 0 from [0:inf);
 parameter real tfall = 0 from [0:inf);
 parameter real tdel  = 0 from [0:inf);
 parameter real vtrans  = 0.45;
 
 
 real out_scaled; // output scaled as fraction of 1024
 
 
 analog begin
 
 out_scaled = 0;
 
 out_scaled = out_scaled + ((V(vd9) > vtrans) ? 512 : 0);
 
 out_scaled = out_scaled + ((V(vd8) > vtrans) ? 256 : 0);
 
 out_scaled = out_scaled + ((V(vd7) > vtrans) ? 128 : 0);
 
 out_scaled = out_scaled + ((V(vd6) > vtrans) ? 64 : 0);
 
 out_scaled = out_scaled + ((V(vd5) > vtrans) ? 32 : 0);
 
 out_scaled = out_scaled + ((V(vd4) > vtrans) ? 16 : 0);
 
 out_scaled = out_scaled + ((V(vd3) > vtrans) ? 8 : 0);
 
 out_scaled = out_scaled + ((V(vd2) > vtrans) ? 4 : 0);
 
 out_scaled = out_scaled + ((V(vd1) > vtrans) ? 2 : 0);
 
 out_scaled = out_scaled + ((V(vd0) > vtrans) ? 1 : 0);
 
 V(vout) <+ transition( vref*out_scaled/1024, tdel, trise, tfall );
 end
 endmodule
 | 
 |