详解汉明纠错码原理以及FPGA实现

文章目录

  • 一、汉明纠错码简介
  • 二、汉明码编码原理以及步骤
  • 三、汉明码纠错原理以及步骤
  • 四、FPGA实现74汉明编码器
  • 五、FPGA实现74汉明解码器


一、汉明纠错码简介

  汉明纠错码(Hamming Code)是一种用于检测和纠正数据传输中错误的编码方法。它由理查德·汉明(Richard Hamming)在 1950 年代提出。汉明码的主要特点是能够在传输过程中检测和纠正单个比特错误,同时能够检测到双比特错误。
  现在的通信系统一般都是指香农在1948年贝尔实验室建立的,其模型如下:

在这里插入图片描述
  在此通信系统中:

  1. 信源:发送信息的来源,一般由文字、图像、语音组成。信源将信息转换成消息。
  2. 发送器:将消息转换成信号传输到信道上。
  3. 信道:信号在信道中传递,会被噪声干扰,噪声源根据不同的统计特征分为不同类型的噪声,例如噪声模型为高斯正态分布的白噪声。
  4. 接收器:将接受到的信号转换为消息。
  5. 信宿:将消息还原成信息:文字、图像等。

  我们在前面UART通信中知道了什么是奇偶校验:就是通过增加一位信号的冗余位来判断当前传输信号中1的个数,接收端在接收到信号时也通过奇偶校验位来判断当前接受到的信号是否受到了干扰。但是奇偶校验也有缺点:

  1. 就是只能检测当前信号传输中1位数据的错误,不能检测两位或者多位的错误;
  2. 只能检测出错误但是不能纠正错误。

  而汉明码简单理解就是升级版的奇偶校验位,他能够检测并且纠正1位信号的错误,能检测出两位的错误但是不能纠正,所以汉明码也叫汉明纠错码。

二、汉明码编码原理以及步骤

  汉明码通过在数据中插入冗余位来实现错误检测和纠正。 对与一个k位的数据插入r位的冗余位来组成汉明码,插入冗余位的位数需要满足公式:

2 r > = k + r + 1 2^r >= k + r + 1 2r>=k+r+1

  汉明在他的第一篇论文中给出的例子是:信息一共4位,增加l3位冗余位一共组7位编码,满足 2 3 > = 3 + 4 + 1 2^3 >= 3+4+1 23>=3+4+1,所以汉明码也叫74码。原理是使用简单的奇偶校验,再通过分组的方式进行编码,原理如下:
  假如一个4位信号data从高到低 = {d3,d2,d1,d0},需要增加3个冗余位 p2,p1,p0组成7位编码,冗余位的位置由 2 n 2^n 2n来确定,比如第一个冗余位p0的位置为 2 0 = 1 2^0=1 20=1,第二个冗余位p1的位置为 2 1 = 2 2^1=2 21=2,第三个冗余位p2的位置为 2 2 = 4 2^2=4 22=4等等以此类推。

  1. 第一步:确认编码后数据中信息位和冗余位的位置,根据上面冗余位的位置可知,冗余位为1,2,4,8等等,所以编码后的数据为:
编码后的位数 第7位第6位 第5位第4位第3位第2位第1位
原始数据位 d3 d2d1d0
冗余数据位 p2p1p0
  最终编码后的数据为 hanming = {d3,d2,d1,p2,d0,p1,p0}
  1. 第二步:将每个原始数据位的位置拆分成n个冗余位数据位的位置之和
  • 由上面表格可知:原始数据位的位置为7,6,5,3;冗余数据位的位置为4,2,1。
  • 数据位7 = 4 + 2 + 1,表示编码后的数据第7位由第4位p2,第2位p1和第1位p0冗余数据来校验;
  • 数据位6 = 4 + 2,表示编码后的数据第6位由第4位p2和第2位p1冗余数据来校验;
  • 数据位5 = 4 + 1,表示编码后的数据第5位由第4位p2和第1位p0冗余数据来校验;
  • 数据位3 = 2 + 1,表示编码后的数据第3位由第2位p1和第1位p0冗余数据来校验;
  1. 第三步:根据上面的拆解结果进行分组
  • 由上可知,第1位冗余位p0需要校验数据第7位,数据第5位,数据第3位;因此把(p0,d3,d1,d0)分成偶校验第一组;
  • 第2位冗余位p1需要校验数据第7位,数据第6位,数据第3位,因此把(p1,d3,d2,d0)分成偶校验第二组;
  • 第3位冗余位p2需要校验数据第7位,数据第6位,数据第5位,因此把(p2,d3,d2,d1)分成偶校验第三组;
       分组后的结果如下所示:
