int Encode_stop() { encoder.bits_to_follow++; if (encoder.low < FIRST_QUATER) { output_bits(0); } else { output_bits(1); } printf("\n"); return 0; }
void Decoder_LDPC_IEEE_802_11ad::Init() { // Set code and decoder parameters Set_LDPC_Parameters(); mean_iterations.Reset(); flipped_bits.Reset(); // Resize output buffers and internal RAMs. try { // Output RAM content for each iteration. output_bits().Resize(num_iterations(), num_variable_nodes_); output_bits_llr_app().Resize(num_iterations(), num_variable_nodes_); // Decoder RAMs app_ram_.Resize(dst_parallelism_, num_variable_nodes_ / dst_parallelism_); msg_ram_.Resize(dst_parallelism_, num_check_nodes_ * max_check_degree_ / dst_parallelism_); } catch(bad_alloc&) { Msg(ERROR, instance_name(), "Memory allocation failure!"); throw; } param_list_.config_modified(false); input_data_list_.port_modified(false); }
int Encode_one_symbol(unsigned int symbol) { long range = encoder.high - encoder.low + 1; encoder.high = encoder.low + (range * probability_model[symbol + 1] / upper_bound) - 1; encoder.low = encoder.low + (range * probability_model[symbol] / upper_bound); while (1) { if (encoder.high < HALF_VALUE) { // Output 0; output_bits(0); } else if (encoder.low >= HALF_VALUE) { // Output 1; output_bits(1); encoder.high -= HALF_VALUE; encoder.low -= HALF_VALUE; } else if (encoder.low >= FIRST_QUATER && encoder.high < THIRD_QUATER) { encoder.bits_to_follow++; encoder.high -= FIRST_QUATER; encoder.low -= FIRST_QUATER; } else { break; } encoder.low = 2 * encoder.low; encoder.high = 2 * encoder.high + 1; } return 0; }
int Decoder_LDPC_IEEE_802_11ad::Run() { unsigned int pchk_satisfied; unsigned int iter = 0; bool next_iter_is_last_iter = false; bool last_iter = false; decoding_successful().Write(false); num_modified_systematic_bits().Write(0); if(param_list_.config_modified()) Init(); // Read the channel values and store them in app_ram_. Init_APP_RAM(is_IRA_code_, input_bits_llr(), app_ram_); do { // Perform one ldpc decoder iteration. switch(scheduling()) { case LAYERED: pchk_satisfied = Decode_Layered(app_ram_, msg_ram_, iter); break; case TWO_PHASE: pchk_satisfied = Decode_Two_Phase(app_ram_, msg_ram_, iter, app_parity_check()); break; default: pchk_satisfied = 0; Msg(ERROR, instance_name(), "Selected scheduling not supported for these codes!"); break; } /* * Read the app_ram_ and store APP values in output_bits_llr_app() and * hard decoded bits in output_bits buffer. */ Read_APP_RAM(app_ram_, iter, output_bits_llr_app(), output_bits()); // Check whether all parity checks were satisfied in the previous iteration. last_iter = next_iter_is_last_iter; // Are all parity checks satisfied? if (pchk_satisfied == num_check_nodes_) { decoding_successful().Write(true); next_iter_is_last_iter = true; // Do one more iteration, as it is done in hardware! } // Store the number of flipped bits if (iter != 0) { flipped_bits(iter)().Write(Calc_Flipped_Bits(iter, output_bits())); } // Increase iteration counter. iter++; mean_iterations(iter)().Write(iter); /* * Abort conditions: * 1) maximum number of iterations is reached * 2) all parity checks are satisfied: Since the hardware performs one more * iteration after all parity checks are satisfied, we delay the stopping * in the software as well. */ } while (iter < num_iterations() && last_iter == false); // Write the number of unsatisfied parity checks. num_unsatisfied_parity_checks().Write(num_check_nodes_ - pchk_satisfied); // Set number of used iterations in output buffer. iterations_performed().Write(iter); // Get statistic about modified bits. num_modified_systematic_bits().Write(Calc_Modified_Systematic_Bits(iter, input_bits_llr(), output_bits())); // Fill the output buffer and the status port for the remaining iterations. for(unsigned int i = iter; i < num_iterations(); i++) { mean_iterations(i + 1)().Write(iter); output_bits_llr_app()[i] = output_bits_llr_app()[iter - 1]; output_bits()[i] = output_bits()[iter - 1]; } return 0; }
int do_output(match_ctx ctx, search_nodep snp, encode_match_data emd, encode_match_f * f, struct membuf *outbuf, int *literal_sequences_used) { int pos; int pos_diff; int max_diff; int diff; int copy_used = 0; output_ctxp old; output_ctx out; output_ctx_init(out, outbuf); old = emd->out; emd->out = out; pos = output_get_pos(out); pos_diff = pos; max_diff = 0; LOG(LOG_DUMP, ("pos $%04X\n", out->pos)); output_gamma_code(out, 16); output_bits(out, 1, 0); /* 1 bit out */ diff = output_get_pos(out) - pos_diff; if(diff > max_diff) { max_diff = diff; } LOG(LOG_DUMP, ("pos $%04X\n", out->pos)); LOG(LOG_DUMP, ("------------\n")); while (snp != NULL) { const_matchp mp; mp = snp->match; if (mp != NULL && mp->len > 0) { if (mp->offset == 0) { if(mp->len == 1) { /* literal */ LOG(LOG_DUMP, ("literal byte: $%02X\n", ctx->buf[snp->index])); output_byte(out, ctx->buf[snp->index]); output_bits(out, 1, 1); } else { int i; for(i = 0; i < mp->len; ++i) { output_byte(out, ctx->buf[snp->index + i]); } output_bits(out, 16, mp->len); output_gamma_code(out, 17); output_bits(out, 1, 0); copy_used = 1; } } else { f(mp, emd); output_bits(out, 1, 0); } pos_diff += mp->len; diff = output_get_pos(out) - pos_diff; if(diff > max_diff) { max_diff = diff; } } LOG(LOG_DUMP, ("------------\n")); snp = snp->prev; } LOG(LOG_DUMP, ("pos $%04X\n", out->pos)); /* output header here */ optimal_out(out, emd); LOG(LOG_DUMP, ("pos $%04X\n", out->pos)); output_bits_flush(out); emd->out = old; if(literal_sequences_used != NULL) { *literal_sequences_used = copy_used; } return max_diff; }
static int generate_output(match_ctx ctx, search_nodep snp, struct sfx_decruncher *decr, encode_match_f * f, encode_match_data emd, int load, int len, int start, unsigned char *buf) { int pos; int pos_diff; int max_diff; int diff; static output_ctx out; output_ctxp old; output_ctx_init(out); old = emd->out; emd->out = out; pos = output_get_pos(out); pos_diff = pos; max_diff = 0; output_gamma_code(out, 16); output_bits(out, 1, 0); /* 1 bit out */ diff = output_get_pos(out) - pos_diff; if(diff > max_diff) { max_diff = diff; } while (snp != NULL) { const_matchp mp; mp = snp->match; if (mp != NULL && mp->len > 0) { if (mp->offset == 0) { /* literal */ output_byte(out, ctx->buf[snp->index]); output_bits(out, 1, 1); } else { f(mp, emd); output_bits(out, 1, 0); } pos_diff += mp->len; diff = output_get_pos(out) - pos_diff; if(diff > max_diff) { max_diff = diff; } } snp = snp->prev; } /* output header here */ optimal_out(out, emd); output_bits_flush(out); output_word(out, (unsigned short int) (load + len)); len = output_get_pos(out); decr->load(out, (unsigned short int) load - max_diff); output_copy_bytes(out, 0, len); /* second stage of decruncher */ decr->stages(out, (unsigned short int) start); /*len = output_ctx_close(out, of);*/ len = out->pos - out->start; memcpy(buf, out->buf + out->start, len); emd->out = old; return len; }