Commit f11ba504 authored by hbilel's avatar hbilel

Add ldpc encoder + decoder

parent de4712e7
......@@ -1042,6 +1042,9 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_encoder.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -34,6 +34,7 @@
#else
#include "PHY/TOOLS/time_meas.h"
#endif
#include "nrLDPC_decoder.h"
#define CRC24_A 0
#define CRC24_B 1
......@@ -79,6 +80,15 @@ int32_t lte_segmentation(uint8_t *input_buffer,
uint32_t *Kminus,
uint32_t *F);
int32_t nr_segmentation(unsigned char *input_buffer,
unsigned char **output_buffers,
unsigned int B,
unsigned int *C,
unsigned int *Kplus,
unsigned int *Kminus,
unsigned int *Zout,
unsigned int *F);
/** \fn int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs)
\brief this functions calculates the delta MCS in dB based on the lte_segmentation function
\param tbs transport block size
......
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "choose_generator_matrix.h"
//#include "Gen_shift_value.h"
short *ldpc_encoder_header(short *test_input,short block_length,double rate)
{
printf("ldpc encoder %d\n", test_input[0]);
short *c; //padded codeword
short *channel_input; //output sequence
short *Gen_shift_values, *no_shift_values, *pointer_shift_values;
short BG,Zc,Kb,nrows,ncols;
short channel_temp;
int i1,i2,i3,i4,i5,t,temp,temp_prime;
int no_punctured_columns;
//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};
//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
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;
}
else if (BG==2)
{
no_shift_values=(short*) no_shift_values_BG2;
pointer_shift_values=(short*) pointer_shift_values_BG2;
}
Gen_shift_values=choose_generator_matrix(BG,Zc);
no_punctured_columns=(int)((nrows+Kb-2)*Zc-block_length/rate)/Zc;
//printf("%d\n",no_punctured_columns);
//padded input sequence
c=(short *)malloc(sizeof(short) * Kb * Zc);
channel_input = (short *)malloc( (Kb+nrows-no_punctured_columns) * Zc *sizeof(short));
memset(c,0,sizeof(short) * Kb * Zc);
memcpy(c,test_input,block_length * sizeof(short));
// parity check part
for (i2=0; i2 < Zc; i2++)
{
t=Kb*Zc+i2;
//rotate matrix here
for (i5=0; i5 < Kb; i5++)
{
temp = c[i5*Zc];
memmove(&c[i5*Zc], &c[i5*Zc+1], (Zc-1)*sizeof(short));
c[i5*Zc+Zc-1] = temp;
}
// calculate each row in base graph
for (i1=0; i1 < nrows-no_punctured_columns; i1++)
{
channel_temp=0;
for (i3=0; i3 < Kb; i3++)
{
temp_prime=i1 * ncols + i3;
for (i4=0; i4 < no_shift_values[temp_prime]; i4++)
{
channel_temp = channel_temp ^ c[ i3*Zc + Gen_shift_values[ pointer_shift_values[temp_prime]+i4 ] ];
}
}
channel_input[t+i1*Zc]=channel_temp;
}
}
// information part
memcpy(channel_input,c,Kb*Zc*sizeof(short));
return channel_input;
}
......@@ -570,6 +570,8 @@ typedef struct {
uint32_t Kplus;
/// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
uint32_t F;
/// LDPC lifting factor
uint32_t Z;
/// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17)
uint8_t Nl;
/// current delta_pucch
......
......@@ -665,18 +665,27 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
printf("mod_order %d\n",mod_order);
#endif
double rate = 0.33;
#ifdef DEBUG_DLSCH_CODING
printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]);
#endif
start_meas(te_stats);
threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r],
/*threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r],
Kr>>3,
&dlsch->harq_processes[harq_pid]->d[r][96],
(r==0) ? dlsch->harq_processes[harq_pid]->F : 0,
f1f2mat_old[iind*2], // f1 (see 36121-820, page 14)
f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14)
);
);*/
printf("start ldpc encoder\n");
printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
dlsch->harq_processes[harq_pid]->d[r][96] = ldpc_encoder_header((short *)dlsch->harq_processes[harq_pid]->c[r],dlsch->harq_processes[harq_pid]->B,rate);
printf("end ldpc encoder\n");
printf("output %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->d[r][96], dlsch->harq_processes[harq_pid]->d[r][96+1], dlsch->harq_processes[harq_pid]->d[r][96+2],dlsch->harq_processes[harq_pid]->d[r][96+3], dlsch->harq_processes[harq_pid]->d[r][96+4]);
stop_meas(te_stats);
#ifdef DEBUG_DLSCH_CODING
......
......@@ -37,8 +37,14 @@
#include "SCHED/extern.h"
#include "SIMULATION/TOOLS/defs.h"
#include "targets/RT/USER/lte-softmodem.h"
#include "PHY/CODING/nrLDPC_types.h"
//#define DEBUG_DLSCH_DECODING
#define OAI_LDPC_MAX_NUM_LLR 26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
static int8_t llrRes [OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
static int8_t llrProcBuf[OAI_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
extern double cpuf;
void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch)
......@@ -165,6 +171,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t decoder_switch,
uint8_t llr8_flag)
{
......@@ -181,6 +188,23 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
short dummy_w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0;
uint8_t crc_type;
t_nrLDPC_dec_params decParams;
t_nrLDPC_dec_params* p_decParams = &decParams;
int8_t llrOut_inter;
int8_t* p_llrOut_inter = &llrOut_inter;
t_nrLDPC_proc_time procTime;
t_nrLDPC_proc_time* p_procTime =&procTime ;
p_procTime->llr2llrProcBuf = 0.0;
p_procTime->llr2CnProcBuf= 0.0;
p_procTime->cnProc= 0.0;
p_procTime->bnProcPc=0.0;
p_procTime->bnProc=0.0;
p_procTime->cn2bnProcBuf=0.0;
p_procTime->bn2cnProcBuf=0.0;
p_procTime->llrRes2llrOut=0.0;
p_procTime->llr2bit=0.0;
p_procTime->total=0.0;
#ifdef DEBUG_DLSCH_DECODING
uint16_t i;
#endif
......@@ -305,8 +329,14 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
&harq_process->Kminus,
&harq_process->F);
// CLEAR LLR's HERE for first packet in process
}
p_decParams->Z = 128;
p_decParams->BG = 2;
p_decParams->R = 13;
p_decParams->numMaxIter = 5;
/*
else {
printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
......@@ -473,6 +503,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
*/
//#ifndef __AVX2__
#if 1
if (err_flag == 0) {
/*
......@@ -488,6 +519,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
start_meas(dlsch_turbo_decoding_stats);
#endif
LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
//if (decoder_switch ==0){
ret = tc
(&harq_process->d[r][96],
harq_process->c[r],
......@@ -503,7 +535,43 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
&phy_vars_ue->dlsch_tc_gamma_stats,
&phy_vars_ue->dlsch_tc_ext_stats,
&phy_vars_ue->dlsch_tc_intl1_stats,
&phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
&phy_vars_ue->dlsch_tc_intl2_stats);
//(is_crnti==0)?harq_pid:harq_pid+1);
//}
//else{
/*nr_segmentation(NULL,
NULL,
harq_process->B,
&harq_process->C,
&harq_process->Kplus,
&harq_process->Kminus,
&harq_process->Z,
&harq_process->F);
p_decParams->Z = harq_process->Z;*/
/*nrLDPC_decoder(p_decParams,
&harq_process->d[r][96],
harq_process->c[r],
p_procTime);}
*/
//__m256i *m11_128
//llrRes = (__m256i *)harq_process->d[r][96];
//printf("start LDPC decoder\n");
/*nrLDPC_decoder(p_decParams,
llrRes,
llrProcBuf,
p_procTime);*/
//harq_process->c[r] = (uint8_t *) p_llrOut_inter;
/*printf("harq process dr %d\n",harq_process->d[r][96]);
nrLDPC_decoder(p_decParams,
&harq_process->d[r][96],
harq_process->c[r],
p_procTime);*/
//}
#if UE_TIMING_TRACE
stop_meas(dlsch_turbo_decoding_stats);
......@@ -657,6 +725,13 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
}
#endif
/*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n",
harq_process->C,
r,
dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
if ((err_flag == 0) && (ret>=(1+dlsch->max_turbo_iterations))) {// a Code segment is in error so break;
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1);
......@@ -698,8 +773,8 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
return((1+dlsch->max_turbo_iterations));
} else {
#if UE_DEBUG_TRACE
LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d\n",
phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
phy_vars_ue->Mod_id,nr_tti_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
#endif
harq_process->status = SCH_IDLE;
......@@ -2225,7 +2300,7 @@ int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], ui
}
uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
uint8_t nr_tti_rx,
uint8_t subframe,
PDSCH_t dlsch_id,
uint8_t eNB_id)
{
......@@ -2251,7 +2326,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
mac_xface->macphy_exit("Could not find attached eNB for DLSCH emulation");
}
LOG_D(PHY,"[UE] dlsch_decoding_emul : nr_tti_rx %d, eNB_id %d, dlsch_id %d\n",nr_tti_rx,eNB_id2,dlsch_id);
LOG_D(PHY,"[UE] dlsch_decoding_emul : subframe %d, eNB_id %d, dlsch_id %d\n",subframe,eNB_id2,dlsch_id);
// printf("dlsch_eNB_ra->harq_processes[0] %p\n",PHY_vars_eNB_g[eNB_id]->dlsch_eNB_ra->harq_processes[0]);
......
......@@ -748,9 +748,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
#if UE_TIMING_TRACE
stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]);
#if DISABLE_LOG_X
printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
//printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
#else
LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
//LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0));
#endif
#endif
// MRC
......
......@@ -1325,6 +1325,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
uint8_t subframe,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t decoder_switch,
uint8_t llr8_flag);
/*
uint32_t dlsch_decoding_mthread(PHY_VARS_UE *phy_vars_ue,
......
......@@ -444,7 +444,9 @@ typedef struct {
uint8_t llr_slot1_available;
uint8_t dci_slot0_available;
uint8_t first_symbol_available;
//uint8_t channel_level;
uint8_t decoder_switch;
int counter_decoder;
uint8_t channel_level;
int eNB_id;
int harq_pid;
int llr8_flag;
......
......@@ -3572,7 +3572,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
frame_rx,
nr_tti_rx,
0,
0,1);
0,0,1);
printf("start pmch dlsch decoding\n");
#endif
} else { // abstraction
......@@ -4007,7 +4007,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
frame_rx,
nr_tti_rx,
harq_pid,
pdsch==PDSCH?1:0,
pdsch==PDSCH?1:0,proc->decoder_switch,
dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
printf("start cW0 dlsch decoding\n");
#endif
......@@ -4020,9 +4020,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
printf("AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
#else
LOG_D(PHY, " --> Unscrambling for CW0 %5.3f\n",
LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n",
(ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
#endif
......@@ -4088,7 +4088,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
frame_rx,
nr_tti_rx,
harq_pid,
pdsch==PDSCH?1:0,
pdsch==PDSCH?1:0,proc->decoder_switch,
dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
printf("start cw1 dlsch decoding\n");
#endif
......@@ -4108,7 +4108,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
#endif
#endif
LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
LOG_I(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0));
}
......@@ -5107,6 +5107,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
int pmch_flag=0;
int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx;
proc->decoder_switch = 0;
//int counter_decoder = 0;
uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
......@@ -5377,9 +5379,16 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
// do procedures for C-RNTI
LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) {
proc->counter_decoder++;
printf("counter decoder %d\n", proc->counter_decoder);
if (proc->counter_decoder > 6)
{
proc->decoder_switch = 1;
printf("switch to LDPC\n");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
#if UE_TIMING_TRACE
start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]);
start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
#endif
ue_pdsch_procedures(ue,
proc,
......@@ -5391,7 +5400,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
ue->frame_parms.symbols_per_tti-1,
abstraction_flag);
LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
LOG_I(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_tti_rx);
#if UE_TIMING_TRACE
stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
......
......@@ -492,6 +492,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
PHY_VARS_UE *UE = rtd->UE;
int ret;
//proc->counter_decoder = 0;
proc->instance_cnt_rxtx=-1;
proc->subframe_rx=proc->sub_frame_start;
......@@ -658,6 +659,9 @@ void *UE_thread(void *arg) {
int i;
char threadname[128];
int th_id;
UE->proc.proc_rxtx[0].counter_decoder = 0;
UE->proc.proc_rxtx[1].counter_decoder = 0;
UE->proc.proc_rxtx[2].counter_decoder = 0;
static uint8_t thread_idx = 0;
......
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