Turbo编译码Matlab仿真解读 -- WuYufei_matlab
吴雨霏博士版本的Turbo编译码仿真较为经典,以下就原码进行解读。
一、仿真代码架构
“turbo_sys_demo.m”是程序的主体框架,Turbo编译码均在此程序展开。程序开始需要用户需要如下几个参数:
1)译码算法:选择使用0:Log-MAP,1:SOVA
这是让用户选择使用何种Turbo译码算法。若Tubo为多次迭代译码,则选用Log-MAP算法;否则选SOVA。默认选择0;
2)选择帧长:帧长=信息长度+卷尾;
根据自己需要选择帧长,程序默认选择400(396+4);
3)输入Turbo码生成多项式g:默认为[111 101], 即 [7 5];
有两点需要注意:
1) 生成多项式为八进制表示;
2)若反馈多项式为7,即RSC分量码表示,则生成多项式表示形式为:[7 5;7]
4)选择Turbo码是否打孔:0 – punctured;1—unpunctured
LTE Turbo未打孔码默认码率为1/3,打孔后默认码率为1/2;
- 选择每帧迭代次数: Turbo译码一般迭代5 ~ 7次,程序默认选择5次;
- 选择终止程序的帧错误次数:程序默认选择15帧;
- 选择系统信噪比Eb/N0:程序默认为2.0;
图1为输入显示图:
图1 代码参数输入仿真运行图
二、编码程序流程梳理
参数说明:
errs – 比特错误计数
nferr – 帧错误计数
nfame – 帧计数
1)产生数据源
源码中使用sort函数产生Turbo编码所使用的交织器,仿真时仍倾向采用LTE自带的交织器,代价是限定码长(因为每一个交织器都与特定的码长对应);
2)Turbo编码
output = function encoderm( x, g, alpha, puncture )
- 交织器映射采用 alpha数组;
- puncture = 1,表示不需要Turbo码打孔,默认码率为1/3;
- puncture = 0,表示对Turbo码打孔,输出码率为1/2;
2.1 Turbo编码流程梳理
先给出编码部分总体流程图
(不管是自己设计程序还是读别人程序,强烈建议梳理流程图这一步骤必不可少。因为认识事物的客观规律也是从宏观到微观,从整体到局部。如果一开始就陷入细节,对完成目标就很困难了):
图2 编码整理流程图
根据生成多项式矩阵g,得到以下参数:
- 寄存器阶数 m = 矩阵g 列数 – 1;
- 总编码信息长度 L_total = 信息长度 + m(加入尾比特处理,迫使寄存器状态最终归0)
程序调用 rsc_encode(g,input,1)函数:
1)首先,生成系统信息比特 d_k:
% generate the codeword
for i = 1:L_totalif terminated<0 | (terminated>0 & i<=L_info)d_k = x(1,i);elseif terminated>0 & i>L_info% terminate the trellisd_k = rem( g(1,2:K)*state', 2 );enda_k = rem( g(1,:)*[d_k state]', 2 );[output_bits, state] = encode_bit(g, a_k, state);
若归零标志 terminated >0(代码里terminated = 1)并且编码序号 i < 信息长度 L_info)
d_k = x(1,i);
否则,d_k = rem( g(1,2:K) * state', 2 );
2)a_k = rem( g(1,:) * [d_k state]', 2 );
3)调用函数 encode_bit,输出output为总信息长度的2倍,即800bit:
% the rate is 1/n
% k is the constraint length
% m is the amount of memory
[n,k] = size(g);
m = k-1;% determine the next output bit
for i=1:noutput(i) = g(i,1)*input;for j = 2:koutput(i) = xor(output(i),g(i,j)*state(j-1));end
endstate = [input, state(1:m-1)];
该函数详见流程图解析。如果对代码还不是很理解,那就说明对卷积码编码原理理解还不到位。这里推荐大家再回顾一下卷积码编码原理:
卷积码编码原理https://blog.csdn.net/snowman898/article/details/124148068
output1 = rsc_encode(g,input,1);
% make a matrix with first row corresponing to info sequence
% second row corresponsing to RSC #1's check bits.
% third row corresponsing to RSC #2's check bits.
y(1,:) = output1(1:2:2*L_total);
y(2,:) = output1(2:2:2*L_total);
y 的第一行为系统比特,即信息比特;
y的第二行为校验比特1;
同样的方法, 在encoder.m文件中再次调用rsc_encode(g,input,-1)函数。和上次不同的是,归零标志 terminated = -1,即校验码2并不归零。
这时,交织器开始起作用,输入rsc_encode里面也不再是原始数据,而是经过交织器交织后、长度变为L_total的数据:
% interleave input to second encoder
for i = 1:L_total
input1(1,i) = y(1,alpha(i));
endoutput2 = rsc_encode(g, input1(1,1:L_total), -1 );
% third row corresponsing to RSC #2's check bits.
y(3,:) = output2(2:2:2*L_total);
2.2 Turbo码打孔 (速率匹配)
(1)不打孔,即 puncture = 1
rate = 1 / ( 2 + puncture ) ,则不打孔时默认速率为1/3;
最终输出 en_output 按照 [ sys_data ; parity_data1; parity_data2 ] 列模式方式输出,即 en_ouput 共有3行,有 L_total 列;
(2)打孔,puncture = 0
按照上述公式计算,打孔后 Turbo码率提高至 1/2;
for i=1:L_total
en_output(1,n*(i-1)+1) = y(1,i);
if rem(i,2)
% odd check bits from RSC1
en_output(1,n*i) = y(2,i);
else
% even check bits from RSC2
en_output(1,n*i) = y(3,i);
end
end
即:输出的奇数项为 系统信息, 偶数项 为 RSC1 校验位 和 RSC2 校验位。
最终,对en_output进行极性变换输出:
% antipodal modulation: +1/-1
en_output = 2 * en_output - ones(size(en_output));
三、 Turbo译码流程梳理
对下列参数进行初始化:
nferr , errs = 0,随后根据信噪比产生信号和噪声的叠加 recv signal:
r = en_output+sigma*randn(1,L_total*(2+puncture)); % received bits
接下来,我们仍给出译码流程图:
图3 译码整理流程图
3.1 logmapo 函数介绍
L_all = logmapo(rec_s,g,L_a,ind_dec)
输入参数:
1)rec_s:scaled received bits 缩放接收比特
rec_s = 0.5 * L_c * yk = ( 2 * a * rate * Eb/N0 ) * yk
2)g:生产码多项式
3)L_a:先验 L 值
4)ind_dec: index of decoder. Either 1 or 2. Encoder 1 is assumed to be terminated, while encoder 2 is open.
该函数是turbo译码的核心,因此,先给出函数流程图:
图4 logmapo流程图
3.2 Trellis函数介绍
trellis函数主要是根据码生成多项式,推出以下参数:
- 后向输出 next_output
- 后向状态 next_state
- 前向输出 last_output
- 前向状态 last_state
1)首先,确定各个初始参数:
% g = [ 1 1 1; 1 0 1];
[n,K] = size(g); % n = 2, K = 3
m = K - 1; % m = 2
max_state = 2^m; % max_state = 4for state=1:max_state
state_vector = bin_state( state-1, m ); % 将整数向量state转换成 m-bit 向量形式
end
state_vector 四个状态为:[ 0, 0 ] , [ 0, 1 ] , [ 1, 0 ] , [ 1, 1 ]
2)当输入为0时:d_k = 0
a_k = rem( g(1,:)*[0 state_vector]', 2 );
[out_0, state_0] = encode_bit(g, a_k, state_vector);
可以认为根据 g, a_k, state_vector 完成一次 Turbo编码,得到 next_out, next_state;
encode_bit函数在编码流程中已详细梳理,此次不再赘述。最终,我们给出trellis网格图:
表1 LTE Turbo Trellis
当前状态 state_vector |
输入d_k=0 |
输入d_k=1 |
|
next_vector (bit形式) |
[ 0, 0 ] |
[ 0, 0 ] |
[ 1, 0 ] |
[ 0, 1 ] |
[ 1, 0 ] |
[ 0, 0 ] |
|
[ 1, 0 ] |
[ 1, 1 ] |
[ 0, 1 ] |
|
[ 1, 1 ] |
[ 0, 1 ] |
[ 1, 1 ] |
|
next_out (bit形式) |
[ 0, 0 ] |
[ 0, 0 ] |
[ 1, 1 ] |
[ 0, 1 ] |
[ 0, 0 ] |
[ 1, 1 ] |
|
[ 1, 0 ] |
[ 0, 1 ] |
[ 1, 0 ] |
|
[ 1, 1 ] |
[ 0, 1 ] |
[ 1, 0 ] |
|
next_out (双极性形式) |
[ 0, 0 ] |
[ -1 -1 1 1 ] |
|
[ 0, 1 ] |
[ -1 -1 1 1 ] |
||
[ 1, 0 ] |
[ -1 1 1 -1 ] |
||
[ 1, 1 ] |
[ -1 1 1 -1 ] |
||
next_state (整数形式) |
[ 0, 0 ] |
[ 1 3] |
|
[ 0, 1 ] |
[ 3 1] |
||
[ 1, 0 ] |
[ 4 2] |
||
[ 1, 1 ] |
[ 2 4] |
同时,根据该表,由当前 [d_k, next_out, next_state] 推导出前一时刻的 [ last_out, last_state]:
% find out which two previous states can come to present state
last_state = zeros(max_state,2);
for bit=0:1
for state=1:max_state
last_state(next_state(state,bit+1), bit+1)=state;
last_out(next_state(state, bit+1), bit*2+1:bit*2+2) ...
= next_out(state, bit*2+1:bit*2+2);
end
end
表2 LTE Turbo Trellis
当前状态 state_vector |
输入d_k=0 |
输入d_k=1 |
|
last_vector (bit形式) |
[ 0, 0 ] |
[ 0, 0 ] |
[ 0, 1 ] |
[ 0, 1 ] |
[ 1, 1 ] |
[ 1, 0 ] |
|
[ 1, 0 ] |
[ 0, 1 ] |
[ 0, 0 ] |
|
[ 1, 1 ] |
[ 1, 0 ] |
[ 1, 1 ] |
|
last_out (bit形式) |
[ 0, 0 ] |
[ 0, 0 ] |
[ 1, 1 ] |
[ 0, 1 ] |
[ 0, 1 ] |
[ 1, 0 ] |
|
[ 1, 0 ] |
[ 0, 0 ] |
[ 1, 1 ] |
|
[ 1, 1 ] |
[ 0, 1 ] |
[ 1, 0 ] |
|
last_out (双极性形式) |
[ 0, 0 ] |
[ -1 -1 1 1 ] |
|
[ 0, 1 ] |
[ -1 1 1 -1 ] |
||
[ 1, 0 ] |
[ -1 -1 1 1 ] |
||
[ 1, 1 ] |
[ -1 1 1 -1 ] |
||
last_state (整数形式) |
[ 0, 0 ] |
[ 1 2] |
|
[ 0, 1 ] |
[ 4 3] |
||
[ 1, 0 ] |
[ 2 1] |
||
[ 1, 1 ] |
[ 3 4] |
p.s. 这里提供另一角度去计算 last_out:
根据当前状态和输入 [ state,d_k ] 查表 last_state, 再由 [last_stae d_k] 查找 next_output;
3.3 前向度量计算
前向度量 α 计算由双循环组成:
内循环:以所有状态为循环:state = 1 : 2^m
外循环:以所有信息数量为循环:k = 2 : L_total + 1
先计算输入 d_k = 0时:
% Log_MAP算法计算
gamma( last_state(state2,1) ) = ( -rec_s(2*k-3) + rec_s(2*k-2) * last_out(state2,2) )
- log(1+exp(L_a(k-1)));
再计算输入 d_k = 1时:
gamma(last_state(state2,2)) = (rec_s(2*k-3)+rec_s(2*k-2)*last_out(state2,4))
+ L_a(k-1) - log(1+exp(L_a(k-1)));
log_map算法目前用的不多,由于计算量较大,主流均采用 max-log-map计算,这里只给出计算公式,详细算法不再推导;
p.s. 未完,见后续(2)
一定要看哈,文末有彩蛋(* ̄︶ ̄)
吴雨霏博士论文集及MATLAB原版程序https://download.csdn.net/download/qq_36756847/12036978?utm_medium=distribute.pc_relevant_download.none-task-download-2~default~BlogCommendFromBaidu~Rate-15-12036978-download-4229931.dl_default&depth_1-utm_source=distribute.pc_relevant_download.none-task-download-2~default~BlogCommendFromBaidu~Rate-15-12036978-download-4229931.dl_default&dest=https%3A%2F%2Fdownload.csdn.net%2Fdownload%2Fqq_36756847%2F12036978&spm=1003.2020.3001.6616.17
Turbo编译码Matlab仿真解读 -- WuYufei_matlab相关推荐
- 卷积码译码matlab程序,卷积码的编译码MATLAB程序
<卷积码的编译码MATLAB程序>由会员分享,可在线阅读,更多相关<卷积码的编译码MATLAB程序(5页珍藏版)>请在人人文库网上搜索. 1.survivor state是一个 ...
- turbo编译码误码率性能matlab仿真
目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 Turbo码是一种极为复杂的信道编码技术,译码算法往往由于硬件实现的复杂度太高或者译码时延太 ...
- 基于matlab的卷积码实验报告,基于MATLAB的卷积码编译码设计仿真.doc
摘要:在数字信号的传输过程中,会受到信道特性不理想和噪声的影响,通常采用差错控制编码来提高系统的可靠性.卷积码是P.Elias等人提出的,这一编码技术至今广泛使用.目前,卷积码已普遍在无线通信标准使用 ...
- 基于matlab的LDPC编译码误码率仿真,调制方式为64QAM
目录 1.算法概述 2.仿真效果 3.MATLAB仿真源码 1.算法概述 "LDPC编译码 低密度校验码(LDPC码)是一种前向纠错码,LDPC码最早在20世纪60年代由Gallager在他 ...
- 基于MATLAB的LDPC编译码误码率仿真,仿真调制为64QAM,对比不同译码迭代次数
目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 LDPC码是麻省理工学院Robert Gallager于1963年在博士论文中提出的一种具有稀疏校验 ...
- 基于hamming编译码matlab误码率仿真
目录 1.算法仿真效果 2.MATLAB源码 3.算法概述 4.部分参考文献 1.算法仿真效果 matlab2022a仿真结果如下: 2.MATLAB源码 %********************* ...
- 基于polar码和SCMA的多用户检测的联合检测译码matlab仿真,polar采用SCAN软译码,SCMA用MPA算法
目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 构造的核心是通过信道极化(channel polarization)处理,在编码侧采用方法使各个子信 ...
- (2,1,2)卷积码BCJR译码matlab仿真
文章目录 前言 一.卷积码 1.1 卷积码状态转移图 1.2 分支度量 1.3 前向状态度量 1.4 后向状态度量 1.5 比特似然计算 二.仿真代码 1.设置仿真参数 2.仿真所需系统对象 3.定义 ...
- 【MATLAB教程案例39】语音信号的PCM编解码matlab仿真学习
FPGA教程目录 MATLAB教程目录 ----------------------------------------------------------------------- 目录 1.软件版 ...
- m基于EAN13字符编码规则的一维条形码条码宽度计算和数字译码matlab仿真
目录 1.算法仿真效果 2.MATLAB核心程序 3.算法涉及理论知识概要 3.1一维条码概述 3.2EAN-13码符号的特征 3.3EAN-13码符号的特征 4.完整MATLAB 1.算法仿真效果 ...
最新文章
- Java 理论与实践: 修复 Java 内存模型,第 2 部分 (VOLATILE, FINA...
- Java 多线程编程之 interruptException
- 神经网络 | 网络优化-线性神经网络-delta学习规则-梯度下降法(单层感知器-异或问题Python源代码)
- Matplotlib 中文用户指南 4.6 编写数学表达式
- Django Rest Framework 部分源码剖析
- java 可见性_Java并发编程-volatile可见性详解
- Java基础知识点复习知识点(一)变量,流程控制,数组
- C# 自定义网格 dataGridView 三角箭头移动 获取当前行列序号 滚动条显示改变 滚动条定位索引
- Xenko C#开源游戏引擎
- 互联网行业哪个职业比较有前途?
- 只要你足够好——写给理想受挫的人们
- 【蓝桥系列】——十三届蓝桥杯PythonB组第五题E题蜂巢(AC代码)
- 规则引擎 Drools--决策表(Decision Table)使用简介
- SCI论文编辑教你如何准备SCI论文和写作 [转]
- joycon 连不上_switch手柄连接不上ns 连接不上蓝牙手柄硬件等问题解决方案
- 电脑端使用Fiddler对手机APP进行抓包分析示范
- 道路视频摄像机智能分析功能测试规范
- android动态申请权限第三方库,Android 关于动态申请权限
- Mac安装Tableau Desktop 2019 for Mac中文版安装教程
- python中烦人的锟斤拷(\xef\xbf\xbd)
热门文章
- 三星v版系统更新无法连接到服务器,美国V版三星S9/S9+迎来安卓9更新 展示新One UI用户界面...
- Ubuntu操作系统
- 明月浩空html播放器,明月浩空音乐-绚丽彩虹|HTML5网站音乐播放器源码带后台-仅研究学习...
- 共轭梯度法python实现
- 统计学贾俊平第六版pdf下载|贾俊平统计学第六版pdf下载电子书
- 方舟原始恐惧mod生物代码_方舟:生存进化新手攻略
- 网通修改了偶的ADSL登录密码
- 【工具类】使用ffmpeg下载视频
- Unity 官方教程2
- bodymovin输出Json动画为黑白的解决方案