FPGA设计与应用 (7, 4)汉明编译码实验报告
班级:1105103 姓名:郭诚 学号:1110510304 日期:2014年10月30日
实验性质:验证性 开课单位:电信院 一、实验目的
实验类型:必做 学时:2学时
1、了解线性分组码的基本原理; 2、掌握汉明码的编码和译码方法;
3、掌握利用串口通信配合进行编解码测试的方法; 二、实验准备(1分)
2.1 (7, 4)汉明码的编译码基本原理 答:1.编码原理
(7, 4)汉明码每组码元有7位,其中有4个信息位,3个监督位。设每组码元中的信息位为C6, C5, C4和C3,监督位为C2, C1和C0,那么监督位可根据下列线性方程求得:
C2C6C4C3C1C6C5C4C0C5C4C3
其一致监督矩阵H和生成矩阵G为
1H1010G00011100110010111001000110100011010111001101
[C6C5C4C3]G[C6C5C4C3C2C1C0],可实现编码,再在最后
即HC=0,以及
一位加0即可形成8位的码元。
2.译码原理
假设接收到的码字为R[R6R5R4R3R2R1R0],伴随校验子为
R6R51011100R4S1STHRT1110010R3S2 0111001R2S3R1R0得到校验子后,通过校验子得到正确的信息位和监督位。然后根据图样来校正错误,码校正子与错误图样的对应关系表,如图所示:
错误码位 无错误 C0 C1 C2 C3 C4 C5 C6 校验子 000 001 010 100 101 111 011 110 错误图样 0000000 0000001 0000010 0000100 0001000 0010000 0100000 1000000 2.2 (7, 4)汉明码编码程序的仿真验证
答:编码程序的仿真分析如下:
学号最后一位为4,输入的数据位0100。编码后输出数据为46H,即:01000110,其对应的数码管7段码显示的码字为:
0100——>1100110, 0110——>1111101。 2.3 (7, 4)汉明码解码程序的仿真验证
答:解码程序的译码仿真如下,学号最后一位为4,故输入码字为46H:
三、代码及测试
3.1 (7, 4)汉明码的编译码程序(3分) library ieee;
use ieee.std_logic_11.all; use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity gcreceive is port(
gc_rxd : in std_logic; gc_clk_11m5: in std_logic;
gc_rxd_ena : out std_logic:='0';
gc_rxd_data: out std_logic_vector(7 downto 0) ); end gcreceive;
architecture behave of gcreceive is
type gc_rxd_state is (gc_rxd_idle, gc_rxd_work, gc_rxd_stop);
signal gc_current_state : gc_rxd_state;
signal gc_data : std_logic_vector(7 downto 0) := (others => '0');
begin
process(gc_clk_11m5)
variable count_h : integer := 0;
variable count_l : integer := 0; variable count_all : integer := 0; variable num_gc_data : integer := 0;
begin
if (rising_edge(gc_clk_11m5)) then
case gc_current_state is
when gc_rxd_idle =>
count_all := count_all + 1; if(gc_rxd = '0') then
count_l:= count_l + 1;
end if;
if(count_all =100) then
if(count_l>70) then
gc_current_state <= gc_rxd_work; count_all := 0; num_gc_data := 0; count_l := 0; count_h := 0; gc_rxd_ena<='0';
end if; count_all:=0;
end if;
when gc_rxd_work =>
count_all := count_all + 1; if(gc_rxd = '0') then
count_l := count_l + 1;
else
count_h := count_h + 1;
end if;
if(count_all = 100) then
if(count_l > 70) then
gc_data(num_gc_data) <= '0';
end if;
if(count_h > 70) then
gc_data(num_gc_data) <= '1';
end if; count_l :=0; count_h := 0; count_all := 0;
num_gc_data := num_gc_data + 1; if(num_gc_data = 8) then
gc_current_state <= gc_rxd_stop; gc_rxd_data<=gc_data; gc_rxd_ena<='1';
else
gc_current_state <= gc_rxd_work;
end if;
end if;
when gc_rxd_stop =>
if(gc_rxd = '0') then
gc_current_state <= gc_rxd_idle; count_all:=1; count_l:=1;
end if;
end case;
end if;
end process;
end behave;
译码以及纠错的程序为: library ieee;
use ieee.std_logic_11.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;
entity gcyima is
port(gc_clk_50m : in std_logic;
gc_rxd_data: in std_logic_vector(7 downto 0); gc_clk_11m5: in std_logic; gc_rxd_ena : in std_logic;
gc_seg : out std_logic_vector(6 downto 0);
gc_seg_s : out std_logic_vector(3 downto 0):= (others=>'0'));
end gcyima;
architecture behave of gcyima is
signal gc_data,gc_data2 : std_logic_vector(7 downto 0) := (others => '0'); signal gc_clk_100 : std_logic;
signal gc_count : std_logic_vector(12 downto 0); signal gc_s : std_logic_vector(1 downto 0); signal gc_m : std_logic_vector(3 downto 0);
begin
process(gc_clk_50m) begin
if gc_clk_50m'event and gc_clk_50m='1' then
if gc_count<250000 then
gc_count<=gc_count+1; gc_clk_100<=gc_clk_100;
else
gc_count <= (others=>'0'); gc_clk_100<=not gc_clk_100;
end if;
end if;
end process;
process(gc_clk_11m5)
variable s1,s2,s3: std_logic;
variable s : std_logic_vector(2 downto 0);
begin
if (gc_rxd_ena='1') then
gc_data<=gc_rxd_data;
end if;
s1:=gc_data(7) xor gc_data(5) xor gc_data(4) xor gc_data(3); s2:=gc_data(7) xor gc_data(6) xor gc_data(5) xor gc_data(2); s3:=gc_data(6) xor gc_data(5) xor gc_data(4) xor gc_data(1); s:=s1&s2&s3; case s is
when
\"000\"=>gc_data2<=gc_data(7)&gc_data(6)&gc_data(5)&gc_data(4)&gc_data(3)&gc_data(2)&gc_data(1)&gc_data(0);
when
\"001\"=>gc_data2<=gc_data(7)&gc_data(6)&gc_data(5)&gc_data(4)&gc_data(3)&gc_data(2)&(not gc_data(1))&gc_data(0);
when
\"010\"=>gc_data2<=gc_data(7)&gc_data(6)&gc_data(5)&gc_data(4)&gc_data(3)&(not gc_data(2))&gc_data(1)&gc_data(0);
when
\"011\"=>gc_data2<=gc_data(7)&(not
gc_data(6))&gc_data(5)&gc_data(4)&gc_data(3)&gc_data(2)&gc_data(1)&gc_data(0);
when
\"100\"=>gc_data2<=gc_data(7)&gc_data(6)&gc_data(5)&gc_data(4)&(not gc_data(3))&gc_data(2)&gc_data(1)&gc_data(0);
when \"101\"=>gc_data2<=gc_data(7)&gc_data(6)&gc_data(5)&(not
gc_data(4))&gc_data(3)&gc_data(2)&gc_data(1)&gc_data(0);
when
\"110\"=>gc_data2<=(not
gc_data(7))&gc_data(6)&gc_data(5)&gc_data(4)&gc_data(3)&gc_data(2)&gc_data(1)&gc_data(0);
when
\"111\"=>gc_data2<=gc_data(7)&gc_data(6)&(not
gc_data(5))&gc_data(4)&gc_data(3)&gc_data(2)&gc_data(1)&gc_data(0);
when others => null;
end case;
end process;
process(gc_clk_100) begin
if gc_clk_100'event and gc_clk_100 = '1' then
case gc_s is
when \"00\" => gc_seg_s <=\"0001\";gc_m <= gc_data2(3
downto 0);gc_s <= \"01\";
when \"01\" => gc_seg_s <=\"0010\";gc_m <= downto 4);gc_s <= \"10\";
when \"10\" => gc_seg_s <=\"0100\";gc_m <= downto 0);gc_s <= \"11\";
when \"11\" => gc_seg_s <=\"1000\";gc_m <= downto 4);gc_s <= \"00\";
when others => null;
end case;
end if;
end process;
process(gc_m) begin case gc_m is when \"0000\" => gc_seg <= \"0111111\"; when \"0001\" => gc_seg <= \"0000110\"; when \"0010\" => gc_seg <= \"1011011\"; when \"0011\" => gc_seg <= \"1001111\"; when \"0100\" => gc_seg <= \"1100110\"; when \"0101\" => gc_seg <= \"1101101\"; when \"0110\" => gc_seg <= \"1111101\"; when \"0111\" => gc_seg <= \"0000111\";
when \"1000\" => gc_seg <= \"1111111\";
gc_data2(7
gc_data(3
gc_data(7
when \"1001\" => gc_seg <= \"1101111\"; when \"1010\" => gc_seg <= \"1110111\"; when \"1011\" => gc_seg <= \"1111100\"; when \"1100\" => gc_seg <= \"0111001\"; when \"1101\" => gc_seg <= \"1011110\"; when \"1110\" => gc_seg <= \"1111001\"; when \"1111\" => gc_seg <= \"1110001\"; when others => null;
end case;
end process;
end behave;
3.2 (7, 4)汉明码的SignalTap II测试结果(1分) 答:其SignalTap的截图为:
四、论述
给出在信息出现1个比特错误时,如何进行正确的解码,举例说明。例子应和自己学号的最后两位相关。规则为:把自己学号的最后一位作为信息位,首先给出该信息位对应的正确汉明码字;然后依据自己学号的倒数第二位(假设为数字j),来对正确的汉明码字的第j位取反(最高位设为第0位),得到错误的汉明码字。并解释该错误汉明码的解码过程。例如学号最后两位为15,该学号最后一位(值为5)所对应的汉明码为5CH;用学号的倒数第二位(值为1)将该码字的第1位取反,即得到错误码字DCH。给出该错误码字的解码过程及分析。(1分)
答:学号为04,则4对应的汉明码为46H。正确的码字为:0100 0110。 第0位取反,得错误的码字为:1100 0110(C6H)。
由错误码元得到的校验子矩阵为:
R6R51011100R4S11STHRT1110010R3S21
0111001R2S30R1R0校验子为110,由下表可知错误码元为C6位,也即最高位错误。 错误码位 无错误 C0 C1 C2 C3 C4 C5 C6
将错误码(11000110)最高位取反,即可得正确的码字为:01000110,从而完成了纠一位错的功能。
校验子 000 001 010 100 101 111 011 110 错误图样 0000000 0000001 0000010 0000100 0001000 0010000 0100000 1000000