mirror of
https://github.com/aicodix/code.git
synced 2026-04-27 14:30:36 +00:00
added CA-SCL example similar to DVB 2/3 LDPC+BCH code
- use floating point for numerical stability - shortened message by 736 to get 64800 codeword bits - replaced 10*16 bits of BCH coding with a 32 bit CRC
This commit is contained in:
parent
0e1a5a45e4
commit
ee9fe7439f
1 changed files with 36 additions and 24 deletions
|
|
@ -25,13 +25,15 @@ bool get_bit(const uint32_t *bits, int idx)
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
const int M = 11;
|
const int M = 16;
|
||||||
const int N = 1 << M;
|
const int N = 1 << M;
|
||||||
|
const int C = 32;
|
||||||
|
const int S = 65536 - 64800;
|
||||||
|
const int K = 43200 - 10*16 + C + S;
|
||||||
const bool systematic = true;
|
const bool systematic = true;
|
||||||
const bool crc_aided = true;
|
const bool crc_aided = true;
|
||||||
CODE::CRC<uint32_t> crc(0xD419CC15);
|
CODE::CRC<uint32_t> crc(0xD419CC15);
|
||||||
const int C = 32;
|
#if 0
|
||||||
#if 1
|
|
||||||
typedef int8_t code_type;
|
typedef int8_t code_type;
|
||||||
double SCALE = 2;
|
double SCALE = 2;
|
||||||
#else
|
#else
|
||||||
|
|
@ -55,22 +57,22 @@ int main()
|
||||||
auto codeword = new code_type[N];
|
auto codeword = new code_type[N];
|
||||||
auto temp = new simd_type[N];
|
auto temp = new simd_type[N];
|
||||||
|
|
||||||
long double erasure_probability = 0.5;
|
long double erasure_probability = (long double)(N - K) / N;
|
||||||
int K = (1 - erasure_probability) * N;
|
|
||||||
double design_SNR = 10 * std::log10(-std::log(erasure_probability));
|
double design_SNR = 10 * std::log10(-std::log(erasure_probability));
|
||||||
std::cerr << "design SNR: " << design_SNR << std::endl;
|
std::cerr << "design SNR: " << design_SNR << std::endl;
|
||||||
|
auto freeze = new CODE::PolarCodeConst0<M>;
|
||||||
|
std::cerr << "sizeof(PolarCodeConst0<M>) = " << sizeof(CODE::PolarCodeConst0<M>) << std::endl;
|
||||||
|
double better_SNR = design_SNR + 1.59175;
|
||||||
|
std::cerr << "better SNR: " << better_SNR << std::endl;
|
||||||
|
long double probability = std::exp(-pow(10.0, better_SNR / 10));
|
||||||
|
(*freeze)(frozen, M, K, probability);
|
||||||
|
delete freeze;
|
||||||
if (0) {
|
if (0) {
|
||||||
CODE::PolarFreezer freeze;
|
std::cout << "static const uint32_t frozen[" << (N+31)/32 << "] = { " << std::hex;
|
||||||
long double freezing_threshold = 0 ? 0.5 : std::numeric_limits<float>::epsilon();
|
for (int i = 0; i < (N+31)/32; ++i)
|
||||||
K = freeze(frozen, M, erasure_probability, freezing_threshold);
|
std::cout << "0x" << frozen[i] << ", ";
|
||||||
} else {
|
std::cout << "};" << std::endl;
|
||||||
auto freeze = new CODE::PolarCodeConst0<M>;
|
return 0;
|
||||||
std::cerr << "sizeof(PolarCodeConst0<M>) = " << sizeof(CODE::PolarCodeConst0<M>) << std::endl;
|
|
||||||
double better_SNR = design_SNR + 1.59175;
|
|
||||||
std::cerr << "better SNR: " << better_SNR << std::endl;
|
|
||||||
long double probability = std::exp(-pow(10.0, better_SNR / 10));
|
|
||||||
(*freeze)(frozen, M, K, probability);
|
|
||||||
delete freeze;
|
|
||||||
}
|
}
|
||||||
std::cerr << "Polar(" << N << ", " << K << ")" << std::endl;
|
std::cerr << "Polar(" << N << ", " << K << ")" << std::endl;
|
||||||
auto message = new code_type[K];
|
auto message = new code_type[K];
|
||||||
|
|
@ -105,15 +107,17 @@ int main()
|
||||||
while (uncorrected_errors < 1000 && ++loops < 1000) {
|
while (uncorrected_errors < 1000 && ++loops < 1000) {
|
||||||
if (crc_aided) {
|
if (crc_aided) {
|
||||||
crc.reset();
|
crc.reset();
|
||||||
for (int i = 0; i < K-C; ++i) {
|
for (int i = 0; i < K-C-S; ++i) {
|
||||||
bool bit = data();
|
bool bit = data();
|
||||||
crc(bit);
|
crc(bit);
|
||||||
message[i] = 1 - 2 * bit;
|
message[i] = 1 - 2 * bit;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < C; ++i) {
|
for (int i = 0; i < C; ++i) {
|
||||||
bool bit = (crc() >> i) & 1;
|
bool bit = (crc() >> i) & 1;
|
||||||
message[K-C+i] = 1 - 2 * bit;
|
message[K-C-S+i] = 1 - 2 * bit;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < S; ++i)
|
||||||
|
message[K-S+i] = 1;
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < K; ++i)
|
for (int i = 0; i < K; ++i)
|
||||||
message[i] = 1 - 2 * data();
|
message[i] = 1 - 2 * data();
|
||||||
|
|
@ -146,6 +150,14 @@ int main()
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
codeword[i] = CODE::PolarHelper<code_type>::quant(fact * symb[i]);
|
codeword[i] = CODE::PolarHelper<code_type>::quant(fact * symb[i]);
|
||||||
|
|
||||||
|
for (int i = 0, j = 0; i < N && j < K; ++i) {
|
||||||
|
if (!get_bit(frozen, i)) {
|
||||||
|
if (j >= K-S)
|
||||||
|
codeword[i] = CODE::PolarHelper<code_type>::quant(9000);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
noisy[i] = codeword[i];
|
noisy[i] = codeword[i];
|
||||||
|
|
||||||
|
|
@ -153,7 +165,7 @@ int main()
|
||||||
(*decode)(metric, decoded, codeword, frozen, M);
|
(*decode)(metric, decoded, codeword, frozen, M);
|
||||||
auto end = std::chrono::system_clock::now();
|
auto end = std::chrono::system_clock::now();
|
||||||
auto usec = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
auto usec = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
||||||
double mbs = (double)K / usec.count();
|
double mbs = (double)(K-C-S) / usec.count();
|
||||||
avg_mbs += mbs;
|
avg_mbs += mbs;
|
||||||
|
|
||||||
if (systematic) {
|
if (systematic) {
|
||||||
|
|
@ -173,7 +185,7 @@ int main()
|
||||||
if (crc_aided) {
|
if (crc_aided) {
|
||||||
for (int k = 0; k < SIMD_WIDTH; ++k) {
|
for (int k = 0; k < SIMD_WIDTH; ++k) {
|
||||||
crc.reset();
|
crc.reset();
|
||||||
for (int i = 0; i < K; ++i)
|
for (int i = 0; i < K-S; ++i)
|
||||||
crc(decoded[i].v[order[k]] < 0);
|
crc(decoded[i].v[order[k]] < 0);
|
||||||
if (crc() == 0) {
|
if (crc() == 0) {
|
||||||
best = order[k];
|
best = order[k];
|
||||||
|
|
@ -186,23 +198,23 @@ int main()
|
||||||
awgn_errors += noisy[i] * (orig[i] < 0);
|
awgn_errors += noisy[i] * (orig[i] < 0);
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
quantization_erasures += !noisy[i];
|
quantization_erasures += !noisy[i];
|
||||||
for (int i = 0; i < K; ++i)
|
for (int i = 0; i < K-C-S; ++i)
|
||||||
uncorrected_errors += decoded[i].v[best] * message[i] <= 0;
|
uncorrected_errors += decoded[i].v[best] * message[i] <= 0;
|
||||||
for (int i = 0; i < K; ++i)
|
for (int i = 0; i < K-C-S; ++i)
|
||||||
ambiguity_erasures += !decoded[i].v[best];
|
ambiguity_erasures += !decoded[i].v[best];
|
||||||
}
|
}
|
||||||
|
|
||||||
avg_mbs /= loops;
|
avg_mbs /= loops;
|
||||||
|
|
||||||
max_mbs = std::max(max_mbs, avg_mbs);
|
max_mbs = std::max(max_mbs, avg_mbs);
|
||||||
double bit_error_rate = (double)uncorrected_errors / (double)(K * loops);
|
double bit_error_rate = (double)uncorrected_errors / (double)((K-C-S) * loops);
|
||||||
if (!uncorrected_errors)
|
if (!uncorrected_errors)
|
||||||
min_SNR = std::min(min_SNR, SNR);
|
min_SNR = std::min(min_SNR, SNR);
|
||||||
else
|
else
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
int MOD_BITS = 1; // BPSK
|
int MOD_BITS = 1; // BPSK
|
||||||
double code_rate = (double)K / (double)N;
|
double code_rate = (double)(K-C-S) / (double)N;
|
||||||
double spectral_efficiency = code_rate * MOD_BITS;
|
double spectral_efficiency = code_rate * MOD_BITS;
|
||||||
double EbN0 = 10 * std::log10(sigma_signal * sigma_signal / (spectral_efficiency * 2 * sigma_noise * sigma_noise));
|
double EbN0 = 10 * std::log10(sigma_signal * sigma_signal / (spectral_efficiency * 2 * sigma_noise * sigma_noise));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue