卷积码实验报告
实验五 信道编解码()
本章目标
掌握数字频带传输系统调制解调的仿真过程 掌握数字频带传输系统误码率仿真分析方法 5.1实验目的
1. 使用MATLAB 进行卷积码编/译码器的仿真。 2. 熟练掌握MATLAB 软件、语句。 3. 了解卷积码编/译码器的原理、知识。 5.2实验要求
1. 编写源程序、准备测试数据。
2. 在 MATLAB环境下完成程序的编辑、编译、运行,获得程序结果。如果结果有误,
应找出原因,并设法更正之。 5.3 实验原理
(一) 卷积码编码器 1. 连接表示
卷积码由3个整数n ,k ,N 描述。k /n 也表示编码效率(每编码比特所含的信
N 称为约束长度,息量);但n 与线性分组码中的含义不同,不再表示分组或码子长度;
表示在编码移位寄存器中k 元组的级数。卷积码不同于分组码的一个重要特征就是编码器的记忆性,即卷积码编码过程中产生的n 元组,不仅是当前输入k 元组的函数,而且还是前面N -1个输入k 元组的函数。实际情况下,n 和k 经常取较小的值,而通过N 的变化来控制编码的能力和复杂性。
下面以图1中的卷积码编码器为例介绍卷积码编码器。该图表示一个约束长度
K =3的(2,1)卷积译码器,模2加法器的数目为n =2,因此,编码效率k /n =1/2。
在每个输入比特时间上,1位信息比特移入寄存器最左端的一级,同时将寄存器中原有比特均右移一级,接着便交替采样两个模2加法器,得到的码元就是与该输入比特相对应的分支字。对每一个输入信号比特都重复上述采样过程。
图1卷积码编码器(编码效率1/2,K =3)
用于描述反馈移位寄存器实现循环码时所使用的生成多项式也可用户描述卷积码编码器的连接。应用n 个生成多项式描述编码的移位寄存器与模2加法器的连接方式,
n 个生成多项式分别对应n 个模2加法器,每个生成多项式不超过K -1阶。仍以图
1中的编码器为例,用生成多项式g 1(X ) 代表上方连接,g 2(X ) 代表下方连接,则有:
g 1(X ) =1+X +X 2g 2(X ) =1+X
2
多项式中的最低阶项对应于寄存器的输入级。输出序列根据如下方式求得:
U (X ) =m (X ) g 1(X ) 与m (X ) g 2(X ) 交织
其中m 表示输入的信息矢量。 2. 状态图
卷积编码器属于有限状态机的器件。“有限”表明状态机制只有有限个不同的状态。有限状态机的状态可以用设备的当前输入和最少的信息量,来预测设备的输出。状态提供了有关过去序列过程及一组将来可能输出序列的限制,下一状态总是受到前一状态的限制。将编码器在时刻t i 的状态定义为X i =m i -1, m i -2,..., m i -K +1。
01
图2状态转移图
如图2所示,方框内的状态表示寄存器最右端N -1级的内容,状态间的路径表示由此状态转移时的输出分支字。对应于两种可能的输入bit ,从每个状态出发只有两种转移。
3. 编码器网格图
a 00
b 10
c 01
d 11
输入比特0
输入比特1
虽然状态图完全地描述了编码器的特性,但由于没有表示时间过程,所以采用状态图跟踪编码器的状态转移很不方便。树状图在状态图的基础上增加了时间尺度。每个相继输入信息比特的编码过程可表述为从左向右经过树状图,每条数值代表一个输出分支字。树状图上增加的时间尺度是我们可以动态地描述输入序列的编码过程。但由于树状图的规模增长很快,因而只适于序列中分支子数目较小的情况。
我们采用移位寄存器的4种可能状态来标注树图的各个节点,
a =00, b =01, c =10, d =11。树结构的第一次分支在时刻t 1,产生一对节点,记为a , b ;
在后继的各个分支处,节点数翻倍。第二次分支在时刻t 2,生成4个节点,记为a , b , c , d ;第三次分支后共有8个节点。网格图利用了结构上的重复性,从而能够更加方便地描述编码器。
(二) 维特比译码算法
维特比译码算法由维特比在1967年提出。维特比算法的实质是最大似然译码,但它利用了编码网格图的特殊结构,从而降低了计算的复杂性。该算法包括计算网格图上在时刻t i 到达各个状态的路径和接受序列之间的相似度,或者说距离。维特比算法考虑的是,去除不可能成为最大似然选择对象的网格图上的路径,即如果有两条路径到达同一状态,则具有最佳量度的路径被选中,成为幸存路径。对所有状态都将进行这样的选路操作,译码器不断在网格图上深入,通过去除可能性最小的路径实现判决。
网格图中每个时刻t i 上有2
K -1
条路径到达。维特比译码包括计算到达每个状态的两条路径的路径量度,并舍弃其中一条路径。在时刻t i ,算法对2
K -1
并重复上述过程。在一个给定的时刻,各状态的幸存路径量度就是该状态在该时刻的状态量度。
图3编码器网格图
个状态,这里的K 是约束长度,每种状态都可经两
个状态(节点)都进行上述计算,然后进入时刻t i +1,
输入数据序列 m:发送序列 U:接受序列 Z: 1 1 11 01 11 0100101 1 00 10 1 01 01
a 00
b 10
c 01
d 11
输入比特0
输入比特1
图4译码器网格图
5.4实验内容
在MA TLAB 上设计一个(2,1,3)卷积编码器和对应的采用维特比译码算法的译码器。编码器的生成多项式为:
g 1(X ) =1+X +X 2g 2(X ) =1+X
2
将编码器的输出经过一个高斯白噪声信道的结果作为译码器的输入,观察比较译码器输出和编码器输入,了解卷积码的容错性,并计算译码结果的误比特率。基本流程如错误!未找到引用源。所示。实验报告要求附加程序代码,并对代码中每个函数模块的实验方式和功能进行简要的说明。
输出编码结果
卷积码编码模块: 卷积码编码子程序:
function out_put=conv_enc(msg) g1=[1 1 1]; g2=[1 0 1]; m1=conv(msg,g1); m2=conv(msg,g2); L1=length(m1); for i=1:L1
out_put(2*i-1)=rem(m1([i]),2);
out_put(2*i)=rem(m2([i]),2); end end
该模块将对输入信息码子编码。
维特比算法解码器的实现函数:
function decoder_output=viterbi_hard(y,L) global G;
G=[1 1 1;1 0 1]; n=size(G,1); K=size(G,2);
number_of_states=2^(K-1);
%------ -生成各分支的输出-------------------- for j=0:number_of_states-1 for t=0:1
[next_state,memory_contents]=next_state_fun(j,t,K); input(j+1,next_state+1)=t;
branch_output=rem(memory_contents*G',2); nextstate(j+1,t+1)=next_state;
output(j+1,t+1)=bin2deci(branch_output); end end
%------------------------------------------------
metric_of_states=zeros(1,number_of_states); %各状态的度量 metricmetric_of_states_c=zeros(number_of_states,2); %各状态两个输入的度量
length_seq=length(y)/n;
%符号个数
decoder_output=zeros(1,length_seq-K+1); %解码输出
channel_output_matrix=reshape(y,n,length_seq);
%将解调输出的比特按符号排列
survivor_state=zeros(number_of_states,length_seq+1); %留存路径 input_of_state=zeros(number_of_states,length_seq+1,2);
%汇聚到各状态的分支对应的输入
state_sequence=zeros(1,length_seq+1); count=zeros(1,number_of_states);
for i=1:length_seq-K+1 for j=0:number_of_states-1 for t=0:1
binary_output=deci2bin(output(j+1,t+1),n);
%将各分支的输出转换为2进制
for kk=1:n
branch_metric=0;
branch_metric=Hamming_dis(channel_output_matrix(:,i)',binary_output); end
count(nextstate(j+1,t+1)+1)=count(nextstate(j+1,t+1)+1)+1;
metric_of_states_c(nextstate(j+1,t+1)+1,count(nextstate(j+1,t+1)+1))=metric_of_states(j+1)+branch_metric; %计算累积度量(加)
input_of_state(nextstate(j+1,t+1)+1,:,count(nextstate(j+1,t+1)+1))=survivor_state(j+1,:);
%该分支所在路径的对应的输入
input_of_state(nextstate(j+1,t+1)+1,i,count(nextstate(j+1,t+1)+1))=t; end ; end ;
%----------------比较汇聚到同一状态的两条路径,选取距离较小的
------------------
for j=0:number_of_states-1
if metric_of_states_c(j+1,1)>=metric_of_states_c(j+1,2) metric_of_states(j+1)=metric_of_states_c(j+1,2); survivor_state(j+1,:)=input_of_state(j+1,:,2); else
metric_of_states(j+1)=metric_of_states_c(j+1,1); survivor_state(j+1,:)=input_of_state(j+1,:,1); end ; end ;
count=zeros(1,number_of_states);
%--------------------------截短输出----------------------------------- if i>L
[min_metric,location]=min(metric_of_states); decoder_output(i-L)=survivor_state(location,i-L); end ; end
%----------------------最后L 个比特译码输出
----------------------------------
[min_metric,location]=min(metric_of_states);
decoder_output(length_seq-K+1-L+1:length_seq-K+1)=survivor_state(location,length_seq-K+1-L+1:length_seq-K+1);
这是witerbi 算法的主程序,上面的witerbi 函数所用的子函数如下:
十进制转化为二进制的程序: function y=deci2bin(x,n) y=zeros(1,n); i=1;
while x>=0 & i
y=y(n:-1:1);
二进制转化为十进制的程序 function y=bin2deci(x) n=length(x); y=(n-1:-1:0); y=2.^y; y=x*y';
海明距离函数:
function distance=Hamming_dis(x,y) if x==y distance=0; else distance=1; end
求witerbi 下一个状态的函数:
function [next_state,memory_contents]=next_state_fun(j,t,K) binary_state=deci2bin(j,K-1); binary_input=deci2bin(t,1);
next_state_binary=[binary_input,binary_state(1:(K-2))]; next_state=bin2deci(next_state_binary) ; memory_contents=[binary_input,binary_state];
1、写完所有的子函数以后,先不加噪声,对输入比特进行卷积码编码,然后解码输出。将编码器输出的序列与卷积码理论编码比较,判断编码是否正确。对编码输出的序列进行译码,再将译码输出与原始码子比较,判断译码是否正确。
主程序为:(convende.m 文件)
clear all ; close all ;
m=[1 0 0 1 1] %输入序列 L=length(m);
out_put=conv_enc(m) %编码输出 y=out_put;
mm=viterbi_hard(y,L) %解码输出
运行后得到:m =
1 0 0 1 1
out_put =
1 1 1 0 1 1 1 1 0 1 0 1 1 1
mm =
1 0 0 1 1 编码译码均正确。
将输入序列改为m=[1 0 0 1 1 0 1 1 0 1]
运行程序:
m =
1 0 0 1 1 0 1 1 0 1
out_put = 1 1 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 1 0 0 1 0 1 1 mm =
1 0 0 1 1 0 1 1 0 1 显然编解码均正确。
2、编解码正确后,对编码输出序列加高斯白噪声,然后解码,将解码输出与原始码子比较,
计算误码率,同时画出误码率曲线。 主程序:(conende2.m 文件)
clear all ; close all ;
L=6000; %带编码的序列长度。 Snr=-2:0.5:15; k2=length(Snr); Ber=zeros(1,k2); for i=1:k2
%产生随即序列
msg=randint(1,L); out_put=conv_enc(msg); snr=Snr(i);
L2=length(out_put); n0=1/10^(snr/10); p=n0/2;
%加高斯白噪声
Guass_noise = sqrt(p) * randn(1,L2); code_out = out_put + Guass_noise; for j = 1:L2
if code_out (j) >= 0.5
code_out (j) = 1; else
code_out (j) = 0; end end
%译码
mm2=viterbi_hard(code_out,L); %算误码率
Sr=zeros(1,L);
ber=sum(mm2~=msg)/L; Ber(i)=ber; End
%误码率曲线。
semilogy(Snr,Ber);
得到如图所示的误码率曲线:
由于用的序列长度为6000,比较小,所以误码率曲线不太光滑。
本编解码系统没有使用调制解调,没有调制解调的数字通信系统误码率当然比较大,采用psk, 获fsk 调制后可大大降低误码率。