※ ※ ※ ※ ※ ※ ※ ※ ※
※
※
2007 级学生数字通信
※
※
原理课程设计
※
※
※ ※ ※ ※ ※ ※ ※ ※ ※
数字通信原理课程设计报告书
基于 VHDL 语言的(7,4)汉明码编译
课题名称
姓
学
名
号
码的设计
冯 煜
0712402-01
院、系、部
物理与电信工程系
专
业
指导教师
通信工程
曾专武
2010 年 1 月 11 日
一、 设计任务及要求
设计目的
掌握 Quartus Ⅱ设计软件中 VHDL 语言的编程方法,并且熟练运用 VHDL 语
言编写汉明码的编译码过程。熟悉汉明码的重要公式和基本概念。进一步掌握(7,
4)汉明码的编码和译码的原理和设计步骤。学会应用流程图来表示设计实体的
具体运行步骤。掌握运用 VHDL 语言对(7,4)汉明码的编译码的设计。
设计要求
通过应用硬件描述语言 VHDL,编写出(7,4)汉明码的编码和译码的程序,
并对编译码程序进行编译和仿真分析。通过运用相关工具画出(7,4)汉明码的
编译码流程图和仿真图,并对相关结果进行分析得出结论。
二、指导教师评语:
三、成绩
指导教师签名:
2010 年 1 月 11 日
指导教师签名:
2010 年 1 月 11 日
验收盖章
2010 年 1 月 11 日
基于 VHDL 语言的(7,4)汉明码编译码的设计
0712402*01 冯煜
一、设计目的
学会运用 Quartus Ⅱ软件中 VHDL 语言编写(7,4)汉明码的编译码的程序。
熟悉汉明码的重要公式和基本概念。进一步掌握(7,4)汉明码的编码和译码的
原理和设计步骤。学会应用流程图来表示设计实体的具体运行步骤。掌握运用
VHDL 语言对(7,4)汉明码的编译码的设计。
二、设计要求及原理
通过应用硬件描述语言 VHDL,编写出(7,4)汉明码的编码和译码的程序,
并对编译码程序进行编译和仿真分析。通过运用相关工具画出(7,4)汉明码的
编译码流程图和仿真图,并对相关结果进行分析。
三、设计步骤
1.(7,4)汉明码的编码的原理和程序设计
汉明码是在原编码的基础上附加一部分代码,使其满足纠错码的条件。它属
于线性分组码,由于汉明码的抗干扰能力较强,至今仍是应用比较广泛的一类码。
在(n,k)汉明码中,(n-k)个附加的监督码元是由信息码元的线性运算产生的。
码长为 n,信息码元长度为 k,2k 个码组构成 n 维线性空间中的一个 k 维子空间,
编码的实质就是要在 n 维空间中,找出一组长为 n 的 k 个线性无关的矢量,使
得每个码组 a 都可以表示为 k 个矢量的线性组合,其中,a i∈{0,1},i=0,1,
a0]是带编码信息的信息组,G 是一个 k*n 阶
⋯ ,k-1。由此,[an-1 an-2 ⋯
矩阵,G 称为(n,k)汉明码的生成矩阵。当 G 确定以后,编码的问题也就解决了。
根据监督码元是有信息码元的线性运算产生的关系可知,监督码(a0,a1,a2)
满足以下关系式:
a
a
6
a
a
a
3
a
2
a
a
1
a
0
3
5
a
a
5
a
4
4
6
6
即可算出三位监督位,再与信息位结合,可得到(7,4)汉明码
然后根据(7,4)汉明码的编码编码原理,画出程序设计的流程图:
图 1.1 编码流程图
然后根据流程图进行编写程序。首先,输入信息码 a3a2a1a0,即使用语句:
port(a:in std_logic_vector(3 downto 0);就可以得到监督位与信息码之间的
对应关系,使用异或运算,即:
b(2)<=a(3) xor a(2) xor a(1);
b(1)<=a(3) xor a(2) xor a(0);
b(0)<=a(3) xor a(1) xor a(0);
最后,将算好的监督位与原来输入的信息码一起输出,这样,编码程序就算完成
了。
2.(7,4)汉明码的译码的原理和程序设计
若码长为 n,信息位数为 k,则监督位数为 r=n-k。如果希望用 r
个监督位构造出 r 个监督关系式来指示一位错码的 n 种可能位置,则
要求 2 r-1>=n 或 2 r>=k+r+1。设(7,4)汉明码中,n=7,k=4,为了
纠错一位码。用 a6a5 ⋯ a0 表示要进行译码的码元,用 S2、S1 和 S0
表示监督关系式的校正子,则 S0、S1 和 S2 的值与错码对应关系可
以规定如表 2-3 所示,由表可知,当一位错码的位置在 a2、a4、a5
或 a6 时,校正子为 1;否则为 0,可推知,a2,a4,a5 或 a6 4 个码
元构成偶数监督关系:
S2=a6⊕a5⊕a4⊕a2
S1=a6⊕a5⊕a3⊕a1
S0=a6⊕a4⊕a3⊕a0
接收到每个码组之后,先按照式以上三个等式计算出 S2,S1,S0,
再按照表 1 判断错码情况。例如接收码组为 0000011,可计算出 S1=0,
S2=1,S3=1。由于 S1S2S3=011,可知 a3 位出错,只需对其取反即可。
表 1 (7,4)码校正子与错误图样的对应关系
S
E
序
号
0
1
2
3
4
5
6
7
错误码位
无错码
a0
a1
a2
a3
a4
a5
a6
e6 e5 e4 e3 e2 e1 e0
0 0 0 0 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 1 0
0 0 0 0 1 0 0
0 0 0 1 0 0 0
0 0 1 0 0 0 0
0 1 0 0 0 0 0
1 0 0 0 0 0 0
S0 S1 S2
0 0 0
0 0 1
0 1 0
1 0 0
0 1 1
1 0 1
1 1 0
1 1 1
然后根据(7,4)汉明码的译码原理,画出 程序设计的流程图:
图 1.2 译码流程图
然后根据流程图编写编码程序。首先,输入 7 位汉明码 a6a5a4a3a2a1a0,
用语句来:port(a:in std_logic_vector(6 downto 0)来实现。然后,根据这 7
位码 a6a5a4a3a2a1a0,计算校正子 s2s1s0 的值,可知校正子 S 与(7,4)汉明码
各位之间的关系,即:
ss(2):=a(6) xor a(5) xor a(3) xor a(2);
ss(1):=a(6) xor a(4) xor a(3) xor a(1);
ss(0):=a(5) xor a(4) xor a(3) xor a(0);
第三,要判定校正子与 0 的关系,使用 if 语句,若等于 0,则表示没有错
误;若不为 0,则表示其中有一位出错。才用 case 语句,编写程序如下:
when "001" =>bb(0):= not bb(0);n<="000";
when "010" =>bb(1):= not bb(1);n<="001";
when "100" =>bb(2):=not
bb(2);n<="010";
when "011" =>bb(3):=not
bb(3);n<="011";
when "101" =>bb(4):=not
bb(4);n<="100";
when "110" =>bb(5):=not
bb(5);n<="101";
when "111" =>bb(6):=not
bb(6);n<="110";
上述程序中,bb 是变量,存放的是输入 7 位汉明码 a6a5a4a3a2a1a0,当
S="001",时,表示 a0 出错,则只需将这一位的值取反,然后再送给输出。a1、
a2、a3、a4、a5、a6 出错的原理也是一样的。最后,将没有错误的(7,4)汉明
码或已经纠正 1 个错误的(7,4)汉明码输出,这样译码程序就完成了。为了方便
阅读波形,加入输出了校正子 S 和错误位数 N。若第 0 位(a0)出错,则 N 输出
0,依次类推;若无错,则输出 7。
四、程序设计
1.(7,4)汉明码的编码程序:
library ieee;
use ieee.std_logic_1164.all;
entity bm is
port(a:in std_logic_vector(3 downto 0);
b:out std_logic_vector(6 downto 0));
end ;
architecture one of bm is
begin
b(6)<=a(3);
b(5)<=a(2);
b(4)<=a(1);
b(3)<=a(0);
b(2)<=a(3) xor a(2) xor a(1);
b(1)<=a(3) xor a(2) xor a(0);
b(0)<=a(3) xor a(1) xor a(0);
end;
2.(7,4)汉明码的译码程序:
library ieee;
use ieee.std_logic_1164.all;
entity ym is
port(a:in std_logic_vector(6 downto 0);
s:out std_logic_vector(2 downto 0);
b:out std_logic_vector(3 downto 0);
c:out std_logic_vector(2 downto 0));
end ;
architecture one of ym is
begin
process(a)
variable ss:std_logic_vector(2 downto 0);
variable bb:std_logic_vector(6 downto 0);
begin
ss(2):=a(6) xor a(5) xor a(4) xor a(2);
ss(1):=a(6) xor a(5) xor a(3) xor a(1);
ss(0):=a(6) xor a(4) xor a(3) xor a(0);
bb:=a;
if ss> "000"
then
case ss is