BCH信道编译码

通信的目的是要把对方不知道的消息即时可靠地(有时还要秘密地)传送给对方。当信道中存在干扰,可能使发送的消息出错。数字通信中,通常使用纠错码技术来进行差错控制,这样可以提高数据传输的可靠性。

BCH码就是一种应用广泛的能纠正多重错误的分组码,具有极佳的纠错性能。本文对BCH码的原理进行深入分析,介绍BCH的编解码原理。重点介绍了BCH编码解码的计算方法以及BCH编码的性能分析。最后,本文采用MATLAB编写相应的BCH编解码代码进行仿真和误码率分析,并在Simulink中搭建BCH模块进行误码率统计分析。本文所作的研究成果具有一定的科研价值,为BCH的进一步研究或在硬件系统上的实现提供了良好的理论基础。

1.1 本课题研究背景

数字信号在传输系统中传输时,不可避免受到各种因素的干扰,使到达接收端的数字信号中混有噪声,从而引发错误判决,为了抗击干扰,必然要利用纠错码的差错控制技术。

纠错码的分类有以下几种:

·按照对信息序列处理方式的不同,分为分组码与卷积码两大类,在分组码中按照码的结构特点,又可分为循环码和非循环码。

·根据信息位与校验位之间的关系分为线性码与非线性码。

·按照适用的差错类型,分成纠随机差错码和纠突发差错码两种,也有介于中间的纠随机/突发差错码。

·按构码理论,有代数、几何、算术、组合码等。

除了上述分类外,有多少观察问题的角度,就有多少分类方法。比如,按每个码元的取值,可以分为二进制码与多进制码;按码字之间的关系,有循环码和非循环码之分;不同的分类方法只是从不同的角度抓住码的某一特性加以归类而己,并不能说明某个码的为全部特性。比如某线性码可能同时又是分组码,循环码,纠突发差错码,代数码,二进码。

1.2 线性分组码和循环码

扫描二维码关注公众号,回复: 11796093 查看本文章

线性分组码是分组码中最重要的一类码,用(n,k)表示,其中n表示码长,k表示信息位数目,n-k=r表示校验位数目,二进制(n,k)线性分组码可以定义为GF(2)域上的n维线性空间Vn中的一个k维子空间。

在线性分组码中有三个重要参数,分别为码率、码的汉明距离和汉明重量。码率R=k/n,它说明了分组码传输信息的有效性。码的汉明距离指两个码字对应位上码元不同的个数,简称距离。汉明重量指码字中非零码元的个数,简称重量。在(n,k)线性分组码中,将任两个码字距离的最小值称为最小距离d0。由于线性分组码是群码,由群码的封闭性可知,若码字C1,C2均是(n,k)码的码字,则C1+C2也必是该分组码的另一码字,可见(n,k)线性分组码的最小距离等于非零码字的最小重量。最小距离d。直接在理论上决定了该码的检错和纠错能力。

循环码是线性分组码中最重要的一个子类,它的代数结构比较清晰,编译码相对于其它码来讲简单且易于实现,因此循环码在差错控制系统中得到广泛的应用,BCH码就是循环码中很重要的一类码。

在GF(2)上的n维线性空间气中,若是的一个k维子空间,对任何,有,则是循环码。

由编码理论推导出的循环码纠错能力只是一个理论值,在现实中能否达到这个理论值还与所用的译码方法有关。一个好的译码方法,不仅应使纠错能力能够达到理论极限,而且应能高速度、低成本地实现,因为速度和成本有时会成为某种码能否实用的决定性因素。

译码电路通常要比编码电路复杂得多,因此我们说,理论的复杂性常体现在编码上,而工程的复杂性常体现在译码上。从对输入信号的量化程度,译码可分为硬判决译码(BSC信道)和软判决译码(DMC信道)。

