赞
踩
SOQPSK(Shaped Offset Quadrature Phase Shift Keying),整形偏移四相相移键控。其中,S(shaped)指的是信号的波形经过特殊设计,以优化传输性能,O(offset)表示信号的相位被偏移以改善调制方案的性能。
SOQPSK是一种基于QPSK调制方式的改进版本,通过特殊的波形设计和相位调整来改善性能。在QPSK中,将基带码元分成I、Q两路,相邻码元的最大相位差为180°,这样的相位突变在频带受限的系统中会引起信号包络的很大起伏,为了减小此相位突变,在OQPSK中,将I、Q两路在时间上错开半个码元,使之不可能同时改变,此时相邻码元的相位差的最大值为90°,从而减小了信号振幅的起伏,包络恒定,相对于传统的QPSK,它具有更好的抗多径衰落和功率放大器非线性的性能,其频谱旁瓣要低于QPSK信号的旁瓣,且有较高的功率利用率。
然而,OQPSK依旧具有90°的相位跳变,并且变化并不连续,使得OQPSK的高频滚降变慢,频带变宽。从OQPSK到SOQPSK的实现方式是通过改变附加相位中的频率成形函数,以保证相位的连续变化。在OQPSK中频率成形函数是冲激函数,对应的相位成形函数是矩形函数,因此相位不连续。若要相位成形函数连续,可采用矩形函数或升余弦函数作为频率成形函数,由此得到的相位成形函数是连续的,因而频谱较窄,频谱利用率较高。是连续相位调制(CPM)中的一种特殊调制方式,适用于功率受限且频带受限的通信信道中。
QPSK、OQPSK、SOQPSK的相位曲线
SOQPSK作为一种特殊的CPM调制方式,区别于传统CPM的一个明显特征是,实际传输的三元符号集{ }为{-1,0,1}。
SOQPSK调制的时域表达式为:
代表一个码元的持续时间, 代表 时间内码元的能量, 代表SOQPSK时域信号的载波频率, 为相位函数, 为初始相位 。其中,
频率脉冲函数为
相位函数q(t)为频率脉冲函数的积分,即
因此,可得到相位信息
为原始输入的二进制数据 ,取值为{0,1},经过预编码
得到,取值为{0,+1,-1}。经过与编码的 ,1和-1不相邻,保证了SOQPSK相邻码元的相位变化最大为 。
根据以上SOQPSK的基本原理,对SOQPSK在基带上调制解调过程进行matlab仿真。基本参数设置如下
对随机产生的二进制码元进行turbo编码后,对其进行预编码,转化为三进制码元,并进行四倍采样,得到的采样序列如图所示
I路和Q路以及SOQPSK调制后的的基带调制波形如下
可以看出SOQPSK为恒包络信号
其相位曲线为
星座图
当采样率足够大时,该星座图为一个连续的圆,即SOQPSK相位连续;采样率为1时,SOQPSK星座图与QPSK的星座图相同。
信号频谱如下
可以看出,经过SOQPSK调制后的信号频谱较窄,频谱利用率高。
在信道内加入高斯白噪声,信噪比为20db
加入噪声后的相位曲线:
星座图
频谱
硬判决:
对加噪后的相位曲线每隔一个码元周期对其进行最小二乘拟合,得到的斜率为
以+0.5和-0.5作为判决门限,得到的判决结果为
与原二进制编码后的输入数据几乎相同
matlab 代码如下(仅仅显示核心代码)
clear ; % 清除所有变量 close all; % 关闭所有窗口 clc; % 清屏 %% 基本参数 M=224*8; % 产生码元数 Ns=4; % 每码元复制L次,每个码元采样次数4 Tb=1; % 每个比特的持续时间1 Rb=1/Tb; % 码元速率1 dt=Tb/Ns; % 采样间隔0.25 Fs=1/dt; % 采样间隔的倒数即采样频率4 %% 产生二进制数据 %% M_data = 0x1:0xE0; binStr = dec2bin(M_data); binData = binStr - '0'; data = reshape(binData',M,1)'; %% turbo编码 encoded_data=TurboEncode(data); %% SOQPSK 调制 s = soqpsk_mod(encoded_data); %% 信道 s_n=awgn(s,-20,'measured');%加入高斯白噪声20db % 度量 L=length(DI); %分支度量 gammaI_0 = zeros(1,length(DI)); gammaI_1 = zeros(1,length(DI)); gammaI_2 = zeros(1,length(DI)); gammaI_3 = zeros(1,length(DI)); gammaQ_0 = zeros(1,length(DI)); gammaQ_1 = zeros(1,length(DI)); gammaQ_2 = zeros(1,length(DI)); gammaQ_3 = zeros(1,length(DI)); %前向度量 %初始化前向度量 alphaI_0 = zeros(1, L+1); alphaI_1 = zeros(1, L+1); alphaQ_0 = zeros(1, L+1); alphaQ_1 = zeros(1, L+1); %前向度量的递推 %后向度量 %初始化后向度量 betaI_0 = zeros(1, L+1); betaI_1 = zeros(1, L+1); betaQ_0 = zeros(1, L+1); betaQ_1 = zeros(1, L+1); %后向度量的递推 % 计算软信息 decoded_data = [llrQ,llrI]; %Turbo译码 turbodecoded_data=lteTurboDecode(decoded_data'); % 计算误码比特数 num_errors = sum(turbodecoded_data' ~= data); % 计算总比特数 total_bits = length(data); % 计算误码率 BER = num_errors / total_bits
得出的误码率为零。代码是示意代码。
上文已经描述了详细的原理和matlab仿真,下一步就是用FPGA进行实现;
包含了完整的信源和信宿、误码率比较;
包含有加扰和解扰;
包含有soqpsk调制和解调;
包含有turbo编译码;
最终输出的数据和发射的数据保持一致;
// 生成224 8Bit数据; gen_Incremental_223 gen_Incremental_224( .clk (clk ), .rst (rst ), .start (start_data ), .dout (din ), .dout_clk_p ( ), .dout_en (din_clk_p ) ); // turbo 编码 // 1/3Turbo Encode Turbo_Encode_1_3( .clk (clk ), .rst (rst ), .din_dout (din_dout ), .before_sc_dat_en (before_sc_dat_en), .before_sc_dat_p (before_sc_dat_p), .dat_choose (dat_choose ), .src_din_p (src_din_p ), .all_dat_clk_p (all_dat_clk_p ) ); Scrambler #( .FRAME_LENGTH(ALL_DAT-1) ) // 1792*3+12-1 = 5387 Scrambler ( .clk(clk ),//系统时钟 .rst(rst ),//系统复位,高有效 .din(dat_choose ),//待加扰数据 .din_p(src_din_p ),//待加扰数据帧头,脉冲型 .din_en(all_dat_clk_p ),//帧同步后的使能信号,便于写入FIFO .dout(scr_dat ),//加扰后数据 .dout_en(scr_en ),//加扰后数据使能信号 .dout_p( ) //加扰后数据帧头指示信号,脉冲型 ); // tb:判断是否完成调制 soqpsk_mod( .clk (clk ), .rst (rst ), .scr_dat (scr_dat ), .scr_en (scr_en ), .is_End_SOQPSK_Mod(is_End_SOQPSK_Mod), .pulses_dout_i (pulses_dout_i), .pulses_dout_q (pulses_dout_q), .pulses_dout_clk_p(), .ram_cnts_write (ram_cnts_write) ); // 组帧 blk_mem_24_32768 blk_mem_24_32768 ( .clka(clk), // input wire clka .ena(1'b1), // input wire ena .wea(1'b1), // input wire [0 : 0] wea .addra(ram_cnts_write ), // input wire [14 : 0] addra_write .dina({pulses_dout_i,pulses_dout_q}), // input wire [23 : 0] dina .clkb(clk), // input wire clkb .enb(1'b1), // input wire enb .addrb(addrb_read), // input wire [14 : 0] addrb_read .doutb({lut_dout_i,lut_dout_q}) // output wire [23 : 0] doutb ); soqpsk_demod_gamma( .clk (clk ), .rst (rst ), .start (is_End_SOQPSK_Mod ), .addrb_read (addrb_read ), .lut_dout_i (lut_dout_i ), .lut_dout_q (lut_dout_q ), .is_End_SOQPSK_gamma (is_End_SOQPSK_gamma), .gammaI_0_ram (gammaI_0_ram ), .gammaI_1_ram (gammaI_1_ram ), .gammaI_2_ram (gammaI_2_ram ), .gammaI_3_ram (gammaI_3_ram ), .gammaQ_0_ram (gammaQ_0_ram ), .gammaQ_1_ram (gammaQ_1_ram ), .gammaQ_2_ram (gammaQ_2_ram ), .gammaQ_3_ram (gammaQ_3_ram ), // Q28.22 .read_gamma_addrb (read_gamma_addrb ) ); // 解调第四步: 前向度量 soqpsk_demod_alpha ( .clk (clk ), .rst (rst ), .start (is_End_SOQPSK_gamma ), .gammaI_0_ram (gammaI_0_ram ), .gammaI_1_ram (gammaI_1_ram ), .gammaI_2_ram (gammaI_2_ram ), .gammaI_3_ram (gammaI_3_ram ), .gammaQ_0_ram (gammaQ_0_ram ), .gammaQ_1_ram (gammaQ_1_ram ), .gammaQ_2_ram (gammaQ_2_ram ), .gammaQ_3_ram (gammaQ_3_ram ), .read_gamma_addrb (read_gamma_addrb_forward), .is_End_SOQPSK_alpha (is_End_SOQPSK_alpha ), .alphaI_0_ram (alphaI_0_ram ), .alphaI_1_ram (alphaI_1_ram ), .alphaQ_0_ram (alphaQ_0_ram ), .alphaQ_1_ram (alphaQ_1_ram ), .read_alpha_addrb (read_gamma_addrb_IIr ) ); // 解调第五步: 后向度量 soqpsk_demod_beta( .clk (clk ), .rst (rst ), .start (is_End_SOQPSK_alpha ), .gammaI_0_ram (gammaI_0_ram ), .gammaI_1_ram (gammaI_1_ram ), .gammaI_2_ram (gammaI_2_ram ), .gammaI_3_ram (gammaI_3_ram ), .gammaQ_0_ram (gammaQ_0_ram ), .gammaQ_1_ram (gammaQ_1_ram ), .gammaQ_2_ram (gammaQ_2_ram ), .gammaQ_3_ram (gammaQ_3_ram ), .read_gamma_addrb (read_gamma_addrb_backward), .is_End_SOQPSK_beta (is_End_SOQPSK_beta ), .betaI_0_ram (betaI_0_ram), .betaI_1_ram (betaI_1_ram), .betaQ_0_ram (betaQ_0_ram), .betaQ_1_ram (betaQ_1_ram), .read_beta_addrb (read_gamma_addrb_IIr + 1) ); // 解调第六步: 计算软信息 soqpsk_demod_llr( .clk (clk ), .rst (rst ), .start (is_End_SOQPSK_beta ), .gammaI_0_ram (gammaI_0_ram), .gammaI_1_ram (gammaI_1_ram), .gammaI_2_ram (gammaI_2_ram), .gammaI_3_ram (gammaI_3_ram), .gammaQ_0_ram (gammaQ_0_ram), .gammaQ_1_ram (gammaQ_1_ram), .gammaQ_2_ram (gammaQ_2_ram), .gammaQ_3_ram (gammaQ_3_ram), .read_gamma_addrb (read_gamma_addrb_IIr), .betaI_0_ram (betaI_0_ram), .betaI_1_ram (betaI_1_ram), .betaQ_0_ram (betaQ_0_ram), .betaQ_1_ram (betaQ_1_ram), .read_beta_addrb (), .alphaI_0_ram (alphaI_0_ram), .alphaI_1_ram (alphaI_1_ram), .alphaQ_0_ram (alphaQ_0_ram), .alphaQ_1_ram (alphaQ_1_ram), .read_alpha_addrb (), .is_End_SOQPSK_llr (is_End_SOQPSK_llr), .llrI (llrI ), .llrQ (llrQ ), .llr_clk_p (llr_clk_p ) ); // 转化为串行的数据流 soqpsk_demod_2p1s # ( .ALL_DAT (ALL_DAT ), .ALL_DAT_PADDING(ALL_DAT_PADDING) ) soqpsk_demod_2p1s( .clk (clk), .rst (rst), .bs_cut_i (llrI[26:19]), .bs_cut_q (llrQ[26:19]), .dout_cut_en (llr_clk_p), .bs_din (bs_din), .bs_din_p (bs_din_p), .bs_din_en (bs_din_en) ); /*----------------------------------------------------------------------- 下面是进入解扰的模块 -----------------------------------------------------------------------*/ Descrambler # ( .ALL_DAT(ALL_DAT) ) Descrambler( .clk (clk ), .rst (rst ), .bs_din (bs_din ), .bs_din_p (bs_din_p ), .bs_din_en (bs_din_en ), .soft_din (soft_din), .soft_din_clk_p (soft_din_clk_p) ); //准备送入Turbo 译码器 Turbo_Decode_1_3 Turbo_Decode_1_3( .clk(clk), .rst(rst), .soft_din(soft_din), .soft_din_clk_p(soft_din_clk_p), .dout(turbo_dout), .dout_clk_p(turbo_dout_clk_p) ); // 解调第八步: turbo译码 // tb: 误码率统计 fifo_1_8 FIFOS ( .clk(clk ), // input wire clk .srst(rst ), // input wire srst .din(turbo_dout ), // input wire [0 : 0] din .wr_en(turbo_dout_clk_p), // input wire wr_en .rd_en( rd_en11 ), // input wire rd_en .dout( fifo_dout11 ), // output wire [7 : 0] dout .full( ), // output wire full .empty( ), // output wire empty .rd_data_count(rd_data_count ) // output wire [9 : 0] rd_data_count );
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。