首页>>科技 >>内容

代码纠错器,实现汉明纠错码的编码和解码方案设计

发布时间:2023-10-13 21:36:11编辑:温柔的背包来源:

很多朋友对代码纠错器,实现汉明纠错码的编码和解码方案设计不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。

代码纠错器,实现汉明纠错码的编码和解码方案设计

本实验的目的是实现汉明纠错码的编解码

1.1 汉明码简介

汉明码是电信领域的一种线性调试码,以其发明者理查德韦斯利汉明(Richard Wesley Hamming) 的名字命名。汉明码将验证码插入到传输的消息流中。当计算机存储或移动数据时,可能会发生数据位错误,以检测并纠正单位错误。由于汉明码的简单性,它们在内存中被广泛使用。

与其他错误检查码类似,汉明码也利用奇偶校验位的概念。通过在数据位后面添加一些位,可以验证数据的有效性。汉明码使用多个校验位,不仅可以检查数据是否有效,而且如果数据错误,还可以指出错误的位置。 (汉明码可以检测两位错误并纠正一位错误)。

1.2 编码规则

要理解汉明码,我们必须首先了解奇偶校验。奇校验就是在一串码中添加一个校验位,使这串码中1的个数为奇数。偶校验也是如此,使编码中1 的数量成为偶数。

汉明码的编码位数n与纠错码的位数k的关系:2^k=n+k+1。以下是n和k的常用值:

n12-45-1112-2627-5758-120k234567 我们将纠错码添加到相应的编码中。纠错码的位置必须在2^n位置。以10101100为例进行编码。该序列为8 位,需要4 个纠错码。我们首先将序列编号为1 到8

1234567810101100 然后将纠错码(p1,p2,p3,p4)添加到这个序列中的2^n位置,并以二进制重新编号

000100100011010001010110011110001001101010111100p1p21p3010p41100 然后我们求p1、p2、p3、p4的值。首先将上述序列组号xxx1分为一组,xx1x分为一组,x1xx分为一组,1xxx分为一组。

xxx1:p1,1,0,0,1,0

xx1x:p2,1,1,0,1,0

x1xx:p3,0,1,0,0

1xxx:p4,1,1,0,0

我们采用偶校验,所以p1=1,p2=1,p3=1,p4=0。这样我们就得到了10101100 111101001100的汉明码。

那么汉明码是如何纠错的呢?

我们按照p4、p3、p2、p1的顺序排列,得到0111。这就是错误的位数。由于是二进制传输,我们可以通过将相应的位取反来得到正确的序列。

1.3FPGA实现

对于p1、p2、p3、p4的计算,用fpga实现时,只需要按位异或即可。输入数据位为8 位,需要4 个纠错位。

1.3.1 顶层架构

信号说明

信号功能说明clk 工作时钟外部输入rst_n 系统复位外部输入数据输入数据外部输入wren 写使能外部输入rden 读使能外部输入q 输出数据输出hc_out 汉明编码后输出hc_in 输入海明码外部输入顶层代码

模块humming_coder12_8(clk, rst_n, data, q, rden, wren, hc_out, hc_in);输入clk, rst_n;输入[7:0] 数据;输出[7:0] q;输入rden, wren;输出[11: 0] hc_out;输入[11:0] hc_in;hamming_encoder HE(.clk(clk),rst_n(rst_n),wren(wren),data(data),hc_out(hc_out));hamming_decoder HD(. clk(clk),rst_n(rst_n),rden(rden),q(q),hc_in(hc_in));endmodule1.3.2编码模块

编码模块只需要将分组后的各组数据(不包括p)进行异或,然后赋值给p。

编码模块代码

模块hamming_encoder(clk, rst_n, wren, data, hc_out);输入clk, rst_n;输入wren;输入[7:0] 数据;输出reg [11:0] hc_out;连线p0, p1, p2, p3;分配p0=data[6] ^ data[4] ^ data[3] ^ data[1] ^ data[0];分配p1=data[6] ^ data[5] ^ data[3] ^ data[2] ^ data [0];分配p2=数据[7] ^ 数据[3] ^ 数据[2] ^ 数据[1];分配p3=数据[7] ^ 数据[6] ^ 数据[5] ^ 数据[4];始终@ (posege clk 或negedge rst_n)beginIF(!rst_n)hc_out=0;else if(wren)hc_out={data[7:4], p3, data[3:1],p2, data[0], p1 , p0};elsehc_out=0;endendmodule

