architecture RTL of Hamming4 is

 begin

   process (DataOut,DataIn,CheckIn)
      variable PgenL:         Std_Logic_Vector(0 to 3);  -- Generated parity
      variable SyndL:         Std_Logic_Vector(0 to 3);  -- Syndrome
      variable FlipL:         Std_Logic_Vector(0 to 3);  -- Bits to invert
      variable ChipL:         Std_Logic_Vector(0 to 3);  -- Errors in parity

     begin

      -- Check bit generator
      PgenL(0) := not (DataIn(0) xor DataIn(1) xor DataIn(2));
      PgenL(1) :=      DataIn(0) xor DataIn(1) xor DataIn(3);
      PgenL(2) := not (DataIn(0) xor DataIn(2) xor DataIn(3));
      PgenL(3) :=      DataIn(1) xor DataIn(2) xor DataIn(3);

      -- Syndrome bit generator
      SyndL(0) := PgenL(0) xor not CheckIn(0);
      SyndL(1) := PgenL(1) xor not CheckIn(1);
      SyndL(2) := PgenL(2) xor     CheckIn(2);
      SyndL(3) := PgenL(3) xor     CheckIn(3);

      -- Bit corrector
      if SyndL="1110" then
         FlipL(0) := '1';
      else
         FlipL(0) := '0';
      end if;
      if SyndL="1101" then
         FlipL(1) := '1';
      else
         FlipL(1) := '0';
      end if;
      if SyndL="1011" then
         FlipL(2) := '1';
      else
         FlipL(2) := '0';
      end if;
      if SyndL="0111" then
         FlipL(3) := '1';
      else
         FlipL(3) := '0';
      end if;

      -- Single error in check bits
      if SyndL="0001" then
         ChipL(0) := '1';
      else
         ChipL(0) := '0';
      end if;
      if SyndL="0010" then
         ChipL(1) := '1';
      else
         ChipL(1) := '0';
      end if;
      if SyndL="0100" then
         ChipL(2) := '1';
      else
         ChipL(2) := '0';
      end if;
      if SyndL="1000" then
         ChipL(3) := '1';
      else
         ChipL(3) := '0';
      end if;

      -- Corrected data
      DataCorr(0) < = DataIn(0) xor FlipL(0);
      DataCorr(1) < = DataIn(1) xor FlipL(1);
      DataCorr(2) < = DataIn(2) xor FlipL(2);
      DataCorr(3) < = DataIn(3) xor FlipL(3);

      -- Check bits
      CheckOut(0) < = not (not (DataOut(0) xor DataOut(1) xor DataOut(2)));
      CheckOut(1) < = not (     DataOut(0) xor DataOut(1) xor DataOut(3));
      CheckOut(2) < =     (not (DataOut(0) xor DataOut(2) xor DataOut(3)));
      CheckOut(3) < =     (     DataOut(1) xor DataOut(2) xor DataOut(3));

      -- Single correctable error flag
      SingleErr   < = (FlipL(0) or FlipL(1) or FlipL(2) or FlipL(3)) xor
                     (ChipL(0) or ChipL(1) or ChipL(2) or ChipL(3));

      -- double correctable error flag
      DoubleErr   < = '0';

      -- Uncorrectable error flag
      if SyndL="0011" or SyndL="0101" or
         SyndL="0110" or SyndL="1001" or
         SyndL="1010" or SyndL="1100" or
         SyndL="1111" then
         MultipleErr    < = '1';
      else
         MultipleErr    < = '0';
      end if;
   end process;
 end RTL;