Commit 6529f900 authored by letr's avatar letr Committed by Florian Kaltenberger

update testbench LDPC

parent 03d9f414
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -26,6 +26,8 @@
#include "SIMULATION/TOOLS/defs.h"
#include "Gen_shift_value.h"
#include "test.h"
// 4-bit quantizer
char quantize4bit(double D,double x)
{
......@@ -62,8 +64,8 @@ char quantize(double D,double x,unsigned char B)
return((char)qxd);
}
#define MAX_BLOCK_LENGTH 6000
#define MAX_BLOCK_LENGTH 8448
/*
int test_ldpc(unsigned int coded_bits,
double sigma,
unsigned char qbits,
......@@ -74,35 +76,160 @@ int test_ldpc(unsigned int coded_bits,
unsigned int *uerrors,
unsigned int *crc_misses,
unsigned int *iterations)
*/
int test_ldpc(short No_iteration,
double rate,
double SNR,
unsigned char qbits,
unsigned int block_length,
unsigned int ntrials,
unsigned int *errors,
unsigned int *crc_misses)
{
unsigned char test_input[block_length+1];
unsigned char decoded_output[block_length];
short *channel_input, *channel_output;
unsigned int i,trial=0;
unsigned int crc=0;
unsigned char ret;
unsigned char uerr;
short test_input[block_length];
short *c; //padded codeword
short *esimated_output;
short *channel_input;
double *channel_output;
double *modulated_input;
short *channel_output_fixed;
unsigned int i,trial=0;
unsigned char crc_type;
channel_input = (short *)malloc(coded_bits*sizeof(short));
channel_output = (short *)malloc(coded_bits*sizeof(short));
short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
short BG,Zc,Kb,nrows,ncols;
int i1,i2,i3,i4,t;
*iterations=0;
//Table of possible lifting sizes
short lift_size[51]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
*errors=0;
*crc_misses=0;
*uerrors=0;
while (trial++ < ntrials) {
// generate input block
for (i=0; i<block_length; i++) {
// printf("encoding\n");
// test_input[0] = 0x80;
for (i=0; i<block_length; i++) {
test_input[i] = (unsigned char)(taus()&0xff);
//test_input[i] = (unsigned char)(taus()&0xff);
test_input[i]=rand()%2;
}
//determine number of bits in codeword
if (block_length>3840)
{
BG=1;
Kb = 22;
nrows=46;
ncols=22;
}
else if (block_length<=3840)
{
BG=2;
nrows=42;
ncols=10;
if (block_length>640)
Kb = 10;
else if (block_length>560)
Kb = 9;
else if (block_length>192)
Kb = 8;
else
Kb = 6;
}
//find minimum value in all sets of lifting size
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
{
Zc = lift_size[i1];
// printf("%d\n",Zc);
break;
}
}
// load base graph of generator matrix
if (BG==1)
{
no_shift_values=(short*) no_shift_values_BG1;
pointer_shift_values=(short*) pointer_shift_values_BG1;
if (Zc==2||Zc==4||Zc==8||Zc==16||Zc==32||Zc==64||Zc==128||Zc==256)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_2;
else if (Zc==3||Zc==6||Zc==12||Zc==24||Zc==48||Zc==96||Zc==192||Zc==384)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_3;
else if (Zc==5||Zc==10||Zc==20||Zc==40||Zc==80||Zc==160||Zc==320)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_5;
else if (Zc==7||Zc==14||Zc==28||Zc==56||Zc==112||Zc==224)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_7;
else if (Zc==9||Zc==18||Zc==36||Zc==72||Zc==144||Zc==288)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_9;
else if (Zc==11||Zc==22||Zc==44||Zc==88||Zc==176||Zc==352)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_11;
else if (Zc==13||Zc==26||Zc==52||Zc==104||Zc==208)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_13;
else if (Zc==15||Zc==30||Zc==60||Zc==120||Zc==240)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_15;
}
else if (BG==2)
{
no_shift_values=(short*) no_shift_values_BG2;
pointer_shift_values=(short*) pointer_shift_values_BG2;
if (Zc==2||Zc==4||Zc==8||Zc==16||Zc==32||Zc==64||Zc==128||Zc==256)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_2;
else if (Zc==3||Zc==6||Zc==12||Zc==24||Zc==48||Zc==96||Zc==192||Zc==384)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_3;
else if (Zc==5||Zc==10||Zc==20||Zc==40||Zc==80||Zc==160||Zc==320)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_5;
else if (Zc==7||Zc==14||Zc==28||Zc==56||Zc==112||Zc==224)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_7;
else if (Zc==9||Zc==18||Zc==36||Zc==72||Zc==144||Zc==288)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_9;
else if (Zc==11||Zc==22||Zc==44||Zc==88||Zc==176||Zc==352)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_11;
else if (Zc==13||Zc==26||Zc==52||Zc==104||Zc==208)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_13;
else if (Zc==15||Zc==30||Zc==60||Zc==120||Zc==240)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_15;
}
c=(short *)malloc(sizeof(short) * Kb * Zc);
channel_input = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
modulated_input = (double *)malloc( (Kb+nrows) * Zc*sizeof(double));
//channel_output = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
channel_output = (double *)malloc( (Kb+nrows) * Zc*sizeof(double));
channel_output_fixed = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
//padded input sequence
memset(c,0,sizeof(short) * Kb * Zc);
memcpy(c,test_input,block_length * sizeof(short));
//encode the input sequence
memset(channel_input,0,(Kb+nrows) * Zc*sizeof(short));
// parity check part
for (i1=0,t=Kb*Zc; i1 < nrows; i1++)
{
for (i2=0; i2 < Zc; i2++)
{
for (i3=0; i3 < Kb; i3++)
{
for (i4=0; i4 < no_shift_values[i1 * ncols + i3]; i4++)
{
channel_input[t] = channel_input[t] + c[ i3*Zc + (Gen_shift_values[ pointer_shift_values[i1 * ncols + i3]+i4 ] + i2 + Zc) % Zc ];
//start pointer %element %shift Z
}
}
channel_input[t]=channel_input[t]&1;
t++;
}
}
// information part
memcpy(channel_input,c,Kb*Zc*sizeof(short));
//for (i=0;i<(Kb+nrows) * Zc;i++)
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
//replace with ldpc encoder, write to channel_input
/*
dlsch_encoding(test_input,
......@@ -114,22 +241,30 @@ int test_ldpc(unsigned int coded_bits,
&PHY_vars_eNB->dlsch_rate_matching_stats,
&PHY_vars_eNB->dlsch_turbo_encoding_stats,
&PHY_vars_eNB->dlsch_interleaving_stats);
*/
uerr=0;
for (i = 0; i < coded_bits; i++) {
*/
for (i = 0; i < (Kb+nrows) * Zc; i++) {
#ifdef DEBUG_CODER
if ((i&0xf)==0)
printf("\ne %d..%d: ",i,i+15);
#endif
channel_output[i] = (short)quantize(sigma/4.0,(2.0*channel_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
//channel_output[i] = (short)quantize(sigma/4.0,(2.0*channel_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
if (channel_input[i]==0)
modulated_input[i]=1/sqrt(2); //QPSK
else
modulated_input[i]=-1/sqrt(2);
channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
channel_output_fixed[i] = (short) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
//printf("%lf %d\n",channel_output[i], channel_output_fixed[i]);
//printf("v[%d]=%lf\n",i,modulated_input[i]);
}
#ifdef DEBUG_CODER
printf("\n");
exit(-1);
#endif
esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, rate);
//for (i=0;i<(Kb+nrows) * Zc;i++)
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
// replace this with ldpc decoder
/*
......@@ -142,73 +277,43 @@ int test_ldpc(unsigned int coded_bits,
subframe,
PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid,
num_pdcch_symbols,1);
*/
*/
/*
if (ret < dlsch_ue->max_turbo_iterations+1) {
*iterations = (*iterations) + ret;
// if (ret>1)
// printf("ret %d\n",ret);
} else
*iterations = (*iterations) + (ret-1);
if (uerr==1)
*uerrors = (*uerrors) + 1;
*/
for (i=0; i<block_length; i++) {
for (i=0;i<(Kb+nrows) * Zc;i++) {
if (decoded_output[i] != test_input[i]) {
if (esimated_output[i] != channel_input[i]) {
*errors = (*errors) + 1;
// printf("*%d, ret %d\n",*errors,ret);
/*
if (ret < dlsch_ue->max_turbo_iterations+1)
*crc_misses = (*crc_misses)+1;
*/
break;
}
}
/*
if (ret == dlsch_ue->max_turbo_iterations+1) {
// exit(-1);
}
*/
if (*errors == 100) {
printf("trials %d\n",trial);
break;
}
}
}
//printf("%d\n",*errors);
return *errors;
*trials = trial;
// printf("lte: trials %d, errors %d\n",trial,*errors);
return(0);
}
#define NTRIALS 10000
//#define NTRIALS 10000
#define NTRIALS 300
int main(int argc, char *argv[])
{
int ret,ret2;
unsigned int errors,uerrors,errors2,crc_misses,iterations,trials,trials2,block_length,errors3,trials3;
double SNR,sigma,rate=.5;
unsigned char qbits,mcs;
char done0=0;
char done1=1;
char done2=1;
unsigned int coded_bits;
unsigned int errors,crc_misses;
unsigned int block_length=1280;
short No_iteration=25;
double rate=0.2;
double SNR,SNR_lin;
unsigned char qbits;
unsigned char NB_RB=25;
int num_pdcch_symbols = 1;
int subframe = 6;
int i=0;
randominit(0);
//logInit();
......@@ -217,26 +322,15 @@ int main(int argc, char *argv[])
else
qbits = 4;
printf("Quantization bits %d\n",qbits);
printf("Coded_bits (G) = %d\n",coded_bits);
for (SNR=-5; SNR<15; SNR+=.1) {
sigma = pow(10.0,-.05*SNR);
printf("\n\nSNR %f dB => sigma %f\n",SNR,sigma);
errors=0;
crc_misses=0;
errors2=0;
errors3=0;
iterations=0;
if (done0 == 0) {
//printf("Quantization bits %d\n",qbits);
unsigned int decoded_errors[2]; // initiate the size of matrix equivalent to
// size of SNR
for (SNR=-3; SNR<-2.8; SNR+=.1) {
SNR_lin = pow(10,SNR/10);
/*
ret = test_ldpc(coded_bits,
sigma, // noise standard deviation
qbits,
......@@ -247,20 +341,23 @@ int main(int argc, char *argv[])
&uerrors,
&crc_misses,
&iterations);
if (ret>=0)
printf("%f,%f,%f,%f\n",SNR,(double)errors/trials,(double)crc_misses/trials,(double)iterations/trials);
if (((double)errors/trials) < 1e-2)
done0=1;
}
if ((done0==1) && (done1==1) && (done2==1)) {
printf("done\n");
break;
}
*/
decoded_errors[i]=test_ldpc(No_iteration,
rate,
SNR_lin, // noise standard deviation
qbits,
block_length, // block length bytes
NTRIALS,
&errors,
&crc_misses);
i=i+1;
}
printf("%d\n",decoded_errors[0]);
printf("%d\n",decoded_errors[1]);
//printf("%d\n",errors[2]);
return(0);
}
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "SIMULATION/TOOLS/defs.h"
#include "Gen_shift_value.h"
#include "test.h"
// 4-bit quantizer
char quantize4bit(double D,double x)
{
double qxd;
qxd = floor(x/D);
// printf("x=%f,qxd=%f\n",x,qxd);
if (qxd <= -8)
qxd = -8;
else if (qxd > 7)
qxd = 7;
return((char)qxd);
}
char quantize(double D,double x,unsigned char B)
{
double qxd;
char maxlev;
qxd = floor(x/D);
// printf("x=%f,qxd=%f\n",x,qxd);
maxlev = 1<<(B-1);
if (qxd <= -maxlev)
qxd = -maxlev;
else if (qxd >= maxlev)
qxd = maxlev-1;
return((char)qxd);
}
//#define MAX_BLOCK_LENGTH 6000
#define MAX_BLOCK_LENGTH 8448
/*
int test_ldpc(unsigned int coded_bits,
double sigma,
unsigned char qbits,
unsigned int block_length,
unsigned int ntrials,
unsigned int *errors,
unsigned int *trials,
unsigned int *uerrors,
unsigned int *crc_misses,
unsigned int *iterations)
*/
int test_ldpc(short No_iteration,
double rate,
double SNR,
unsigned char qbits,
unsigned int block_length,
unsigned int ntrials,
unsigned int *errors,
unsigned int *crc_misses)
{
//unsigned char test_input[block_length+1];
short test_input[block_length];
short *c; //padded codeword
short *esimated_output;
short *channel_input;
double *channel_output;
double *modulated_input;
short *channel_output_fixed;
unsigned int i,trial=0;
unsigned char crc_type;
short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
short BG,Zc,Kb,nrows,ncols;
int i1,i2,i3,i4,t;
//Table of possible lifting sizes
short lift_size[51]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
*errors=0;
*crc_misses=0;
while (trial++ < ntrials) {
// printf("encoding\n");
// test_input[0] = 0x80;
// generate input block
for (i=0; i<block_length; i++) {
//test_input[i] = (unsigned char)(taus()&0xff);
test_input[i]=rand()%2;
}
//determine number of bits in codeword
if (block_length>3840)
{
BG=1;
Kb = 22;
nrows=46;
ncols=22;
}
else if (block_length<=3840)
{
BG=2;
nrows=42;
ncols=10;
if (block_length>640)
Kb = 10;
else if (block_length>560)
Kb = 9;
else if (block_length>192)
Kb = 8;
else
Kb = 6;
}
//find minimum value in all sets of lifting size
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
{
Zc = lift_size[i1];
// printf("%d\n",Zc);
break;
}
}
// load base graph of generator matrix
if (BG==1)
{
no_shift_values=(short*) no_shift_values_BG1;
pointer_shift_values=(short*) pointer_shift_values_BG1;
if (Zc==2||Zc==4||Zc==8||Zc==16||Zc==32||Zc==64||Zc==128||Zc==256)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_2;
else if (Zc==3||Zc==6||Zc==12||Zc==24||Zc==48||Zc==96||Zc==192||Zc==384)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_3;
else if (Zc==5||Zc==10||Zc==20||Zc==40||Zc==80||Zc==160||Zc==320)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_5;
else if (Zc==7||Zc==14||Zc==28||Zc==56||Zc==112||Zc==224)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_7;
else if (Zc==9||Zc==18||Zc==36||Zc==72||Zc==144||Zc==288)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_9;
else if (Zc==11||Zc==22||Zc==44||Zc==88||Zc==176||Zc==352)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_11;
else if (Zc==13||Zc==26||Zc==52||Zc==104||Zc==208)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_13;
else if (Zc==15||Zc==30||Zc==60||Zc==120||Zc==240)
Gen_shift_values=(short*) Gen_shift_values_BG1_a_15;
}
else if (BG==2)
{
no_shift_values=(short*) no_shift_values_BG2;
pointer_shift_values=(short*) pointer_shift_values_BG2;
if (Zc==2||Zc==4||Zc==8||Zc==16||Zc==32||Zc==64||Zc==128||Zc==256)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_2;
else if (Zc==3||Zc==6||Zc==12||Zc==24||Zc==48||Zc==96||Zc==192||Zc==384)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_3;
else if (Zc==5||Zc==10||Zc==20||Zc==40||Zc==80||Zc==160||Zc==320)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_5;
else if (Zc==7||Zc==14||Zc==28||Zc==56||Zc==112||Zc==224)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_7;
else if (Zc==9||Zc==18||Zc==36||Zc==72||Zc==144||Zc==288)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_9;
else if (Zc==11||Zc==22||Zc==44||Zc==88||Zc==176||Zc==352)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_11;
else if (Zc==13||Zc==26||Zc==52||Zc==104||Zc==208)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_13;
else if (Zc==15||Zc==30||Zc==60||Zc==120||Zc==240)
Gen_shift_values=(short*) Gen_shift_values_BG2_a_15;
}
c=(short *)malloc(sizeof(short) * Kb * Zc);
channel_input = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
modulated_input = (double *)malloc( (Kb+nrows) * Zc*sizeof(double));
//channel_output = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
channel_output = (double *)malloc( (Kb+nrows) * Zc*sizeof(double));
channel_output_fixed = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
//padded input sequence
memset(c,0,sizeof(short) * Kb * Zc);
memcpy(c,test_input,block_length * sizeof(short));
//encode the input sequence
memset(channel_input,0,(Kb+nrows) * Zc*sizeof(short));
// parity check part
for (i1=0,t=Kb*Zc; i1 < nrows; i1++)
{
for (i2=0; i2 < Zc; i2++)
{
for (i3=0; i3 < Kb; i3++)
{
for (i4=0; i4 < no_shift_values[i1 * ncols + i3]; i4++)
{
channel_input[t] = channel_input[t] + c[ i3*Zc + (Gen_shift_values[ pointer_shift_values[i1 * ncols + i3]+i4 ] + i2 + Zc) % Zc ];
//start pointer %element %shift Z
}
}
channel_input[t]=channel_input[t]&1;
t++;
}
}
// information part
memcpy(channel_input,c,Kb*Zc*sizeof(short));
//for (i=0;i<(Kb+nrows) * Zc;i++)
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
//replace with ldpc encoder, write to channel_input
/*
dlsch_encoding(test_input,
&PHY_vars_eNB->lte_frame_parms,
num_pdcch_symbols,
PHY_vars_eNB->dlsch_eNB[0][0],
0,
subframe,
&PHY_vars_eNB->dlsch_rate_matching_stats,
&PHY_vars_eNB->dlsch_turbo_encoding_stats,
&PHY_vars_eNB->dlsch_interleaving_stats);
*/
// uerr=0;
//for (i = 0; i < coded_bits; i++) {
for (i = 0; i < (Kb+nrows) * Zc; i++) {
#ifdef DEBUG_CODER
if ((i&0xf)==0)
printf("\ne %d..%d: ",i,i+15);
#endif
//channel_output[i] = (short)quantize(sigma/4.0,(2.0*channel_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
if (channel_input[i]==0)
modulated_input[i]=1/sqrt(2); //QPSK
else
modulated_input[i]=-1/sqrt(2);
channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
channel_output_fixed[i] = (short) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
//printf("%lf %d\n",channel_output[i], channel_output_fixed[i]);
//printf("v[%d]=%lf\n",i,modulated_input[i]);
}
#ifdef DEBUG_CODER
printf("\n");
exit(-1);
#endif
esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, rate);
//for (i=0;i<(Kb+nrows) * Zc;i++)
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
// replace this with ldpc decoder
/*
ret = dlsch_decoding(PHY_vars_UE,
channel_output,
&PHY_vars_UE->lte_frame_parms,
PHY_vars_UE->dlsch_ue[0][0],
PHY_vars_UE->dlsch_ue[0][0]->harq_processes[PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid],
frame,
subframe,
PHY_vars_UE->dlsch_ue[0][0]->current_harq_pid,
num_pdcch_symbols,1);
*/
for (i=0;i<(Kb+nrows) * Zc;i++) {
if (esimated_output[i] != channel_input[i]) {
*errors = (*errors) + 1;
break;
}
}
}
//printf("%d\n",*errors);
return *errors;
}
//#define NTRIALS 10000
#define NTRIALS 300
int main(int argc, char *argv[])
{
unsigned int errors,crc_misses;
unsigned int block_length=1280;
short No_iteration=25;
double rate=0.2;
double SNR,SNR_lin;
unsigned char qbits;
unsigned char NB_RB=25;
int num_pdcch_symbols = 1;
int subframe = 6;
int i=0;
randominit(0);
//logInit();
if (argc>1)
qbits = atoi(argv[1]);
else
qbits = 4;
//printf("Quantization bits %d\n",qbits);
unsigned int decoded_errors[2]; // initiate the size of matrix equivalent to
// size of SNR
for (SNR=-3; SNR<-2.8; SNR+=.1) {
SNR_lin = pow(10,SNR/10);
/*
ret = test_ldpc(coded_bits,
sigma, // noise standard deviation
qbits,
block_length, // block length bytes
NTRIALS,
&errors,
&trials,
&uerrors,
&crc_misses,
&iterations);
*/
decoded_errors[i]=test_ldpc(No_iteration,
rate,
SNR_lin, // noise standard deviation
qbits,
block_length, // block length bytes
NTRIALS,
&errors,
&crc_misses);
i=i+1;
}
printf("%d\n",decoded_errors[0]);
printf("%d\n",decoded_errors[1]);
//printf("%d\n",errors[2]);
return(0);
}
short sign(short x) {
return (x > 0) - (x < 0);
}
short *ldpc_decoder(short *msgChannel,short block_length,short No_iteration,double rate) {
// input
//short No_iteration;
//int *shift_value, *Col_position, *no_one_element, Z, BG,Kb;
//double rate;
//output
//char *output_estimate;
short *v_estimate; //estimated codeword
//variables
//int *shift_value, *Col_position, *no_one_element, Zc, BG,Kb;
int Zc, BG,Kb;
int nrows, ncols, nEdge_base_graph;
int irow, iShift, iZ,p1,p2,t1,temp_row,temp_col,iBit,iEdge;
int nEdge,nCheck,nBit;
int rows_total_La1=0,rows_total_La2=0,rows_total_La3=0,*no_rows_La1, *no_rows_La2, *no_rows_La3;
int i1, i2, i3, sum, sum1, sum2, no_punctured_columns, layer, iLayer, n=1, flag=0;
int *idxBit, idxCheck,*degBit, *degCheck,*degBit_base_graph, *pointerCheck, *pointerBit, *pointerCheck_temp, *pointerBit_temp;
int *idxEdge2Bit,*idxEdge2Check;
int *no_rows;
int rows_total;
short *msgBit2Check, *msgCheck2Bit, *msgBit; //variables for message passing algorithm
short mini;
short sgn;
int isEqual;
char syn; //syndrome
short lift_size[51]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
short shift_value[197]={9,117,204,26,189,205,0,0,167,166,253,125,226,156,224,252,0,0,81,114,44,52,240,1,0,0,8,58,158,104,209,54,18,128,0,0,179,214,71,0,231,41,194,159,103,0,155,228,45,28,158,0,129,147,140,3,116,0,142,94,230,0,203,205,61,247,0,11,185,0,117,0,11,236,210,56,0,63,111,14,0,83,2,38,222,0,115,145,3,232,0,51,175,213,0,203,142,8,242,0,254,124,114,64,0,220,194,50,0,87,20,185,0,26,105,29,0,76,42,210,0,222,63,0,23,235,238,0,46,139,8,0,228,156,0,29,143,160,122,0,8,151,0,98,101,135,0,18,28,0,71,240,9,84,0,106,1,0,242,44,166,0,132,164,235,0,147,85,36,0,57,40,63,0,140,38,154,0,219,151,0,31,66,38,0,239,172,34,0,0,75,120,0,129,229,118,0};
short Col_position[197]={0,1,2,3,6,9,10,11,0,3,4,5,6,7,8,9,11,12,0,1,3,4,8,10,12,13,1,2,4,5,6,7,8,9,10,13,0,1,11,14,0,1,5,7,11,15,0,5,7,9,11,16,1,5,7,11,13,17,0,1,12,18,1,8,10,11,19,0,1,6,7,20,0,7,9,13,21,1,3,11,22,0,1,8,13,23,1,6,11,13,24,0,10,11,25,1,9,11,12,26,1,5,11,12,27,0,6,7,28,0,1,10,29,1,4,11,30,0,8,13,31,1,2,32,0,3,5,33,1,2,9,34,0,5,35,2,7,12,13,36,0,6,37,1,2,5,38,0,4,39,2,5,7,9,40,1,13,41,0,5,12,42,2,7,10,43,0,12,13,44,1,5,11,45,0,2,7,46,10,13,47,1,5,11,48,0,7,12,49,2,10,13,50,1,5,11,51};
short no_one_element[42]={8, 10, 8, 10, 4, 6, 6, 6, 4, 5, 5, 5, 4, 5, 5, 4, 5, 5, 4, 4, 4, 4, 3, 4, 4, 3, 5, 3, 4, 3, 5, 3, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4};
if (block_length>3840)
{
BG=1;
Kb = 22;
nrows=46;
ncols=68;
}
else if (block_length<=3840)
{
BG=2;
nrows=42;
if (block_length>640)
{
Kb = 10;
ncols=52;
}
else if (block_length>560)
{
Kb = 9;
ncols=51;
}
else if (block_length>192)
{
Kb = 8;
ncols=50;
}
else
{
Kb = 6;
ncols=48;
}
}
//find minimum value in all sets of lifting size
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
{
Zc = lift_size[i1];
// printf("%d",Zc);
break;
}
}
nEdge_base_graph=197;
nEdge=nEdge_base_graph*Zc;
nCheck=nrows*Zc;
nBit=ncols*Zc;
//initial positions of pointers to check nodes
//degrees of check nodes
pointerCheck = (int *)malloc(sizeof(int) * nCheck);
degCheck=(int *)malloc(sizeof(int) * nCheck);
for (i1=0,temp_row=0; i1 < nrows; i1++)
{
for (i2=0; i2 < Zc; i2++)
{
degCheck[i1*Zc+i2] = no_one_element[i1]; //degree equals number of 1 elements in a row
pointerCheck[i1*Zc+i2] = temp_row;
temp_row = temp_row + no_one_element[i1];
}
}
//initial positions of pointers to bit nodes
//degrees of bit nodes
pointerBit = (int *)malloc(sizeof(int) * nBit);
degBit=(int *)malloc(sizeof(int) * nBit);
degBit_base_graph=(int *)malloc(sizeof(int) * ncols);
memset(degBit_base_graph,0,sizeof(int) * ncols);
for (iBit=0; iBit < nEdge_base_graph; ++iBit)
{
++degBit_base_graph[Col_position[iBit]]; //number of 1 elements in a columns in base graph
}
for (i1=0,temp_col=0; i1 < ncols; i1++)
{
for (i2=0; i2 < Zc; i2++)
{
degBit[i1*Zc+i2] = degBit_base_graph[i1]; //degree equals number of 1 elements in a column
pointerBit[i1*Zc+i2] = temp_col;
temp_col = temp_col + degBit_base_graph[i1];
}
}
//indice and degrees of check nodes and bit nodes
//divide layer for message passing algorithm
idxBit=(int *)malloc(sizeof(int) * nEdge);
// idxCheck=mxMalloc(sizeof(int) * nEdge);
idxEdge2Bit=(int *)malloc(sizeof(int) * nEdge);
idxEdge2Check=(int *)malloc(sizeof(int) * nEdge);
pointerCheck_temp = (int *)malloc(sizeof(int) * nCheck);
memcpy(pointerCheck_temp,pointerCheck,sizeof(int) * nCheck);
pointerBit_temp = (int *)malloc(sizeof(int) * nBit);
memcpy(pointerBit_temp,pointerBit,sizeof(int) * nBit);
no_rows_La1=(int *)malloc(sizeof(int) * nBit);
no_rows_La2=(int *)malloc(sizeof(int) * nBit);
no_rows_La3=(int *)malloc(sizeof(int) * nBit);
for (irow=0,p1=0,t1=0,iEdge=0; irow < nrows; ++irow) //loop for rows in base graph
{
temp_row=irow*Zc;
sum=0;sum1=0;sum2=0;
for (iShift=0; iShift < no_one_element[irow]; ++iShift) //loop for 1 elements in one row of base graph
{
temp_col=Col_position[p1]*Zc;
if ( ((rate==0.2)&&(BG==2)&&(Kb==10)) || ((rate==0.33)&&(BG==1)&&(Kb==22)) ) //layer , no rate matching
{
layer=2;
if (Col_position[p1]==0||Col_position[p1]==1)
sum++;
}
else if ( ( (BG==1) && (rate>=0.33) && (rate<=0.89) )||( (BG==2) && (rate>=0.2) && (rate<=0.67) ) ) //layer, rate matching
{
layer=3;
no_punctured_columns=ceil(nBit/Zc-2-Kb/rate);
if (Col_position[p1]==0 || Col_position[p1]==1)
sum1++;
if ( (Col_position[p1] >= ncols-no_punctured_columns) && (Col_position[p1] < ncols) )
sum2++;
}
for (iZ=0,p2=0; iZ < Zc; iZ++) //loop for lift size
{
idxBit[t1] = (shift_value[p1]+p2)%Zc + temp_col; //column positions
p2++;
idxCheck = temp_row + iZ; // row positions
idxEdge2Check[ pointerCheck_temp[idxCheck] ] = iEdge; //label and store the edges connecting to check nodes
++pointerCheck_temp[idxCheck];
idxEdge2Bit[ pointerBit_temp[idxBit[t1]] ] = iEdge; //label and store the edges connecting to bit nodes
++pointerBit_temp[idxBit[t1]];
iEdge++;
t1++;
}
p1++;
}
if ( ((rate==0.2)&&(BG==2)&&(Kb==10)) || ((rate==0.33)&&(BG==1)&&(Kb==22)) )
{
if (sum==1||sum==0)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La1[rows_total_La1]=irow*Zc + i1;
rows_total_La1++;
}
}
else
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La2[rows_total_La2]=irow*Zc + i1;
rows_total_La2++;
}
}
}
else if (( (BG==1) && (rate>=0.33) && (rate<=0.89) )||( (BG==2) && (rate>=0.2) && (rate<=0.67) ))
{
sum=sum1+sum2;
if (sum==1)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La1[rows_total_La1]=irow*Zc + i1;
rows_total_La1++;
}
}
else if (sum==2)
{
if (sum1==1)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La2[rows_total_La2]=irow*Zc + i1;
rows_total_La2++;
}
}
else if (sum1==2)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La3[rows_total_La3]=irow*Zc + i1;
rows_total_La3++;
}
}
}
else if (sum==3)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La2[rows_total_La2]=irow*Zc + i1;
rows_total_La2++;
}
}
else if (sum==0)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La3[rows_total_La3]=irow*Zc + i1;
rows_total_La3++;
}
}
}
}
// allocate memory for message passing algorithm
msgBit2Check=(short *)malloc(sizeof(short) * nEdge);
msgCheck2Bit=(short *)malloc(sizeof(short) * nEdge);
msgBit=(short *)malloc(sizeof(short) * nBit);
memset(msgCheck2Bit,0,sizeof(short) * nEdge);
v_estimate=(short *)malloc(sizeof(short) * nBit);
// initial values of LLR of bit nodes
memcpy(msgBit,msgChannel,nBit*sizeof(short));
//message passing algorithm
while (n<=No_iteration)
{
for (iLayer=1;iLayer<=layer;iLayer++)
{
if (iLayer==1)
{
no_rows=no_rows_La1;
rows_total=rows_total_La1;
}
else if (iLayer==2)
{
no_rows=no_rows_La2;
rows_total=rows_total_La2;
}
else if (iLayer==3)
{
no_rows=no_rows_La3;
rows_total=rows_total_La3;
}
//message from bit nodes to check nodes
for(i1 = 0; i1 < rows_total; ++i1)
{
for(i2 = 0; i2 < degCheck[no_rows[i1]]; ++i2)
{
msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2] ] = msgBit[ idxBit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2] ] ]
-msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2] ];
}
}
//message from check nodes to bit nodes
for(i1 = 0; i1 < rows_total; ++i1)
{
for(i2 = 0; i2 < degCheck[no_rows[i1]]; ++i2)
{
mini=32640;
sgn=1;
for(i3 = 0; i3 < degCheck[no_rows[i1]]; ++i3)
{
if (idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] != idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ])
{
sgn *=sign(msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] ]);
if (abs(msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] ]) < mini)
mini=abs(msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] ]);
}
}
msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ]=sgn * mini;
//atanh(1)=19.07, 19.07 is converted to fixed-point 9_7= 19.07*2^7=2441
if ( msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] > 2441)
msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] = 2441;
if (msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] < -2441)
msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] = -2441;
}
}
// LLR
for(iBit = 0; iBit < nBit; ++iBit)
{
msgBit[iBit]=msgChannel[iBit];
for(i1 = 0; i1 < degBit[iBit]; ++i1)
msgBit[iBit] += msgCheck2Bit[idxEdge2Bit[ pointerBit[iBit]+i1 ] ];
if (msgBit[iBit]>=0)
v_estimate[iBit]=0;
else
v_estimate[iBit]=1;
}
// // LLR
// for(iBit = 0; iBit < nBit; ++iBit)
// {
// msgBit[iBit]=msgChannel[iBit];
// for(i1 = 0; i1 < degBit[iBit]; ++i1)
// msgBit[iBit] += msgCheck2Bit[idxEdge2Bit[ pointerBit[iBit]+i1 ] ];
// }
//
// //estimate codeword
// v_estimate=mxMalloc(sizeof(char) * nBit);
// for(iBit = 0; iBit < nBit; ++iBit)
// {
// if (msgBit[iBit]>=0)
// v_estimate[iBit]=0;
// else
// v_estimate[iBit]=1;
// }
//check syndrome=0
for (i1=0,isEqual=1; i1 < nCheck; ++i1)
{
syn=0;
for(i2 = 0; i2 < degCheck[i1]; ++i2)
{
//sum of bits of estimated codeword in the positions where there are 1 elements in graph
syn += v_estimate[ idxBit[ idxEdge2Check[ pointerCheck[ i1 ] + i2 ] ] ];
}
syn=syn%2;
if (syn != 0)
{
isEqual=0;
break;
}
}
if (isEqual==1) //syndrome=0, break
{
flag=1;
break;
}
}
if (flag==1)
{
break;
}
n++;
}
return v_estimate;
}
short sign(short x) {
return (x > 0) - (x < 0);
}
short *ldpc_decoder(short *msgChannel,short block_length,short No_iteration,double rate) {
// input
//short No_iteration;
//int *shift_value, *Col_position, *no_one_element, Z, BG,Kb;
//double rate;
//output
//char *output_estimate;
short *v_estimate; //estimated codeword
//variables
//int *shift_value, *Col_position, *no_one_element, Zc, BG,Kb;
int Zc, BG,Kb;
int nrows, ncols, nEdge_base_graph;
int irow, iShift, iZ,p1,p2,t1,temp_row,temp_col,iBit,iEdge;
int nEdge,nCheck,nBit;
int rows_total_La1=0,rows_total_La2=0,rows_total_La3=0,*no_rows_La1, *no_rows_La2, *no_rows_La3;
int i1, i2, i3, sum, sum1, sum2, no_punctured_columns, layer, iLayer, n=1, flag=0;
int *idxBit, idxCheck,*degBit, *degCheck,*degBit_base_graph, *pointerCheck, *pointerBit, *pointerCheck_temp, *pointerBit_temp;
int *idxEdge2Bit,*idxEdge2Check;
int *no_rows;
int rows_total;
short *msgBit2Check, *msgCheck2Bit, *msgBit; //variables for message passing algorithm
short mini;
short sgn;
int isEqual;
char syn; //syndrome
short lift_size[51]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
short shift_value[197]={9,117,204,26,189,205,0,0,167,166,253,125,226,156,224,252,0,0,81,114,44,52,240,1,0,0,8,58,158,104,209,54,18,128,0,0,179,214,71,0,231,41,194,159,103,0,155,228,45,28,158,0,129,147,140,3,116,0,142,94,230,0,203,205,61,247,0,11,185,0,117,0,11,236,210,56,0,63,111,14,0,83,2,38,222,0,115,145,3,232,0,51,175,213,0,203,142,8,242,0,254,124,114,64,0,220,194,50,0,87,20,185,0,26,105,29,0,76,42,210,0,222,63,0,23,235,238,0,46,139,8,0,228,156,0,29,143,160,122,0,8,151,0,98,101,135,0,18,28,0,71,240,9,84,0,106,1,0,242,44,166,0,132,164,235,0,147,85,36,0,57,40,63,0,140,38,154,0,219,151,0,31,66,38,0,239,172,34,0,0,75,120,0,129,229,118,0};
short Col_position[197]={0,1,2,3,6,9,10,11,0,3,4,5,6,7,8,9,11,12,0,1,3,4,8,10,12,13,1,2,4,5,6,7,8,9,10,13,0,1,11,14,0,1,5,7,11,15,0,5,7,9,11,16,1,5,7,11,13,17,0,1,12,18,1,8,10,11,19,0,1,6,7,20,0,7,9,13,21,1,3,11,22,0,1,8,13,23,1,6,11,13,24,0,10,11,25,1,9,11,12,26,1,5,11,12,27,0,6,7,28,0,1,10,29,1,4,11,30,0,8,13,31,1,2,32,0,3,5,33,1,2,9,34,0,5,35,2,7,12,13,36,0,6,37,1,2,5,38,0,4,39,2,5,7,9,40,1,13,41,0,5,12,42,2,7,10,43,0,12,13,44,1,5,11,45,0,2,7,46,10,13,47,1,5,11,48,0,7,12,49,2,10,13,50,1,5,11,51};
short no_one_element[42]={8, 10, 8, 10, 4, 6, 6, 6, 4, 5, 5, 5, 4, 5, 5, 4, 5, 5, 4, 4, 4, 4, 3, 4, 4, 3, 5, 3, 4, 3, 5, 3, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4};
if (block_length>3840)
{
BG=1;
Kb = 22;
nrows=46;
ncols=68;
}
else if (block_length<=3840)
{
BG=2;
nrows=42;
if (block_length>640)
{
Kb = 10;
ncols=52;
}
else if (block_length>560)
{
Kb = 9;
ncols=51;
}
else if (block_length>192)
{
Kb = 8;
ncols=50;
}
else
{
Kb = 6;
ncols=48;
}
}
//find minimum value in all sets of lifting size
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
{
Zc = lift_size[i1];
// printf("%d",Zc);
break;
}
}
nEdge_base_graph=197;
nEdge=nEdge_base_graph*Zc;
nCheck=nrows*Zc;
nBit=ncols*Zc;
//initial positions of pointers to check nodes
//degrees of check nodes
pointerCheck = (int *)malloc(sizeof(int) * nCheck);
degCheck=(int *)malloc(sizeof(int) * nCheck);
for (i1=0,temp_row=0; i1 < nrows; i1++)
{
for (i2=0; i2 < Zc; i2++)
{
degCheck[i1*Zc+i2] = no_one_element[i1]; //degree equals number of 1 elements in a row
pointerCheck[i1*Zc+i2] = temp_row;
temp_row = temp_row + no_one_element[i1];
}
}
//initial positions of pointers to bit nodes
//degrees of bit nodes
pointerBit = (int *)malloc(sizeof(int) * nBit);
degBit=(int *)malloc(sizeof(int) * nBit);
degBit_base_graph=(int *)malloc(sizeof(int) * ncols);
memset(degBit_base_graph,0,sizeof(int) * ncols);
for (iBit=0; iBit < nEdge_base_graph; ++iBit)
{
++degBit_base_graph[Col_position[iBit]]; //number of 1 elements in a columns in base graph
}
for (i1=0,temp_col=0; i1 < ncols; i1++)
{
for (i2=0; i2 < Zc; i2++)
{
degBit[i1*Zc+i2] = degBit_base_graph[i1]; //degree equals number of 1 elements in a column
pointerBit[i1*Zc+i2] = temp_col;
temp_col = temp_col + degBit_base_graph[i1];
}
}
//indice and degrees of check nodes and bit nodes
//divide layer for message passing algorithm
idxBit=(int *)malloc(sizeof(int) * nEdge);
// idxCheck=mxMalloc(sizeof(int) * nEdge);
idxEdge2Bit=(int *)malloc(sizeof(int) * nEdge);
idxEdge2Check=(int *)malloc(sizeof(int) * nEdge);
pointerCheck_temp = (int *)malloc(sizeof(int) * nCheck);
memcpy(pointerCheck_temp,pointerCheck,sizeof(int) * nCheck);
pointerBit_temp = (int *)malloc(sizeof(int) * nBit);
memcpy(pointerBit_temp,pointerBit,sizeof(int) * nBit);
no_rows_La1=(int *)malloc(sizeof(int) * nBit);
no_rows_La2=(int *)malloc(sizeof(int) * nBit);
no_rows_La3=(int *)malloc(sizeof(int) * nBit);
for (irow=0,p1=0,t1=0,iEdge=0; irow < nrows; ++irow) //loop for rows in base graph
{
temp_row=irow*Zc;
sum=0;sum1=0;sum2=0;
for (iShift=0; iShift < no_one_element[irow]; ++iShift) //loop for 1 elements in one row of base graph
{
temp_col=Col_position[p1]*Zc;
if ( ((rate==0.2)&&(BG==2)&&(Kb==10)) || ((rate==0.33)&&(BG==1)&&(Kb==22)) ) //layer , no rate matching
{
layer=2;
if (Col_position[p1]==0||Col_position[p1]==1)
sum++;
}
else if ( ( (BG==1) && (rate>=0.33) && (rate<=0.89) )||( (BG==2) && (rate>=0.2) && (rate<=0.67) ) ) //layer, rate matching
{
layer=3;
no_punctured_columns=ceil(nBit/Zc-2-Kb/rate);
if (Col_position[p1]==0 || Col_position[p1]==1)
sum1++;
if ( (Col_position[p1] >= ncols-no_punctured_columns) && (Col_position[p1] < ncols) )
sum2++;
}
for (iZ=0,p2=0; iZ < Zc; iZ++) //loop for lift size
{
idxBit[t1] = (shift_value[p1]+p2)%Zc + temp_col; //column positions
p2++;
idxCheck = temp_row + iZ; // row positions
idxEdge2Check[ pointerCheck_temp[idxCheck] ] = iEdge; //label and store the edges connecting to check nodes
++pointerCheck_temp[idxCheck];
idxEdge2Bit[ pointerBit_temp[idxBit[t1]] ] = iEdge; //label and store the edges connecting to bit nodes
++pointerBit_temp[idxBit[t1]];
iEdge++;
t1++;
}
p1++;
}
if ( ((rate==0.2)&&(BG==2)&&(Kb==10)) || ((rate==0.33)&&(BG==1)&&(Kb==22)) )
{
if (sum==1||sum==0)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La1[rows_total_La1]=irow*Zc + i1;
rows_total_La1++;
}
}
else
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La2[rows_total_La2]=irow*Zc + i1;
rows_total_La2++;
}
}
}
else if (( (BG==1) && (rate>=0.33) && (rate<=0.89) )||( (BG==2) && (rate>=0.2) && (rate<=0.67) ))
{
sum=sum1+sum2;
if (sum==1)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La1[rows_total_La1]=irow*Zc + i1;
rows_total_La1++;
}
}
else if (sum==2)
{
if (sum1==1)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La2[rows_total_La2]=irow*Zc + i1;
rows_total_La2++;
}
}
else if (sum1==2)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La3[rows_total_La3]=irow*Zc + i1;
rows_total_La3++;
}
}
}
else if (sum==3)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La2[rows_total_La2]=irow*Zc + i1;
rows_total_La2++;
}
}
else if (sum==0)
{
for (i1=0; i1 < Zc; i1++)
{
no_rows_La3[rows_total_La3]=irow*Zc + i1;
rows_total_La3++;
}
}
}
}
// allocate memory for message passing algorithm
msgBit2Check=(short *)malloc(sizeof(short) * nEdge);
msgCheck2Bit=(short *)malloc(sizeof(short) * nEdge);
msgBit=(short *)malloc(sizeof(short) * nBit);
memset(msgCheck2Bit,0,sizeof(short) * nEdge);
v_estimate=(short *)malloc(sizeof(short) * nBit);
// initial values of LLR of bit nodes
memcpy(msgBit,msgChannel,nBit*sizeof(short));
//message passing algorithm
while (n<=No_iteration)
{
for (iLayer=1;iLayer<=layer;iLayer++)
{
if (iLayer==1)
{
no_rows=no_rows_La1;
rows_total=rows_total_La1;
}
else if (iLayer==2)
{
no_rows=no_rows_La2;
rows_total=rows_total_La2;
}
else if (iLayer==3)
{
no_rows=no_rows_La3;
rows_total=rows_total_La3;
}
//message from bit nodes to check nodes
for(i1 = 0; i1 < rows_total; ++i1)
{
for(i2 = 0; i2 < degCheck[no_rows[i1]]; ++i2)
{
msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2] ] = msgBit[ idxBit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2] ] ]
-msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2] ];
}
}
//message from check nodes to bit nodes
for(i1 = 0; i1 < rows_total; ++i1)
{
for(i2 = 0; i2 < degCheck[no_rows[i1]]; ++i2)
{
mini=32640;
sgn=1;
for(i3 = 0; i3 < degCheck[no_rows[i1]]; ++i3)
{
if (idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] != idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ])
{
sgn *=sign(msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] ]);
if (abs(msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] ]) < mini)
mini=abs(msgBit2Check[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i3] ]);
}
}
msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ]=sgn * mini;
//atanh(1)=19.07, 19.07 is converted to fixed-point 9_7= 19.07*2^7=2441
if ( msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] > 2441)
msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] = 2441;
if (msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] < -2441)
msgCheck2Bit[ idxEdge2Check[ pointerCheck[no_rows[i1]] + i2 ] ] = -2441;
}
}
// LLR
for(iBit = 0; iBit < nBit; ++iBit)
{
msgBit[iBit]=msgChannel[iBit];
for(i1 = 0; i1 < degBit[iBit]; ++i1)
msgBit[iBit] += msgCheck2Bit[idxEdge2Bit[ pointerBit[iBit]+i1 ] ];
if (msgBit[iBit]>=0)
v_estimate[iBit]=0;
else
v_estimate[iBit]=1;
}
// // LLR
// for(iBit = 0; iBit < nBit; ++iBit)
// {
// msgBit[iBit]=msgChannel[iBit];
// for(i1 = 0; i1 < degBit[iBit]; ++i1)
// msgBit[iBit] += msgCheck2Bit[idxEdge2Bit[ pointerBit[iBit]+i1 ] ];
// }
//
// //estimate codeword
// v_estimate=mxMalloc(sizeof(char) * nBit);
// for(iBit = 0; iBit < nBit; ++iBit)
// {
// if (msgBit[iBit]>=0)
// v_estimate[iBit]=0;
// else
// v_estimate[iBit]=1;
// }
//check syndrome=0
for (i1=0,isEqual=1; i1 < nCheck; ++i1)
{
syn=0;
for(i2 = 0; i2 < degCheck[i1]; ++i2)
{
//sum of bits of estimated codeword in the positions where there are 1 elements in graph
syn += v_estimate[ idxBit[ idxEdge2Check[ pointerCheck[ i1 ] + i2 ] ] ];
}
syn=syn%2;
if (syn != 0)
{
isEqual=0;
break;
}
}
if (isEqual==1) //syndrome=0, break
{
flag=1;
break;
}
}
if (flag==1)
{
break;
}
n++;
}
printf("%d\n",layer);
return v_estimate;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment