文章目录

  • 汉明码
    • 定义
    • 校验位个数
    • 编码规则
    • 一个例子
      • 编码
      • 解码
    • C++实现
      • 功能编写
      • 测试结果
    • Verilog实现
      • .v功能代码
      • testbench
      • 波形

汉明码

定义

  • 在传输的信息流中插入验证码,侦测单一比特错误
  • 只能发现和修正一位错误,对于两位或两位以上的错误无法发现与修正

校验位个数

  • 2r ≥ k + r + 1
  • 其中:
    • k为数据位
    • r为校验位

编码规则

  • 在新的编码的2(k - 1)( k >= 0)位上填入0(即校验位),把新的编码的其余位把源码按原顺序填入
  • 校验位的编码方式为:
    • 第k位校验码从则从新的编码的第2(k - 1)位开始,每计算2(k - 1)位的异或,跳2(k - 1)位,再计算下一组2(k - 1)位的异或,填入2(k - 1)
    • 比如:
      • 第1位校验码位于新的编码的第1位(2 (1-1) == 1)(汉明码从1位开始),计算1,3,5,7,9,11,13,15,…位的异或,填入新的编码的第1位
      • 第2位校验码位于新的编码的第2位(2 (2-1) == 2),计算2,3,6,7,10,11,14,15,…位的异或,填入新的编码的第2位
      • 第3位校验码位于新的编码的第4位(2 (3-1) == 4),计算4,5,6,7,12,13,14,15,20,21,22,23,…位的异或,填入新的编码的第4位
      • 第4位校验码位于新的编码的第8位(2 (4-1) == 8),计算8-15,24-31,40-47,…位的异或,填入新的编码的第8位
      • 第5位校验码位于新的编码的第16位(2 (5-1) == 16),计算16-31,48-63,80-95,…位的异或,填入新的编码的第16位

一个例子

  • 以10101编码为例,创建一个汉明码编码的空间,并且需要将原本数据位的校验位放置于对应位置中
  • 计算校验位数
    • 23 < 5 + 3 + 1
    • 24 ≥ 5 + 4 + 1
    • r = 4
  • 数据位记为P1~P5 = 10101
  • 校验位记为C1~C4
  • 数据输出为:C1C2P1C3P2P3P4C4P5
编码
  • 计算校验位

    • C1 = P1 ^ P2 ^ P4 ^ P5 = 1 ^ 0 ^ 0 ^ 1 = 0
    • C2 = P1 ^ P3 ^ P4 = 1 ^ 1 ^ 0 = 0
    • C3 = P2 ^ P3 ^ P4 = 0 ^ 1 ^ 0 = 1
    • C4 = P5 = 1
  • 插入校验位
    • C1C2P1C3P2P3P4C4P5 = 001101011
解码
  • 假设收到的编码数据为:001101001
  • 计算校验位数
    • 23 < 5 + 3 + 1
    • 24 ≥ 5 + 4 + 1
    • r = 4
  • 2(k - 1)(k = 1, 2, 3, 4)为校验位位置
  • 校验
    • C1 ^ P1 ^ P2 ^ P4 ^ P5 = 0 ^ 1 ^ 0 ^ 0 ^ 1 = 0
    • C2 ^ P1 ^ P3 ^ P4 = 0 ^ 1 ^ 1 ^ 0 = 0
    • C3 ^ P2 ^ P3 ^ P4 = 1 ^ 0 ^ 1 ^ 0 = 0
    • C4 ^ P5 = 0 ^ 1 = 1
  • 将各校验结果逆序排列 = 2’b1000 = 1’d8
  • 则第8位出错,纠正后 = 001101001 -> 001101011

C++实现

功能编写
  • 计算编码校验位
// calculate the number of check digits for encode
auto cal(size_t sz) -> decltype(auto)
{decltype(sz) k = 0;decltype(sz) cur = 1;while (cur - 1 < sz + k){cur <<= 1;k++;}return k;
}
  • 编码
// encode
bool encode(const string &data, string &str)
{str.clear();auto check = cal(data.size());str.resize(data.size() + check);for (decltype(str.size()) i = 0, j = 0, p = 0; i != str.size(); i++){if ((i + 1) == pow(2, p) && p < check){str[i] = '0';p++;}else if (data[j] == '0' || data[j] == '1'){str[i] = data[j++];}else{return false;}}for (auto i = 0; i != check; i++){int count = 0, index = 1 << i;for (auto j = index - 1; j < str.size(); j += index){for (auto k = 0; k != index && j < str.size(); k++, j++){count ^= str[j] - '0';}str[index - 1] = '0' + count;}}return true;
}
  • 计算解码校验位
// calculate the number of check digits for decode
auto antical(size_t sz) -> decltype(auto)
{decltype(sz) k = 0;decltype(sz) cur = 1;while (cur < sz){cur <<= 1;k++;}return k;
}
  • 解码
// decode
auto decode(string &data, string &str) -> decltype(auto)
{data.clear();auto check = antical(str.size());data.resize(str.size() - check);decltype(data.size()) sum = 0;for (decltype(check) i = 0; i != check; i++){int pAnti = 0;decltype(check) index = 1 << i;for (decltype(str.size()) j = index - 1; j < str.size(); j += index){for (auto k = 0; k < index && j < str.size(); j++, k++){pAnti ^= str[j] - '0';}}sum += pAnti << i;}if (sum != 0){str[sum - 1] = (1 - (int)(str[sum - 1] - '0')) + '0';}for (decltype(str.size()) i = 0, j = 0, k = 0; i != str.size(); i++){if ((i + 1) == (1 << j) && j < check){j++;}else{data[k++] = str[i];}}return sum;
}
测试结果
int main()
{string source, dest;while (cin >> source){if (encode(source, dest)){cout << "source            : " << source << endl;cout << "dest              : " << dest << endl;}size_t index;cout << "input error index : ";cin >> index;auto check = dest.size();if (index != 0 && index <= dest.size()){dest[index - 1] = (1 - (int)(dest[index - 1] - '0')) + '0';}cout << "code              : " << dest << endl;auto ret = decode(source, dest);if (ret == 0){cout << "source            : " << source << endl;cout << "dest              : " << dest << endl;}else{cout << "error index       : " << ret << endl;cout << "corret source     : " << source << endl;cout << "corret dest       : " << dest << endl;}cout << endl;}return 0;
}
  • 结果

Verilog实现

.v功能代码
  • 编码
module ham_encoder(input  wire        clk,input  wire        rst_n,input  wire        data_v,input  wire [ 7:0] data_in,output reg         encode,output reg  [11:0] data_out
);always @ (posedge clk or negedge rst_n) beginif (!rst_n) beginencode <= 1'b0;end else beginencode <= 1'b1;end
endalways @ (posedge clk or negedge rst_n) beginif (!rst_n) begindata_out <= 12'b0;end else if (data_v) begindata_out[11:4] <= data_in[7:0];data_out[3]    <= data_in[7]^data_in[5]^data_in[3]^data_in[2];data_out[2]    <= data_in[7]^data_in[6]^data_in[4]^data_in[2]^data_in[1];data_out[1]    <= data_in[7]^data_in[6]^data_in[5]^data_in[3]^data_in[1]^data_in[0];data_out[0]    <= data_in[6]^data_in[4]^data_in[3]^data_in[0];end else begindata_out <= 12'b0;end
endendmodule
  • 解码
