1 //
2 // Hamming(12,8) code test
3 //
4 // Tests syndrome decoding
5 //
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include "liquid.internal.h"
11 
print_bitstring(unsigned int _x,unsigned int _n)12 void print_bitstring(unsigned int _x,
13                      unsigned int _n)
14 {
15     unsigned int i;
16     for (i=0; i<_n; i++)
17         printf("%1u", (_x >> (_n-i-1)) & 1);
18 }
19 
20 unsigned char hamming128_P[4] = {
21         0xda,   // 1101 1010
22         0xb6,   // 1011 0110
23         0x71,   // 0111 0001
24         0x0f};  // 0000 1111
25 
main(int argc,char * argv[])26 int main(int argc, char*argv[])
27 {
28     // ...
29     unsigned int sym_org = 0x21;    // original symbol
30     unsigned int sym_enc;           // encoded symbol
31     unsigned int e = 0x001;         // error vector
32     unsigned int sym_rec;           // received symbol
33     unsigned int sym_dec;           // decoded symbol
34 
35     unsigned int i;
36 
37     // encode symbol
38     unsigned int p0 = liquid_c_ones[sym_org & hamming128_P[0]] & 0x01;
39     unsigned int p1 = liquid_c_ones[sym_org & hamming128_P[1]] & 0x01;
40     unsigned int p2 = liquid_c_ones[sym_org & hamming128_P[2]] & 0x01;
41     unsigned int p3 = liquid_c_ones[sym_org & hamming128_P[3]] & 0x01;
42     unsigned int parity = (p0 << 3) | (p1 << 2) | (p2 << 1) | (p3 << 0);
43     sym_enc = (parity << 8) | sym_org;
44 
45     // received symbol (add error)
46     sym_rec = sym_enc ^ e;
47 
48     //
49     // decode symbol
50     //
51     sym_dec = sym_rec & 0xff;
52     unsigned int e_hat = 0x000;
53     // compute syndrome vector; s = r*H^T = ( H*r^T )^T
54     unsigned int s = 0x0;   // 4 bits resolution
55     for (i=0; i<4; i++) {
56         s <<= 1;
57 
58         unsigned int p =
59             ( (sym_rec & (1<<(12-i-1))) ? 1 : 0 ) +
60             liquid_c_ones[sym_rec & hamming128_P[i]];
61 
62         s |= p & 0x01;
63     }
64     // compute weight of s
65     unsigned int ws = liquid_count_ones(s);
66     printf("    syndrome    :           "); print_bitstring(s,  4); printf(" (%u)\n", ws);
67 
68     if (ws == 0) {
69         printf("no errors detected\n");
70     } else {
71         // estimate error location
72         unsigned int e_test = 0x001;
73         int syndrome_match = 0;
74 
75         // TODO : these can be pre-computed
76         unsigned int n;
77         for (n=0; n<12; n++) {
78             // compute syndrome
79             unsigned int s_hat = 0;
80 
81             for (i=0; i<4; i++) {
82                 s_hat <<= 1;
83 
84                 unsigned int p =
85                     ( (e_test & (1<<(12-i-1))) ? 1 : 0 ) +
86                     liquid_c_ones[e_test & hamming128_P[i]];
87 
88                 s_hat |= p & 0x01;
89             }
90 
91             // print results
92             //printf("e_test:"); print_bitstring(e_test, 72);
93             printf("    %2u e = ", n);
94             print_bitstring(e_test,12);
95             printf(" s = ");
96             print_bitstring(s_hat,4);
97             if (s == s_hat) printf(" *");
98             printf("\n");
99 
100             if (s == s_hat) {
101                 e_hat = e_test;
102                 syndrome_match = 1;
103             }
104 
105             // shift e_test
106             e_test <<= 1;
107         }
108 
109         // apply error correction and return
110         if (syndrome_match)
111             sym_dec = (sym_rec ^ e_hat) & 0xff;
112     }
113 
114 
115     // print results
116     printf("    sym org     :       "); print_bitstring(sym_org,  8); printf("\n");
117     printf("    sym enc     :   ");     print_bitstring(sym_enc, 12); printf("\n");
118     printf("    sym rec     :   ");     print_bitstring(sym_rec, 12); printf("\n");
119     printf("    sym dec     :       "); print_bitstring(sym_dec,  8); printf("\n");
120 
121     // print number of bit errors
122     printf("    bit errors  :   %u\n", count_bit_errors(sym_org, sym_dec));
123 
124     return 0;
125 }
126 
127 
128