1.3.3 解码模块

解码模块只需判断哪一位出错,然后将其取反,并删除纠错位。

解码模块代码

模块hamming_decoder(clk, rst_n, rden, q, hc_in);输入clk, rst_n;输入rden;输出reg [7:0] q;输入[11:0] hc_in;连线g0_error, g1_error, g2_error,g3_error;分配g0_error=hc_in[10] ^ hc_in[8] ^ hc_in[6] ^ hc_in[4] ^ hc_in[2] ^ hc_in[0];赋值g1_error=hc_in[10] ^ hc_in[9] ^ hc_in[6] ^ hc_in [5] ^ hc_in[2] ^ hc_in[1];分配g2_error=hc_in[11] ^ hc_in[6] ^ hc_in[5] ^ hc_in[4] ^ hc_in[3];分配g3_error=hc_in[11] ^ hc_in[10] ^ hc_in[9] ^ hc_in[8] ^ hc_in[7];总是@ (posege clk 或negedge rst_n)beginif(!rst_n)q=0;else if(rden)case ({g3_error, g2_error, g1_error, g0_error})4'b0000 : q={hc_in[11:8], hc_in [6:4], hc_in[2]};4'b0001 : q={hc_in[11:8], hc_in[6:4], hc_in[2]};4'b0010 : q={hc_in[11: 8], hc_in[6:4], hc_in[2]};4'b0011 : q={hc_in[11:8], hc_in[6:4], ~hc_in[2]};4'b0100 : q={hc_in[11:8], hc_in[6:4], hc_in[2]};4'b0101 : q={hc_in[11:8], hc_in[6:5], ~hc_in[4], hc_in[ 2]};4'b0110 : q={hc_in[11:8], hc_in[6], ~hc_in[5], hc_in [4], hc_in[2]};4'b0111 : q={hc_in[11] :8], ~hc_in[6], hc_in[5], hc_in[4], hc_in[2]};4'b1000 : q={hc_in[11:8], hc_in[6], hc_in[5], hc_in[4], hc_in[2]};4'b1001 : q={hc_in[11:9], ~hc_in[8] , hc_in[6:4], hc_in[2]};4'b1010 : q={hc_in[11:10], ~hc_in[9], hc_in[8], hc_in[6:4], hc_in[2] };4'b1011 : q={hc_in[11], ~hc_in[10], hc_in[9], hc_in[8], hc_in[6:4], hc_in[2]};4'b1100 : q={ ~hc_in[11], hc_in[10], hc_in[9], hc_in[8] , hc_in[6:4], hc_in[2]};default: q=0;endcaseelseq=0;endendmodule模拟验证

我们使用$random系统函数生成的随机数作为编码模块数据,并使用$random系统函数生成的随机数来反转hc_out的哪一位用于模拟噪声。并判断输入数据和输出数据是否相等,验证纠错功能。使用$display 和$error 系统函数生成报告。

测试文件代码

模块humming_coder12_8_tb;reg clk, rst_n;reg [7:0] 数据;reg rden, wren;wire [11:0] hc_out;reg [11:0] hc_in;wire [7:0] q;reg [7:0 ] temp1, temp2;humming_coder12_8 DUT(.clk(clk),rst_n(rst_n),data(data),wren(wren),q(q),rden(rden),hc_out(hc_out),hc_in(hc_in));整数pn, i;初始beginpn=0;hc_in=0;永远开始@ (posege clk)pn={$random} %12;#1for (i=0; i12; i=i+ 1 ) beginif (i!=pn)hc_in=hc_out;elsehc_in=~hc_out;endendendalways @ (posege clk)begintemp1=data;temp2=temp1;endalways @ (*)beginif (wren) begin#1if (temp2==q) $显示('确定:时间=%0t 数据=%0d q=%0d', $time, temp2, q);else$error('错误:时间=%0t 数据=%0d q=%0d', $time , temp2, q);endendinitial beginclk=1;rst_n=0;data=0;rden=0;wren=0;#200@ (posege clk)rst_n=1;#200forever begin@ (thoughtge clk)wren=1 ;数据={$random} % 9'b10000_0000;@ (posege clk)wren=1;数据={$random} % 9'b10000_0000;rden=1;endendalways #10 clk=~clk;initial #5000 $stop;在endmodule生成的报告中,我们可以看到错误的数据可以修改为原来的正确数据,证明我们的编解码模块功能正确。

以上知识分享希望能够帮助到大家!