南京邮电大学通信原理实验OFDM施工卷积码编译码部分记录

一:卷积码编译码原理

1.卷积码编码原理

(1)实验指导书原文部分:

信道编码采用卷积码进行编码。以(n,k,m)来描述卷积码,其中k为每次输入到卷积编码器的bit数,n为每个k元组码字对应的卷积码输出n元组码字,码率为k/n。编码器在任何一段规定时间内产生的n个码元,不仅和当前的k比特信息段有关,而且还同前面的m-1个信息段有关。一个码组中的监督码元监督着m个信息段,nm称为编码约束长度。

如图3.3.2所示是一个卷积码的编码器(2,1,6)。编码器的输入信息位,一方面可以直接通过1级移位寄存器直接输出,另一方面还可以暂存于6级移位寄存器中。每当进入编码器一个信息位,就立即计算出一监督位,并且此监督位紧跟此信息位之后发送出去。这种卷积码的参量为:k=1,n=2,m=6,约束长度等于nm,即12,码率为1/2。编码器输出与输入的关系如图3.4.3所示。

图3.3.2卷积编码器

图3.3.3 编码器的输入输出关系

OFDM系统实验中,卷积码使用码率为1/2的卷积码或1/3的卷积码,编码器输入输出对应的生成多项式为9位,可表示为:

1/2卷积码:[561,753]

1/3卷积码:[557, 663, 711]

其中1/2卷积码的编码器框图如图3.3.4所示。

图3.3.4 1/2卷积码, [561,753]

第1个多项式中的系数为101 110 001,从右边起每3比特进行分段,转化为8进制为[561]

第2个多项式中的系数为111 101 011,从右边起每3比特进行分段,转化为8进制为[753]

编码时需要注意添加尾比特,在输入数据后面添加8个0,再进行卷积编码。

(2)我们如何描述一个编(译)码器

综合上文以及通信原理课程我们知道有六种的方法描述一个(n,k,m)的编(译)码器

1.编码器框图

2.生成多项式

3.(matlab常用)八进制矩阵组(对应二进制穿孔向量puncture vector)

4.转移状态图

5.转移网格图

6.转移码树图

后三种实验内不做要求所以略过。

如无意外一般我们看到的编(译)码器的形如【561】,【753】的都是八进制矩阵上文讲了如何把八进制矩阵组化成生成多项式和框图。每个输出位比特对应一个多项式和八进制矩阵,共n个。

我们知道k/n对应的是码率,k代表每组进入移位寄存器的码元数,n代表每组输出的码元数。但是指导书中的m与其他常用的指代有所区别。一般来讲指导书中的m(常用l)就是所谓的约束长度。n*m或是n*l代表的是内存大小,即编码器可能的状态数。在此强调以免造成混乱。

我们使用迭代算法如Viterbi(维特比)算法译码时所用的回溯深度应满足以下关系:回溯深度≥约束长度

(3)回溯深度和约束长度

下面我们讲如何计算回溯深度和约束长度

(不做要求仅作了解)

来源:信道编码:MATLAB使用卷积编译码函数_vitdec函数-CSDN博客

gpt翻译:一般估计一个典型的回溯深度值大约是(约束长度 - 1)/ (1 - 码率) 的两到三倍。编码器的约束长度由公式 (log2(trellis.numStates) + 1) 确定。码率等于 (K/N) × (puncturePattern 的长度 / puncturePattern 的总和)。其中,K 是输入符号的数量,N 是输出符号的数量,puncturePattern 是穿孔模式向量。例如,应用这一一般估计,可以得到以下近似的回溯深度值。 一个码率为 1/2 的码具有回溯深度为 5*(约束长度 - 1)。 一个码率为 2/3 的码具有回溯深度为 7.5*(约束长度 - 1)。 一个码率为 3/4 的码具有回溯深度为 10*(约束长度 - 1)。 一个码率为 5/6 的码具有回溯深度为 15*(约束长度 - 1)。

上例中:取回溯深度=2.5*(约束长度-1)/(1-码率)(2~3之间皆可,此处取2.5)

*给出的约束长度的计算为约束长度=(log2(转移状态总数)+1)

码率=(k/n)*(穿孔向量长度/穿孔向量和)

穿孔向量即八进制转出的二进制向量组

【561,753】对应的【101110001,111101011】

穿孔向量的长度=编码器约束长度,穿孔向量和=穿孔向量中为1的量的数量

另:原文中【171】转二进制应为【1111001】而非【1111111】

2.主要函数使用

信道编码:MATLAB使用卷积编译码函数_vitdec函数-CSDN博客

还是这篇文章,我们要用的就是这三个函数,下面是省流版

(1)poly2trellis

直接定义一个卷积码编(译)码器的结构,服务于接下来要用的函数

trellis = poly2trellis(ConstraintLength,CodeGenerator)

ConstraintLength即约束长度,CodeGenerator要求我们输入设定的八进制穿孔向量矩阵

OFDM实验中要求的是1/2码率的[561,753]和1/3的[557, 663, 711]

(2)convenc

codedout = convenc(msg,trellis)
codedout = convenc(msg,trellis,puncpat)

msg即输入的待编码码元

trellis就是我们上面定义的编码器

(3)vitdec(译码部分)

decodedout = vitdec(codedin,trellis,tbdepth,opmode,dectype)
decodedout = vitdec(codedin,trellis,tbdepth,opmode,'soft',nsdec)
decodedout = vitdec(codedin,trellis,tbdepth,opmode,dectype,puncpat)

codein编码部分生成的卷积码

trellis略

由于实验要求添加8个尾比特0,

故:tbdepth回溯深度取8

opmode选用cont即可

dectype选用hard即可。
关于opmode和dectype其他参数下异同见引用文章

