▲基于QPP交织器和咬尾编码的Turbo编译码MATLAB误码率仿真
目录
✅1.引言
Turbo码由并行级联卷积码(PCCC) 构成,核心是两个递归系统卷积码(RSC) 编码器通过一个交织器并联,并在译码端通过两个软输入软输出(SISO)译码器进行迭代信息交换,逼近香农极限。传统卷积码用归零(Trellis Termination) 让编码器回到零状态,但需额外发送m个尾比特,造成码率损失,短码尤为明显。咬尾码要求编码器的起始状态=结束状态,使网格首尾相连成"环",从而消除尾比特开销、保持码率,并避免边界比特保护不足的问题。
✅2.基于QPP交织器和咬尾编码的Turbo编译码原理
Turbo码由并行级联卷积码(PCCC) 构成,核心是两个递归系统卷积码(RSC) 编码器通过一个交织器并联,并在译码端通过两个软输入软输出(SISO)译码器进行迭代信息交换,逼近香农极限。
2.1 RSC编码的状态方程
本程序采用LTE标准的8状态RSC,生成多项式:

其中g0为反馈多项式(八进制13),g1为前馈多项式(八进制15)。
设寄存器状态sk=[m1,m2,m3]T,输入比特uk。由于是递归系统码,反馈输入为:

2.2 QPP交织器原理
二次置换多项式(Quadratic Permutation Polynomial, QPP) 是LTE采用的交织方案,其映射定义为:

对于K=1024,取f1=31, f2=64。QPP成为双射(无冲突排列)的充要条件是:f1与K互质,且f2的所有素因子均整除K。
其优点:
2.3 咬尾Tail-Biting机制
传统卷积码用归零(Trellis Termination) 让编码器回到零状态,但需额外发送m个尾比特,造成码率损失,短码尤为明显。咬尾码要求编码器的起始状态=结束状态,使网格首尾相连成"环",从而消除尾比特开销、保持码率,并避免边界比特保护不足的问题。
2.3.1 咬尾初始状态的求解
设循环初始状态为sc。在无外部输入贡献分离后,输入序列驱动的末状态可写为:

其中sf0是从零状态出发编码整个序列得到的末状态(即程序中第一步试编码结果)。咬尾条件要求sK=sc,代入得:
2.3.2 Max-Log-MAP译码原理
BPSK经AWGN信道后,接收符号r对应的对数似然比(LLR) 为:

网格中从状态s经输入u的分支转移度量(对数域):

其中La为来自另一译码器的先验(外)信息,p为该分支的校验比特。
标准BCJR的前向α、后向β递推涉及log∑exp运算。Max-Log-MAP用max近似:

2.3.3 咬尾网格的α/β初始化
普通Turbo码因首尾状态已知(零态),α0和βK可确定初始化。但咬尾码的循环初始状态在译码端未知,因此本程序采用环绕(wrap-around)初始化:
初始时各状态等概(对数域置 0);
沿网格递推一遍后,将末端值αK环绕赋给α0,再迭代一遍;
β同理。
这等效于在循环网格上逼近真实的稳态初值,迭代遍数越多越精确。
2.3.4 软判决LLR输出
对每个时刻k,综合所有分支计算后验LLR:

外信息(去除内信息后传递):

译码器1的外信息经交织送给译码器2作先验,译码器2的外信息解交织反馈给译码器1,如此迭代nIter次后硬判决:

✅3.MATLAB程序
本系统的matlab核心程序如下:
%全局参数
K = 1024; % 信息位长度
rate = '1/2';
EbN0dB = 0:1:10; % 仿真信噪比范围
maxFrm = 1000; % 每个SNR最大帧数
maxErr = 100; % 每个SNR目标错误帧
nIter = 1; % Turbo迭代次数
% 构建RSC网格 (8状态)
trellis = buildTrellis();
% QPP交织器索引 (0-based -> 1-based)
[f1,f2] = qppParams(K);
piIdx = mod(f1*(0:K-1) + f2*(0:K-1).^2, K) + 1;
% A^K 用于咬尾循环状态求解
AK = gf2_AK(K);
...........................................................
figure('Color','w');
semilogy(EbN0dB, BER, '-o','LineWidth',1.8,'MarkerFaceColor','b');
grid on;
xlabel('Eb/N0 (dB)');
ylabel('BER');
title(sprintf('咬尾Turbo码性能 (K=%d, 码率=%s, Max-Log-MAP)',K,rate));
if nIter == 1
save R1.mat EbN0dB BER
end
if nIter == 2
save R2.mat EbN0dB BER
end
if nIter == 3
save R3.mat EbN0dB BER
end
if nIter == 10
save R4.mat EbN0dB BER
end
figure
load R1.mat
semilogy (EbN0dB,BER,'-bs',...
'LineWidth',1,...
'MarkerSize',6,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.9,0.0,0.0]);
hold on
load R2.mat
semilogy (EbN0dB,BER,'-mo',...
'LineWidth',1,...
'MarkerSize',6,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.5,0.9,0.0]);
hold on
load R3.mat
semilogy (EbN0dB,BER,'-b^',...
'LineWidth',1,...
'MarkerSize',6,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.2,0.9,0.5]);
hold on
load R4.mat
semilogy (EbN0dB,BER,'-r>',...
'LineWidth',1,...
'MarkerSize',6,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[0.9,0.9,0.0]);
grid on;
xlabel('Eb/N0 (dB)');
ylabel('BER');
legend('nIter = 1','nIter = 2','nIter = 3','nIter = 10');
✅4.仿真结果分析
测试结果如下:

nIter=1(蓝色方块线,性能最差)
只做1次译码迭代,没有充分利用迭代译码的置信信息迭代优化,无论高低信噪比,误码率始终是四条曲线里最高的。
即使信噪比拉到 10dB,BER 仅降到约5×10^−3,远达不到可靠通信级别。
nIter=2(绿色圆形线,性能中等)
第二次迭代修正了第一次的译码软信息,误码性能明显优于迭代1次;
随着Eb/N0升高,BER 快速下降,10dB 时误码率来到10^−5量级。
nIter=3(蓝色三角线,性能大幅提升)
迭代3次后,译码性能提升幅度非常显著:在6dB之后,误码率下降速度远快于迭代1、2次的曲线;
在8dB时BER就已经达到10^−5,只用3次迭代就实现了很高的通信可靠性。
nIter=10(红色三角线,性能最优)
迭代次数提升到10次,是四条曲线里误码性能最好的一条:
在低信噪比(0~4dB)区间,迭代3次、10次两条曲线几乎重合,低噪条件下迭代次数增益很小;
当Eb/N0>4dB后进入瀑布区(误码陡降区),迭代次数越多,误码下降越快;
8dB时迭代10次BER已经低于10^−5,是四条曲线里最低的。

浙公网安备 33010602011771号