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