信道编码:MATLAB使用卷积编译码函数_vitdec函数-CSDN博客

下面我们试验下尾比特数对编译码的影响

我们实验发现,基于链接文档中的代码当尾比特达到30时,主体码组1000比特时仍无错误

n = 2;
k = 1;
rate = k/n; % rate为 1/2
L = 7;
tblen = 5*(L-1); % 回溯深度
trellis = poly2trellis(L,[171 133]);

code_data = convenc(msg_source,trellis);

d = vitdec(code_data,trellis,tblen,'cont','hard');

figure(1);
stairs(msg_source(1:end-30),':*r');
hold on;
stairs(d(31:end),':+b');
ylim([-0.1,1.1]);
grid on;
legend('原始信息','恢复信息');

此时得到的msg_source有30个尾比特,d有30个首比特

msg_source的30个尾比特是我们添加的,以保证码段大于回溯深度30以免引起错误.若取更多的尾比特数,则可以改变回溯深度使之相等或者直接用下文的方法删除等量的首比特0

d的30个首比特0等于回溯深度

假设你有一个向量或矩阵 A,你想去除从第 i 项到第 j 项之间的元素。你可以这样做:

% 假设 A 是你的向量或矩阵
i = 3; % 开始索引
j = 5; % 结束索引

% 创建一个逻辑索引,将第 i 到第 j 项之间的元素标记为 0,其他元素标记为 1
index = true(size(A)); % 创建一个与 A 大小相同的逻辑索引
index(i:j) = false; % 将第 i 到第 j 项之间的元素标记为 false

% 使用逻辑索引去除元素
A = A(index);

这样就会将矩阵或向量 A 中从第 i 项到第 j 项之间的元素去除掉,并返回去除后的结果。

我们可以先去除msg_source和d的多余位,然后用isequal函数验证

index=true(size(d));
index(1:30)=false;
d=d(index);
index=true(size(msg_source));
index(1001:1030)=false;
msg_source=msg_source(index);

然后再命令行使用

isequal(d,msg_source);

结果如下

译码与原码相同,验证成功

3.卷积码编码器函数OFDM_TXTrchCoder

function [out_data] = OFDM_TxTrchCoder(input_data, coder_type)
input_num=length(input_data);
%% 功能实现
switch coder_type
    case 0  %% 不编码
        out_data = zeros(1, input_num);     %#ok
        out_data = input_data;
case 1  %% 1/2卷积码
        CodeGenerator = [561, 753];
%第一步添加尾比特(在输入数据后添加8个0)
    %第二步卷积编码
case 2  %% 1/3卷积码
CodeGenerator = [557, 663, 711];
%第一步添加尾比特(在输入数据后添加8个0)
    %第二步卷积编码
    otherwise
       fprintf('error \n');
end 

我们将给定的程序补齐

4.卷积码译码器函数OFDM_RxTrchDecoder

function [out_data] = OFDM_RxTrchDecoder(input_data, coder_type)
input_num=length(input_data);
%% 功能实现
switch coder_type
    case 0 %% 不编码
        out_data = zeros(1, input_num); %#ok
        out_data = input_data;
case 1  %% 1/2卷积码
%第一步卷积译码
    %第二步去掉尾比特
case 2  %% 1/3卷积码
%第一步卷积译码
    %第二步去掉尾比特
    otherwise
        fprintf('error\n');
end 

将它补齐

function [out_data] = OFDM_TxTrchCoder(input_data, coder_type)
input_num=length(input_data);
%% 功能实现
switch coder_type
    case 0  %% 不编码
        out_data = zeros(1, input_num);     %#ok
        out_data = input_data;
case 1  %% 1/2卷积码
        CodeGenerator = [561,753];
        tail_bits=zeros(1,8);%插入尾比特
        input_data=[input_data,tail_bits];
        trellis=poly2trellis(9,CodeGenerator);%定义寄存器
        out_data=convenc(input_data,trellis);%生成卷积码
case 2  %% 1/3卷积码
CodeGenerator = [557,663,711];
        tail_bits=zeros(1,8);%插入尾比特
        input_data=[input_data,tail_bits];
        trellis=poly2trellis(9,CodeGenerator);%定义寄存器
        out_data=convenc(input_data,trellis);%生成卷积码
    otherwise
       fprintf('error \n');
end 
function [out_data] = OFDM_RxTrchDecoder(input_data, coder_type)
input_num=length(input_data);
%% 功能实现
switch coder_type
    case 0 %% 不编码
      out_data = zeros(1, input_num); %#ok
        out_data = input_data;
case 1  
        trellis = poly2trellis(9, [561, 753]);%定义解码器
            decoded_data = vitdec(input_data, trellis, 8, 'cont', 'hard');%维特比译码
            out_data = decoded_data(9:end); % 去除添加的8个尾比特
case 2 
   trellis = poly2trellis(9, [557,663,711]);%定义解码器
            decoded_data = vitdec(input_data, trellis, 8, 'cont', 'hard');%维特比译码
            out_data = decoded_data(9:end); %去除添加的8个尾比特
    otherwise
        fprintf('error\n');
end 

5实验验证

clear all
msg_source = [randi([0 1],1,1000),zeros([1,8])]; 
a=OFDM_TxTrchCoder(msg_source,1);
b=OFDM_RxTrchDecoder(a,1);

clear all
msg_source = [randi([0 1],1,1000),zeros([1,8])]; 
a=OFDM_TxTrchCoder(msg_source,2);
b=OFDM_RxTrchDecoder(a,2);

代码部分验证成功

6.拓展:(n,k,m)情形下的设计

MATLAB 仿真实现任意(n,k,m)卷积码译码_维特比译码matlab-CSDN博客

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值