Merge branch 'nr_pdsch' of https://gitlab.eurecom.fr/oai/openairinterface5g into nr_pdsch
This commit is contained in:
@@ -686,7 +686,7 @@ function main() {
|
||||
echo_info "Compiling unitary tests simulators"
|
||||
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
|
||||
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
|
||||
simlist="dlsim ulsim"
|
||||
simlist="dlsim ulsim polartest ldpctest"
|
||||
for f in $simlist ; do
|
||||
compilations \
|
||||
lte-simulators $f \
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "SIMULATION/TOOLS/sim.h"
|
||||
#include "PHY/CODING/nrLDPC_encoder/defs.h"
|
||||
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
|
||||
@@ -38,6 +39,10 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define NR_LDPC_PROFILER_DETAIL
|
||||
#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
|
||||
|
||||
// 4-bit quantizer
|
||||
char quantize4bit(double D,double x)
|
||||
{
|
||||
@@ -53,13 +58,33 @@ char quantize4bit(double D,double x)
|
||||
return((char)qxd);
|
||||
}
|
||||
|
||||
char quantize8bit(double D,double x)
|
||||
{
|
||||
double qxd;
|
||||
//char maxlev;
|
||||
qxd = floor(x/D);
|
||||
|
||||
//maxlev = 1<<(B-1);
|
||||
|
||||
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
|
||||
|
||||
if (qxd <= -128)
|
||||
qxd = -128;
|
||||
else if (qxd >= 128)
|
||||
qxd = 127;
|
||||
|
||||
return((char)qxd);
|
||||
}
|
||||
|
||||
char quantize(double D,double x,unsigned char B)
|
||||
{
|
||||
double qxd;
|
||||
char maxlev;
|
||||
short maxlev;
|
||||
qxd = floor(x/D);
|
||||
// printf("x=%f,qxd=%f\n",x,qxd);
|
||||
maxlev = 1<<(B-1);
|
||||
|
||||
maxlev = 1<<(B-1);//(char)(pow(2,B-1));
|
||||
|
||||
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
|
||||
|
||||
if (qxd <= -maxlev)
|
||||
qxd = -maxlev;
|
||||
@@ -69,45 +94,78 @@ char quantize(double D,double x,unsigned char B)
|
||||
return((char)qxd);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
double n_iter_mean;
|
||||
double n_iter_std;
|
||||
int n_iter_max;
|
||||
} n_iter_stats_t;
|
||||
|
||||
#define MAX_BLOCK_LENGTH 8448
|
||||
|
||||
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};
|
||||
|
||||
int test_ldpc(short No_iteration,
|
||||
//int nom_rate,
|
||||
//int denom_rate,
|
||||
int nom_rate,
|
||||
int denom_rate,
|
||||
double SNR,
|
||||
unsigned char qbits,
|
||||
unsigned short block_length,
|
||||
short block_length,
|
||||
unsigned int ntrials,
|
||||
int n_segments,
|
||||
unsigned int *errors,
|
||||
unsigned int *crc_misses)
|
||||
unsigned int *errors_bit,
|
||||
double *errors_bit_uncoded,
|
||||
unsigned int *crc_misses,
|
||||
time_stats_t *time_optim,
|
||||
time_stats_t *time_decoder,
|
||||
n_iter_stats_t * dec_iter)
|
||||
{
|
||||
//clock initiate
|
||||
time_stats_t time,time_optim,tinput,tprep,tparity,toutput;
|
||||
//time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
|
||||
time_stats_t time, tinput,tprep,tparity,toutput;
|
||||
double n_iter_mean = 0;
|
||||
double n_iter_std = 0;
|
||||
int n_iter_max = 0;
|
||||
unsigned int segment_bler = 0;
|
||||
|
||||
double sigma;
|
||||
sigma = 1.0/sqrt(2*SNR);
|
||||
|
||||
opp_enabled=1;
|
||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||
//short test_input[block_length];
|
||||
unsigned char *test_input[MAX_NUM_DLSCH_SEGMENTS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
|
||||
//short *c; //padded codeword
|
||||
unsigned char *estimated_output;
|
||||
unsigned char *estimated_output[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *estimated_output_bit[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *test_input_bit;
|
||||
unsigned char *channel_input[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *channel_output_uncoded[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned char *channel_input_optim[MAX_NUM_DLSCH_SEGMENTS];
|
||||
double *channel_output;
|
||||
double *modulated_input;
|
||||
char *channel_output_fixed;
|
||||
double *modulated_input[MAX_NUM_DLSCH_SEGMENTS];
|
||||
char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS];
|
||||
unsigned int i,j,trial=0;
|
||||
short BG,Zc,Kb;
|
||||
//short nrows,ncols;
|
||||
//int no_punctured_columns,removed_bit;
|
||||
short BG,Zc,Kb,nrows;//,ncols;
|
||||
int no_punctured_columns,removed_bit;
|
||||
int i1;
|
||||
int R_ind = 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};
|
||||
int n_segments=8;
|
||||
int N; //length encoded block
|
||||
//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};
|
||||
//int n_segments=1;
|
||||
int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89};
|
||||
//double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
|
||||
|
||||
t_nrLDPC_dec_params decParams;
|
||||
int n_iter;
|
||||
|
||||
t_nrLDPC_time_stats decoder_profiler;
|
||||
t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ;
|
||||
|
||||
int32_t n_iter = 0;;
|
||||
|
||||
*errors=0;
|
||||
*errors_bit=0;
|
||||
*errors_bit_uncoded=0;
|
||||
*crc_misses=0;
|
||||
|
||||
// generate input block
|
||||
@@ -115,37 +173,450 @@ int test_ldpc(short No_iteration,
|
||||
test_input[j]=(unsigned char *)malloc16(sizeof(unsigned char) * block_length/8);
|
||||
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||
channel_input_optim[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||
channel_output_uncoded[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
|
||||
estimated_output[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
estimated_output_bit[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
modulated_input[j] = (double *)malloc16(sizeof(double) * 68*384);
|
||||
channel_output_fixed[j] = (char *)malloc16(sizeof( char) * 68*384);
|
||||
}
|
||||
modulated_input = (double *)malloc(sizeof(double) * 68*384);
|
||||
channel_output = (double *)malloc(sizeof(double) * 68*384);
|
||||
channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
|
||||
estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
|
||||
memset(channel_output_fixed,0,sizeof(char) * 68*384);
|
||||
//modulated_input = (double *)malloc(sizeof(double) * 68*384);
|
||||
//channel_output = (double *)malloc(sizeof(double) * 68*384);
|
||||
//channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
|
||||
//modulated_input = (double *)calloc(68*384, sizeof(double));
|
||||
channel_output = (double *)calloc(68*384, sizeof(double));
|
||||
//channel_output_fixed = (double *)calloc(68*384, sizeof(double));
|
||||
//channel_output_fixed = (unsigned char*)calloc(68*384, sizeof(unsigned char*));
|
||||
//estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);///8);
|
||||
//estimated_output_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
test_input_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
|
||||
|
||||
reset_meas(&time);
|
||||
reset_meas(&time_optim);
|
||||
reset_meas(time_optim);
|
||||
reset_meas(time_decoder);
|
||||
reset_meas(&tinput);
|
||||
reset_meas(&tprep);
|
||||
reset_meas(&tparity);
|
||||
reset_meas(&toutput);
|
||||
//Reset Decoder profiles
|
||||
reset_meas(&decoder_profiler.llr2llrProcBuf);
|
||||
reset_meas(&decoder_profiler.llr2CnProcBuf);
|
||||
reset_meas(&decoder_profiler.cnProc);
|
||||
reset_meas(&decoder_profiler.cnProcPc);
|
||||
reset_meas(&decoder_profiler.bnProc);
|
||||
reset_meas(&decoder_profiler.bnProcPc);
|
||||
reset_meas(&decoder_profiler.cn2bnProcBuf);
|
||||
reset_meas(&decoder_profiler.bn2cnProcBuf);
|
||||
reset_meas(&decoder_profiler.llrRes2llrOut);
|
||||
reset_meas(&decoder_profiler.llr2bit);
|
||||
//reset_meas(&decoder_profiler.total);
|
||||
|
||||
for (j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
for (i=0; i<block_length/8; i++) {
|
||||
test_input[j][i]=(unsigned char) rand();
|
||||
//test_input[j][i]=j%256;
|
||||
//test_input[j][i]=252;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//determine number of bits in codeword
|
||||
if ((block_length>3840) && (block_length <= MAX_BLOCK_LENGTH))
|
||||
if (block_length>3840)
|
||||
{
|
||||
BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
//ncols=22; //info bits
|
||||
}
|
||||
else if (block_length<=3840)
|
||||
{
|
||||
BG=2;
|
||||
nrows=42; //parity check bits
|
||||
//ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
|
||||
if (nom_rate == 1)
|
||||
if (denom_rate == 5)
|
||||
if (BG == 2)
|
||||
R_ind = 0;
|
||||
else
|
||||
printf("Not supported");
|
||||
else if (denom_rate == 3)
|
||||
R_ind = 1;
|
||||
else if (denom_rate == 2)
|
||||
//R_ind = 3;
|
||||
printf("Not supported");
|
||||
else
|
||||
printf("Not supported");
|
||||
|
||||
else if (nom_rate == 2)
|
||||
if (denom_rate == 5)
|
||||
//R_ind = 2;
|
||||
printf("Not supported");
|
||||
else if (denom_rate == 3)
|
||||
R_ind = 4;
|
||||
else
|
||||
printf("Not supported");
|
||||
|
||||
else if ((nom_rate == 22) && (denom_rate == 30))
|
||||
//R_ind = 5;
|
||||
printf("Not supported");
|
||||
else if ((nom_rate == 22) && (denom_rate == 27))
|
||||
//R_ind = 6;
|
||||
printf("Not supported");
|
||||
else if ((nom_rate == 22) && (denom_rate == 25))
|
||||
if (BG == 1)
|
||||
R_ind = 7;
|
||||
else
|
||||
printf("Not supported");
|
||||
else
|
||||
printf("Not supported");
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
|
||||
for (i1=0; i1 < 51; i1++)
|
||||
{
|
||||
if (lift_size[i1] >= (double) block_length/Kb)
|
||||
{
|
||||
Zc = lift_size[i1];
|
||||
//printf("%d\n",Zc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length,BG, Zc, Kb);
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
|
||||
// printf("puncture:%d\n",no_punctured_columns);
|
||||
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
|
||||
if (ntrials==0)
|
||||
ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1);
|
||||
|
||||
for (trial=0; trial < ntrials; trial++)
|
||||
{
|
||||
segment_bler = 0;
|
||||
//// encoder
|
||||
start_meas(&time);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_orig(test_input[j], channel_input[j],block_length,BG,0);
|
||||
}
|
||||
stop_meas(&time);
|
||||
|
||||
start_meas(time_optim);
|
||||
ldpc_encoder_optim_8seg(test_input,channel_input_optim,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
|
||||
/*for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_optim(test_input[j],channel_input_optim[j],block_length,BG,&tinput,&tprep,&tparity,&toutput);
|
||||
}*/
|
||||
stop_meas(time_optim);
|
||||
|
||||
if (ntrials==1)
|
||||
for (j=0;j<n_segments;j++)
|
||||
for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
|
||||
if (channel_input[j][i]!=channel_input_optim[j][i]) {
|
||||
printf("differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
|
||||
return (-1);
|
||||
}
|
||||
//else{
|
||||
// printf("NOT differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
|
||||
// }
|
||||
if (trial== 0) {
|
||||
printf("nrows: %d\n", nrows);
|
||||
printf("no_punctured_columns: %d\n", no_punctured_columns);
|
||||
printf("removed_bit: %d\n", removed_bit);
|
||||
printf("To: %d\n", (Kb+nrows-no_punctured_columns) * Zc-removed_bit);
|
||||
printf("number of undecoded bits: %d\n", (Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
|
||||
|
||||
}
|
||||
|
||||
//print_meas_now(&time, "", stdout);
|
||||
|
||||
// for (i=0;i<6400;i++)
|
||||
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
//printf("%d ",channel_input[i]);
|
||||
|
||||
//if ((BG==2) && (Zc==128||Zc==256))
|
||||
if (1) { // Transmitting one segment
|
||||
for(j=0;j<n_segments;j++) {
|
||||
for (i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++) {
|
||||
#ifdef DEBUG_CODER
|
||||
if ((i&0xf)==0)
|
||||
printf("\ne %d..%d: ",i,i+15);
|
||||
#endif
|
||||
|
||||
if (channel_input[j][i-2*Zc]==0)
|
||||
modulated_input[j][i]=1.0;///sqrt(2); //QPSK
|
||||
else
|
||||
modulated_input[j][i]=-1.0;///sqrt(2);
|
||||
|
||||
///channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
|
||||
//channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
|
||||
//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
|
||||
|
||||
//channel_output_fixed[i] = (char)quantize(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
|
||||
channel_output_fixed[j][i] = (char)quantize(sigma/4.0/4.0,modulated_input[j][i] + sigma*gaussdouble(0.0,1.0),qbits);
|
||||
//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
|
||||
//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
|
||||
//printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
|
||||
|
||||
|
||||
//channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);
|
||||
|
||||
//Uncoded BER
|
||||
if (channel_output_fixed[j][i]<0)
|
||||
channel_output_uncoded[j][i]=1; //QPSK demod
|
||||
else
|
||||
channel_output_uncoded[j][i]=0;
|
||||
|
||||
if (channel_output_uncoded[j][i] != channel_input[j][i-2*Zc])
|
||||
*errors_bit_uncoded = (*errors_bit_uncoded) + 1;
|
||||
|
||||
}
|
||||
} // End segments
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
//{
|
||||
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
//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
|
||||
|
||||
decParams.BG=BG;
|
||||
decParams.Z=Zc;
|
||||
decParams.R=code_rate_vec[R_ind];//13;
|
||||
decParams.numMaxIter=No_iteration;
|
||||
decParams.outMode = nrLDPC_outMode_BIT;
|
||||
//decParams.outMode =nrLDPC_outMode_LLRINT8;
|
||||
|
||||
start_meas(time_decoder);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
// decode the sequence
|
||||
// decoder supports BG2, Z=128 & 256
|
||||
//esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
|
||||
///nrLDPC_decoder(&decParams, channel_output_fixed, estimated_output, NULL);
|
||||
n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_decoder_profiler);
|
||||
}
|
||||
stop_meas(time_decoder);
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
|
||||
|
||||
//count errors
|
||||
for(j=0;j<n_segments;j++) {
|
||||
for (i=0; i<block_length>>3; i++)
|
||||
{
|
||||
//printf("block_length>>3: %d \n",block_length>>3);
|
||||
/// printf("i: %d \n",i);
|
||||
///printf("estimated_output[%d]: %d \n",i,estimated_output[i]);
|
||||
///printf("test_input[0][%d]: %d \n",i,test_input[0][i]);
|
||||
if (estimated_output[j][i] != test_input[j][i])
|
||||
{
|
||||
|
||||
|
||||
//////printf("error pos %d (%d, %d)\n\n",i,estimated_output[i],test_input[0][i]);
|
||||
segment_bler = segment_bler + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<block_length; i++)
|
||||
{
|
||||
estimated_output_bit[j][i] = (estimated_output[j][i/8]&(1<<(i&7)))>>(i&7);
|
||||
test_input_bit[i] = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments
|
||||
if (estimated_output_bit[j][i] != test_input_bit[i])
|
||||
{
|
||||
*errors_bit = (*errors_bit) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//if (*errors == 1000)
|
||||
//break;
|
||||
|
||||
n_iter_mean = n_iter_mean + n_iter;
|
||||
n_iter_std = n_iter_std + pow(n_iter-1,2);
|
||||
|
||||
if ( n_iter > n_iter_max )
|
||||
n_iter_max = n_iter;
|
||||
|
||||
} // end segments
|
||||
|
||||
if (segment_bler != 0)
|
||||
*errors = (*errors) + 1;
|
||||
|
||||
}
|
||||
/*else if (trial==0)
|
||||
printf("decoder is not supported\n");*/
|
||||
}
|
||||
|
||||
|
||||
dec_iter->n_iter_mean = n_iter_mean/(double)ntrials/(double)n_segments - 1;
|
||||
dec_iter->n_iter_std = sqrt(n_iter_std/(double)ntrials/(double)n_segments - pow(n_iter_mean/(double)ntrials/(double)n_segments - 1,2));
|
||||
dec_iter->n_iter_max = n_iter_max -1;
|
||||
|
||||
*errors_bit_uncoded = *errors_bit_uncoded / (double)((Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
|
||||
|
||||
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
free(test_input[j]);
|
||||
free(channel_input[j]);
|
||||
free(channel_output_uncoded[j]);
|
||||
free(channel_input_optim[j]);
|
||||
free(modulated_input[j]);
|
||||
free(channel_output_fixed[j]);
|
||||
free(estimated_output[j]);
|
||||
free(estimated_output_bit[j]);
|
||||
}
|
||||
//free(modulated_input);
|
||||
free(channel_output);
|
||||
//free(channel_output_fixed);
|
||||
//free(estimated_output);
|
||||
|
||||
print_meas(&time,"ldpc_encoder",NULL,NULL);
|
||||
print_meas(time_optim,"ldpc_encoder_optim",NULL,NULL);
|
||||
print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
|
||||
print_meas(&tprep,"ldpc_encoder_optim(prep)",NULL,NULL);
|
||||
print_meas(&tparity,"ldpc_encoder_optim(parity)",NULL,NULL);
|
||||
print_meas(&toutput,"ldpc_encoder_optim(output)",NULL,NULL);
|
||||
printf("\n");
|
||||
print_meas(time_decoder,"ldpc_decoder",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2llrProcBuf,"llr2llrProcBuf",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2CnProcBuf,"llr2CnProcBuf",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cnProc,"cnProc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cnProcPc,"cnProcPc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bnProc,"bnProc (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bnProcPc,"bnProcPc(per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.cn2bnProcBuf,"cn2bnProcBuf (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.bn2cnProcBuf,"bn2cnProcBuf (per iteration)",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llrRes2llrOut,"llrRes2llrOut",NULL,NULL);
|
||||
print_meas(&decoder_profiler.llr2bit,"llr2bit",NULL,NULL);
|
||||
printf("\n");
|
||||
|
||||
return *errors;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int errors, errors_bit, crc_misses;
|
||||
double errors_bit_uncoded;
|
||||
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
|
||||
short No_iteration=5;
|
||||
int n_segments=1;
|
||||
//double rate=0.333;
|
||||
int nom_rate=1;
|
||||
int denom_rate=3;
|
||||
double SNR0=-2.0,SNR,SNR_lin;
|
||||
unsigned char qbits=8;
|
||||
unsigned int decoded_errors[10000]; // initiate the size of matrix equivalent to size of SNR
|
||||
int c,i=0, i1 = 0;
|
||||
|
||||
int n_trials = 1;
|
||||
double SNR_step = 0.1;
|
||||
|
||||
randominit(0);
|
||||
int test_uncoded= 0;
|
||||
|
||||
time_stats_t time_optim[10], time_decoder[10];
|
||||
n_iter_stats_t dec_iter[3];
|
||||
|
||||
|
||||
|
||||
short BG,Zc,Kb;
|
||||
|
||||
while ((c = getopt (argc, argv, "q:r:s:S:l:n:d:i:t:u:h")) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'q':
|
||||
qbits = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
nom_rate = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
denom_rate = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
block_length = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_trials = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
SNR0 = atof(optarg);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
n_segments = atof(optarg);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
SNR_step = atof(optarg);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
No_iteration = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
test_uncoded = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
printf("CURRENTLY SUPPORTED CODE RATES: \n");
|
||||
printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n");
|
||||
printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n");
|
||||
printf("-h This message\n");
|
||||
printf("-q Quantization bits, Default: 8\n");
|
||||
printf("-r Nominator rate, (1, 2, 22), Default: 1\n");
|
||||
printf("-d Denominator rate, (3, 5, 25), Default: 1\n");
|
||||
printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");
|
||||
printf("-n Number of simulation trials, Default: 1\n");
|
||||
//printf("-M MCS2 for TB 2\n");
|
||||
printf("-s SNR per information bit (EbNo) in dB, Default: -2\n");
|
||||
printf("-S Number of segments (Maximum: 8), Default: 1\n");
|
||||
printf("-t SNR simulation step, Default: 0.1\n");
|
||||
printf("-i Max decoder iterations, Default: 5\n");
|
||||
printf("-u Set SNR per coded bit, Default: 0\n");
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||
//printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
|
||||
//printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
|
||||
printf("block length %d: \n", block_length);
|
||||
printf("n_trials %d: \n", n_trials);
|
||||
printf("SNR0 %f: \n", SNR0);
|
||||
|
||||
|
||||
|
||||
|
||||
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
|
||||
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (block_length>3840)
|
||||
{
|
||||
BG=1;
|
||||
Kb = 22;
|
||||
//nrows=46; //parity check bits
|
||||
//ncols=22; //info bits
|
||||
}
|
||||
else if (block_length<=3840)
|
||||
else if (block_length<=3840)
|
||||
{
|
||||
BG=2;
|
||||
//nrows=42; //parity check bits
|
||||
@@ -159,14 +630,11 @@ int test_ldpc(short No_iteration,
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
else {
|
||||
printf("block_length %d not supported\n",block_length);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
|
||||
for (i1=0; i1 < 51; i1++)
|
||||
{
|
||||
if (lift_size[i1] >= (double) block_length/Kb)
|
||||
@@ -177,192 +645,87 @@ int test_ldpc(short No_iteration,
|
||||
}
|
||||
}
|
||||
|
||||
if (BG==1)
|
||||
N=66*Zc;
|
||||
else if (BG==2)
|
||||
N=50*Zc;
|
||||
char fname[200];
|
||||
sprintf(fname,"../../../openair1/PHY/CODING/TESTBENCH/ldpctest_BG_%d_Zc_%d_rate_%d-%d_block_length_%d_maxit_%d.txt",BG,Zc,nom_rate,denom_rate,block_length, No_iteration);
|
||||
FILE *fd=fopen(fname,"w");
|
||||
AssertFatal(fd!=NULL,"cannot open %s\n",fname);
|
||||
|
||||
printf("ldpc_test: block_length %d, BG %d, Zc %d, Kb %d, N %d\n",block_length,BG, Zc, Kb, N);
|
||||
//no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
|
||||
// printf("puncture:%d\n",no_punctured_columns);
|
||||
//removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
|
||||
if (ntrials==0)
|
||||
ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1);
|
||||
|
||||
for (trial=0; trial < ntrials; trial++)
|
||||
fprintf(fd,"SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX\n");
|
||||
|
||||
for (SNR=SNR0;SNR<SNR0+20.0;SNR+=SNR_step)
|
||||
{
|
||||
|
||||
//// encoder
|
||||
start_meas(&time);
|
||||
for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_orig(test_input[j], channel_input[j],block_length,BG,0);
|
||||
}
|
||||
stop_meas(&time);
|
||||
|
||||
start_meas(&time_optim);
|
||||
ldpc_encoder_optim_8seg(test_input,channel_input_optim,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
|
||||
/*for(j=0;j<n_segments;j++) {
|
||||
ldpc_encoder_optim(test_input[j],channel_input_optim[j],block_length,BG,&tinput,&tprep,&tparity,&toutput);
|
||||
}*/
|
||||
stop_meas(&time_optim);
|
||||
|
||||
if (ntrials==1)
|
||||
for (j=0;j<n_segments;j++)
|
||||
for (i = 0; i < 3*block_length; i++)
|
||||
if (channel_input[j][i]!=channel_input_optim[j][i]) {
|
||||
printf("differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
//print_meas_now(&time, "", stdout);
|
||||
|
||||
// for (i=0;i<6400;i++)
|
||||
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
|
||||
//printf("%d ",channel_input[i]);
|
||||
|
||||
for (i = 2*Zc; i < 3*block_length; i++)
|
||||
{
|
||||
#ifdef DEBUG_CODER
|
||||
if ((i&0xf)==0)
|
||||
printf("\ne %d..%d: ",i,i+15);
|
||||
#endif
|
||||
|
||||
if (channel_input[0][i-2*Zc]==0)
|
||||
modulated_input[i]=1/sqrt(2); //BPSK
|
||||
else
|
||||
modulated_input[i]=-1/sqrt(2);
|
||||
|
||||
channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
|
||||
if (channel_output[i]>1.0)
|
||||
channel_output_fixed[i]=127;
|
||||
else if (channel_output[i]<-1.0)
|
||||
channel_output_fixed[i]=-128;
|
||||
else
|
||||
channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
|
||||
//printf("llr[%d]=%d (%f)\n",i,channel_output_fixed[i],channel_output[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
the LDPC decoder supports several rates and the input has to be adapted accordingly (by padding with zeros to the next lower supported rate). Moreover, the first 2*Z LLRs are zero (since they are punctured and not transmitted) then you have the LLRs corresponding to the systematic bits. After that come the filler bits, the encoder uses 0 for the filler bits hence for the decoder you need to put 127 (max LLR for bit 0) at their place. Then come the LLRs corresponding to the punctured bits followed by zeros to pad for the supported decoder rate.
|
||||
*/
|
||||
for (i=0;i<2*Zc;i++)
|
||||
channel_output_fixed[i] = 0;
|
||||
|
||||
decParams.BG=BG;
|
||||
decParams.Z=Zc;
|
||||
decParams.R=13;
|
||||
decParams.numMaxIter=6;
|
||||
decParams.outMode = nrLDPC_outMode_BIT;
|
||||
|
||||
// decode the sequence
|
||||
// decoder supports BG2, Z=128 & 256
|
||||
//estimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
|
||||
|
||||
n_iter = nrLDPC_decoder(&decParams, (int8_t*) channel_output_fixed, (int8_t*) estimated_output, NULL);
|
||||
|
||||
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
|
||||
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
|
||||
|
||||
//count errors
|
||||
for (i=0; i<block_length>>3; i++)
|
||||
{
|
||||
if (estimated_output[i] != test_input[0][i])
|
||||
{
|
||||
printf("error pos %d (%d, %d)\n",i,estimated_output[i],test_input[0][i]);
|
||||
*errors = (*errors) + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
|
||||
free(test_input[j]);
|
||||
free(channel_input[j]);
|
||||
free(channel_input_optim[j]);
|
||||
}
|
||||
free(modulated_input);
|
||||
free(channel_output);
|
||||
free(channel_output_fixed);
|
||||
free(estimated_output);
|
||||
|
||||
print_meas(&time,"ldpc_encoder",NULL,NULL);
|
||||
print_meas(&time_optim,"ldpc_encoder_optim",NULL,NULL);
|
||||
print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
|
||||
print_meas(&tprep,"ldpc_encoder_optim(prep)",NULL,NULL);
|
||||
print_meas(&tparity,"ldpc_encoder_optim(parity)",NULL,NULL);
|
||||
print_meas(&toutput,"ldpc_encoder_optim(output)",NULL,NULL);
|
||||
return *errors;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int errors,crc_misses;
|
||||
short block_length=576; // decoder supports length: 1201 -> 1280, 2401 -> 2560
|
||||
short No_iteration=25;
|
||||
//double rate=0.333;
|
||||
//int nom_rate=1;
|
||||
//int denom_rate=3;
|
||||
double SNR0=-2.0,SNR,SNR_lin;
|
||||
unsigned char qbits=4;
|
||||
unsigned int decoded_errors[100]; // initiate the size of matrix equivalent to size of SNR
|
||||
int c,i=0;
|
||||
|
||||
int n_trials = 1;
|
||||
|
||||
randominit(0);
|
||||
|
||||
while ((c = getopt (argc, argv, "q:s:l:n:h")) != -1)
|
||||
switch (c)
|
||||
{
|
||||
case 'q':
|
||||
qbits = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
block_length = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
n_trials = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
SNR0 = atoi(optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 'h':
|
||||
printf("usage ldpctest -h -l blocklength -n n_trials -s SNR\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
|
||||
//printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
|
||||
//printf("rate: %d/%d\n",nom_rate,denom_rate);
|
||||
printf("block length %d: \n", block_length);
|
||||
printf("n_trials %d: \n", n_trials);
|
||||
printf("SNR0 %f: \n", SNR0);
|
||||
|
||||
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
|
||||
for (SNR=SNR0;SNR<SNR0+1.0;SNR+=1.0)
|
||||
{
|
||||
SNR_lin = pow(10,SNR/10);
|
||||
//reset_meas(&time_optim);
|
||||
//reset_meas(&time_decoder);
|
||||
//n_iter_stats_t dec_iter = {0, 0, 0};
|
||||
if (test_uncoded == 1)
|
||||
SNR_lin = pow(10,SNR/10.0);
|
||||
else
|
||||
SNR_lin = pow(10,SNR/10.0)*nom_rate/denom_rate;
|
||||
printf("Linear SNR: %f\n", SNR_lin);
|
||||
decoded_errors[i]=test_ldpc(No_iteration,
|
||||
//nom_rate,
|
||||
//denom_rate,
|
||||
nom_rate,
|
||||
denom_rate,
|
||||
SNR_lin, // noise standard deviation
|
||||
qbits,
|
||||
block_length, // block length bytes
|
||||
n_trials,
|
||||
n_segments,
|
||||
&errors,
|
||||
&crc_misses);
|
||||
&errors_bit,
|
||||
&errors_bit_uncoded,
|
||||
&crc_misses,
|
||||
time_optim,
|
||||
time_decoder,
|
||||
dec_iter);
|
||||
|
||||
printf("SNR %f, BLER %f (%d/%d)\n",SNR,(float)decoded_errors[i]/(float)n_trials,decoded_errors[i],n_trials);
|
||||
printf("SNR %f, BER %f (%d/%d)\n",SNR,(float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments ,decoded_errors[i],n_trials);
|
||||
printf("SNR %f, Uncoded BER %f (%d/%d)\n",SNR,errors_bit_uncoded/(float)n_trials/(double)n_segments ,decoded_errors[i],n_trials);
|
||||
printf("SNR %f, Mean iterations: %f\n",SNR, dec_iter->n_iter_mean);
|
||||
printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std);
|
||||
printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max);
|
||||
printf("\n");
|
||||
printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz);
|
||||
printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)));
|
||||
printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/cpu_freq_GHz);
|
||||
printf("\n");
|
||||
printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz);
|
||||
printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)));
|
||||
printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/cpu_freq_GHz);
|
||||
|
||||
fprintf(fd,"%f %f %f %f %f %f %f %f %f %f %f %f %d \n",
|
||||
SNR,
|
||||
(double)decoded_errors[i]/(double)n_trials ,
|
||||
(double)errors_bit/(double)n_trials/(double)block_length/(double)n_segments ,
|
||||
errors_bit_uncoded/(double)n_trials/(double)n_segments ,
|
||||
(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,
|
||||
sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)),
|
||||
(double)time_optim->max/1000.0/cpu_freq_GHz,
|
||||
(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,
|
||||
sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)),
|
||||
(double)time_decoder->max/1000.0/cpu_freq_GHz,
|
||||
dec_iter->n_iter_mean,
|
||||
dec_iter->n_iter_std,
|
||||
dec_iter->n_iter_max
|
||||
);
|
||||
|
||||
if (decoded_errors[i] == 0)
|
||||
break;
|
||||
i=i+1;
|
||||
|
||||
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
#include "nrLDPC_cnProc.h"
|
||||
#include "nrLDPC_bnProc.h"
|
||||
|
||||
#define NR_LDPC_ENABLE_PARITY_CHECK
|
||||
#define NR_LDPC_PROFILER_DETAIL
|
||||
|
||||
#ifdef NR_LDPC_DEBUG_MODE
|
||||
#include "nrLDPC_tools/nrLDPC_debug.h"
|
||||
#endif
|
||||
|
||||
@@ -68,7 +68,7 @@ int encode_parity_check_part_orig(unsigned char *c,unsigned char *d, short BG,sh
|
||||
printf("problem with BG\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,sho
|
||||
int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
|
||||
{
|
||||
|
||||
short Kb,Zc,nrows,ncols;
|
||||
short Zc,Kb,nrows,ncols;
|
||||
int i,i1;
|
||||
int no_punctured_columns,removed_bit;
|
||||
|
||||
@@ -211,26 +211,31 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
|
||||
int simd_size;
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (BG==1)
|
||||
{
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
else if (BG==2)
|
||||
{
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
//determine number of bits in codeword
|
||||
//if (block_length>3840)
|
||||
if (BG==1)
|
||||
{
|
||||
//BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
//else if (block_length<=3840)
|
||||
else if (BG==2)
|
||||
{
|
||||
//BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
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
|
||||
Zc=0;
|
||||
@@ -316,7 +321,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
|
||||
int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
|
||||
{
|
||||
|
||||
short Kb,Zc,nrows,ncols;
|
||||
short Zc,Kb,nrows,ncols;
|
||||
int i,i1,j;
|
||||
int no_punctured_columns,removed_bit;
|
||||
//Table of possible lifting sizes
|
||||
@@ -343,14 +348,18 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
|
||||
|
||||
//determine number of bits in codeword
|
||||
//if (block_length>3840)
|
||||
if (BG==1)
|
||||
{
|
||||
//BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
else if (BG==2)
|
||||
//else if (block_length<=3840)
|
||||
else if (BG==2)
|
||||
{
|
||||
//BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
@@ -362,7 +371,7 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
}
|
||||
|
||||
//find minimum value in all sets of lifting size
|
||||
Zc=0;
|
||||
@@ -481,12 +490,12 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
// if (((block_length-(2*Zc))&31)>0) l1++;
|
||||
|
||||
for (i=0;i<l1;i++)
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
|
||||
|
||||
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
|
||||
|
||||
for (i1=0;i1<l2;i1++,i++)
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
|
||||
for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_LDPC
|
||||
@@ -494,10 +503,10 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
#endif
|
||||
// do non-SIMD version
|
||||
for (i=0;i<(block_length-2*Zc);i++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
channel_input[j][i] = (c[2*Zc+i]>>j)&1;
|
||||
for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
for (j=0; j<n_segments; j++)
|
||||
channel_input[j][block_length-2*Zc+i] = (d[i]>>j)&1;
|
||||
}
|
||||
|
||||
@@ -508,3 +517,217 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
|
||||
stop_meas(toutput);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length,int nom_rate,int denom_rate,int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
|
||||
{
|
||||
|
||||
short BG,Zc,Kb,nrows,ncols;
|
||||
int i,i1,j;
|
||||
int no_punctured_columns,removed_bit;
|
||||
//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};
|
||||
char temp;
|
||||
int simd_size;
|
||||
int macro_segment, macro_segment_end;
|
||||
|
||||
|
||||
macro_segment = 8*macro_num;
|
||||
macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
|
||||
///printf("macro_segment: %d\n", macro_segment);
|
||||
///printf("macro_segment_end: %d\n", macro_segment_end );
|
||||
|
||||
#ifdef __AVX2__
|
||||
__m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
|
||||
__m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats.
|
||||
__m256i zero256 = _mm256_setzero_si256();
|
||||
__m256i masks[8];
|
||||
register __m256i c256;
|
||||
masks[0] = _mm256_set1_epi8(0x1);
|
||||
masks[1] = _mm256_set1_epi8(0x2);
|
||||
masks[2] = _mm256_set1_epi8(0x4);
|
||||
masks[3] = _mm256_set1_epi8(0x8);
|
||||
masks[4] = _mm256_set1_epi8(0x10);
|
||||
masks[5] = _mm256_set1_epi8(0x20);
|
||||
masks[6] = _mm256_set1_epi8(0x40);
|
||||
masks[7] = _mm256_set1_epi8(0x80);
|
||||
#endif
|
||||
|
||||
///AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (block_length>3840)
|
||||
{
|
||||
BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
else if (block_length<=3840)
|
||||
{
|
||||
BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
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
|
||||
Zc=0;
|
||||
for (i1=0; i1 < 51; i1++)
|
||||
{
|
||||
if (lift_size[i1] >= (double) block_length/Kb)
|
||||
{
|
||||
Zc = lift_size[i1];
|
||||
//printf("%d\n",Zc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LDPC
|
||||
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
|
||||
LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
|
||||
#endif
|
||||
|
||||
AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
|
||||
|
||||
if ((Zc&31) > 0) simd_size = 16;
|
||||
else simd_size = 32;
|
||||
|
||||
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
|
||||
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
|
||||
|
||||
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
|
||||
|
||||
// calculate number of punctured bits
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
|
||||
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3);
|
||||
// printf("%d\n",no_punctured_columns);
|
||||
// printf("%d\n",removed_bit);
|
||||
// unpack input
|
||||
memset(c,0,sizeof(unsigned char) * ncols * Zc);
|
||||
memset(d,0,sizeof(unsigned char) * nrows * Zc);
|
||||
|
||||
start_meas(tinput);
|
||||
#if 0
|
||||
for (i=0; i<block_length; i++) {
|
||||
//for (j=0; j<n_segments; j++) {
|
||||
for (j=macro_segment; j < macro_segment_end; j++) {
|
||||
|
||||
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
|
||||
//printf("c(%d,%d)=%d\n",j,i,temp);
|
||||
c[i] |= (temp << (j-macro_segment));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef __AVX2__
|
||||
for (i=0; i<block_length>>5; i++) {
|
||||
c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
|
||||
//for (j=1; j<n_segments; j++) {
|
||||
for (j=macro_segment+1; j < macro_segment_end; j++) {
|
||||
c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[j])[i]), shufmask),andmask),zero256),masks[j-macro_segment]),c256);
|
||||
}
|
||||
((__m256i *)c)[i] = c256;
|
||||
}
|
||||
|
||||
for (i=(block_length>>5)<<5;i<block_length;i++) {
|
||||
//for (j=0; j<n_segments; j++) {
|
||||
for (j=macro_segment; j < macro_segment_end; j++) {
|
||||
|
||||
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
|
||||
//printf("c(%d,%d)=%d\n",j,i,temp);
|
||||
c[i] |= (temp << (j-macro_segment));
|
||||
}
|
||||
}
|
||||
#else
|
||||
AssertFatal(1==0,"Need AVX2 for this\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
stop_meas(tinput);
|
||||
|
||||
if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
|
||||
// extend matrix
|
||||
start_meas(tprep);
|
||||
for (i1=0; i1 < ncols; i1++)
|
||||
{
|
||||
memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
|
||||
memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
|
||||
}
|
||||
for (i1=1;i1<simd_size;i1++) {
|
||||
memcpy(&c_extension[(2*ncols*Zc*i1)], &c_extension[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
|
||||
// memset(&c_extension[(2*ncols*Zc*i1)],0,i1);
|
||||
/*
|
||||
printf("shift %d: ",i1);
|
||||
for (int j=0;j<64;j++) printf("%d ",c_extension[(2*ncols*Zc*i1)+j]);
|
||||
printf("\n");
|
||||
*/
|
||||
}
|
||||
stop_meas(tprep);
|
||||
//parity check part
|
||||
start_meas(tparity);
|
||||
encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
|
||||
stop_meas(tparity);
|
||||
}
|
||||
else {
|
||||
if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
|
||||
printf("Problem with encoder\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
start_meas(toutput);
|
||||
// information part and puncture columns
|
||||
/*
|
||||
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
|
||||
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
|
||||
*/
|
||||
#ifdef __AVX2__
|
||||
if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
|
||||
//AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
|
||||
//AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
|
||||
uint32_t l1 = (block_length-(2*Zc))>>5;
|
||||
uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
|
||||
__m256i *c256p = (__m256i *)&c[2*Zc];
|
||||
__m256i *d256p = (__m256i *)&d[0];
|
||||
// if (((block_length-(2*Zc))&31)>0) l1++;
|
||||
|
||||
for (i=0;i<l1;i++)
|
||||
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
|
||||
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j-macro_segment),masks[0]);
|
||||
|
||||
|
||||
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
|
||||
|
||||
for (i1=0;i1<l2;i1++,i++)
|
||||
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
|
||||
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j-macro_segment),masks[0]);
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_LDPC
|
||||
LOG_W(PHY,"using non-optimized version\n");
|
||||
#endif
|
||||
// do non-SIMD version
|
||||
for (i=0;i<(block_length-2*Zc);i++)
|
||||
//for (j=0; j<n_segments; j++)
|
||||
for (j=macro_segment; j < macro_segment_end; j++)
|
||||
channel_input[j][i] = (c[2*Zc+i]>>(j-macro_segment))&1;
|
||||
for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
|
||||
//for (j=0; j<n_segments; j++)
|
||||
for (j=macro_segment; j < macro_segment_end; j++)
|
||||
channel_input[j][block_length-2*Zc+i] = (d[i]>>(j-macro_segment))&1;
|
||||
}
|
||||
|
||||
#else
|
||||
AssertFatal(1==0,"Need AVX2 for now\n");
|
||||
#endif
|
||||
|
||||
stop_meas(toutput);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ short *choose_generator_matrix(short BG,short Zc)
|
||||
return Gen_shift_values;
|
||||
}
|
||||
|
||||
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,unsigned char gen_code)
|
||||
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code)
|
||||
{
|
||||
unsigned char c[22*384]; //padded input, unpacked, max size
|
||||
unsigned char d[68*384]; //coded output, unpacked, max size
|
||||
@@ -378,26 +378,30 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
int indlist2[1000];
|
||||
|
||||
//determine number of bits in codeword
|
||||
if (BG==1)
|
||||
{
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
else if (BG==2)
|
||||
{
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
//if (block_length>3840)
|
||||
if (BG==1)
|
||||
{
|
||||
//BG=1;
|
||||
Kb = 22;
|
||||
nrows=46; //parity check bits
|
||||
ncols=22; //info bits
|
||||
}
|
||||
//else if (block_length<=3840)
|
||||
else if (BG==2)
|
||||
{
|
||||
//BG=2;
|
||||
nrows=42; //parity check bits
|
||||
ncols=10; // info bits
|
||||
|
||||
if (block_length>640)
|
||||
Kb = 10;
|
||||
else if (block_length>560)
|
||||
Kb = 9;
|
||||
else if (block_length>192)
|
||||
Kb = 8;
|
||||
else
|
||||
Kb = 6;
|
||||
}
|
||||
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
|
||||
Zc=0;
|
||||
@@ -415,8 +419,6 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int K = ncols*Zc;
|
||||
|
||||
Gen_shift_values=choose_generator_matrix(BG,Zc);
|
||||
if (Gen_shift_values==NULL) {
|
||||
printf("ldpc_encoder_orig: could not find generator matrix\n");
|
||||
@@ -438,15 +440,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
}
|
||||
|
||||
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
|
||||
//nrows - no_punctured_columns = 2 +2*block_length/Zc
|
||||
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3);
|
||||
// ((nrows-no_punctured_columns) * Zc-removed_bit) =
|
||||
// 2Zc + 2*block_length
|
||||
//printf("%d\n",no_punctured_columns);
|
||||
//printf("%d\n",removed_bit);
|
||||
//printf("%d\n",nrows-no_punctured_columns);
|
||||
//printf("%d\n",((nrows-no_punctured_columns) * Zc-removed_bit));
|
||||
|
||||
// unpack input
|
||||
memset(c,0,sizeof(unsigned char) * ncols * Zc);
|
||||
memset(d,0,sizeof(unsigned char) * nrows * Zc);
|
||||
@@ -614,8 +610,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
|
||||
}
|
||||
|
||||
// information part and puncture columns
|
||||
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); //systematic bits
|
||||
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); //systematic bits 2Zc + 2*block_length
|
||||
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
|
||||
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
|
||||
//memcpy(channel_input,c,Kb*Zc*sizeof(unsigned char));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user