欢迎光临散文网 会员登陆 & 注册

Vcm-based时序的SAR,matlab代码

2023-08-05 18:28 作者:瞬间思路i  | 我要投稿

已完成:Vcm-based时序,比较器噪声与失调,电容失配,kT/C噪声,建立时间

未完成:功耗计算,冗余校正,后端校准

留档自用,复制进matlab内可直接运行。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%                        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 质数

%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可改,代表多出来的时间取出digital code

Tcompset = Tcomp/2;%只有一半的时间周期建立

Tsampleset = 3*Tcomp; %同步时序一般是3*Tcomp


K_sampleset = Tsampleset/tau %对于10bit,建立系数7.6

K_compset = Tcompset/tau     %    12bit,建立系数9

                             %    14bit,建立系数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);%总权重,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 次的量化结果


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%                        Vcm-based logic                           % 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

tic; % 记录开始时间

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)';%注意转置

Dout = D_record*DACWeight;

Dout = Dout/2^(Resol)*2*VFS-VFS;

elapsed_time = toc; % 记录结束时间并计算经过的时间

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

% %调整图像布局

% 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'); % 使用红色实线

hold on; % 开启 hold on 模式

% 延迟一个采样周期绘制 Dout

% 使用 plot 函数画阶梯状曲线

t_delay=t(2)-t(1);

stairs(t+t_delay, Dout, 'b'); % 使用蓝色阶梯状线,延迟一个时间步长

xlabel('Time (s)');

ylabel('Voltage (V)');

legend({'Vip - Vin', 'Dout'}, 'Location', 'best');% 添加图例

hold off;% 关闭 hold on 模式

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%                    FFT calculate SNDR,ENOB                       % 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


Dout=reshape(Dout,'',1)';%注意转置

Dout=Dout-(max(Dout(1:end))+min(Dout(1:end)))/2;

% figure(4);

% hold on;

% stairs(Dout(1:FFTN));%权值量


numpt2=fix(FFTN/2);

Dout=Dout(1:FFTN);


Window=hann(FFTN)';%汉宁窗口,注意转置

span=5;

Doutw=Dout.*Window;

DoutFFT=fft(Doutw,FFTN);


SumPower=(abs(DoutFFT)).*(abs(DoutFFT));

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%不归一化,则可以不计算最大功率并删除/maxPower %

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

maxPower = max(SumPower);% 计算最大功率值

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');  % 将当前坐标轴改为对数轴,去除该行则线性x轴坐标。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


Vcm-based时序的SAR,matlab代码的评论 (共 条)

分享到微博请遵守国家法律