Vcm-based時(shí)序的SAR,matlab代碼
已完成:Vcm-based時(shí)序,比較器噪聲與失調(diào),電容失配,kT/C噪聲,建立時(shí)間
未完成:功耗計(jì)算,冗余校正,后端校準(zhǔn)
留檔自用,復(fù)制進(jìn)matlab內(nèi)可直接運(yùn)行。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? ? ? Set parameter? ? ? ? ? ? ? ? ? ? ? ? ? ? ?%?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FFT parameter
Resol = 12;
FFTN = 2^Resol;? % FFT number,namely,least SamplePoints
Fs =40e6;
Fin = 61*Fs/2^Resol; % 31 can be replaced other 質(zhì)數(shù)
%Conversion parameter
Vcm = 0.55;
VFS = 1.1;
Vrefp = 1.1;%VDD
Vrefn = 0;%GND
% Comp parameter
Vos = 500e-6;
CompNoise = 500e-6 * randn(1,Resol);
% Sample parameter
R = 0.5e3;? ? %Switch Ron
C = 0.125e-12;? ? %Cap total 2pF~14bit 125f~12bit C*4,bit+1
tau = R*C;
% Setting time
Tcomp = ((1/Fs)/(Resol+3+1)); %3是采樣;1可改,代表多出來的時(shí)間取出digital code
Tcompset = Tcomp/2;%只有一半的時(shí)間周期建立
Tsampleset = 3*Tcomp; %同步時(shí)序一般是3*Tcomp
K_sampleset = Tsampleset/tau %對(duì)于10bit,建立系數(shù)7.6
K_compset = Tcompset/tau? ? ?%? ? 12bit,建立系數(shù)9
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?%? ? 14bit,建立系數(shù)10.4
% Cap Noise parameter
k = 1.38*1e-23;
T = 300;
Noise_kT_C = (k*T/C)^0.5;
NoisePos = 0.5*Noise_kT_C * randn(1,FFTN);
NoiseNeg = 0.5*Noise_kT_C * randn(1,FFTN);
% CDAC_Weight parameter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Accoding Resol,generate CapWeight,<16bit %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CapWeight = [32768,16384,8192,4096,2048,1024,...
? ? ? ? ? ? ?512,256,128,64,32,16,8,4,2,1,1];% last "1" is dummy
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?% can be delete
CapWeight = flip(CapWeight);
CapWeight = CapWeight(1:Resol+1);
CapWeight = flip(CapWeight);
C_totalWeight= sum(CapWeight);%總權(quán)重,10bit 2048? ? ? ? ? ? ? ? ? ? ? ? ?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CapMismatch = 0.00;
CapWeightPos = normrnd( CapWeight, sqrt( CapWeight ) * CapMismatch );
CapWeightNeg = normrnd( CapWeight, sqrt( CapWeight ) * CapMismatch );
C_totalPos = sum(CapWeightPos);
C_totalNeg = sum(CapWeightNeg);
% When Sample
t = 0:1/Fs:(FFTN-1)*(1/Fs);
Vip = Vcm+VFS/2*sin(2*pi*Fin*t)+NoisePos;
Vin = Vcm-VFS/2*sin(2*pi*Fin*t)+NoiseNeg;
? ? ? ?
%Trend Vp & Vn
Burst = 1;? ? ?%第 burst 次的量化結(jié)果
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? ? ? Vcm-based logic? ? ? ? ? ? ? ? ? ? ? ? ? ?%?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tic; % 記錄開始時(shí)間
D_record = zeros(FFTN, Resol);
Vp_record = zeros(FFTN, Resol+1);
Vn_record = zeros(FFTN, Resol+1);
for SamPoint = 1:FFTN? ?% certain Sample
? ? Vp = Vip(SamPoint)*(1-exp(-Tsampleset/tau));
? ? Vn = Vin(SamPoint)*(1-exp(-Tsampleset/tau));
? ? Vp_record (SamPoint,1) = Vp;
Vn_record (SamPoint,1) = Vn;
? ??
? ? D = zeros(1, Resol);
? ??
? ? for bit = 1:Resol? ?% quantitize
? ? ? ? if Vp + CompNoise(bit) + Vos >=? Vn?
? ? ? ? ? ? D(bit) = 1;
? ? ? ? ? ? Vp = Vp - (VFS / 2 * CapWeightPos(bit) / C_totalPos) ...
? ? ? ? ? ? ? ? ? ? ? ? * (1-exp(-Tcompset/tau));
? ? ? ? ? ? Vn = Vn + (VFS / 2 * CapWeightNeg(bit) / C_totalNeg) ...
? ? ? ? ? ? ? ? ? ? ? ? * (1-exp(-Tcompset/tau));
? ? ? ? ? ? Vp_record (SamPoint,bit+1) = Vp;
? ? ? ? ? ? Vn_record (SamPoint,bit+1) = Vn;
? ? ? ? else
? ? ? ? ? ? D(bit) = 0;
? ? ? ? ? ? Vp = Vp + (VFS / 2 * CapWeightPos(bit) / C_totalPos) ...
? ? ? ? ? ? ? ? ? ? ? ? * (1-exp(-Tcompset/tau));
? ? ? ? ? ? Vn = Vn - (VFS / 2 * CapWeightNeg(bit) / C_totalNeg) ...
? ? ? ? ? ? ? ? ? ? ? ? * (1-exp(-Tcompset/tau));
? ? ? ? ? ? Vp_record (SamPoint,bit+1) = Vp;
? ? ? ? ? ? Vn_record (SamPoint,bit+1) = Vn;
? ? ? ? end
? ? end
? ? D_record(SamPoint,:) = D;
end
% ↑↑↑ D_record gets all sample points' quantitize digital code
DACWeight = CapWeight(1:Resol)';%注意轉(zhuǎn)置
Dout = D_record*DACWeight;
Dout = Dout/2^(Resol)*2*VFS-VFS;
elapsed_time = toc; % 記錄結(jié)束時(shí)間并計(jì)算經(jīng)過的時(shí)間
disp(['Elapsed time: ' num2str(elapsed_time) ' seconds']);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? ? ? Plot Vip & Vin? ? ? ? ? ? ? ? ? ? ? ? ? ? %?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %繪制圖像
% figure(1);
%?
% plot(t, Vip);
% %title('Vip');
% xlabel('Time (s)');
% ylabel('Voltage (V)');
% hold on?
% plot(t, Vin);
% %title('Vin');
% xlabel('Time (s)');
% ylabel('Voltage (V)');
% hold off
% %調(diào)整圖像布局
% sgtitle('Vip and Vin Signals');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? ? ? Trend of Vp & Vn? ? ? ? ? ? ? ? ? ? ? ? ? %?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
?figure(2)
?%? Vp_record = reshape(Vp_record',1,[]);
?%? Vn_record = reshape(Vn_record',1,[]);
?%? new_t = 1:1:(Resol+1)*4096;
?%? stairs(new_t,Vp_record,'r');
?%? hold on
?%? stairs(new_t,Vn_record,'b');
?%? hold off
?new_t = 1:1:Resol+1;
?stairs(new_t,Vp_record(Burst,:),'r');
?hold on
?stairs(new_t,Vn_record(Burst,:),'b');
?hold off
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? ? ? ?Energy consumption? ? ? ? ? ? ? ? ? ? ? ?%?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? ? ? ?Plot Vi & Dout? ? ? ? ? ? ? ? ? ? ? ? ? ?%?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 繪制圖像
figure(3);
% 合并子圖并繪制 Vip - Vin
subplot(1,1,1);
plot(t, Vip - Vin, 'r'); % 使用紅色實(shí)線
hold on; % 開啟 hold on 模式
% 延遲一個(gè)采樣周期繪制 Dout
% 使用 plot 函數(shù)畫階梯狀曲線
t_delay=t(2)-t(1);
stairs(t+t_delay, Dout, 'b'); % 使用藍(lán)色階梯狀線,延遲一個(gè)時(shí)間步長
xlabel('Time (s)');
ylabel('Voltage (V)');
legend({'Vip - Vin', 'Dout'}, 'Location', 'best');% 添加圖例
hold off;% 關(guān)閉 hold on 模式
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%? ? ? ? ? ? ? ? ? ? FFT calculate SNDR,ENOB? ? ? ? ? ? ? ? ? ? ? ?%?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Dout=reshape(Dout,'',1)';%注意轉(zhuǎn)置
Dout=Dout-(max(Dout(1:end))+min(Dout(1:end)))/2;
% figure(4);
% hold on;
% stairs(Dout(1:FFTN));%權(quán)值量
numpt2=fix(FFTN/2);
Dout=Dout(1:FFTN);
Window=hann(FFTN)';%漢寧窗口,注意轉(zhuǎn)置
span=5;
Doutw=Dout.*Window;
DoutFFT=fft(Doutw,FFTN);
SumPower=(abs(DoutFFT)).*(abs(DoutFFT));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%不歸一化,則可以不計(jì)算最大功率并刪除/maxPower %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
maxPower = max(SumPower);% 計(jì)算最大功率值
SumPower_dB=10*log10(SumPower/maxPower);%歸一化
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[MaxdB,FinPoint]=max(SumPower_dB(1:numpt2));
spanh=3;
DcPower=sum(SumPower(1:span));
if FinPoint>span
? ? SinglePower=sum(SumPower(FinPoint-span:FinPoint+span));
else
? ? SinglePower=0;
end
SingleHarmonyNumber2=floor(FFTN/FinPoint);%或者為Fs/(Fin)
SingleHarmonyPower=zeros(SingleHarmonyNumber2);
SingleHarmonyPower(1)=SinglePower;
SingleHarmonyFrequency=zeros(SingleHarmonyNumber2);
SingleHarmonyFrequency(1)=Fs*(FinPoint)/FFTN;
SingleHarmonyStep=FinPoint;
for SingleHarmonyNumber=1:SingleHarmonyNumber2/2
? ? if (SingleHarmonyStep<=0) break; end
? ? HarmonyFrequencyPoint=SingleHarmonyStep*SingleHarmonyNumber+FinPoint;
? ? if (HarmonyFrequencyPoint<=numpt2)
? ? ? ? if SingleHarmonyNumber==1
? ? ? ? ? ? BaseHarmonyFrequencyPoint=HarmonyFrequencyPoint;
? ? ? ? end
? ? ? ? SingleHarmonyPower(SingleHarmonyNumber+1)=sum(SumPower(HarmonyFrequencyPoint-spanh:HarmonyFrequencyPoint+spanh));
? ? ? ? SingleHarmonyFrequency(SingleHarmonyNumber+1)=(HarmonyFrequencyPoint)*Fs/FFTN;
? ? end
end
Fin=SingleHarmonyFrequency(1);
HarmonyPowerNumber=floor(FFTN/FinPoint)/2;%或者為Fs/(Fin)/2
HarmonyPower=sum(SingleHarmonyPower(1:HarmonyPowerNumber))-SingleHarmonyPower(1);
NoisePower=sum(SumPower(1:numpt2))-DcPower-SinglePower;
ss=sqrt((sum(Dout.^2)/sum(Doutw.^2))*NoisePower*2)/FFTN;%*sqrt(12);
HarmonyRange=floor(FFTN/FinPoint)/2;%或者為Fs/(Fin)/2
SNDR=10*log10(SinglePower/NoisePower);
THD=10*log10(HarmonyPower/SingleHarmonyPower(1));
SFDR=10*log10(SingleHarmonyPower(1)/max(SingleHarmonyPower(2:HarmonyRange)));
ENOBloc=(SNDR-1.76)/6.02;
figure(5);
hold on;
semilogx([0:numpt2-1] * Fs / FFTN, SumPower_dB(1:numpt2), '-');
text_handle = text(Fin * 5, -20, sprintf('SNDR = %4.1f dB \nENOB = %2.2f bits ', SNDR, ENOBloc), ...
? ? 'EdgeColor', 'red', 'LineWidth', 3, 'BackgroundColor', [1 1 1], 'Margin', 10);
title('FREQ DOMAIN');
xlabel('ADC FFT SPECTRUM');
ylabel('AMPLITUDE(dB)');
set(gca, 'XScale', 'log');? % 將當(dāng)前坐標(biāo)軸改為對(duì)數(shù)軸,去除該行則線性x軸坐標(biāo)。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%