编码后的位数 第7位第6位 第5位第4位第3位第2位第1位
原始数据位 d3 d2d1d0
冗余数据位 p2p1p0
偶校验第0组d3 d1d0p0
偶校验第1组d3 d2d0p1
偶校验第2组d3 d2d1p2
  1. 第四步:根据各分组的偶校验确定p0,p1,p2的值
  • 在偶校验第0组中,如果(d3,d1,d0)中1的个数为偶数个,则p0=0,否则p0=1;
  • 在偶校验第1组中,如果(d3,d2,d0)中1的个数为偶数个,则p1=0,否则p1=1;
  • 在偶校验第2组中,如果(d3,d2,d1)中1的个数为偶数个,则p2=0,否则p2=1;

   举个例子:如果待发送的信息数据为{d3,d2,d1,d0}={1,1,0,1},填入表格中则为:

编码后的位数 第7位第6位 第5位第4位第3位第2位第1位
原始数据位 1 101
冗余数据位 p2p1p0
偶校验第0组1 01p0
偶校验第1组1 11p1
偶校验第2组1 10p2
  • 在偶校验第0组中,(d3,d1,d0)中1的个数为偶数个,所以p0=0;
  • 在偶校验第1组中,(d3,d2,d0)中1的个数为奇数个,所以p1=1;
  • 在偶校验第2组中,(d3,d2,d1)中1的个数为偶数个,所以p2=0;
  • 最终编码后的数据为{1,1,0,0,1,1,0}

三、汉明码纠错原理以及步骤

   由于偶校验分组中都可以发现这一组中奇数个错误,所以在汉明分组中的交集出就能指出错误的位置,如下图所示:

在这里插入图片描述
   例如上面的例子中,原始信息为{d3,d2,d1,d0}={1,1,0,1},经过汉明编码后变成为{1,1,0,0,1,1,0};如果传输过程中某一位发生了错误,如第4位被打反数据变成{1,1,0,1,1,1,0},接收方将收到数据后继续分组:

接受数据的位数 第7位第6位 第5位第4位第3位第2位第1位
接受数据位 d3 d2d1p2d0p1p0
接受数据位 1 101110
冗余数据位 p2p1p0
偶校验第0组1 010
偶校验第1组1 111
偶校验第2组1 101

   在偶校验第0组中,(d3,d1,d0)中1的个数为偶数个,接受到的p0=0,正确;
   在偶校验第1组中,(d3,d2,d0)中1的个数为奇数个,接受到的p1=1,正确;
   在偶校验第2组中,(d3,d2,d1)中1的个数为偶数个,接受到的p2=1,错误;

在这里插入图片描述
   如上所示,三个分组中只有偶校验第2组发生了错误,其它两组都是正确的,因此三个分组没有交集,错误的只有冗余位p2,原始数据位没有发生错误,因此恢复出来的原始数据就是{1,1,0,1},和发送的原始数据与一致。

   再用相同的例子:原始信息为{d3,d2,d1,d0}={1,1,0,1},经过汉明编码后变成为{1,1,0,0,1,1,0};如果传输过程中第5位发生了错误,接收到的信号为{1,1,1,0,1,1,0},接收方依然对其分组检验如下所示:

