Reputation: 3
Please help me with checking this code for correcting error using hamming code in VHDL. I have being able to detect error but not correct it. I have three modules my encoder, decoder and an error injector. I have a feeling it my decoder that is having issues. Below is my decoder code
library ieee;
use ieee.std_logic_1164.all;
entity hamdec8 is
port(
datain: in std_logic_vector (7 downto 0);
parin : in std_logic_vector(4 downto 0);
Dataout : out std_logic_vector(7 downto 0);
Parout : out std_logic_vector(4 downto 0);
NE : out std_logic;
DED : out std_logic;
SEC : out std_logic
);
Constant MaskP1 : std_logic_vector(7 downto 0) := "01011011";
Constant MaskP2 : std_logic_vector(7 downto 0) := "01101101";
Constant MaskP3 : std_logic_vector(7 downto 0) := "10001110";
Constant MaskP4 : std_logic_vector(7 downto 0) := "11110000";
end hamdec8;
architecture beh of hamdec8 is
signal synd : std_logic_vector(4 downto 1);
signal P0 : std_logic;
signal din1, din2, din3, din4 : std_logic_vector(7 downto 0); --to hold datain AND maskp
begin
process(Datain, Parin)
begin
NE <= '1';
DED <= '0';
SEC <= '0';
Dataout <= Datain;
Parout <= Parin;
P0 <= (Parin(0) XOR Parin(1) XOR Parin(2) XOR Parin(3) XOR
Parin(4) XOR Datain(0) XOR Datain(1) XOR Datain(2) XOR
Datain(3) XOR Datain(4) XOR Datain(5) XOR Datain(6) XOR
Datain(7));
din1 <= Datain AND MaskP1;
Synd(1) <= din1(0) XOR din1(1) XOR din1(2) XOR din1(3) XOR
din1(4) XOR din1(5) XOR din1(6) XOR din1(7) XOR Parin(1);
din2 <= Datain AND MaskP2;
Synd(2) <= din2(0) XOR din2(1) XOR din2(2) XOR din2(3) XOR
din2(4) XOR din2(5) XOR din2(6) XOR din2(7) XOR Parin(2);
din3 <= Datain AND MaskP3;
Synd(3) <= din3(0) XOR din3(1) XOR din3(2) XOR din3(3) XOR
din3(4) XOR din3(5) XOR din3(6) XOR din3(7) XOR Parin(3);
din4 <= Datain AND MaskP4;
Synd(4) <= din4(0) XOR din4(1) XOR din4(2) XOR din4(3) XOR
din4(4) XOR din4(5) XOR din4(6) XOR din4(7) XOR Parin(4);
if (synd = "0000") then
IF (P0 = '0') then
--Dataout <= Datain;
--NE <= '1';
--DED <= '0';
--SEC <= '0';
--Parout <= Parin;
null;
elsif (P0 = '1') then --single error
NE <= '0';
DED <= '0';
SEC <= '1';
case synd is
when "0000" => Parout(0) <= NOT Parin(0);
when "0001" => Parout(1) <= NOT Parin(1);
when "0010" => Parout(2) <= NOT Parin(2);
when "0011" => Dataout(0) <= NOT Datain(0);
when "0100" => Parout(3) <= NOT parin(3);
when "0101" => Dataout(1) <= NOT Datain(1);
when "0110" => Dataout(2) <= NOT Datain(2);
when "0111" => Dataout(3) <= NOT Datain(3);
when "1000" => parout(4) <= parin(4);
when "1001" => Dataout(4) <= NOT Datain(4);
when "1010" => Dataout(5) <= NOT Datain(5);
when "1011" => Dataout(6) <= NOT Datain(6);
when "1100" => Dataout(7) <= NOT Datain(7);
when others =>
Parout <= parin;
Dataout <= Datain;
end case;
Dataout <= "00000000";
Parout <= "00000";
end if;
elsif (P0 = '0') then
if (synd /= "0000") then
NE <= '0';
DED <= '1';
SEC <= '0';
Dataout <= "00000000";
Parout <= "00000";
end if;
end if;
end process;
end beh;
Thank you
Upvotes: 0
Views: 7428
Reputation: 11271
What's up with this code?
IF (P0 = '0') then
-- commented out stuff
[...]
null;
elsif (P0 = '1') then --single error
[...]
end if;
Why not just use:
if p0 = '1' then
[...]
end if;
or at least
if p0 = '0' then
[stuff for when p0 is '0']
else
[stuff for when p0 is not '0']
end if;
Upvotes: 0
Reputation: 16231
Your signals P0
, synd
, din1
, din2
, din3
, din4
should be declared as variables in the process or you should extract the xor calculation from process.
Second variant with extracted xor calculation, extended sensitivity list and fixed code indentation:
library ieee;
use ieee.std_logic_1164.all;
entity hamdec8 is
port (
datain: in std_logic_vector (7 downto 0);
parin : in std_logic_vector(4 downto 0);
Dataout : out std_logic_vector(7 downto 0);
Parout : out std_logic_vector(4 downto 0);
NE : out std_logic;
DED : out std_logic;
SEC : out std_logic
);
end hamdec8;
architecture beh of hamdec8 is
Constant MaskP1 : std_logic_vector(7 downto 0) := "01011011";
Constant MaskP2 : std_logic_vector(7 downto 0) := "01101101";
Constant MaskP3 : std_logic_vector(7 downto 0) := "10001110";
Constant MaskP4 : std_logic_vector(7 downto 0) := "11110000";
signal synd : std_logic_vector(4 downto 1);
signal P0 : std_logic;
signal din1, din2, din3, din4 : std_logic_vector(7 downto 0); --to hold datain AND maskp
begin
P0 <= Parin(0) XOR Parin(1) XOR Parin(2) XOR Parin(3) XOR Parin(4) XOR
Datain(0) XOR Datain(1) XOR Datain(2) XOR Datain(3) XOR Datain(4) XOR
Datain(5) XOR Datain(6) XOR Datain(7);
din1 <= Datain AND MaskP1;
din2 <= Datain AND MaskP2;
din3 <= Datain AND MaskP3;
din4 <= Datain AND MaskP4;
Synd(1) <= din1(0) XOR din1(1) XOR din1(2) XOR din1(3) XOR
din1(4) XOR din1(5) XOR din1(6) XOR din1(7) XOR Parin(1);
Synd(2) <= din2(0) XOR din2(1) XOR din2(2) XOR din2(3) XOR
din2(4) XOR din2(5) XOR din2(6) XOR din2(7) XOR Parin(2);
Synd(3) <= din3(0) XOR din3(1) XOR din3(2) XOR din3(3) XOR
din3(4) XOR din3(5) XOR din3(6) XOR din3(7) XOR Parin(3);
Synd(4) <= din4(0) XOR din4(1) XOR din4(2) XOR din4(3) XOR
din4(4) XOR din4(5) XOR din4(6) XOR din4(7) XOR Parin(4);
process(Datain, Parin, synd, P0)
begin
NE <= '1';
DED <= '0';
SEC <= '0';
Dataout <= Datain;
Parout <= Parin;
if (synd = "0000") then
IF (P0 = '0') then
--Dataout <= Datain;
--NE <= '1';
--DED <= '0';
--SEC <= '0';
--Parout <= Parin;
null;
elsif (P0 = '1') then --single error
NE <= '0';
DED <= '0';
SEC <= '1';
case synd is
when "0000" => Parout(0) <= NOT Parin(0);
when "0001" => Parout(1) <= NOT Parin(1);
when "0010" => Parout(2) <= NOT Parin(2);
when "0011" => Dataout(0) <= NOT Datain(0);
when "0100" => Parout(3) <= NOT parin(3);
when "0101" => Dataout(1) <= NOT Datain(1);
when "0110" => Dataout(2) <= NOT Datain(2);
when "0111" => Dataout(3) <= NOT Datain(3);
when "1000" => parout(4) <= parin(4);
when "1001" => Dataout(4) <= NOT Datain(4);
when "1010" => Dataout(5) <= NOT Datain(5);
when "1011" => Dataout(6) <= NOT Datain(6);
when "1100" => Dataout(7) <= NOT Datain(7);
when others => null;
end case;
--Dataout <= "00000000"; -- these lines override all calculations
--Parout <= "00000"; -- from previous case statement
end if;
elsif (P0 = '0') then
if (synd /= "0000") then
NE <= '0';
DED <= '1';
SEC <= '0';
Dataout <= "00000000";
Parout <= "00000";
end if;
end if;
end process;
end beh;
Upvotes: 1
Reputation: 3421
The correction logic implemented in the case statement is only reached when the syndrome is "0000"
and the overall parity is '1'
. That doesn't cover all the other possible syndrome values. The indentation of the single-error elsif
makes this confusing. You need to rework the nested if
statements so that correction is applied for all syndromes.
Upvotes: 1