软判决由于采用了大于2的量化级数,能更充分地利用接收信号包含的信息,与硬判决相比,在AWGN信道、10-2-10币误码率范围时可有2dB的编码增益,因此代表了译码的发展方向。从差错控制方式,译码可分为纠错和检错两种。纠错译码器总有输出,但有两种可能:一是收码的差错数量在纠错能力之内,译码器认定的正确真的是正确。二是差错数量超出纠错能力,译码器认定的正确其实是错的。由于难以判断差错数量是否超出纠错能力,纠错译码器不能保证输出数据完全可靠,所以纠错译码器常用于数字语音、图像、视频信号的前向纠错(FEC)中。

1.3 BCH编码的研究和应用

BCH码于1959年由霍昆格姆、1960年由博和雷-查德胡里三人分别提出,并以这三个发现者的名字命名。BCH码是迄今为止所发现的一类很好的线性纠错码类。它的纠错能力很强,特别在中等和短码长条件下,BCH码的性能接近理论上的最佳值,并且构造方便,编码简单。特别是它具有严密的代数结构,在代数编码理论中起着重要作用。BCH码是迄今为止研究得最为详尽、了解得最为透彻、取得成果最多的一类线性分组码。

1960年彼得逊从理论上解决了二进制BCH码的译码算法,奠定了BCH码译码的理论基础。稍后,格林斯坦和齐勒尔把它推广到多进制。1966年伯利坎普利用迭代算法译BCH码,从而大大加快了译码速度,从实际上解决了BCH码的译码问题。由于BCH码性能优良,结构简单,编译码设备也不太复杂,使得它在实际使用中受到工程技术人员的欢迎,是目前用得最广泛的码类之一。

在英国模拟移动通信系统中,基站采用了具有纠正2位随机错误能力的BCH(40,28)码,移动台采用了可纠正2位随机错误的BCH(48,36)码;在我国无线寻呼系统中,采用了BCH(31,21)码加一位奇偶校验位作为FEC方式;在视频编码协议H.261、H.263中采用了BCH(511,493)码进行视频纠错。

第三章 BCH码理论简介

3.1 BCH码简介

BCH码是循环码的一个重要子类,它具有纠多个错误的能力,BCH码有严密的代数理论,是目前研究最透彻的一类码。它的生成多项式与最小码距之间有密切的关系,人们可以根据所要求的纠错能力t很容易构造出BCH码,它们的译码器也容易实现,是线性分组码中应用最普遍的一类码。

3.1.1伽罗华域

编码原理中最基本、最重要的域是二元伽罗华域GF(2)及二元扩域GF(2m)。有限正数集合F={0,1,2,3,…,q-1}(q是素数)在模q加、模q乘运算下构成一个q阶有限域,又称伽罗华(Galois)域,记为GF(q)。当q=2时,就是二元域GF(2)。

在有限域中定义的运算满足闭合性,即有限域GF(q)上任意两个元素A、B对运算⊙满足:A⊙B∈GF(q)。

如果p是素数,m是正整数,GF(2m)的最小子域是GF(p),p称为GF(2m)的特征,在特征为2的伽罗华域中,任一域元素B有-B=B。

设B为GF(q)上的任一元素,则B=Bq。

每个伽罗华域GF(q)至少包含有一个本原元素α,且GF(q)上除零以外的其它任意域元素均可表示为本原元素的乘幂。

任一有限域均可由一本原多项式来构成,有限域的任一多项式对本原多项式求模,可得到一个次数低于本原多项式次数的多项式,即有限域的元素。

·加法运算

域元素的加法运算,即根据域元素表格,转换成对应的m-1次多项式系数(m重矢量)。两个域元素相加等效于两个m-1次多项式的同次项系数模2相加,即异或运算。

·乘法运算

乘法有三种实现途径:

第一就是把域元素对应的多项式系数直接移位,比如a×b,只要找到b对应的幂次,假设是x,将a左移x次,每次左移之前判断移位前的值高位是否为1,如果是1,移位后与本原多项式除高次幂后的多项式相加;

第二种方法就是从b的高位开始,如果b7=1,将a左移7次,如果b6=1,将前面左移结果再左移6次。