module   ham_decoder(input    wire              clk,input     wire              rst_n,input   wire            data_v,input    wire   [11:0] data_in,output reg   [ 7:0] data_out,output reg               decode
);wire [ 3:0] checkout;
wire [11:0] data;always @ (posedge clk or negedge rst_n) beginif(!rst_n) begin decode <= 1'd0;end else begindecode <= 1'b1;end
endassign checkout[3] = data_in[11]^data_in[ 9]^data_in[7]^data_in[6]^data_in[3];
assign checkout[2] = data_in[11]^data_in[10]^data_in[8]^data_in[6]^data_in[5]^data_in[2];
assign checkout[1] = data_in[11]^data_in[10]^data_in[9]^data_in[7]^data_in[5]^data_in[4]^data_in[1];
assign checkout[0] = data_in[10]^data_in[ 8]^data_in[7]^data_in[4]^data_in[0];assign   data[11] = data_in[11]^( checkout[3]& checkout[2]& checkout[1]&~checkout[0]);
assign  data[10] = data_in[10]^(~checkout[3]& checkout[2]& checkout[1]& checkout[0]);
assign  data[ 9] = data_in[ 9]^( checkout[3]&~checkout[2]& checkout[1]&~checkout[0]);
assign  data[ 8] = data_in[ 8]^(~checkout[3]& checkout[2]&~checkout[1]& checkout[0]);
assign  data[ 7] = data_in[ 7]^( checkout[3]&~checkout[2]& checkout[1]& checkout[0]);
assign  data[ 6] = data_in[ 6]^( checkout[3]& checkout[2]&~checkout[1]&~checkout[0]);
assign  data[ 5] = data_in[ 5]^(~checkout[3]& checkout[2]& checkout[1]&~checkout[0]);
assign  data[ 4] = data_in[ 4]^(~checkout[3]&~checkout[2]& checkout[1]& checkout[0]);
assign  data[ 3] = data_in[ 3]^( checkout[3]&~checkout[2]&~checkout[1]&~checkout[0]);
assign  data[ 2] = data_in[ 2]^(~checkout[3]& checkout[2]&~checkout[1]&~checkout[0]);
assign  data[ 1] = data_in[ 1]^(~checkout[3]&~checkout[2]& checkout[1]&~checkout[0]);
assign  data[ 0] = data_in[ 0]^(~checkout[3]&~checkout[2]&~checkout[1]& checkout[0]);always @(posedge clk or negedge rst_n) beginif (!rst_n) begindata_out<= 12'b0;end else if(decode) begindata_out <= data[11:4];end else begindata_out <= 12'b0;end
endendmodule
testbench
`timescale  1ns / 1ps
`include "ham_encoder.v"
`include "ham_decoder.v"module tb_ham;// edge_detect Parameters
parameter PERIOD  = 10;// Inputs
reg         clk                                  = 0 ;
reg         rst_n                                = 0 ;
reg         data_v                               = 0 ;
reg  [ 7:0] data_in                                  ;// Output
wire [11:0] encoder                                  ;
wire        encode                                   ;
wire [ 7:0] decoder                                  ;
wire        decode                                   ;initial beginforever begin#(PERIOD) clk = ~clk;end
endinitial begin#(PERIOD*2) rst_n = ~rst_n;
endinitial begin#(PERIOD*2)@ (posedge clk)data_in = 8'h35;data_v  = 1'b1;#(PERIOD*2)data_in = 8'h0;data_v  = 1'b0;endinitial
begin$dumpfile("./build/ham.vcd");$dumpvars;#1000$finish;
endham_encoder  u_ham_encoder (.clk                     ( clk                         ),.rst_n                   ( rst_n                       ),.data_v                  ( data_v                      ),.data_in                 ( data_in   [ 7:0]            ),.encode                  ( encode                      ),.data_out                ( encoder                     )
);wire [11:0] err_encoder;
assign err_encoder = {encoder[11:1], ~encoder[0]};ham_decoder  u_ham_decoder (.clk                     ( clk                         ),.rst_n                   ( rst_n                       ),.data_v                  ( encode                      ),.data_in                 ( err_encoder                 ),.data_out                ( decoder[ 7:0]               ),.decode                  ( decode                      )
);endmodule
波形

【Verilog】汉明码相关推荐

  1. Verilog与SystemVerilog编程陷阱:怎样避免101个常犯的编码错误

    这篇是计算机类的优质预售推荐>>>><Verilog与SystemVerilog编程陷阱:怎样避免101个常犯的编码错误> 编辑推荐 纠错式学习,从"陷阱 ...

  2. 芯片开发语言:Verilog 在左,Chisel 在右

    来源 | 老石谈芯 在最近召开的RISC-V中国峰会上,中科院计算所的包云岗研究员团队正式发布了名为"香山"的开源高性能处RISC-V处理器.前不久我有幸和包老师就这个事情做了一次 ...

  3. sublime Text3安装和verilog安装

    百度下载sublime text3,安装 百度:sublime text 3 Package Control安装步骤 (在sublime中安装package control) 到官网去下载Packag ...

  4. 关于Verilog HDL的一些技巧、易错、易忘点(不定期更新)

    本文记录一些关于Verilog HDL的一些技巧.易错.易忘点等(主要是语法上),一方面是方便自己忘记语法时进行查阅翻看,另一方面是分享给大家,如果有错的话,希望大家能够评论指出. 关键词: ·技巧篇 ...

  5. Verilog代码规范I

    Verilog代码规范I "规范"这问题 "规范"这个富含专业气息的词汇(个人感觉),其实规范这种东西,就是大家都约定熟成的东西,一旦你不遵守这个东西,专业人士 ...

  6. Verilog有符号数运算

    在数字电路中,出于应用的需要,我们可以使用无符号数,即包括0及整数的集合:也可以使用有符号数,即包括0和正负数的集合.在更加复杂的系统中,也许这两种类型的数,我们都会用到. 有符号数通常以2的补码形式 ...

  7. Vim之代码异步检测插件 ALE -- 实时检查verilog等代码的正确性

    Vim之代码异步检测插件 ALE 前言 知名的 vim 代码检测插件主要是两个 syntastic neomake ALE ALE 虽是后起之秀,但目前是功能最强大的一个 实时检测.为了让代码可以在编 ...

  8. gvim中进行verilog语言信号追踪、显示拓扑插件

    2019独角兽企业重金招聘Python工程师标准>>> 插件使用方法及功能: vtags 是一款在gvim下实现类似verdi的信号追踪.显示拓扑等功能的插件.vtags插件完全使用 ...

  9. (多图) 基于Verilog HDL的FIR数字滤波器设计与仿真

    引言:数字滤波器是语音与图像处理.模式识别.雷达信号处理.频谱分析等应用中的一种基本的处理部件,它能满足波器对幅度和相位特性的严格要求,避免模拟滤波器所无法克服的电压漂移.温度漂移和噪声等问题.有限冲 ...

最新文章

  1. 2019 年ML NLP领域十大研究热点
  2. 用Greasemonkey脚本收藏网站会员信息到本地
  3. http method
  4. 饥荒机器人怎么用避雷针充电_新款iPhone充电线怎么这么好看~安卓也可以用!...
  5. spring中bean的细节之三种创建Bean对象的方式
  6. 【Java必备资料包】
  7. 组播穿越MPLS ***+SSM
  8. 帝国列表页分开调取年份和月份单独调用的方法?
  9. Linux文件压缩,解压常用命令
  10. 如何用pdb命令调试python代码
  11. matlab axes坐标轴长度,[转载]Matlab 坐标轴(axes),数据提示(data
  12. RESTful Connector
  13. 多目标遗传优化算法nsga2[python源码实现]
  14. 《缠中说禅108课》59:图解分析示范四
  15. C#线性表约瑟夫环(Joseph Ring)
  16. 三创赛优秀作品_厉害了!珠海这所学校的大学生夺得“三创赛”全国总决赛一等奖...
  17. 年龄在线计算机,年龄计算器在线计算2021 抖音上很火的精确年龄岁数计算器查询 - 房贷计算器...
  18. 互联网访问检测服务器
  19. linux将目录路径加入环境变量中,如何添加路径到PATH环境变量
  20. 同态算法FHEW笔记

热门文章

  1. 骗取搜索引擎排名的黑帽SEO方法说明
  2. javascript深入理解js闭包(摘自网络)
  3. 快学Big Data -- Spark SQL总结(二十四)
  4. python进阶《面向对象编程》类和对象
  5. python中choices_Django之choices选项和富文本编辑器的使用详解
  6. 亲手搭建美团外卖、饿了么外卖红包公众号
  7. 从“十一五”到“十四五”国家四大区域经济板块发展战略
  8. 微信公众号图文排版?看这一篇就够了!
  9. 十日均线算法oracle,十日均线的操盘法
  10. Xilinx Jtag Access/svf文件/BSCANE2