Harbin Institute of Technology信息论与编码报告题目:循环码编译码实验院(系)电子与信息工程学院班级通信1班学生学号序号哈尔滨工业大学循环码编译码实验1 设计内容循环码是线性分组码中最重要的一类码,它的结构完全建立在有限域多项式的基础上,它具有两个基本特点:一是编码电路与译码电路非常简单,易于实现;二是其代数性质好,分析方便,有一定的成熟的译码方法。
一个(n ,k )线性分组码C ,如果码组中的一个码字的循环移位也是这个码组中的一个码字,则称C 为循环码。
本实验主要完成以下四项内容:(1)利用(7,4)系统循环码的生成多项式为:3()1g x x x =++,请设计该循环码的编码器。
(2)随机产生重量为0或1的八种错误图样中的一种,得到实际接收码字。
(3)根据接收到的码字进行译码,译码方式分为校验子译码和梅吉特译码两种。
(4)对于在BSC 信道传输时的情形进行讨论,验证(7,4)系统循环码的纠错能力。
2 编程环境本实验采用Matlab 作为编程工具,所有代码均在Matlab 软件中运行,此软件功能强大,应用广泛,在此不再赘述。
3 各模块设计3.1 编码器模块利用(7,4)系统循环码的生成多项式为:3()1g x x x =++,请设计该循环码的编码器。
流程图为:图1 (7,4)循环码编码流程图图2 4位信息码元编码流程图在学生设计的演示工具中输入的信息码元可以为任意多个,系统自动按每4个连续的码字一组进行编码,当输入的信息码元不是4的倍数时,自动补零到与信息码元长度最接近的4的倍数。
译码时也是按照每7个连续的码字一组进行译码。
但是为了流程图的清晰明了,在本文的流程图除流程图1以外,其余均按一个循环码码字(即7位)来描述。
编码器模块源程序如下:%%%函数功能:(7,4)系统循环码编码器%%%编程时间:2013-11-29%%%该系统循环码编码器的生成多项式是g(x) = x^3 + x + 1;% %%系统循环码编码的原理是,首先用x^r乘以信息码字多项式m(x),这里r = 3;然后用x^r*m(x)除以生成多项式g(x),% %%得余式r(x);最后得系统循环码多项式c(x) = x^r*m(x) + r(x)function [code_out,code_in_L] = coder(code_in)%%code_in:输入信息码字%%code_out:输出编码后的码字%%L:输入的信息码元的长度n=7;%%每个码字长度k=4;%%每个码字中信息码元长度code_in_L=length(code_in);a=rem(code_in_L,k);%信息码元的长度除以k后的余数if a~=0 %%%信息码元长度不是k的整数倍,则补0array_0=zeros(1,k-a);%%%补零个数code_in=[code_in ,array_0];endcode_in_4=(reshape(code_in,k,length(code_in)/k))';%%%将补零后的码元变成length(code_in)/4行,4列矩阵for loop=1:length(code_in)/kmes_code = [code_in_4(loop,:),zeros(1,3)]; % 在信息码字后面补上三个零,相当于乘上x^rgen = [1 0 1 1]; % 生成多项式向量% 在二元域进行运算,必须把信息码字多项式向量和生成多项式向量转到二元域GF(2)上% 函数gf(X,M)用于从向量X生成GF(2^M)上对应的向量mes_g = gf(mes_code,1);gen_g = gf(gen,1);% 用x^r*m(x)除以生成多项式g(x)[Q,rem_g] = deconv(mes_g,gen_g); % 多项式除法其实就是解卷积运算,得到除法的商式Q,余式rem_g%%相应的,多项式乘法其实是系数的卷积code_rem = rem_g.x; % rem_g.x表示二元域向量rem_g的一个属性,即多项式的系数。
%rem_g.x是在实数域中,而rem_g是在二元域中% 输出系统循环码code_out(loop,:) = [code_in_4(loop,:),code_rem(5:n)];endend3.2 产生错误图样模块本模块产生随机产生重量为0或1的八种错误图样中的一种,并得到实际接收码字。
程序流程图如图3所示。
图3 产生随机错误图样流程图产生错误图样源程序如下:%%函数功能:随机产生重量为0或1的八种错误图样中的一种,得到实际接收码字%%时间:2013-11-29function [code_R,error_picture] = error_pattern(code_S)% code_S:本来发送的码字% code_R:实际接收到的码字% error_picture:随机生成的重量为0或1的八种错误图样中的一种n=7;k=4;[L,W]=size(code_S);num=L*W;code_send=reshape(code_S',1,num);code_send_7=(reshape(code_send,n,length(code_send)/n))';%%%将码元变成length(code_in)/n行,n列矩阵for loop=1:length(code_send)/7error=zeros(1,n); %错误图样序列error_place=randi([0,n],1,1); %错误图样位置if (error_place==0)code_R(loop,:)=code_send_7(loop,:);elseerror(8-error_place)=1;for i=1:ncode_temp=mod(code_send_7(loop,i)+error(i),2); %接收码字序列code_R(loop,i) =code_temp;endenderror_picture(loop,:)=error;endend3.3 译码模块学生设计了校验子译码和梅吉特译码两种译码方式,其中校验子译码时校验子多项式与错误图样多项式的对应关系表如下:表1 校验子多项式与错误图样多项式对应关系梅吉特译码电路如下图:图4 梅吉特译码电路图5 校验子译码流程图 图6 梅吉特译码流程图校验子译码源程序如下:%%函数功能:校验子译码 %%时间:2013-11-29function [C_decode_n,C_decode_k] = check(code_R,code_in_L) % code_R :接收码字序列 %code_in_L :信息码元长度 %C_decode_n :译码后的码字序列 %C_decode_k :译码后的信息码元 n=7; k=4;gen = [1 0 1 1]; % 生成多项式向量[L,W]=size(code_R);num=L*W;code_recrive=reshape(code_R',1,num);code_recrive_7=(reshape(code_recrive,n,length(code_recrive)/n))';%%%将码元变成length(code_in)/n行,n 列矩阵for loop=1:length(code_recrive)/7% 在二元域进行运算,必须把信息码字多项式向量和生成多项式向量转到二元域GF(2)上% 函数gf(X,M)用于从向量X生成GF(2^M)上对应的向量R_g = gf(code_recrive_7(loop,:),1);gen_g = gf(gen,1);% 用R_g除以生成多项式g(x)[Q,rem_g] = deconv(R_g,gen_g); % 多项式除法其实就是解卷积运算,得到除法的商式Q,余式rem_gS_rem_2 = rem_g.x; % rem_g.x表示二元域向量rem_g的一个属性,即多项式的系数%rem_g.x是在实数域中,而rem_g是在二元域中L_S_rem_2=length(S_rem_2);%%长度S_rem=S_rem_2(L_S_rem_2)+2*S_rem_2(L_S_rem_2-1)+4*S_rem_2(L_S_rem_2-2);%%2进制转化为10进制error=zeros(1,n);if S_rem==0error=[0 0 0 0 0 0 0];elseif S_rem==1error=[0 0 0 0 0 0 1];elseif S_rem==2error=[0 0 0 0 0 1 0];elseif S_rem==4error=[0 0 0 0 1 0 0];elseif S_rem==3error=[0 0 0 1 0 0 0];elseif S_rem==6error=[0 0 1 0 0 0 0];elseif S_rem==7error=[0 1 0 0 0 0 0];elseif S_rem==5error=[1 0 0 0 0 0 0];endfor i=1:length(error)if error(i)==1E_place=i;%%定位错误的位置code_recrive_7(loop,E_place)=~code_recrive_7(loop,E_place); %错误码字译码endendcode_temp=code_recrive_7(loop,:);% 输出译码C_decode_n(loop,:) =code_temp;C_decode_k0(loop,:) =code_temp(1:k);end% 输出译码% C_decode_n=reshape(C_decode_n0',1,length(code_recrive));C_decode_k1=reshape(C_decode_k0',1,length(code_recrive)/7*4);C_decode_k=C_decode_k1(1:code_in_L);end梅吉特译码源程序如下:%%函数功能:(7,4)系统循环码梅吉特译码%%编程时间:2013-11-29function [C_decode_n,C_decode_k] = encoder(code_R,code_in_L)%%code_R:接收到的码字%%code_in_L:信息码元长度%%C_decode_n:译码之后得到的码字%%C_decode_k:译码之后得到的信息码元n=7;k=4;[L,W]=size(code_R);num=L*W;code_recrive=reshape(code_R',1,num);code_recrive_7=(reshape(code_recrive,n,length(code_recrive)/n))';%%%将码元变成length(code_in)/n行,n 列矩阵for loop=1:length(code_recrive)/7D=[0,0,0];%%开始译码时门打开%%寄存器初始化D=[D0 D1 D2]for i=1:nD_temp(1)=mod(D(3)+code_recrive_7(loop,i),2);D_temp(2)=mod(D(1)+D(3),2);D_temp(3)=D(2);D=D_temp;endfor i=1:n %输入端关闭,移位寄存器中的接收码S=double(D(1)&(~D(2))&D(3)); %模2加后输出,S反馈到D寄存器D_temp(1)=mod(D(3)+S,2);D_temp(2)=mod(D(1)+D(3),2);D_temp(3)=D(2);D=D_temp;code_temp(i)=mod(code_recrive_7(loop,i)+S,2);end% 输出译码C_decode_n(loop,:) =code_temp;C_decode_k0(loop,:) =code_temp(1:k);end% 输出译码% C_decode_n=reshape(C_decode_n0',1,length(code_recrive));C_decode_k1=reshape(C_decode_k0',1,length(code_recrive)/7*4);C_decode_k=C_decode_k1(1:code_in_L);end3.4 BSC信道传输时的译码模块本模块的编程比较简单,主要是调用bsc函数,设置一下错误概率参数p即可,故不在此报告中给出源代码。