第三种方法是直接把域元素的指数相加求模2m-1。这里采用第三种方法。

·求模运算

因为2^m-1转换成二进制数永远是全1,所以根据这个特点,可以用下面的方法求模。把二进制形式的数从低位起每m比特分割,高位不满m比特用0补齐。然后高位段每出现一个1,就把高位减去1,然后把低位加1,这样循环操作直到高位段变成全0。

3.3 BCH译码理论介绍

BCH码的译码可以分为时域译码和频域译码两种。

频域译码是把码字看作一个时域数字序列,对其进行有限域的离散傅氏变换(DFT)将它变换到频域,然后利用其频域特点译码。这样通过对频域伴随式的运算解出指示差错位置的关键方程,再通过离散傅氏反变化还原成时域的纠错信号。

时域译码是把码字看作时间轴上的信号序列,利用码的代数结构进行译码。由于取有限域离散傅氏变换增加了复杂度,频域译码的实现一般较时域译码复杂,因此采用快速傅氏变换(FFT)的频域译码只在某些特殊情况下对特定码长(比如n等于2的幂次)的译码优于时域译码,而在一般情况下应用最广泛的是时域译码。其中BCH译码器的基本结构如下所示:

图3-1 BCH译码器基本结构框图

    通常,我们在MATLAB中设计算法分三个步骤:

·STEP1:由接收到的R(x)计算出伴随式S;

·STEP2:由伴随式得出错误图样E(x);

·STEP3由R(x)-E(x)得到估值码字c(x)。

5.2 BCH编码的系统仿真

     我们根据前面的理论分析,编写MATLAB代码。这里,我们根据要求,进行(511,493)(4095,4035)两种参数的BCH编码,其MATLAB编码函数如下所示:

function code=bchencoder(data,genpoly,n,k);

bb=zeros(1,n-k);

for i=k:-1:1

    feedback = xor(data(i), bb(n-k));

    if feedback~=0

        for j=n-k:-1:2

            if genpoly(n-k-j+2)~=0

                bb(j)=xor(bb(j-1),feedback);

            else

                bb(j)=bb(j-1);

            end

        end

        bb(1)=feedback;

    else

        for j=n-k:-1:2

            bb(j)=bb(j-1);

        end

        bb(1)=feedback;

    end

end

code=[bb,data];

我们在顶层对其进行调用,调用过程如下代码:

for j=1:nwords

encoded_data((j-1)*n+1:(j-1)*n+n)=bchencoder(message((j-1)*k+1:(j-1)*k+k),genpoly,n,k);

end

输入信息为:

…………  1   1   0   1   1   0   0   1   1   1  …………………………

通过BCH编码之后,得到BCH编码信息:

…………  1   1   0   0   0   1   0   0   1   0  …………………………

5.3 BCH译码的系统仿真

    本系统译码我们将采用应用十分普遍的‘钱搜索’法进行译码,前面我们已经简单的介绍了该算法, 其MATLAB代码实现过程如下所示:

lambda_v = zero;

    accu_tb=gf(ones(1, t+1), m);

    for i=1:n,

        lambda_v=lambda*accu_tb';

        accu_tb = accu_tb.*inverse_tb;

        if(lambda_v==zero)

            error(1,n-i+1)=1;

        else

            error(1,n-i+1)=0;

        end

    end

    found = find(error(1,:)~=0);

    for i=1:length(found)

        location=found(i);

        if location <= k;

            rec_data(n-location+1)=rec_data(n-location+1)+one;

        end

    end

    decoded_data((j-1)*k+1:(j-1)*k+k)=rec_data(n-k+1:n);

我们将编码之后得到的信号输入BCH译码部分,输出结果:

…………  1   1   0   1   1   0   0   1   1   1  …………………………

 

 

 

 

 

 

 

 

 

 

5.2.4 不同参数的BCH编解码性能分析

    本章我们将重点对几种不同参数的BCH码进行了仿真。系统信噪比的分析我们主要采用:semilogy进行仿真。我们分别对(511,493)(4095,4035)进行仿真,然后不改变n,k两个参数,改变其纠错能力进行仿真,从而判断BCH编解码的性能。