接受数据的位数 第7位第6位 第5位第4位第3位第2位第1位
接受数据位 d3 d2d1p2d0p1p0
接受数据位 1 110110
冗余数据位 p2p1p0
偶校验第0组1 110
偶校验第1组1 111
偶校验第2组1 110

   在偶校验第0组中,(d3,d1,d0)中1的个数为奇数个,接受到的p0=0,错误;
   在偶校验第1组中,(d3,d2,d0)中1的个数为奇数个,接受到的p1=1,正确;
   在偶校验第2组中,(d3,d2,d1)中1的个数为奇数个,接受到的p2=0,错误;

在这里插入图片描述
   如上分析所示,错误的是第0组和第2组,第一组正确;所以错误的位置为第0组和第2组的交集处 d1,然后接收方对其位置信号打反处理恢复为正确的信号{1,1,0,1}和原始发送的信息一致,其它位以此类推。

四、FPGA实现74汉明编码器

   我们先来实现一下4位数据编码成7位汉明码的过程;原理我们已经知道了,就是增加3位冗余位来组成新的7位数据;3个冗余位的计算过程我们也知道了,就是统计对应分组里面1的个数;我们直接开始仿真来看看编码器是否正确,仿真代码如下:

`timescale 1ns / 1ps
module tb_hanming_code_top();

    reg                                                 sys_clk ;
    reg                                                 sys_rst ;
    reg             [3:0]                               data_in ;
    reg                                                 data_valid  ;
    wire            [6:0]                               encode_data ;
    wire                                                encode_data_valid   ;
    reg             [6:0]                               hanming_data_in ;
    reg                                                 hanming_data_valid ;
    wire            [3:0]                               decode_data ;
    wire                                                decode_data_valid ;  

initial begin
    sys_clk = 0;
    sys_rst = 1;
    data_in = 0;
    data_valid = 0;
    #201;
    @(posedge sys_clk)  
    sys_rst = 0;
    #1000;
    forever begin
        @(posedge sys_clk)
        data_in <= {$random} % 16;
        data_valid <= 1'b1; 
    end    
    #100000;
    $stop;
end

always #5 sys_clk = ~sys_clk;

hanming_code_top u_hanming_code_top(
    .sys_clk             ( sys_clk             ),
    .sys_rst             ( sys_rst             ),
    .data_in             ( data_in             ),
    .data_valid          ( data_valid          ),
    .encode_data         ( encode_data         ),
    .encode_data_valid   ( encode_data_valid   ),
    .hanming_data_in     ( hanming_data_in     ),
    .hanming_data_valid  ( hanming_data_valid  ),
    .decode_data         ( decode_data         ),
    .decode_data_valid   ( decode_data_valid   )
);

endmodule

   我们直接生成4位的随机数给编码器,然后观察编码后的数据是否正确。

在这里插入图片描述
   第一个数据{0,1,0,0}经过编码后变成{0,1,0,1,0,1,0},我们手动算一下:

编码后的位数 第7位第6位 第5位第4位第3位第2位第1位
原始数据位 0 100
冗余数据位 p2p1p0
偶校验第0组0 00p0
偶校验第1组0 10p1
偶校验第2组0 10p2
  • 在偶校验第0组中,(d3,d1,d0)中1的个数为偶数个,所以p0=0;
  • 在偶校验第1组中,(d3,d2,d0)中1的个数为奇数个,所以p1=1;
  • 在偶校验第2组中,(d3,d2,d1)中1的个数为奇数个,所以p2=1;
  • 最终编码后的数据为{0,1,0,1,0,1,0}和我们编码器出来的一致,其他的也是一样的。

五、FPGA实现74汉明解码器

   解码器也是根据分组来寻找错误的交集来打反bit位,我们在仿真代码中,将编码后的数据直接接到解码的输入端口上:

`timescale 1ns / 1ps
module tb_hanming_code_top();

    reg                                                 sys_clk ;
    reg                                                 sys_rst ;
    reg             [3:0]                               data_in ;
    reg                                                 data_valid  ;
    wire            [6:0]                               encode_data ;
    wire                                                encode_data_valid   ;
    wire            [3:0]                               decode_data ;
    wire                                                decode_data_valid ;  

