├── Makefile ├── README.md ├── bch_decoder.c ├── bch_encoder.c ├── bch_encoder_decoder.pdf ├── bch_global.c ├── bug_data_pattern ├── data_codeword.txt ├── data_error.txt ├── data_generator.c ├── data_in.txt ├── data_out.txt ├── error.c ├── release_notes └── test_script.sh /Makefile: -------------------------------------------------------------------------------- 1 | # objects = data_generator.o bch_encoder.o error.o bch_decoder.o 2 | 3 | CC = gcc 4 | 5 | all: data bch_encoder error bch_decoder 6 | 7 | data: data_generator.o 8 | $(CC) -o data_gen data_generator.o -lm 9 | 10 | bch_encoder: bch_encoder.o 11 | $(CC) -o bch_encoder bch_encoder.o -lm 12 | 13 | error: error.o 14 | $(CC) -o error error.o -lm 15 | 16 | bch_decoder: bch_decoder.o 17 | $(CC) -o bch_decoder bch_decoder.o -lm 18 | 19 | .PHONY : clean 20 | clean : 21 | -rm -f data_gen bch_encoder error bch_decoder *.o 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BCH Encoder and Decoder 2 | This is a BCH encoder/decoder for NAND flash based on the code from Micron. 3 | -------------------------------------------------------------------------------- /bch_decoder.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File Name: bch_decoder.c 4 | * Revision: 2.0 5 | * Date: March, 2007 6 | * Email: nandsupport@micron.com 7 | * Company: Micron Technology, Inc. 8 | * 9 | * Description: Micron NAND BCH Decoder 10 | * 11 | * References: 12 | * 1. Error Control Coding, Lin & Costello, 2nd Ed., 2004 13 | * 2. Error Control Codes, Blahut, 1983 14 | ** 15 | * Disclaimer This software code and all associated documentation, comments or other 16 | * of Warranty: information (collectively "Software") is provided "AS IS" without 17 | * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY 18 | * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT 21 | * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE 22 | * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. 23 | * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR 24 | * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, 25 | * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE 26 | * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, 27 | * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, 28 | * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, 29 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, 30 | * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE 31 | * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 32 | * DAMAGES. Because some jurisdictions prohibit the exclusion or 33 | * limitation of liability for consequential or incidental damages, the 34 | * above limitation may not apply to you. 35 | * 36 | * Copyright 2007 Micron Technology, Inc. All rights reserved. 37 | * 38 | * Rev Author Date Changes 39 | * --- --------------- ---------- ------------------------------- 40 | * 1.0 ZS 08/07/2006 Initial release 41 | * 2.0 PF 03/05/2007 Fixed bug that caused some codewords 42 | * to not be corrected 43 | * 44 | * 45 | /*******************************************************************************/ 46 | 47 | #include "bch_global.c" 48 | 49 | int bb[rr_max] ; // Syndrome polynomial 50 | int s[rr_max]; // Syndrome values 51 | int syn_error; // Syndrome error indicator 52 | int count; // Number of errors 53 | int location[tt_max]; // Error location 54 | int ttx2; // 2t 55 | int decode_flag; // Decoding indicator 56 | 57 | void parallel_syndrome() { 58 | /* Parallel computation of 2t syndromes. 59 | * Use the same lookahead matrix T_G_R of parallel computation of parity check bits. 60 | * The incoming streams are fed into registers from left hand 61 | */ 62 | int i, j, iii, Temp, bb_temp[rr_max] ; 63 | int loop_count ; 64 | 65 | // Determine the number of loops required for parallelism. 66 | loop_count = ceil(nn_shorten / (double)Parallel) ; 67 | 68 | // Serial to parallel data conversion 69 | for (i = 0; i < Parallel; i++) 70 | for (j = 0; j < loop_count; j++) 71 | if (i + j * Parallel < nn_shorten) 72 | data_p[i][j] = recd[i + j * Parallel]; 73 | else 74 | data_p[i][j] = 0; 75 | 76 | // Initialize the parity bits. 77 | for (i = 0; i < rr; i++) 78 | bb[i] = 0; 79 | 80 | // Compute syndrome polynomial: S(x) = C(x) mod g(x) 81 | // S(t) = T_G_R S(t-1) + R(t) 82 | // Ref: L&C, pp. 225, Fig. 6.11 83 | for (iii = loop_count - 1; iii >= 0; iii--) { 84 | for (i = 0; i < rr; i++) { 85 | Temp = 0; 86 | for (j = 0; j < rr; j++) 87 | if (bb[j] !=0 && T_G_R[i][j] != 0) 88 | Temp ^= 1 ; 89 | bb_temp[i] = Temp; 90 | } 91 | 92 | for (i = 0; i < rr; i++) 93 | bb[i] = bb_temp[i]; 94 | 95 | for (i = 0; i < Parallel; i++) 96 | bb[i] = bb[i] ^ data_p[i][iii]; 97 | } 98 | 99 | // Computation 2t syndromes based on S(x) 100 | // Odd syndromes 101 | syn_error = 0 ; 102 | for (i = 1; i <= ttx2 - 1; i = i+2) { 103 | s[i] = 0 ; 104 | for (j = 0; j < rr; j++) 105 | if (bb[j] != 0) 106 | s[i] ^= alpha_to[(index_of[bb[j]] + i*j) % nn] ; 107 | if (s[i] != 0) 108 | syn_error = 1 ; // set flag if non-zero syndrome => error 109 | } 110 | 111 | // Even syndrome = (Odd syndrome) ** 2 112 | for (i = 2; i <= ttx2; i = i + 2) { 113 | j = i / 2; 114 | if (s[j] == 0) 115 | s[i] = 0; 116 | else 117 | s[i] = alpha_to[(2 * index_of[s[j]]) % nn]; 118 | } 119 | 120 | if (Verbose) { 121 | fprintf(stdout, "# The syndrome from parallel decoder is:\n") ; 122 | for (i = 1; i <= ttx2; i++) 123 | fprintf(stdout, " %4d (%4d) == 0x%04x (0x%x)\n", s[i],index_of[s[i]],s[i], index_of[s[i]]) ; 124 | fprintf(stdout, "\n\n") ; 125 | } 126 | } 127 | 128 | void decode_bch() { 129 | register int i, j, elp_sum ; 130 | int L[ttx2+3]; // Degree of ELP 131 | int u_L[ttx2+3]; // Difference between step number and the degree of ELP 132 | int reg[tt+3]; // Register state 133 | int elp[ttx2+4][ttx2+4]; // Error locator polynomial (ELP) 134 | int desc[ttx2+4]; // Discrepancy 'mu'th discrepancy 135 | int u; // u = 'mu' + 1 and u ranges from -1 to 2*t (see L&C) 136 | int q; // 137 | 138 | parallel_syndrome() ; 139 | 140 | if (!syn_error) { 141 | decode_flag = 1 ; // No errors 142 | count = 0 ; 143 | } 144 | else { 145 | // Having errors, begin decoding procedure 146 | // Simplified Berlekamp-Massey Algorithm for Binary BCH codes 147 | // Ref: Blahut, pp.191, Chapter 7.6 148 | // Ref: L&C, pp.212, Chapter 6.4 149 | // 150 | // Following the terminology of Lin and Costello's book: 151 | // desc[u] is the 'mu'th discrepancy, where 152 | // u='mu'+1 and 153 | // 'mu' (the Greek letter!) is the step number ranging 154 | // from -1 to 2*t (see L&C) 155 | // l[u] is the degree of the elp at that step, and 156 | // u_L[u] is the difference between the step number 157 | // and the degree of the elp. 158 | 159 | if (Verbose) fprintf(stdout,"Beginning Berlekamp loop\n"); 160 | 161 | // initialise table entries 162 | for (i = 1; i <= ttx2; i++) 163 | s[i] = index_of[s[i]]; 164 | 165 | desc[0] = 0; /* index form */ 166 | desc[1] = s[1]; /* index form */ 167 | elp[0][0] = 1; /* polynomial form */ 168 | elp[1][0] = 1; /* polynomial form */ 169 | //elp[2][0] = 1; /* polynomial form */ 170 | for (i = 1; i < ttx2; i++) { 171 | elp[0][i] = 0; /* polynomial form */ 172 | elp[1][i] = 0; /* polynomial form */ 173 | //elp[2][i] = 0; /* polynomial form */ 174 | } 175 | L[0] = 0; 176 | L[1] = 0; 177 | //L[2] = 0; 178 | u_L[0] = -1; 179 | u_L[1] = 0; 180 | //u_L[2] = 0; 181 | u = -1; 182 | 183 | do { 184 | // even loops always produce no discrepany so they can be skipped 185 | u = u + 2; 186 | if (Verbose) fprintf(stdout,"Loop %d:\n", u); 187 | if (Verbose) fprintf(stdout," desc[%d] = %x\n", u, desc[u]); 188 | if (desc[u] == -1) { 189 | L[u + 2] = L[u]; 190 | for (i = 0; i <= L[u]; i++) 191 | elp[u + 2][i] = elp[u][i]; 192 | } 193 | else { 194 | // search for words with greatest u_L[q] for which desc[q]!=0 195 | q = u - 2; 196 | if (q<0) q=0; 197 | // Look for first non-zero desc[q] 198 | while ((desc[q] == -1) && (q > 0)) 199 | q=q-2; 200 | if (q < 0) q = 0; 201 | 202 | // Find q such that desc[u]!=0 and u_L[q] is maximum 203 | if (q > 0) { 204 | j = q; 205 | do { 206 | j=j-2; 207 | if (j < 0) j = 0; 208 | if ((desc[j] != -1) && (u_L[q] < u_L[j])) 209 | q = j; 210 | } while (j > 0); 211 | } 212 | 213 | // store degree of new elp polynomial 214 | if (L[u] > L[q] + u - q) 215 | L[u + 2] = L[u]; 216 | else 217 | L[u + 2] = L[q] + u - q; 218 | 219 | // Form new elp(x) 220 | for (i = 0; i < ttx2; i++) 221 | elp[u + 2][i] = 0; 222 | for (i = 0; i <= L[q]; i++) 223 | if (elp[q][i] != 0) 224 | elp[u + 2][i + u - q] = alpha_to[(desc[u] + nn - desc[q] + index_of[elp[q][i]]) % nn]; 225 | for (i = 0; i <= L[u]; i++) 226 | elp[u + 2][i] ^= elp[u][i]; 227 | 228 | } 229 | u_L[u + 2] = u+1 - L[u + 2]; 230 | 231 | // Form (u+2)th discrepancy. No discrepancy computed on last iteration 232 | if (u < ttx2) { 233 | if (s[u + 2] != -1) 234 | desc[u + 2] = alpha_to[s[u + 2]]; 235 | else 236 | desc[u + 2] = 0; 237 | 238 | for (i = 1; i <= L[u + 2]; i++) 239 | if ((s[u + 2 - i] != -1) && (elp[u + 2][i] != 0)) 240 | desc[u + 2] ^= alpha_to[(s[u + 2 - i] + index_of[elp[u + 2][i]]) % nn]; 241 | // put desc[u+2] into index form 242 | desc[u + 2] = index_of[desc[u + 2]]; 243 | 244 | } 245 | 246 | if (Verbose) { 247 | fprintf(stdout," deg(elp) = %2d --> elp(%2d):", L[u], u); 248 | for (i=0; i<=L[u]; i++) 249 | fprintf(stdout," 0x%x", elp[u][i]); 250 | fprintf(stdout,"\n"); 251 | fprintf(stdout," deg(elp) = %2d --> elp(%2d):", L[u+2], u+2); 252 | for (i=0; i<=L[u+2]; i++) 253 | fprintf(stdout," 0x%x", elp[u+2][i]); 254 | fprintf(stdout,"\n"); 255 | fprintf(stdout," u_L[%2d] = %2d\n", u, u_L[u]); 256 | fprintf(stdout," u_L[%2d] = %2d\n", u+2, u_L[u+2]); 257 | } 258 | 259 | } while ((u < (ttx2-1)) && (L[u + 2] <= tt)); 260 | if (Verbose) fprintf(stdout,"\n"); 261 | u=u+2; 262 | L[ttx2-1] = L[u]; 263 | 264 | if (L[ttx2-1] > tt) 265 | decode_flag = 0; 266 | else { 267 | // Chien's search to find roots of the error location polynomial 268 | // Ref: L&C pp.216, Fig.6.1 269 | if (Verbose) fprintf(stdout,"Chien Search: L[%d]=%d=%x\n", ttx2-1,L[ttx2-1],L[ttx2-1]); 270 | if (Verbose) fprintf(stdout,"Sigma(x) = \n"); 271 | 272 | if (Verbose) 273 | for (i = 0; i <= L[u]; i++) 274 | if (elp[u][i] != 0) 275 | fprintf(stdout," %4d (%4d)\n", elp[u][i], index_of[elp[u][i]]); 276 | else 277 | fprintf(stdout," 0\n"); 278 | 279 | for (i = 1; i <= L[ttx2-1]; i++) { 280 | reg[i] = index_of[elp[u][i]]; 281 | if (Verbose) fprintf(stdout," reg[%d]=%d=%x\n", i,reg[i],reg[i]); 282 | } 283 | count = 0 ; 284 | // Begin chien search 285 | for (i = 1; i <= nn; i++) { 286 | elp_sum = 1 ; 287 | for (j = 1; j <= L[ttx2-1]; j++) 288 | if (reg[j] != -1) { 289 | reg[j] = (reg[j] + j) % nn ; 290 | elp_sum ^= alpha_to[reg[j]] ; 291 | } 292 | 293 | // store root and error location number indices 294 | if (!elp_sum) { 295 | location[count] = nn - i ; 296 | if (Verbose) fprintf(stdout,"count: %d location: %d L[ttx2-1] %d\n", 297 | count,location[count],L[ttx2-1]); 298 | count++ ; 299 | } 300 | } 301 | 302 | // Number of roots = degree of elp hence <= tt errors 303 | if (count == L[ttx2-1]) { 304 | decode_flag = 1 ; 305 | // Correct errors by flipping the error bit 306 | for (i = 0; i < L[ttx2-1]; i++) 307 | recd[location[i]] ^= 1 ; 308 | } 309 | // Number of roots != degree of ELP => >tt errors and cannot solve 310 | else 311 | decode_flag = 0 ; 312 | } 313 | } 314 | } 315 | 316 | int main(int argc, char** argv) 317 | { int i, j ; 318 | int Help ; 319 | int Input_kk, Output_Syndrome ; // Input & Output switch 320 | int in_count, in_v, in_codeword; // Input statistics 321 | int decode_success, decode_fail; // Decoding statistics 322 | int code_success[kk_max], code_fail[kk_max]; // Decoded and failed words 323 | int codeword[kk_max], recd_data[kk_max], recd_parity[kk_max] ; 324 | char in_char; 325 | 326 | fprintf(stderr, "# Binary BCH decoder. Use -h for details.\n\n"); 327 | 328 | Verbose = 0; 329 | Input_kk = 0; 330 | Help = 0; 331 | mm = df_m; 332 | tt = df_t; 333 | Parallel = df_p; 334 | decode_success = 0; 335 | decode_fail = 0; 336 | for (i=1; i < argc;i++) { 337 | if (argv[i][0] == '-') { 338 | switch (argv[i][1]) { 339 | case 'm': mm = atoi(argv[++i]); 340 | break; 341 | case 't': tt = atoi(argv[++i]); 342 | break; 343 | case 'p': Parallel = atoi(argv[++i]); 344 | break; 345 | case 'k': kk_shorten = atoi(argv[++i]); 346 | Input_kk = 1; 347 | if (kk_shorten % 4 != 0) { 348 | fprintf(stderr, "### k must divide 4.\n\n"); 349 | Help = 1; 350 | } 351 | break; 352 | case 's': Output_Syndrome = 1; 353 | break; 354 | case 'v': Verbose = 1; 355 | break; 356 | default: Help = 1; 357 | } 358 | } 359 | else 360 | Help = 1; 361 | } 362 | 363 | if (Help == 1) { 364 | fprintf(stdout,"# Usage %s: BCH decoder\n",argv[0]); 365 | fprintf(stdout," -h: This help message\n"); 366 | fprintf(stdout," -m : Galois field, GF, for code. Code length is 2^-1.\n"); 367 | fprintf(stdout," The default value is %d for a code length %d. If the parameter is\n", df_m, (int)pow(2,df_m) - 1); 368 | fprintf(stdout," set to 0, the program will estimate the value based upon the values\n"); 369 | fprintf(stdout," chosen for k and t.\n"); 370 | fprintf(stdout," -t : Correction power of the code. Default = %d\n", df_t); 371 | fprintf(stdout," -k : Number of data bits to be encoded. Must divide 4.\n"); 372 | fprintf(stdout," The default value is the maximum supported by the code which\n"); 373 | fprintf(stdout," depends upon the field (-m) and the correction (-t) chosen.\n"); 374 | fprintf(stdout," -p : Parallelism in decoder. Does not effect results but\n"); 375 | fprintf(stdout," does change the algorithm used to generate them. Default = %d\n", df_p); 376 | fprintf(stdout," -s Syndrome output after the decoded data. Default disabled. \n"); 377 | fprintf(stdout," -v Verbose mode. Output detailed information, such as encoded codeword,\n"); 378 | fprintf(stdout," received codeword and decoded codeword. Default disabled. \n"); 379 | fprintf(stdout," : character string to decode in hex format. All other \n"); 380 | fprintf(stdout," characters are ignored. Comments are enclosed in brackets: { }.\n"); 381 | fprintf(stdout," The hex values are converted to binary and taken \n"); 382 | fprintf(stdout," at a time.\n"); 383 | fprintf(stdout," : resulting decoded character string in hex format.\n"); 384 | fprintf(stdout," : information about the decode process as well as error messages.\n"); 385 | } 386 | else { 387 | nn = (int)pow(2, mm) - 1; 388 | nn_shorten = nn; 389 | 390 | // generate the Galois Field GF(2**mm) 391 | generate_gf() ; 392 | 393 | // Compute the generator polynomial and lookahead matrix for BCH code 394 | gen_poly() ; 395 | 396 | // Check if code is shortened 397 | if (Input_kk == 1) 398 | nn_shorten = kk_shorten + rr ; 399 | else { 400 | kk_shorten = nn_shorten - rr ; 401 | // Make the shortened length divide 4 402 | kk_shorten = kk_shorten - kk_shorten % 4 ; 403 | nn_shorten = kk_shorten + rr ; 404 | } 405 | ttx2 = 2 * tt ; 406 | 407 | fprintf(stdout, "{# (m = %d, n = %d, k = %d, t = %d) Binary BCH code.}\n\n", mm, nn_shorten, kk_shorten, tt) ; 408 | 409 | // Set input data. 410 | in_count = 0; 411 | in_codeword = 0; 412 | in_char = getchar(); 413 | while (in_char != EOF) { 414 | if (in_char=='{') { 415 | while ((in_char != EOF) && ((char)in_char != '}')) 416 | in_char = getchar(); 417 | } 418 | in_v = hextoint(in_char); 419 | if (in_v != -1) { 420 | for (i = 3; i >= 0; i--) { 421 | if ((int)pow(2,i) & in_v) 422 | codeword[in_count] = 1 ; 423 | else 424 | codeword[in_count] = 0 ; 425 | in_count++; 426 | } 427 | } 428 | if (in_count == ceil(nn_shorten / (double)4) * 4) { 429 | in_codeword++ ; 430 | // Parity check bits 431 | for (j = kk_shorten; j < nn_shorten; j++) 432 | recd[j - kk_shorten] = codeword[j] ; 433 | // Data bits 434 | for (j = 0; j < kk_shorten; j++) 435 | recd[j + rr] = codeword[j] ; 436 | 437 | decode_bch() ; 438 | 439 | if ( decode_flag == 1 ) { 440 | decode_success++ ; 441 | code_success[decode_success] = in_codeword; 442 | if (count == 0) 443 | fprintf(stdout, "{ Codeword %d: No errors.}\n", in_codeword) ; 444 | else { 445 | fprintf(stdout, "{ Codeword %d: %d errors found at location:", in_codeword, count) ; 446 | for (i = count - 1; i >= 0 ; i--) { 447 | // Convert error location from systematic form to storage form 448 | if (location[i] >= rr) 449 | location[i] = location[i] - rr; 450 | else 451 | location[i] = location[i] + kk_shorten; 452 | 453 | fprintf(stdout, " %d", location[i]) ; 454 | } 455 | fprintf(stdout, "}"); 456 | 457 | printf("\n"); 458 | } 459 | } 460 | else { 461 | decode_fail++ ; 462 | code_fail[decode_fail] = in_codeword; 463 | fprintf(stdout, "{ Codeword %d: Unable to decode!}", in_codeword) ; 464 | printf("\n"); 465 | } 466 | // Convert decoded data into information data and parity checks 467 | for (i = 0; i < kk_shorten; i++) 468 | recd_data[i] = recd[i + rr]; 469 | for (i = 0; i < rr; i++) 470 | recd_parity[i] = recd[i]; 471 | print_hex_low(kk_shorten, recd_data, stdout); 472 | if (Output_Syndrome == 1) { 473 | fprintf(stdout, " "); 474 | print_hex_low(rr, recd_parity, stdout); 475 | if (Verbose) fprintf(stdout,"rr: %d\n",rr); 476 | } 477 | fprintf(stdout, "\n\n"); 478 | in_count = 0; 479 | } 480 | in_char = getchar(); 481 | } 482 | 483 | fprintf(stdout, "{### %d codewords received.}\n", in_codeword) ; 484 | fprintf(stdout, "{@@@ %d codewords are decoded successfully:}\n{", decode_success) ; 485 | for (i = 1; i <= decode_success; i++) 486 | fprintf(stdout, " %d", code_success[i]); 487 | fprintf(stdout, " }\n"); 488 | fprintf(stdout, "{!!! %d codewords are unable to correct:}\n{", decode_fail) ; 489 | for (i = 1; i <= decode_fail; i++) 490 | fprintf(stdout, " %d", code_fail[i]); 491 | fprintf(stdout, " }\n"); 492 | } 493 | 494 | return(0); 495 | } 496 | -------------------------------------------------------------------------------- /bch_encoder.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File Name: bch_encoder.c 4 | * Revision: 1.0 5 | * Date: August, 2006 6 | * Email: nandsupport@micron.com 7 | * Company: Micron Technology, Inc. 8 | * 9 | * Description: Micron NAND BCH Encoder 10 | * 11 | * References: 12 | * 1. Error Control Coding, Lin & Costello, 2nd Ed., 2004 13 | * 2. Error Control Codes, Blahut, 1983 14 | ** 15 | * Disclaimer This software code and all associated documentation, comments or other 16 | * of Warranty: information (collectively "Software") is provided "AS IS" without 17 | * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY 18 | * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT 21 | * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE 22 | * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. 23 | * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR 24 | * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, 25 | * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE 26 | * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, 27 | * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, 28 | * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, 29 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, 30 | * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE 31 | * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 32 | * DAMAGES. Because some jurisdictions prohibit the exclusion or 33 | * limitation of liability for consequential or incidental damages, the 34 | * above limitation may not apply to you. 35 | * 36 | * Copyright 2006 Micron Technology, Inc. All rights reserved. 37 | * 38 | * Rev Author Date Changes 39 | * --- --------------- ---------- ------------------------------- 40 | * 1.0 ZS 08/07/2006 Initial release 41 | * 42 | * 43 | /*******************************************************************************/ 44 | 45 | 46 | #include "bch_global.c" 47 | 48 | int bb[rr_max] ; // Parity checks 49 | 50 | void parallel_encode_bch() 51 | /* Parallel computation of n - k parity check bits. 52 | * Use lookahead matrix T_G_R. 53 | * The incoming streams are fed into registers from the right hand 54 | */ 55 | { int i, j, iii, Temp, bb_temp[rr_max] ; 56 | int loop_count ; 57 | 58 | // Determine the number of loops required for parallelism. 59 | loop_count = ceil(kk_shorten / (double)Parallel) ; 60 | 61 | // Serial to parallel data conversion 62 | for (i = 0; i < Parallel; i++) 63 | { for (j = 0; j < loop_count; j++) 64 | { if (i + j * Parallel < kk_shorten) 65 | data_p[i][j] = data[i + j * Parallel]; 66 | else 67 | data_p[i][j] = 0; 68 | } 69 | } 70 | 71 | // Initialize the parity bits. 72 | for (i = 0; i < rr; i++) 73 | bb[i] = 0; 74 | 75 | // Compute parity checks 76 | // S(t) = T_G_R [ S(t-1) + M(t) ] 77 | // Ref: Parallel CRC, Shieh, 2001 78 | for (iii = loop_count - 1; iii >= 0; iii--) 79 | { for (i = 0; i < rr; i++) 80 | bb_temp[i] = bb[i] ; 81 | for (i = Parallel - 1; i >= 0; i--) 82 | bb_temp[rr - Parallel + i] = bb_temp[rr - Parallel + i] ^ data_p[i][iii]; 83 | 84 | for (i = 0; i < rr; i++) 85 | { Temp = 0; 86 | for (j = 0; j < rr; j++) 87 | Temp = Temp ^ (bb_temp[j] * T_G_R[i][j]); 88 | bb[i] = Temp; 89 | } 90 | } 91 | 92 | } 93 | 94 | int main(int argc, char** argv) 95 | { int i ; 96 | int Help ; 97 | int Input_kk ; // Input indicator 98 | int in_count, in_v, in_codeword; // Input statistics 99 | char in_char; 100 | 101 | fprintf(stderr, "# Binary BCH encoder. Use -h for details.\n\n"); 102 | 103 | Verbose = 0; 104 | Input_kk = 0; 105 | Help = 0; 106 | mm = df_m; 107 | tt = df_t; 108 | Parallel = df_p; 109 | for (i = 1; i < argc;i++) 110 | { if (argv[i][0] == '-') 111 | { switch (argv[i][1]) 112 | { case 'm': mm = atoi(argv[++i]); 113 | if (mm > mm_max) 114 | Help = 1; 115 | break; 116 | case 't': tt = atoi(argv[++i]); 117 | break; 118 | case 'p': Parallel = atoi(argv[++i]); 119 | break; 120 | case 'k': kk_shorten = atoi(argv[++i]); 121 | if (kk_shorten % 4 != 0) 122 | { fprintf(stderr, "### k must divide 4.\n\n"); 123 | Help = 1; 124 | } 125 | Input_kk = 1; 126 | break; 127 | case 'v': Verbose = 1; 128 | break; 129 | default: Help = 1; 130 | } 131 | } 132 | else 133 | Help = 1; 134 | } 135 | 136 | if (Help == 1) 137 | { fprintf(stdout,"# Usage %s: BCH encoder\n", argv[0]); 138 | fprintf(stdout," -h: This help message\n"); 139 | fprintf(stdout," -m : Galois field, GF, for code. Code length is 2^-1.\n"); 140 | fprintf(stdout," The default value is %d for a code length %d. If the parameter is\n", df_m, (int)pow(2,df_m) - 1); 141 | fprintf(stdout," set to 0, the program will estimate the value based upon the values\n"); 142 | fprintf(stdout," chosen for k and t.\n"); 143 | fprintf(stdout," -t : Correction power of the code. Default = %d\n",df_t); 144 | fprintf(stdout," -k : Number of data bits to be encoded. Must divide 4.\n"); 145 | fprintf(stdout," The default value is the maximum supported by the code which\n"); 146 | fprintf(stdout," depends upon the field (-m) and the correction (-t) chosen.\n"); 147 | fprintf(stdout," -p : Parallelism in encoder. Does not effect results but\n"); 148 | fprintf(stdout," does change the algorithm used to generate them. Default = %d\n", df_p); 149 | fprintf(stdout," -v Verbose mode. Output detailed information, such as encoded codeword,\n"); 150 | fprintf(stdout," received codeword and decoded codeword. Default disabled. \n"); 151 | fprintf(stdout," : character string to encode in hex format. All other \n"); 152 | fprintf(stdout," characters are ignored. Comments are enclosed in brackets: { }.\n"); 153 | fprintf(stdout," The hex values are converted to binary and taken \n"); 154 | fprintf(stdout," at a time.\n"); 155 | fprintf(stdout," : resulting encoded character string in hex format.\n"); 156 | fprintf(stdout," : information about the encode process as well as error messages.\n"); 157 | } 158 | else 159 | { nn = (int)pow(2, mm) - 1 ; 160 | nn_shorten = nn ; 161 | 162 | // generate the Galois Field GF(2**mm) 163 | generate_gf() ; 164 | 165 | // Compute the generator polynomial and lookahead matrix for BCH code 166 | gen_poly() ; 167 | 168 | // Check if code is shortened 169 | if (Input_kk == 1) 170 | nn_shorten = kk_shorten + rr ; 171 | else 172 | { kk_shorten = nn_shorten - rr ; 173 | // Make the shortened length divide 4 174 | kk_shorten = kk_shorten - kk_shorten % 4 ; 175 | nn_shorten = kk_shorten + rr ; 176 | } 177 | 178 | fprintf(stdout, "{# (m = %d, n = %d, k = %d, t = %d, r = %d) Binary BCH code.}\n", mm, nn_shorten, kk_shorten, tt, rr) ; 179 | 180 | // Read in data stream 181 | in_count = 0; 182 | in_codeword = 0; 183 | 184 | in_char = getchar(); 185 | while (in_char != EOF) 186 | { if (in_char=='{') 187 | { while ((in_char != EOF) && ((char)in_char != '}')) 188 | in_char = getchar(); 189 | } 190 | in_v = hextoint(in_char); 191 | if (in_v != -1) 192 | { for (i = 3; i >= 0; i--) 193 | { if ((int)pow(2,i) & in_v) 194 | data[in_count] = 1 ; 195 | else 196 | data[in_count] = 0 ; 197 | 198 | in_count++; 199 | } 200 | } 201 | if (in_count == kk_shorten) 202 | { in_codeword++ ; 203 | 204 | parallel_encode_bch() ; 205 | 206 | print_hex_low(kk_shorten, data, stdout); 207 | fprintf(stdout, " "); 208 | print_hex_low(rr, bb, stdout); 209 | fprintf(stdout, "\n") ; 210 | 211 | in_count = 0; 212 | } 213 | in_char = getchar(); 214 | 215 | // For last codeword 216 | if (in_char == EOF && in_count > 0) 217 | { in_codeword++ ; 218 | // Pad zeros 219 | for (i = in_count; i < kk_shorten; i++) 220 | data[i] = 0; 221 | 222 | parallel_encode_bch() ; 223 | 224 | print_hex_low(kk_shorten, data, stdout); 225 | fprintf(stdout, " "); 226 | print_hex_low(rr, bb, stdout); 227 | fprintf(stdout, "\n") ; 228 | in_count = 0; 229 | } 230 | } 231 | fprintf(stdout, "\n{### %d words encoded.}\n", in_codeword) ; 232 | } 233 | 234 | return(0); 235 | } 236 | -------------------------------------------------------------------------------- /bch_encoder_decoder.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyberdong/bch_encoder_decoder/fa20fed7e8f20a1cc987a152499c32c51374ea4c/bch_encoder_decoder.pdf -------------------------------------------------------------------------------- /bch_global.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File Name: bch_global.c 4 | * Revision: 1.0 5 | * Date: August, 2006 6 | * Email: nandsupport@micron.com 7 | * Company: Micron Technology, Inc. 8 | * 9 | * Description: Micron NAND BCH Global Package 10 | * 11 | * Function: 1. Create Galois Field 12 | * 2. Create Generator Polynomial 13 | * 3. Create Parallel Generator Polynomial 14 | * 15 | * References: 16 | * 1. Error Control Coding, Lin & Costello, 2nd Ed., 2004 17 | * 2. Error Control Codes, Blahut, 1983 18 | * 3. Parallel CRC, Shieh, 2001 19 | * 20 | ** 21 | * Disclaimer This software code and all associated documentation, comments or other 22 | * of Warranty: information (collectively "Software") is provided "AS IS" without 23 | * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY 24 | * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 25 | * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES 26 | * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT 27 | * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE 28 | * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. 29 | * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR 30 | * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, 31 | * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE 32 | * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, 33 | * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, 34 | * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, 35 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, 36 | * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE 37 | * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 38 | * DAMAGES. Because some jurisdictions prohibit the exclusion or 39 | * limitation of liability for consequential or incidental damages, the 40 | * above limitation may not apply to you. 41 | * 42 | * Copyright 2006 Micron Technology, Inc. All rights reserved. 43 | * 44 | * 45 | * Rev Author Date Changes 46 | * --- --------------- ---------- ------------------------------- 47 | * 1.0 ZS 08/07/2006 Initial release 48 | * 2.0 PF 03/05/2007 Expanded constants to allow 49 | * larger fields 50 | * 51 | * 52 | /*******************************************************************************/ 53 | 54 | #include 55 | #include 56 | #include 57 | 58 | #define mm_max 15 /* Dimension of Galoise Field */ 59 | #define nn_max 32768 /* Length of codeword, n = 2**m - 1 */ 60 | #define tt_max 20 /* Number of errors that can be corrected */ 61 | #define kk_max 32768 /* Length of information bit, kk = nn - rr */ 62 | #define rr_max 1000 /* Number of parity checks, rr = deg[g(x)] */ 63 | #define parallel_max 32 /* Number of parallel encoding/syndrome computations */ 64 | #define DEBUG 0 65 | 66 | /* Default values */ 67 | int df_m = 13; // BCH code over GF(2**mm) 68 | int df_t = 4; // Number of errors that can be corrected 69 | int df_p = 8; // Number of substreams to calculate in parallel 70 | 71 | int mm, nn, kk, tt, rr; // BCH code parameters 72 | int nn_shorten, kk_shorten; // Shortened BCH code 73 | int Parallel ; // Parallel processing 74 | int Verbose ; // Mode indicator 75 | int p[mm_max + 1], alpha_to[nn_max], index_of[nn_max] ; // Galois field 76 | int gg[rr_max] ; // Generator polynomial 77 | int T_G[rr_max][rr_max], T_G_R[rr_max][rr_max]; // Parallel lookahead table 78 | int T_G_R_Temp[rr_max][rr_max] ; 79 | int data[kk_max], data_p[parallel_max][kk_max], recd[nn_max] ; // Information data and received data 80 | 81 | int hextoint(char hex) 82 | // Convert HEX number to Integer 83 | { int r, h; 84 | r = -1; 85 | h = (int)hex; 86 | if ((h >= 97) && (h <= 102)) 87 | r = h - 87; 88 | else if ((h >= 65) && (h <= 70)) 89 | r = h - 55; 90 | else if ((h >= 48) && (h <= 57)) 91 | r = h - 48; 92 | return r; 93 | } 94 | 95 | char inttohex(int i) 96 | // Convert Integer number to HEX 97 | { char r; 98 | if (i > 9) 99 | r = (char)(55 + i); 100 | else 101 | r = (char)(48 + i); 102 | return r; 103 | } 104 | 105 | void print_hex(int length, int Binary_data[length], FILE *std) 106 | // Print the binary data in HEX form 107 | // 1100 1010 = 5 3 108 | { int i, j, l, v; 109 | l = ceil((double)length / 4); 110 | 111 | for (j = l - 1; j >= 0; j--) 112 | { v = 0; 113 | for(i = 3; i >= 0; i--) 114 | v = v + (int)Binary_data[j * 4 + i] * (int)pow(2, i); 115 | fprintf(std, " %c", inttohex(v)); 116 | } 117 | } 118 | 119 | void print_hex_low(int length, int Binary_data[length], FILE *std) 120 | // Print the binary data in HEX form from low to high order 121 | // 1100 1010 = C A 122 | { int i, j, l, v; 123 | l = ceil((double)length / 4); 124 | 125 | for (j = 0; j < l; j++) 126 | { v = 0; 127 | for(i = 0; i <= 3; i++) 128 | v = v + (int)Binary_data[j * 4 + i] * (int)pow(2, 3-i); 129 | fprintf(std, "%c", inttohex(v)); 130 | } 131 | } 132 | 133 | void generate_gf() 134 | /* Generate GF(2**mm) from the primitive polynomial p(X) in p[0]..p[mm] 135 | The lookup table looks like: 136 | index -> polynomial form: alpha_to[ ] contains j = alpha**i; 137 | polynomial form -> index form: index_of[j = alpha**i] = i 138 | alpha_to[1] = 2 is the primitive element of GF(2**mm) 139 | */ 140 | { int i; 141 | int mask ; // Register states 142 | 143 | // Primitive polynomials 144 | for (i = 1; i < mm; i++) 145 | p[i] = 0; 146 | p[0] = p[mm] = 1; 147 | if (mm == 2) p[1] = 1; 148 | else if (mm == 3) p[1] = 1; 149 | else if (mm == 4) p[1] = 1; 150 | else if (mm == 5) p[2] = 1; 151 | else if (mm == 6) p[1] = 1; 152 | else if (mm == 7) p[1] = 1; 153 | else if (mm == 8) p[4] = p[5] = p[6] = 1; 154 | else if (mm == 9) p[4] = 1; 155 | else if (mm == 10) p[3] = 1; 156 | else if (mm == 11) p[2] = 1; 157 | else if (mm == 12) p[3] = p[4] = p[7] = 1; 158 | else if (mm == 13) p[1] = p[2] = p[3] = p[5] = p[7] = p[8] = p[10] = 1; // 25AF 159 | // else if (mm == 13) p[1] = p[3] = p[4] = 1; 160 | else if (mm == 14) p[2] = p[4] = p[6] = p[7] = p[8] = 1; // 41D5 161 | // else if (mm == 14) p[1] = p[11] = p[12] = 1; 162 | else if (mm == 15) p[1] = 1; 163 | else if (mm == 16) p[2] = p[3] = p[5] = 1; 164 | else if (mm == 17) p[3] = 1; 165 | else if (mm == 18) p[7] = 1; 166 | else if (mm == 19) p[1] = p[5] = p[6] = 1; 167 | else if (mm == 20) p[3] = 1; 168 | 169 | if (Verbose) 170 | { fprintf(stderr, "# The Galois field is GF(2**%d);\n\n", mm); 171 | fprintf(stderr, "# The primitive polynomial is: p(x) = "); 172 | for (i = 0; i <= mm; i++) 173 | { fprintf(stderr, " %d", p[i]); 174 | } 175 | fprintf(stderr, "\n\n"); 176 | } 177 | 178 | // Galois field implementation with shift registers 179 | // Ref: L&C, Chapter 6.7, pp. 217 180 | mask = 1 ; 181 | alpha_to[mm] = 0 ; 182 | for (i = 0; i < mm; i++) 183 | { alpha_to[i] = mask ; 184 | index_of[alpha_to[i]] = i ; 185 | if (p[i] != 0) 186 | alpha_to[mm] ^= mask ; 187 | 188 | mask <<= 1 ; 189 | } 190 | 191 | index_of[alpha_to[mm]] = mm ; 192 | mask >>= 1 ; 193 | for (i = mm + 1; i < nn; i++) 194 | { if (alpha_to[i-1] >= mask) 195 | alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1] ^ mask) << 1) ; 196 | else alpha_to[i] = alpha_to[i-1] << 1 ; 197 | 198 | index_of[alpha_to[i]] = i ; 199 | } 200 | index_of[0] = -1 ; 201 | 202 | // Print out the Galois Field 203 | if (Verbose) 204 | { fprintf(stderr, "# Look-up tables for GF(2**%2d)\n", mm) ; 205 | fprintf(stderr, " i alpha_to[i] index_of[i]\n") ; 206 | for (i=0; i<=nn; i++) 207 | fprintf(stderr, "%3d %3d %3d\n", i, alpha_to[i], index_of[i]) ; 208 | fprintf(stderr, "\n") ; 209 | } 210 | } 211 | 212 | 213 | void gen_poly() 214 | /* Compute generator polynomial of the tt-error correcting Binary BCH code 215 | * g(x) = LCM{M_1(x), M_2(x), ..., M_2t(x)}, 216 | * where M_i(x) is the minimal polynomial of alpha^i by cyclotomic cosets 217 | */ 218 | { int gen_roots[nn + 1], gen_roots_true[nn + 1] ; // Roots of generator polynomial 219 | int i, j, iii, jjj, Temp ; 220 | 221 | // Initialization of gen_roots 222 | for (i = 0; i <= nn; i++) 223 | { gen_roots_true[i] = 0; 224 | gen_roots[i] = 0; 225 | } 226 | 227 | // Cyclotomic cosets of gen_roots 228 | for (i = 1; i <= 2*tt ; i++) 229 | { for (j = 0; j < mm; j++) 230 | { Temp = ((int)pow(2, j) * i) % nn; 231 | gen_roots_true[Temp] = 1; 232 | } 233 | } 234 | 235 | rr = 0; // Count the number of parity check bits 236 | for (i = 0; i < nn; i++) 237 | { if (gen_roots_true[i] == 1) 238 | { rr++; 239 | gen_roots[rr] = i; 240 | } 241 | } 242 | kk = nn - rr; 243 | 244 | // Compute generator polynomial based on its roots 245 | gg[0] = 2 ; // g(x) = (X + alpha) initially 246 | gg[1] = 1 ; 247 | for (i = 2; i <= rr; i++) 248 | { gg[i] = 1 ; 249 | for (j = i - 1; j > 0; j--) 250 | if (gg[j] != 0) 251 | gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]] + index_of[alpha_to[gen_roots[i]]]) % nn] ; 252 | else 253 | gg[j] = gg[j-1] ; 254 | gg[0] = alpha_to[(index_of[gg[0]] + index_of[alpha_to[gen_roots[i]]]) % nn] ; 255 | } 256 | 257 | if (Verbose) 258 | { fprintf(stderr, "# The Generator Polynomial is:\n") ; 259 | for (i=0; i <= rr; i++) 260 | fprintf(stderr, " %d", gg[i]) ; 261 | fprintf(stderr, "\n\n") ; 262 | } 263 | 264 | // for parallel encoding and syndrome computation 265 | // Max parallalism is rr 266 | if (Parallel > rr) 267 | Parallel = rr ; 268 | 269 | // Construct parallel lookahead matrix T_g, and T_g**r from gg(x) 270 | // Ref: Parallel CRC, Shieh, 2001 271 | for (i = 0; i < rr; i++) 272 | { for (j = 0; j < rr; j++) 273 | T_G[i][j] = 0; 274 | } 275 | 276 | for (i = 1; i < rr; i++) 277 | T_G[i][i-1] = 1 ; 278 | 279 | for (i = 0; i < rr; i++) 280 | T_G[i][rr - 1] = gg[i] ; 281 | 282 | for (i = 0; i < rr; i++) 283 | { for (j = 0; j < rr; j++) 284 | T_G_R[i][j] = T_G[i][j]; 285 | } 286 | 287 | // Compute T_G**R Matrix 288 | for (iii = 1; iii < Parallel; iii++) 289 | { for (i = 0; i < rr; i++) 290 | { for (j = 0; j < rr; j++) 291 | { Temp = 0; 292 | for (jjj = 0; jjj < rr; jjj++) 293 | Temp = Temp ^ T_G_R[i][jjj] * T_G[jjj][j]; 294 | 295 | T_G_R_Temp[i][j] = Temp; 296 | } 297 | } 298 | 299 | for (i = 0; i < rr; i++) 300 | { for (j = 0; j < rr; j++) 301 | T_G_R[i][j] = T_G_R_Temp[i][j]; 302 | } 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /bug_data_pattern: -------------------------------------------------------------------------------- 1 | { Correctable by both versions of bch_decoder.c: 8 Errors at:} 2 | { 3145 745 1050 182 3421 2732 3604 1451 } 3 | 000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 4 | 5 | { Uncorrectable by v1.0 but correctable by v2.0 of bch_decoder.c: 8 Errors at:} 6 | { 635 3445 1250 1570 1063 1371 2422 1253 } 7 | 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000240000000000000000000000000000100000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 8 | -------------------------------------------------------------------------------- /data_codeword.txt: -------------------------------------------------------------------------------- 1 | {# (m = 15, n = 16624, k = 16384, t = 16, r = 240) Binary BCH code.} 2 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 BED0F2F8F33FE6DC2155AA71103606D92861CADE0481DF5DD8541E6A9D6E 3 | 4 | {### 1 words encoded.} 5 | -------------------------------------------------------------------------------- /data_error.txt: -------------------------------------------------------------------------------- 1 | { Seed = 1 } 2 | {16 errors applied. Error bits locations are:} 3 | { 3543 4582 8937 4307 5809 10479 16314 11356 14281 11357 282 6139 12562 16379 12771 13654 } 4 | 5 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122023333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEFEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDFEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFDFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBB8CCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0010111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFBF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFE0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF000011112222333344445555666A777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111102223333444455556666777788889999AAAABBBBCCCCDDDDEEEEEFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556466777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDD9DEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCECDDDDEEEEFFFF0010BED0F2F8F33FE6DC2155AA71103606D92861CADE0481DF5DD8541E6A9D6E -------------------------------------------------------------------------------- /data_generator.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File Name: data_generator.c 4 | * Revision: 1.0 5 | * Date: August, 2006 6 | * Email: nandsupport@micron.com 7 | * Company: Micron Technology, Inc. 8 | * 9 | * Description: HEX data generator 10 | * Generate regular bytes 1111 2222 3333 4444 .... 11 | * for easy checking of decoding result 12 | * or random data can be generated by random mode 13 | ** 14 | * Disclaimer This software code and all associated documentation, comments or other 15 | * of Warranty: information (collectively "Software") is provided "AS IS" without 16 | * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY 17 | * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 18 | * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT 20 | * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE 21 | * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. 22 | * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR 23 | * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, 24 | * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE 25 | * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, 26 | * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, 28 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, 29 | * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE 30 | * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 31 | * DAMAGES. Because some jurisdictions prohibit the exclusion or 32 | * limitation of liability for consequential or incidental damages, the 33 | * above limitation may not apply to you. 34 | * 35 | * Copyright 2006 Micron Technology, Inc. All rights reserved. 36 | * 37 | * 38 | * Rev Author Date Changes 39 | * --- --------------- ---------- ------------------------------- 40 | * 1.0 ZS 08/07/2006 Initial release 41 | * 42 | * 43 | /******************************************************************************* 44 | */ 45 | 46 | #include "bch_global.c" 47 | 48 | int main(int argc, char** argv) 49 | { int n ; // Length of generated data in bytes 50 | int i, Temp ; 51 | int Help; 52 | int Random ; // Random mode 53 | 54 | if (argc == 1) 55 | { 56 | fprintf(stderr, "# Data generator. Use -h for details.\n\n"); 57 | return(-1); 58 | } 59 | 60 | Random = 0; 61 | Help = 0; 62 | n = 64 ; 63 | for (i=1; i < argc;i++) 64 | { if (argv[i][0] == '-') 65 | { switch (argv[i][1]) 66 | { case 'n': n = atoi(argv[++i]); 67 | break; 68 | case 'r': Random = 1; 69 | break; 70 | default: Help = 1; 71 | } 72 | } 73 | else 74 | Help = 1; 75 | } 76 | 77 | if (Help == 1) 78 | { fprintf(stdout,"# Usage %s: BCH data generator\n",argv[0]); 79 | fprintf(stdout," -h: This help message\n"); 80 | fprintf(stdout," -n : Number of bytes that will be generated. Default = %d \n", n); 81 | fprintf(stdout," Output is 2*n HEX regular characters.\n"); 82 | fprintf(stdout," -r Random mode generator. Will output random HEX characters.\n"); 83 | fprintf(stdout," : resulting generated character string in hex format.\n"); 84 | fprintf(stdout," : information about the generation process as well as error messages\n"); 85 | fprintf(stdout," Example: ./data -n 2048 > data_in.txt\n"); 86 | } 87 | else 88 | { if (Random == 0) 89 | { fprintf(stdout, "{ Regular mode generator.}\n"); 90 | fprintf(stdout, "{ %d bytes generated.}\n\n", n); 91 | for (i = 1; i <= n/2 ; i++) 92 | { Temp = inttohex(i % 16); 93 | fprintf(stdout, "%c%c%c%c", Temp, Temp, Temp, Temp ); 94 | if (i%16 ==0 ) 95 | fprintf(stdout, "\n"); 96 | } 97 | } 98 | else 99 | { fprintf(stdout, "{ Random mode generator.}\n"); 100 | fprintf(stdout, "{ %d bytes generated.}\n\n", n); 101 | for (i = 1; i <= n * 2 ; i++) 102 | { Temp = rand() % 16 ; 103 | Temp = inttohex(Temp); 104 | fprintf(stdout, "%c", Temp ); 105 | if (i%64 ==0 ) 106 | fprintf(stdout, "\n"); 107 | } 108 | } 109 | } 110 | 111 | return(0); 112 | } 113 | -------------------------------------------------------------------------------- /data_in.txt: -------------------------------------------------------------------------------- 1 | { Regular mode generator.} 2 | { 2048 bytes generated.} 3 | 4 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 5 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 6 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 7 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 8 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 9 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 10 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 11 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 12 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 13 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 14 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 15 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 16 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 17 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 18 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 19 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 20 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 21 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 22 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 23 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 24 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 25 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 26 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 27 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 28 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 29 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 30 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 31 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 32 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 33 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 34 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 35 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 36 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 37 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 38 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 39 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 40 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 41 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 42 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 43 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 44 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 45 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 46 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 47 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 48 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 49 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 50 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 51 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 52 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 53 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 54 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 55 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 56 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 57 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 58 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 59 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 60 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 61 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 62 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 63 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 64 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 65 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 66 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 67 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 68 | -------------------------------------------------------------------------------- /data_out.txt: -------------------------------------------------------------------------------- 1 | {# (m = 15, n = 16624, k = 16384, t = 16) Binary BCH code.} 2 | 3 | { Codeword 1: 16 errors found at location: 282 3543 4307 4582 5809 6139 8937 10479 11356 11357 12562 12771 13654 14281 16314 16379} 4 | 111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF0000 5 | 6 | {### 1 codewords received.} 7 | {@@@ 1 codewords are decoded successfully:} 8 | { 1 } 9 | {!!! 0 codewords are unable to correct:} 10 | { } 11 | -------------------------------------------------------------------------------- /error.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File Name: error_generator.c 4 | * Revision: 2.0 5 | * Date: March, 2007 6 | * Email: nandsupport@micron.com 7 | * Company: Micron Technology, Inc. 8 | * 9 | * Description: corrupt data streams randomly 10 | ** 11 | * Disclaimer This software code and all associated documentation, comments or other 12 | * of Warranty: information (collectively "Software") is provided "AS IS" without 13 | * warranty of any kind. MICRON TECHNOLOGY, INC. ("MTI") EXPRESSLY 14 | * DISCLAIMS ALL WARRANTIES EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | * TO, NONINFRINGEMENT OF THIRD PARTY RIGHTS, AND ANY IMPLIED WARRANTIES 16 | * OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. MTI DOES NOT 17 | * WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS, OR THAT THE 18 | * OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE. 19 | * FURTHERMORE, MTI DOES NOT MAKE ANY REPRESENTATIONS REGARDING THE USE OR 20 | * THE RESULTS OF THE USE OF THE SOFTWARE IN TERMS OF ITS CORRECTNESS, 21 | * ACCURACY, RELIABILITY, OR OTHERWISE. THE ENTIRE RISK ARISING OUT OF USE 22 | * OR PERFORMANCE OF THE SOFTWARE REMAINS WITH YOU. IN NO EVENT SHALL MTI, 23 | * ITS AFFILIATED COMPANIES OR THEIR SUPPLIERS BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES (INCLUDING, 25 | * WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, 26 | * OR LOSS OF INFORMATION) ARISING OUT OF YOUR USE OF OR INABILITY TO USE 27 | * THE SOFTWARE, EVEN IF MTI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 28 | * DAMAGES. Because some jurisdictions prohibit the exclusion or 29 | * limitation of liability for consequential or incidental damages, the 30 | * above limitation may not apply to you. 31 | * 32 | * Copyright 2007 Micron Technology, Inc. All rights reserved. 33 | * 34 | * 35 | * Rev Author Date Changes 36 | * --- --------------- ---------- ------------------------------- 37 | * 1.0 ZS 08/07/2006 Initial release 38 | * 2.0 PF 03/05/2007 Added options "-s" and "-r" 39 | * 40 | * 41 | ******************************************************************************/ 42 | 43 | #include "bch_global.c" 44 | int codeword[16 * kk_max] ; // Incoming data 45 | 46 | int main(int argc, char** argv) 47 | { int i, j ; 48 | int Error_Number ; // Number of errors applied 49 | int Help; 50 | int rec_mode=0; 51 | int in_count, in_v; 52 | int in_count_rec; 53 | int seed; 54 | char in_char; 55 | int wd_cnt[8]; 56 | 57 | fprintf(stderr, "# Random error generator. Use -h for details.\n\n"); 58 | 59 | Help = 0; 60 | Error_Number = 1; 61 | seed = 1; 62 | for (i=1; i < argc;i++) 63 | { if (argv[i][0] == '-') 64 | { switch (argv[i][1]) 65 | { case 'e': Error_Number = atoi(argv[++i]); 66 | break; 67 | case 's': seed = atoi(argv[++i]); 68 | break; 69 | case 'r': rec_mode=1; 70 | break; 71 | default: Help = 1; 72 | } 73 | } 74 | else 75 | Help = 1; 76 | } 77 | 78 | if (Help == 1) 79 | { fprintf(stdout,"# Usage %s: Error generator\n",argv[0]); 80 | fprintf(stdout," -h: This help message\n"); 81 | fprintf(stdout," -r: record based mode, all errors are in a record (terminated by newline).\n"); 82 | fprintf(stdout," -e : Number of errors in codeword. Default = %d\n", Error_Number); 83 | fprintf(stdout," -s : Set the seed for the random number generator. Default = %d\n", seed); 84 | fprintf(stdout," : resulting corrupted data string in hex format.\n"); 85 | fprintf(stdout," : information about the process as well as error messages\n"); 86 | } 87 | else 88 | { in_count = 0; 89 | in_count_rec = 1; 90 | wd_cnt[0]=wd_cnt[1]=wd_cnt[2]=wd_cnt[3]=wd_cnt[4]=wd_cnt[5]=wd_cnt[6]=wd_cnt[7]=0; 91 | in_char = getchar(); 92 | srand(seed); 93 | fprintf(stdout, "{ Seed = %d }\n",seed); 94 | 95 | while (in_char != EOF) 96 | { if (in_char=='{') 97 | { while ((in_char != EOF) && ((char)in_char != '}')) 98 | in_char = getchar(); 99 | } 100 | in_v = hextoint(in_char); 101 | if (in_v != -1) 102 | { for (i = 3; i >= 0; i--) 103 | { if ((int)pow(2,i) & in_v) 104 | codeword[in_count] = 1 ; 105 | else 106 | codeword[in_count] = 0 ; 107 | in_count++; 108 | } 109 | } else 110 | { fprintf(stderr,"in_count: %d\n",in_count); 111 | if (rec_mode && in_count) 112 | { fprintf(stdout, "{%6d) %d errors applied. Errors locations are:}\n{", in_count_rec, Error_Number); 113 | fprintf(stderr, "{%6d) %d errors applied. Errors locations are:}\n{", in_count_rec, Error_Number); 114 | for (i = 0; i < Error_Number; i++) 115 | { j = rand() % in_count ; 116 | codeword[j] = codeword[j] ^ 1; 117 | fprintf(stdout, " %d", j); 118 | fprintf(stderr, " %d", j); 119 | wd_cnt[j*8/in_count]++; 120 | } 121 | fprintf(stdout, " }\n\n"); 122 | fprintf(stderr, " }\n"); 123 | print_hex_low(in_count, codeword, stdout); 124 | fprintf(stdout,"\n"); 125 | in_count=0; 126 | in_count_rec++; 127 | } 128 | } 129 | in_char = getchar(); 130 | } 131 | if (rec_mode) return(0); 132 | fprintf(stderr, "# Total number of bits is: %d.\n\n", in_count) ; 133 | fprintf(stdout, "{%d errors applied. Error bits locations are:}\n{", Error_Number); 134 | for (i = 0; i < Error_Number; i++) 135 | { j = rand() % in_count ; 136 | codeword[j] = codeword[j] ^ 1; 137 | fprintf(stdout, " %d", j); 138 | wd_cnt[j*8/in_count]++; 139 | } 140 | fprintf(stdout, " }\n\n"); 141 | fprintf(stderr, "word counts:"); 142 | for (i=0;i<8;i++) 143 | fprintf(stderr," %d",wd_cnt[i]); 144 | fprintf(stderr,"\n"); 145 | print_hex_low(in_count, codeword, stdout); 146 | } 147 | 148 | return(0); 149 | } 150 | -------------------------------------------------------------------------------- /release_notes: -------------------------------------------------------------------------------- 1 | V1.0 - Initial Release 2 | 3 | V2.0 - The first release exhibited a bug in the Berlekamp-Massey Algorithm. Under rare conditions 4 | the algorithm would report that the codeword was uncorrectable even when it had fewer errors 5 | than the correction power of the code. The bug was a function of the error pattern itself and 6 | could be detected by examining the syndromes. This release of the software contains a data file 7 | that can be piped into the bch_decoder to show the error. To do this, execute the following command: 8 | bch_decoder -k 4096 -m 13 -t 8 -p 8 < bug_data_pattern 9 | 10 | 11 | V2.1 - Makefile added, test script modified, minor code changes by Daniel Liu -------------------------------------------------------------------------------- /test_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # BCH Encoder/Decoder 3 | 4 | # gcc data_generator.c -o data.exe 5 | # gcc bch_encoder.c -o bch_encoder.exe 6 | # gcc error.c -o error.exe 7 | # gcc bch_decoder.c -o bch_decoder.exe 8 | 9 | make 10 | 11 | # MM=13 12 | # KK=4096 13 | # TT=8 14 | # PP=8 15 | # EE=16 16 | 17 | # MM -- BCH code over GF(2**mm), where mm is Galois fields 18 | # 以下参数适用于A15的NAND控制器, Galois fields=15 19 | MM=15 20 | echo "MM="$MM 21 | 22 | KK_bytes=2048 23 | let KK_bits=$KK_bytes*8 24 | echo "KK_bytes="$KK_bytes 25 | echo "KK_bits="$KK_bits 26 | 27 | TT=16 28 | echo "TT="$TT 29 | #TT -- Number of errors that can be corrected 30 | #TT is 16 bits per 2048 Bytes, 会产生30 Bytes的BCH ECC;可纠正2048字节中的16bit的错误; 注入超过16位的错误,就会有不能成功纠错的位 31 | 32 | # PP -- Number of substreams to calculate in parallel 33 | PP=8 34 | 35 | # EE -- the number of error bits injected 36 | EE=16 37 | echo "EE="$EE 38 | 39 | ./data_gen -n $KK_bytes > data_in.txt 40 | ./bch_encoder -m $MM -k $KK_bits -t $TT -p $PP < data_in.txt > data_codeword.txt 41 | ./error -e $EE < data_codeword.txt > data_error.txt 42 | ./bch_decoder -m $MM -k $KK_bits -t $TT -p $PP < data_error.txt > data_out.txt 43 | 44 | 45 | 46 | --------------------------------------------------------------------------------