图5-1 n=511,k=493t=11条件下信噪比

图5-2 n=4095,k=4035t=11条件下信噪比

 

 

图5-3 BCH编码和不编码的性能对比(绿色为未通过编码)

从仿真结果可以看出,对于纠错能力相同的BCH码,码字长度短的相对码字长度长的性能好,且平均仿真一个码字所耗费的时间少。分析原因,是因为在相同的信道条件下,每个码元出现错误的概率是相同的,对于码字长度长的BCH码,平均每个码字中出现错误的码元个数多,所以对于纠错能力相同的BCH码,码字长度长的性能差。

    以上我们详细介绍了MATLAB的BCH编解码和信噪比分析,下面我们将在Siumlink中进行BCH实际仿真,在本系统,我们将基于BPSK进行仿真分析。

    不加BCH的BPSK系统如下所示:

图5-4 BPSK仿真系统

其仿真结果如下所示:

    加入BCH编解码,其系统如下所示:

图5-5 BCH仿真系统

其仿真结果如下所示:

由上图可见,加上BCH编解码后,新能得到大大改善。

·编码和译码

clc;

clear;

close all;

m=9;%输入参数6

k=493;%输入参数4

snr=1;

n=2^m-1;

period=1000;

nwords = ceil(1000/k); 

[genpoly,t] = bchgenpoly(n,k);

simplified = 1;

alpha = gf(2, m);   

zero = gf(0, m);

one = gf(1, m);

message=randint(1,nwords*k);

message1=gf(message);

decoded_data=gf(zeros(1,nwords*k));

alpha_tb=gf(zeros(1, 2*t), m);

for i=1:2*t,

   alpha_tb(i)=alpha^(2*t-i+1);

end;

%BCH编码

for j=1:nwords

encoded_data((j-1)*n+1:(j-1)*n+n)=bchencoder(message((j-1)*k+1:(j-1)*k+k),genpoly,n,k);%由高位到低位

end

%添加噪声

sigma=sqrt(1/(10^(snr/10))/2);

datalength=length(encoded_data);

snum=ceil(datalength/period);

for(i=1:snum-1)

data2((i-1)*period+1:(i-1)*period+period)=encoded_data((i-1)*period+1:(i-1)*period+period)+sigma*randn(1,period);

end

data2((snum-1)*period+1:datalength)=encoded_data((snum-1)*period+1:datalength)+sigma*randn(1,length(encoded_data((snum-1)*period+1:datalength)));

rec_data2=zeros(1,nwords*n);

for i=1:nwords*n

    if abs(encoded_data(i)-data2(i))>0.5

        rec_data2(i)=xor(encoded_data(i),1);

    else

        rec_data2(i)=encoded_data(i);

    end

end

rec_data2=gf(rec_data2,m);

%BCH译码

