Adedamola
Adedamola

Reputation: 3

VHDL Hamming code for correcting error

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

Answers (3)

JHBonarius
JHBonarius

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

Paebbels
Paebbels

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

Kevin Thibedeau
Kevin Thibedeau

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

Related Questions