General algorithm[edit]
The following general algorithm generates a single-error correcting (SEC) code for any number of bits.
- Number the bits starting from 1: bit 1, 2, 3, 4, 5, 6, 7, etc.
- Write the bit numbers in binary: 1, 10, 11, 100, 101, 110, 111, etc.
- All bit positions that are powers of two (have a single 1 bit in the binary form of their position) are parity bits: 1, 2, 4, 8, etc. (1, 10, 100, 1000)
- All other bit positions, with two or more 1 bits in the binary form of their position, are data bits.
- Each data bit is included in a unique set of 2 or more parity bits, as determined by the binary form of its bit position.
- Parity bit 1 covers all bit positions which have the least significant bit set: bit 1 (the parity bit itself), 3, 5, 7, 9, etc.
- Parity bit 2 covers all bit positions which have the second least significant bit set: bit 2 (the parity bit itself), 3, 6, 7, 10, 11, etc.
- Parity bit 4 covers all bit positions which have the third least significant bit set: bits 4–7, 12–15, 20–23, etc.
- Parity bit 8 covers all bit positions which have the fourth least significant bit set: bits 8–15, 24–31, 40–47, etc.
- In general each parity bit covers all bits where the bitwise AND of the parity position and the bit position is non-zero.
The form of the parity is irrelevant. Even parity is mathematically simpler, but there is no difference in practice.
This general rule can be shown visually:
Bit position | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | … | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Encoded data bits | p1 | p2 | d1 | p4 | d2 | d3 | d4 | p8 | d5 | d6 | d7 | d8 | d9 | d10 | d11 | p16 | d12 | d13 | d14 | d15 | ||
Parity bit coverage | p1 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | |||||||||||
p2 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ||||||||||||
p4 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | |||||||||||||
p8 | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ||||||||||||||
p16 | ![]() | ![]() | ![]() | ![]() | ![]() |
VHDL demo
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY HAMMING IS
PORT ( ENTRADA : IN STD_LOGIC_VECTOR(8 DOWNTO 1);
SAIDA : OUT STD_LOGIC_VECTOR(8 DOWNTO 1) );
END HAMMING;
ARCHITECTURE ARCH OF HAMMING IS
SIGNAL VERIFICADOR : STD_LOGIC_VECTOR(4 DOWNTO 1);
SIGNAL TRANSMISSOR : STD_LOGIC_VECTOR(12 DOWNTO 1);
COMPONENT HAMMING_SENDER
PORT (ENTRADA : IN STD_LOGIC_VECTOR(8 DOWNTO 1);
SAIDA : OUT STD_LOGIC_VECTOR(12 DOWNTO 1) );
END COMPONENT;
COMPONENT HAMMING_VERIF
PORT( ENTRADA : IN STD_LOGIC_VECTOR(12 DOWNTO 1);
VERIFICADOR : OUT STD_LOGIC_VECTOR(4 DOWNTO 1));
END COMPONENT;
COMPONENT HAMMING_RED
PORT (ENTRADA : IN STD_LOGIC_VECTOR(12 DOWNTO 1);
VERIFICADOR : IN STD_LOGIC_VECTOR(4 DOWNTO 1);
SAIDA : OUT STD_LOGIC_VECTOR(8 DOWNTO 1));
END COMPONENT;
BEGIN
ENVIO: HAMMING_SENDER PORT MAP(ENTRADA => ENTRADA, SAIDA => TRANSMISSOR);
VERIFICACAO: HAMMING_VERIF PORT MAP(ENTRADA => TRANSMISSOR, VERIFICADOR => VERIFICADOR);
REDUCAO_E_CORRECAO: HAMMING_RED PORT MAP(ENTRADA => TRANSMISSOR, VERIFICADOR => VERIFICADOR, SAIDA => SAIDA);
END ARCH;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY HAMMING_SENDER IS
PORT (ENTRADA : IN STD_LOGIC_VECTOR(8 DOWNTO 1);
SAIDA : OUT STD_LOGIC_VECTOR(12 DOWNTO 1) );
END HAMMING_SENDER;
ARCHITECTURE SENDER OF HAMMING_SENDER IS
BEGIN
-- PRIMEIRAMENTE COLOCO OS BITS DA MENSAGEM NA POSIÇÃO CERTA
SAIDA(3) <= ENTRADA(1);
SAIDA(5) <= ENTRADA(2);
SAIDA(6) <= ENTRADA(3);
SAIDA(7) <= ENTRADA(4);
SAIDA(9) <= ENTRADA(5);
SAIDA(10) <= ENTRADA(6);
SAIDA(11) <= ENTRADA(7);
SAIDA(12) <= ENTRADA(8);
-- AGORA CALCULO OS BITS DE PARIDADE
SAIDA(1) <= ENTRADA(1) XOR ENTRADA(2) XOR ENTRADA(4) XOR ENTRADA(5) XOR ENTRADA(7);
SAIDA(2) <= ENTRADA(1) XOR ENTRADA(3) XOR ENTRADA(4) XOR ENTRADA(6) XOR ENTRADA(7);
SAIDA(4) <= ENTRADA(2) XOR ENTRADA(3) XOR ENTRADA(4) XOR ENTRADA(8);
SAIDA(8) <= ENTRADA(5) XOR ENTRADA(6) XOR ENTRADA(7) XOR ENTRADA(8);
END SENDER;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY HAMMING_VERIF IS
PORT ( ENTRADA : IN STD_LOGIC_VECTOR(12 DOWNTO 1);
VERIFICADOR : OUT STD_LOGIC_VECTOR(4 DOWNTO 1) );
END HAMMING_VERIF;
ARCHITECTURE ARCH OF HAMMING_VERIF IS
BEGIN
VERIFICADOR(1) <= ENTRADA(1) XOR ENTRADA(3) XOR ENTRADA(5) XOR ENTRADA(7) XOR ENTRADA(9) XOR ENTRADA(11);
VERIFICADOR(2) <= ENTRADA(2) XOR ENTRADA(3) XOR ENTRADA(6) XOR ENTRADA(7) XOR ENTRADA(10) XOR ENTRADA(11);
VERIFICADOR(3) <= ENTRADA(4) XOR ENTRADA(5) XOR ENTRADA(6) XOR ENTRADA(7) XOR ENTRADA(12);
VERIFICADOR(4) <= ENTRADA(8) XOR ENTRADA(9) XOR ENTRADA(10) XOR ENTRADA(11) XOR ENTRADA(12);
END ARCH;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY HAMMING_RED IS
PORT (ENTRADA : IN STD_LOGIC_VECTOR(12 DOWNTO 1);
VERIFICADOR : IN STD_LOGIC_VECTOR(4 DOWNTO 1);
SAIDA : OUT STD_LOGIC_VECTOR(8 DOWNTO 1));
END HAMMING_RED;
ARCHITECTURE RED OF HAMMING_RED IS
BEGIN
SAIDA(1) <= NOT ENTRADA(3) WHEN VERIFICADOR = "0011" ELSE ENTRADA(3);
SAIDA(2) <= NOT ENTRADA(5) WHEN VERIFICADOR = "0101" ELSE ENTRADA(5);
SAIDA(3) <= NOT ENTRADA(6) WHEN VERIFICADOR = "0110" ELSE ENTRADA(6);
SAIDA(4) <= NOT ENTRADA(7) WHEN VERIFICADOR = "0111" ELSE ENTRADA(7);
SAIDA(5) <= NOT ENTRADA(9) WHEN VERIFICADOR = "1001" ELSE ENTRADA(9);
SAIDA(6) <= NOT ENTRADA(10) WHEN VERIFICADOR = "1010" ELSE ENTRADA(10);
SAIDA(7) <= NOT ENTRADA(11) WHEN VERIFICADOR = "1011" ELSE ENTRADA(11);
SAIDA(8) <= NOT ENTRADA(12) WHEN VERIFICADOR = "1100" ELSE ENTRADA(12);
END RED;