for j=1:nwords

    rec_data=rec_data2((j-1)*n+1:(j-1)*n+n);

    syndrome=gf(zeros(1, 2*t), m);

    for i=1:n,

        syndrome=syndrome.*alpha_tb+rec_data(n-i+1);

    end;

    lambda = gf([1, zeros(1, t)], m);

    lambda0= lambda;

    b=gf([0, 1, zeros(1, t)], m);

    b2 = gf([0, 0, 1, zeros(1, t)], m);

    k1=0;

    gamma = one;

    delta = zero;

    syndrome_array = gf(zeros(1, t+1), m);

    if(simplified == 1)

        for r=1:t,

            r1 = 2*t-2*r+2;

            r2 = min(r1+t, 2*t);

            num = r2-r1+1;

            syndrome_array(1: num) = syndrome(r1:r2);

            delta = syndrome_array*lambda';

            lambda0 = lambda;

            lambda = gamma*lambda-delta*b2(2:t+2);

            if((delta~= zero) && (k1>=0))

                b2(3)=zero;

                b2(4:3+t) = lambda0(1:t);

                gamma = delta;

                k1 = -k1;

            else

            b2(3:3+t) = b2(1:t+1);

            gamma = gamma;

            k1=k1+2;

            end

            joke=1;

        end

    else

        for r=1:2*t,

            r1 = 2*t-r+1;

            r2 = min(r1+t, 2*t);

            num = r2-r1+1;

            syndrome_array(1:num) = syndrome(r1:r2);

            delta = syndrome_array*lambda';

            lambda0 = lambda;

            lambda = gamma*lambda-delta*b(1:t+1);

            if((delta ~= zero) && (k1>=0))

                b(2:2+t)=lambda0;

                gamma = delta;

                k1=-k1-1;

            else

                b(2:2+t) = b(1:t+1);

                gamma = gamma;

                k1=k1+1;

            end  

            joke=1;

        end

    end

    inverse_tb = gf(zeros(1, t+1), m);

    for i=1:t+1,

        inverse_tb(i) = alpha^(-i+1);

    end;

    %钱搜索法

    lambda_v = zero;

    accu_tb=gf(ones(1, t+1), m);

    for i=1:n,

        lambda_v=lambda*accu_tb';

        accu_tb = accu_tb.*inverse_tb;

        if(lambda_v==zero)

            error(1,n-i+1)=1;

        else

            error(1,n-i+1)=0;

        end

    end

    found = find(error(1,:)~=0);

    for i=1:length(found)

        location=found(i);

        if location <= k;

            rec_data(n-location+1)=rec_data(n-location+1)+one;

        end

    end

    decoded_data((j-1)*k+1:(j-1)*k+k)=rec_data(n-k+1:n);

end

·信噪比仿真

clc;

clear all;

close all;

%参数设置%(511,493)(4095.4035)

givenSNR=0.5:0.5:9.5; %]

% N=511;

% K=493;

N=4095;

K=4035;

T=11;

times=length(givenSNR);

%计算几个值

r=K/N;

Eb_N0=10.^(givenSNR./10);

sigma=(1./(2*r.*Eb_N0).^0.5);

message=randint(times,K,[0,1]);

msg=gf(message);

BCHcode_gf=bchenc(msg,N,K);

%BCH编码

BCHcode_double=-1*ones(times,N);

for code_i=1:times

    for code_j=1:N

        if BCHcode_gf(code_i,code_j)==1

            BCHcode_double(code_i,code_j)=1;

        end

    end

end

%添加噪声

for noise_i=1:length(sigma)

    BCH_receive(:,:,noise_i)=BCHcode_double+sigma(noise_i)*randn(times,N);

end

for noise_i=1:length(sigma)

    for hard_i=1:times

        for hard_j=1:N

          if BCH_receive(hard_i,hard_j,noise_i)>0

             hard_coded(hard_i,hard_j,noise_i)=1;

          end

        end

    end

end

%BCH解码

BCHdecode=gf(zeros(times,K,length(sigma)));

for noise_i=1:length(sigma)

    hard_BCH=hard_coded(:,:,noise_i);

    [BCHdecode_i,error_num]=bchdec(gf(hard_BCH),N, K);

    BCHdecode(:,:,noise_i)=BCHdecode_i;

end

BCHdecode_double=zeros(times,K);

for noise_i=1:length(sigma)

    for gf_to_double_i=1:times

        for gf_to_double_j=1:K

          if BCHdecode(gf_to_double_i,gf_to_double_j,noise_i)==1

               BCHdecode_double(gf_to_double_i,gf_to_double_j,noise_i)=1;

          end

        end

    end

end

for noise_i=1:length(sigma)

    error_BCHcoded_num(noise_i)=sum(sum((abs(BCHdecode_double(:,:,noise_i)-message))));

end

coded_error_rate=error_BCHcoded_num/times/K

semilogy(givenSNR,coded_error_rate,'-*');

ylabel('BER');

xlabel('Eb/N0');

grid on;

 

 

猜你喜欢

转载自blog.csdn.net/ccsss22/article/details/108741397