%
% 此程序适用于4-CPM/QAM 和 16-CPM/QAM 的调制,分别在LFDMA和IFDMA两种映射方案下进行仿真
% 并比较PAPR 及 BER性能。
clc
clear all
close all
set_consts;
global consts;
%================= 设置参数 =======================
% CPM参数
T=1;
L=3; % 关联长度
h=2/3;
pam_type=consts.pam_type;
m=2.^pam_type; % 16进制
p = 2/h; % 累计相位的状态个数
CY=4;
% SC-FDMA参数
M=consts.len_fft;
N=consts.len_ifft;
code_rate=consts.code_rate;
modu=consts.modu;
num_sym=consts.no_data_sym;
no_sym = consts.no_sym;
% 单天线
mimo.num_txs=1;
mimo.num_rxs=1;
% 比特数
num_bits=M*modu*num_sym*code_rate;
loop=50;
% 信道参数
channel_type=1;
% 信噪比设置
ebn0_db=5:5:20;
for jj=1:length(ebn0_db)
ebn0(jj) = ebn0_db(jj) - 10 * log10(CY) + 10 * log10(log2(m));
end
% LFDMA
L_err_bits1 = zeros(1,length(ebn0));
L_err_bits2 = zeros(1,length(ebn0));
% IFDMA
I_err_bits1 = zeros(1,length(ebn0));
I_err_bits2 = zeros(1,length(ebn0));
% PAPR设置
papr_1 = zeros(1,length(ebn0_db)*loop*no_sym); % QAM
papr_2 = zeros(1,length(ebn0_db)*loop*no_sym);
papr_01 = zeros(1,length(ebn0_db)*loop*no_sym); % CPM
papr_02 = zeros(1,length(ebn0_db)*loop*no_sym);
papr0_db = 0:0.2:15;
papr0 = 10.^(papr0_db./10);
%================================================================================================
tic;
for iii=1:length(ebn0)
for ii=1:loop
% ------------ 产生比特信息 -----------------------
source_bits=rand(1,num_bits)>0.5;
%------------- 卷积编码 -----------------------------
[coded_bits,len_code]=conv_code(source_bits,mimo); % 码率为1,数据长度没有变化
%===================== QAM 调制 ===================================
[mod_qam_sig] = qam_modulate(coded_bits,modu);
% 为了与cpm信号长度保持一致,需要对信号进行扩展
[extend_qam_sig] = qam_extend(mod_qam_sig,CY);
%===================== CPM 调制 ===================================
[mod_cpm_sig,qt]=cpm_modulate(coded_bits,L,T,CY,h,p);
[extend_cpm_sig] = cpm_extend(mod_cpm_sig,CY);
%==================== SC-FDMA 调制=====================================
[qam_lfdma_sig1,qam_ifdma_sig1,q_inst_papr_1,q_inst_papr_2,basic_seq_time]=mod_sc_fdma(extend_qam_sig);
[cpm_lfdma_sig2,cpm_ifdma_sig2,c_inst_papr_1,c_inst_papr_2,basic_seq_time]=mod_sc_fdma(extend_cpm_sig);
% QAM
papr_1(1,((iii-1)*loop+ii-1)*no_sym+1:((iii-1)*loop+ii)*no_sym) = q_inst_papr_1;
papr_2(1,((iii-1)*loop+ii-1)*no_sym+1:((iii-1)*loop+ii)*no_sym) = q_inst_papr_2;
% CPM
papr_01(1,((iii-1)*loop+ii-1)*no_sym+1:((iii-1)*loop+ii)*no_sym) = c_inst_papr_1;
papr_02(1,((iii-1)*loop+ii-1)*no_sym+1:((iii-1)*loop+ii)*no_sym) = c_inst_papr_2;
%==================================================================
%
%============================ 信道 =================================
% 瑞利加高斯信道
% QAM
[fade_coefficient,sig_after_fade1,sig_after_fade2] = channel(qam_lfdma_sig1,qam_ifdma_sig1,mimo,channel_type);
[noise_sig1,noise_sig2,noise_pow1,noise_pow2] = add_gnoise(sig_after_fade1,sig_after_fade2,ebn0(iii),mimo);
% CPM
[fade_coefficient,sig_after_fade01,sig_after_fade02] = channel(cpm_lfdma_sig2,cpm_ifdma_sig2,mimo,channel_type);
[noise_sig01,noise_sig02,noise_pow01,noise_pow02] = add_gnoise(sig_after_fade01,sig_after_fade02,ebn0(iii),mimo);
% % 高斯信道
% [noise_sig,noise_pow1] = add_gnoise(sc_fdma_sig,ebn0(iii),mimo);
%===================== SC-FDMA 解调 ==============================
[sig_desc_lfdma1,sig_desc_ifdma1]=demod_sc_fdma(noise_sig1,noise_sig2,noise_pow1,noise_pow2,fade_coefficient,basic_seq_time);
[sig_desc_lfdma2,sig_desc_ifdma2]=demod_sc_fdma(noise_sig01,noise_sig02,noise_pow01,noise_pow02,fade_coefficient,basic_seq_time);
%%%%%%%%%%%%%%%%%%%%%%%%%% LFDMA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%========================== QAM 解调 =======================================
% 去扩展信号
L_sig_before_demo = sig_desc_lfdma1(1:CY:length(sig_desc_lfdma1)-consts.len_fft);
[L_demo_sig1] = qam_demodulate(L_sig_before_demo,modu);
%====================== CPM 解调 =================================
% Viterbi 译码
% 去扩展信号
L_sig_before_cpm_demo = sig_desc_lfdma2(1:length(sig_desc_lfdma2)-(consts.len_fft-4*CY));
[L_demo_cpm_sig]=cpm_demodulate( L_sig_before_cpm_demo,qt,CY,L,h,p,m);
% PAM 逆映射
[L_demo_sig2]=pam_demapping(L_demo_cpm_sig);
%=================================================================
%-----------------------------卷积译码----------------------------
% 包括交织和卷积
% QAM
dectype = 'soft';
L_rx_bits_decoded1= zeros(mimo.num_txs, length(L_demo_sig1(1,:))*code_rate); % 乘以码率后,去掉编码比特
L_data_before_decode1 = rx_deinterleaver(L_demo_sig1, consts.nos_single_user*consts.modu, consts.modu,len_code, consts.nos_single_user);
L_rx_bits_decoded1 = rx_decode(L_data_before_decode1, code_rate, dectype);
L_err_num1=sum(abs(source_bits-L_rx_bits_decoded1));
L_err_bits1(iii) = L_err_bits1(iii) + L_err_num1;
% CPM
dectype = 'soft';
L_rx_bits_decoded2= zeros(mimo.num_txs, length(L_demo_sig2(1,:))*code_rate); % 乘以码率后,去掉编码比特
L_data_before_decode2 = rx_deinterleaver(L_demo_sig2, consts.nos_single_user*consts.modu, consts.modu,len_code, consts.nos_single_user);
L_rx_bits_decoded2 = rx_decode(L_data_before_decode2, code_rate, dectype);
L_err_num2=sum(abs(source_bits-L_rx_bits_decoded2));
L_err_bits2(iii) = L_err_bits2(iii) + L_err_num2;
%%%%%%%%%%%%%%%%%%%%%%%%%% LFDMA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%========================== QAM 解调 =======================================
% 去扩展信号
I_sig_before_demo = sig_desc_ifdma1(1:CY:length(sig_desc_ifdma1)-consts.len_fft);
[I_demo_sig1] = qam_demodulate(I_sig_before_demo,modu);
%====================== CPM 解调 =================================
% Viterbi 译码
% 去扩展信号
I_sig_before_cpm_demo = sig_desc_ifdma2(1:length(sig_desc_ifdma2)-(consts.len_fft-4*CY));
[I_demo_cpm_sig]=cpm_demodulate( I_sig_before_cpm_demo,qt,CY,L,h,p,m);
% PAM 逆映射
[I_demo_sig2]=pam_demapping(I_demo_cpm_sig);
%=================================================================
%-----------------------------卷积译码----------------------------
% 包括交织和卷积
% QAM
dectype = 'soft';
I_rx_bits_decoded1= zeros(mimo.num_txs, length(I_demo_sig1(1,:))*code_rate); % 乘以码率后,去掉编码比特
I_data_before_decode1 = rx_deinterleaver(I_demo_sig1, consts.nos_single_user*consts.modu, consts.modu,len_code, consts.nos_single_user);
I_rx_bits_decoded1 = rx_decode(I_data_before_decode1, code_rate, dectype);
I_err_num1=sum(abs(source_bits-I_rx_bits_decoded1));
I_err_bits1(iii) = I_err_bits1(iii) + I_err_num1;
% CPM
dectype = 'soft';
I_rx_bits_decoded2= zeros(mimo.num_txs, length(I_demo_sig2(1,:))*code_rate); % 乘以码率后,去掉编码比特
I_data_before_decode2 = rx_deinterleaver(I_demo_sig2, consts.nos_single_user*consts.modu, consts.modu,len_code, consts.nos_single_user);
I_rx_bits_decoded2 = rx_decode(I_data_before_decode2, code_rate, dectype);
I_err_num2=sum(abs(source_bits-I_rx_bits_decoded2));
I_err_bits2(iii) = I_err_bits2(iii) + I_err_num2;