initial begin
    sys_clk = 0;
    sys_rst = 1;
    data_in = 0;
    data_valid = 0;
    #201;
    @(posedge sys_clk)  
    sys_rst = 0;
    #1000;
    forever begin
        @(posedge sys_clk)
        data_in <= {$random} % 16;
        data_valid <= 1'b1; 
    end    
    #100000;
    $stop;
end


always #5 sys_clk = ~sys_clk;

hanming_code_top u_hanming_code_top(
    .sys_clk             ( sys_clk             ),
    .sys_rst             ( sys_rst             ),
    .data_in             ( data_in             ),
    .data_valid          ( data_valid          ),
    .encode_data         ( encode_data         ),
    .encode_data_valid   ( encode_data_valid   ),
    .hanming_data_in     ( encode_data     ),
    .hanming_data_valid  ( encode_data_valid  ),
    .decode_data         ( decode_data         ),
    .decode_data_valid   ( decode_data_valid   )
);

endmodule

在这里插入图片描述
  打开仿真我们可以看到数据被正确的解码出来了,和原始的发送数据一致,接下来我们新增一个加噪声的模块,来对编码后的数据进行随机位取反,让后输入到解码模块里,看解码能否正确的解出原始数据,仿真代码如下:

`timescale 1ns / 1ps
module tb_hanming_code_top();

    reg                                                 sys_clk ;
    reg                                                 sys_rst ;
    reg             [3:0]                               data_in ;
    reg                                                 data_valid  ;
    wire            [6:0]                               encode_data ;
    wire                                                encode_data_valid   ;
    reg             [6:0]                               hanming_data_in ;
    reg                                                 hanming_data_valid ;
    wire            [3:0]                               decode_data ;
    wire                                                decode_data_valid ;  

initial begin
    sys_clk = 0;
    sys_rst = 1;
    data_in = 0;
    data_valid = 0;
    #201;
    @(posedge sys_clk)  
    sys_rst = 0;
    #1000;
    forever begin
        @(posedge sys_clk)
        data_in <= {$random} % 16;
        data_valid <= 1'b1; 
    end    
    #100000;
    $stop;
end

always #5 sys_clk = ~sys_clk;

integer i, j;
initial begin
    i <= 0;
    j <= 0;
    hanming_data_in <= 0;
    hanming_data_valid <= 0;
    forever begin
        @(posedge sys_clk) begin
            i <= {$random}%7;     //随机位数
        #1ns
        for (j=0 ; j<7 ; j = j +1) begin
            if((encode_data_valid == 1'b1)&&(i == j))begin
                hanming_data_in[j] <=  ~encode_data[j];
                hanming_data_valid <= 1;
            end
            else if(encode_data_valid == 1'b1)begin
                hanming_data_in[j] <=  encode_data[j];
                hanming_data_valid <= 1;
            end
            else begin
                hanming_data_in <= 0;
                hanming_data_valid <= 0;
            end
        end
    end
    end
end

hanming_code_top u_hanming_code_top(
    .sys_clk             ( sys_clk             ),
    .sys_rst             ( sys_rst             ),
    .data_in             ( data_in             ),
    .data_valid          ( data_valid          ),
    .encode_data         ( encode_data         ),
    .encode_data_valid   ( encode_data_valid   ),
    .hanming_data_in     ( hanming_data_in     ),
    .hanming_data_valid  ( hanming_data_valid  ),
    .decode_data         ( decode_data         ),
    .decode_data_valid   ( decode_data_valid   )
);

endmodule

在这里插入图片描述
  可以看到我们传输过程中模拟噪声,随机将一位的信息取反,解码器依然能正确的恢复出原始数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905858.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无人机光电识别跟踪算法!

一、算法概述 无人机光电识别跟踪算法结合了可见光和红外成像技术&#xff0c;通过光学系统收集目标的光学信息&#xff0c;并将其转换为电信号进行处理和分析。该算法能够实现对目标的快速、准确识别与追踪&#xff0c;极大提升了无人机在复杂环境下的作业能力和效率。 二、…

Ethernet 系列(6)-- 基础学习::OSI Model

&#xff08;写在前面&#xff1a;最近在学习车载以太网的知识&#xff0c;顺便记录一下知识点。&#xff09; OSI&#xff08;Open System Interconnect &#xff09;模型是一种网络通信框架&#xff0c;由国际标准化组织&#xff08;‌ISO&#xff09;在1985年提出&#xff0…

day15:shell基础

一&#xff0c;编程语法分类&#xff08;了解&#xff09; 编程范式&#xff1a; 面向过程&#xff1a;程序通过按步骤执行函数或过程完成任务&#xff0c;强调流程控制和函数调用&#xff0c;适合流程明确的任务&#xff0c;如 C。面向对象&#xff1a;通过“类”和“对象”封…

无人机测绘遥感技术算法概述!

一、数据采集算法 航线规划算法 根据测绘任务需求&#xff0c;利用地理信息系统&#xff08;GIS&#xff09;和遥感技术&#xff0c;对无人机进行航线规划。 考虑地形、气候、障碍物等因素&#xff0c;优化飞行路径&#xff0c;确保数据采集的完整性和准确性。 传感器控制算…

Pytest-Bdd-Playwright 系列教程(6):在测试步骤函数中设置别名数据共享

Pytest-Bdd-Playwright 系列教程&#xff08;6&#xff09;&#xff1a;在测试步骤函数中设置别名&数据共享 前言一、步骤别名二、特性文件三、测试脚本四、运行测试五、小测验总结 前言 有的时候&#xff0c;为了提高可读性&#xff0c;我们需要使用不同的名称来声明相同的…

HTML 分组标签与语义化应用:合理使用 <div>、<span> 和基础语义容器

文章目录 1. `<div>` 标签特点用途示例2. `<span>` 标签特点用途示例3. `<fieldset>` 标签特点用途示例4. `<section>` 标签特点用途示例5. `<article>` 标签特点用途示例总结HTML中的分组(容器)标签用于结构化内容,将页面元素组织成逻辑区域…

关于武汉芯景科技有限公司的马达驱动芯片AT6237开发指南(兼容DRV8837)

一、芯片引脚介绍 1.芯片引脚 二、系统结构图 三、功能描述 逻辑功能

Android View

前面我们了解了Android四大组件的工作流程&#xff0c;Android中还存在一个和四大组件地位相同的概念&#xff1a;View&#xff0c;用于向用户页面展示内容。我们经常使用的TextView、Button、ImageView控件等都继承于它&#xff0c;也会自定义View实现自定义效果。View类源码内…

谷歌插件开发学习指南

什么是谷歌插件 谷歌插件&#xff08;Chrome Extension&#xff09;是为谷歌浏览器&#xff08;Chrome&#xff09;开发的小程序&#xff0c;旨在增强浏览器的功能或用户体验。它们可以通过添加工具栏按钮、修改网页内容、集成其他服务等方式&#xff0c;实现各种功能&#xf…

linux命令行的艺术

文章目录 前言基础日常使用文件及数据处理系统调试单行脚本冷门但有用仅限 OS X 系统仅限 Windows 系统在 Windows 下获取 Unix 工具实用 Windows 命令行工具Cygwin 技巧 更多资源免责声明 熟练使用命令行是一种常常被忽视&#xff0c;或被认为难以掌握的技能&#xff0c;但实际…

Puppeteer 与浏览器版本兼容性:自动化测试的最佳实践

Puppeteer 支持的浏览器版本映射&#xff1a;从 v20.0.0 到 v23.6.0 自 Puppeteer v20.0.0 起&#xff0c;这个强大的自动化库开始支持与 Chrome 浏览器的无头模式和有头模式共享相同代码路径&#xff0c;为自动化测试带来了更多便利。从 v23.0.0 开始&#xff0c;Puppeteer 进…

知识管理新选择!本地大模型助手“知我AI”全功能解析

抖知书老师推荐&#xff1a; 随着人工智能技术的飞速发展&#xff0c;本地大模型知识管理工具逐渐成为提高工作效率的利器。今天&#xff0c;我要向大家介绍一款名为**“知我AI”**的本地知识管理助手&#xff0c;它以其独特的功能和优势&#xff0c;正在成为众多专业人士的新…

Banana Pi BPI-R3路由器开发板运行 OrayOS物联网系统

近日&#xff0c;Banana PI开发板宣布与贝锐达成战略合作&#xff0c;贝锐OrayOS现已成功适配Banana PI的BPI-R3型号&#xff0c;并计划进一步扩展硬件支持&#xff0c;包括目前Banana PI热销的BPI-R4、BPI-R3 Mini等更多型号。这一合作为用户提供了更广泛的开发板选择&#xf…

No.24 笔记 | WEB安全 - 任意文件包含漏洞 part 6

在 Web 安全领域中&#xff0c;任意文件包含漏洞是一种较为常见且具有潜在危险性的漏洞类型。本文将详细介绍任意文件包含漏洞的概念、原理、分类、利用方法以及防护措施&#xff0c;帮助新手小白更好地理解和防范这一漏洞。&#x1f603; 一、概念 包含的定义 开发人员为了提…

森利威尔SL2516D 耐压60V内置5V功率MOS 支持PWM LED恒流驱动器芯片

一、基本特性 型号&#xff1a;SL2516D封装&#xff1a;ESOP8工作频率&#xff1a;140kHz驱动MOS管&#xff1a;内置 二、电气特性 输入电压范围&#xff1a;8V~100V&#xff08;注意&#xff0c;虽然问题中提到耐压60V&#xff0c;但根据官方信息&#xff0c;其实际耐压范围…

Vscode配置CC++编程环境的使用体验优化和补充说明

文章目录 快速编译运行&#x1f47a;code runner插件方案Code Runner Configuration 直接配置 相关指令和快捷键默认task配置和取消默认 配置文件补充介绍(可选 推荐阅读)&#x1f60a;使用vscode预置变量和环境变量环境变量的使用使用环境变量的好处环境变量可能引起的问题 检…

Linux中rpm包和yum仓库介绍及入门配置

rpm包概述 RPM Package Manager,RPM包管理器 由红帽公司提出&#xff0c;适用于Rocky Linux、Redhat、SUSE等系列操作系统 建立集中数据库&#xff0c;记录软件包安装/卸载等变化信息&#xff0c;分析软件包依赖关系 RPM包 文件名特征 软件名-版本信息.操作系统.硬件架/构.r…

L 波段射频信号采集回放系统

L 波段采集回放系统是一套便携式模拟数字采集系统&#xff0c;该系统主要由射频输入模块、中频接收回放模块、FPGA 信号处理单元、服务器系统和存储单元等组成。 L 波段采集回放系统的功能主要用于对 950MHz〜2150MHz 模拟量射频信号的采集、存储记录与回放&#xff1b;采集与…

百度如何打造AI原生研发新范式?

&#x1f449;点击即可下载《百度AI原生研发新范式实践》资料 2024年10月23-25日&#xff0c;2024 NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。本届大会邀请了工业界和学术界的专家&#xff0c;优秀的工程师和产品经理&#xff0c;以及其它行…

Unity3D 开发教程:从入门到精通

Unity3D 开发教程&#xff1a;从入门到精通 Unity3D 是一款强大的跨平台游戏引擎&#xff0c;广泛应用于游戏开发、虚拟现实、增强现实等领域。本文将详细介绍 Unity3D 的基本概念、开发流程以及一些高级技巧&#xff0c;帮助你从零基础到掌握 Unity3D 开发。 目录 Unity3D…