Commit e6804be9 authored by Sakthivel Velumani's avatar Sakthivel Velumani

created worker threads

parent 6042df1a
......@@ -289,6 +289,196 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
static uint32_t prnt_crc_cnt = 0;
#endif
uint32_t nr_processULSegment(void* arg) {
ldpcDecode_t *rdata = (ldpcDecode_t*) arg;
PHY_VARS_gNB *phy_vars_gNB = rdata->gNB;
NR_UL_gNB_HARQ_t *ulsch_harq = rdata->ulsch_harq;
t_nrLDPC_dec_params *p_decoderParms = rdata->p_decoderParms;
int length_dec;
int Kr;
int Kr_bytes;
uint8_t crc_type;
int i;
int j;
int r = rdata->segment_r;
int A = rdata->A;
int E = rdata->E;
int Qm = rdata->Qm;
int rv_index = rdata->rv_index;
int r_offset = rdata->r_offset;
uint8_t kc = rdata->Kc;
uint32_t Tbslbrm = rdata->Tbslbm;
short* ulsch_llr = rdata->ulsch_llr;
int max_ldpc_iterations = rdata->p_decParams->numMaxIter;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
int16_t z [68*384];
int8_t l [68*384];
uint8_t Ilbrm = 0;
Kr = ulsch_harq->K;
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(ulsch_harq->F>>3);
start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// ulsch_llr =====> ulsch_harq->e //////////////////////////////
nr_deinterleaving_ldpc(E,
Qm,
ulsch_harq->e[r],
ulsch_llr+r_offset);
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,ulsch_harq->w[r][i], r_offset);
stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
/*LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
ulsch_harq->TBS,
Qm,
nb_rb,
n_layers,
pusch_pdu->pusch_data.rv_index,
ulsch_harq->round);*/
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// ulsch_harq->e =====> ulsch_harq->d /////////////////////////
start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
p_decParams->Z,
ulsch_harq->d[r],
ulsch_harq->e[r],
ulsch_harq->C,
rv_index,
(ulsch_harq->round==0)?1:0,
E,
ulsch_harq->F,
Kr-ulsch_harq->F-2*(p_decParams->Z))==-1) {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
rdata->decodeIterations = max_ldpc_iterations + 1;
return;
} else {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
}
#ifdef DEBUG_ULSCH_DECODING
if (r==0) {
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
write_output("decoder_in.m","dec",&ulsch_harq->d[0][0],E,1,0);
}
printf("decoder input(segment %u) :", r);
int i;
for (i=0;i<(3*8*Kr_bytes)+12;i++)
printf("%d : %d\n",i,ulsch_harq->d[r][i]);
printf("\n");
#endif
// printf("Clearing c, %p\n",ulsch_harq->c[r]);
memset(ulsch_harq->c[r],0,Kr_bytes);
// printf("done\n");
if (ulsch_harq->C == 1) {
if (A > 3824)
crc_type = CRC24_A;
else
crc_type = CRC16;
length_dec = ulsch_harq->B;
}
else {
crc_type = CRC24_B;
length_dec = (ulsch_harq->B+24*ulsch_harq->C)/ulsch_harq->C;
}
start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,ulsch_harq->C-1, A);
memset(pv,0,2*ulsch_harq->Z*sizeof(int16_t));
memset((pv+K_bytes_F),127,ulsch_harq->F*sizeof(int16_t));
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
}
AssertFatal(kc!=255,"");
j+=(ulsch_harq->F>>3);
for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j]));
}
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
(int8_t*)&pl[0],
llrProcBuf,
ulsch_harq->p_nrLDPC_procBuf[r],
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,ulsch_harq->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
//if (prnt_crc_cnt % 10 == 0)
LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif
rdata->decodeIterations = no_iteration_ldpc;
} else {
#ifdef PRINT_CRC_CHECK
//if (prnt_crc_cnt%10 == 0)
LOG_I(PHY, "CRC NOK\n");
#endif
rdata->decodeIterations = max_ldpc_iterations + 1;
}
for (int m=0; m < Kr>>3; m ++) {
ulsch_harq->c[r][m]= (uint8_t) llrProcBuf[m];
}
#ifdef DEBUG_ULSCH_DECODING
//printf("output decoder %d %d %d %d %d \n", ulsch_harq->c[r][0], ulsch_harq->c[r][1], ulsch_harq->c[r][2],ulsch_harq->c[r][3], ulsch_harq->c[r][4]);
for (int k=0;k<A>>3;k++)
printf("output decoder [%d] = 0x%02x \n", k, ulsch_harq->c[r][k]);
printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
//write_output("dec_output.m","dec0",ulsch_harq->c[0],Kr_bytes,1,4);
#endif
stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
}
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
......@@ -299,12 +489,9 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t harq_pid,
uint32_t G) {
uint32_t A,E;
uint32_t ret, offset;
int32_t no_iteration_ldpc, length_dec;
uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0;
uint8_t crc_type;
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
uint32_t A;
uint32_t ret;
uint32_t r,r_offset=0;
#ifdef PRINT_CRC_CHECK
prnt_crc_cnt++;
......@@ -322,13 +509,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
printf("ulsch_decoding.c: NULL harq_process pointer\n");
return (ulsch->max_ldpc_iterations + 1);
}
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
int16_t z [68*384];
int8_t l [68*384];
uint8_t kc = 255;
uint8_t Ilbrm = 0;
uint32_t Tbslbrm = 950984;
double Coderate = 0.0;
// ------------------------------------------------------------------
......@@ -339,7 +520,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t n_layers = pusch_pdu->nrOfLayers;
// ------------------------------------------------------------------
uint32_t i,j;
uint32_t i;
__m128i *pv = (__m128i*)&z;
__m128i *pl = (__m128i*)&l;
......@@ -350,11 +531,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
return (ulsch->max_ldpc_iterations + 1);
}
if (!frame_parms) {
printf("ulsch_decoding.c: NULL frame_parms pointer\n");
return (ulsch->max_ldpc_iterations + 1);
}
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_ULSCH_DECODING,1);
......@@ -362,7 +538,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
harq_process->round = nr_rv_round_map[pusch_pdu->pusch_data.rv_index];
A = (harq_process->TBS)<<3;
ret = ulsch->max_ldpc_iterations + 1;
LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers);
......@@ -419,6 +594,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
&harq_process->F,
p_decParams->BG);
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
#ifdef DEBUG_ULSCH_DECODING
printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z);
if (!frame%100)
......@@ -431,7 +608,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
p_decParams->numMaxIter = ulsch->max_ldpc_iterations;
p_decParams->outMode= 0;
err_flag = 0;
r_offset = 0;
uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS; //number of segments to be allocated
......@@ -449,200 +625,30 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
#endif
//opp_enabled=1;
Kr = harq_process->K;
Kr_bytes = Kr>>3;
K_bytes_F = Kr_bytes-(harq_process->F>>3);
for (r=0; r<harq_process->C; r++) {
E = nr_get_E(G, harq_process->C, Qm, n_layers, r);
start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// nr_deinterleaving_ldpc ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////// ulsch_llr =====> harq_process->e //////////////////////////////
nr_deinterleaving_ldpc(E,
Qm,
harq_process->e[r],
ulsch_llr+r_offset);
//for (int i =0; i<16; i++)
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats);
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
harq_pid,r, G,
Kr*3,
harq_process->TBS,
Qm,
nb_rb,
n_layers,
pusch_pdu->pusch_data.rv_index,
harq_process->round);
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// nr_rate_matching_ldpc_rx ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// harq_process->e =====> harq_process->d /////////////////////////
start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C);
if (nr_rate_matching_ldpc_rx(Ilbrm,
Tbslbrm,
p_decParams->BG,
p_decParams->Z,
harq_process->d[r],
harq_process->e[r],
harq_process->C,
pusch_pdu->pusch_data.rv_index,
(harq_process->round==0)?1:0,
E,
harq_process->F,
Kr-harq_process->F-2*(p_decParams->Z))==-1) {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n");
return (ulsch->max_ldpc_iterations + 1);
} else {
stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats);
}
union ldpcReqUnion id = {.s={ulsch->rnti,frame,slot,nr_tti_rx,0,0}};
notifiedFIFO_elt_t *req=newNotifiedFIFO_elt(sizeof(ldpcDecode_t), id.p, phy_vars_gNB->respDecode, nr_processULSegment);
ldpcDecode_t * rdata=(ldpcDecode_t *) NotifiedFifoData(req);
rdata->gNB = phy_vars_gNB;
rdata->ulsch_harq = harq_process;
rdata->p_decoderParms = p_decParams;
rdata->ulsch_llr = ulsch_llr;
rdata->Kc = Kc;
rdata->segment_r = r;
rdata->nbSegments = harq_process->C;
rdata->E = E;
rdata->A = A;
rdata->Qm = Qm;
rdata->r_offset = r_offset;
rdata->rv_index = pusch_pdu->pusch_data.rv_index;
rdata->Tbslbrm = Tbslbrm;
r_offset += E;
#ifdef DEBUG_ULSCH_DECODING
if (r==0) {
write_output("decoder_llr.m","decllr",ulsch_llr,G,1,0);
write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
}
printf("decoder input(segment %u) :", r);
int i;
for (i=0;i<(3*8*Kr_bytes)+12;i++)
printf("%d : %d\n",i,harq_process->d[r][i]);
printf("\n");
#endif
// printf("Clearing c, %p\n",harq_process->c[r]);
memset(harq_process->c[r],0,Kr_bytes);
// printf("done\n");
if (harq_process->C == 1) {
if (A > 3824)
crc_type = CRC24_A;
else
crc_type = CRC16;
length_dec = harq_process->B;
}
else {
crc_type = CRC24_B;
length_dec = (harq_process->B+24*harq_process->C)/harq_process->C;
}
if (err_flag == 0) {
start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A);
memset(pv,0,2*harq_process->Z*sizeof(int16_t));
memset((pv+K_bytes_F),127,harq_process->F*sizeof(int16_t));
for (i=((2*p_decParams->Z)>>3), j = 0; i < K_bytes_F; i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
AssertFatal(kc!=255,"");
j+=(harq_process->F>>3);
for (i=Kr_bytes; i < ((kc*p_decParams->Z)>>3); i++, j++) {
pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j]));
}
for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) {
pl[j] = _mm_packs_epi16(pv[i],pv[i+1]);
}
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// nrLDPC_decoder /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// pl =====> llrProcBuf //////////////////////////////////
no_iteration_ldpc = nrLDPC_decoder(p_decParams,
(int8_t*)&pl[0],
llrProcBuf,
p_nrLDPC_procBuf[r],
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
#ifdef PRINT_CRC_CHECK
//if (prnt_crc_cnt % 10 == 0)
LOG_I(PHY, "Segment %d CRC OK\n",r);
#endif
ret = no_iteration_ldpc;
} else {
#ifdef PRINT_CRC_CHECK
//if (prnt_crc_cnt%10 == 0)
LOG_I(PHY, "CRC NOK\n");
#endif
ret = ulsch->max_ldpc_iterations + 1;
}
nb_total_decod++;
if (no_iteration_ldpc > ulsch->max_ldpc_iterations){
nb_error_decod++;
}
for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
}
#ifdef DEBUG_ULSCH_DECODING
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
for (int k=0;k<A>>3;k++)
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
#endif
stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats);
}
if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) {
// 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);
err_flag = 1;
}
//////////////////////////////////////////////////////////////////////////////////////////
}
int32_t frame_rx_prev = frame;
int32_t tti_rx_prev = nr_tti_rx - 1;
if (tti_rx_prev < 0) {
frame_rx_prev--;
tti_rx_prev += frame_parms->slots_per_frame;
}
frame_rx_prev = frame_rx_prev%1024;
return ret;
if (err_flag == 1) {
......
......@@ -252,6 +252,8 @@ typedef struct {
int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
uint32_t E;
/// Number of segments processed so far
uint32_t processedSegments;
//////////////////////////////////////////////////////////////
......@@ -463,6 +465,36 @@ typedef struct {
uint8_t cl_done;
} NR_gNB_PUSCH;
typedef struct LDPCDecode_s {
PHY_BARS_gNB *gNB;
NR_UL_gNB_HARQ_t *ulsch_harq;
t_nrLDPC_dec_params *p_decoderParms;
short* ulsch_llr;
int harq_pid;
int rv_index;
int A;
int E;
int Kc;
int Qm;
int nbSegments;
int segment_r;
int r_offset;
int Tbslbrm;
int decodeIterations;
} ldpcDecode_t
struct ldpcReqId {
uint16_t rnti;
uint16_t frame;
uint8_t subframe;
uint8_t codeblock;
uint16_t spare;
} __attribute__((packed));
union ldpcReqUnion {
struct ldpcReqId s;
uint64_t p;
};
/// Context data structure for RX/TX portion of slot processing
typedef struct {
......@@ -802,6 +834,9 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t rx_dft_stats;
time_stats_t ulsch_freq_offset_estimation_stats;
*/
notifiedFIFO_t *respDecode;
tpool_t *threadPool;
int nbDecode;
} PHY_VARS_gNB;
......
......@@ -225,6 +225,17 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
*/
void nr_postDecode(PHY_VARS_gNB gNB, notifiedFIFO_elt_t *req) {
ldpcDecode_t *rdata = (ldpcDeocde_t*) NotifiedFifoData(req);
NR_UL_gNB_HARQ_t ulsch_harq = rdata->ulsch_harq;
bool decodeSuccess = (rdata->deocdeIterations <= rdata->p_decoderParms->numMaxIter);
ulsch_harq->processedSegments++;
LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n",
rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments);
proc->nbDecode--;
LOG_D(PHY,"remain to decoded in subframe: %d\n", proc->nbDecode);
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
......@@ -282,17 +293,22 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH
//----------------------------------------------------------
start_meas(&gNB->ulsch_decoding_stats);
ret = nr_ulsch_decoding(gNB,
ULSCH_id,
gNB->pusch_vars[ULSCH_id]->llr,
frame_parms,
pusch_pdu,
frame_rx,
slot_rx,
harq_pid,
G);
nr_ulsch_decoding(gNB,
ULSCH_id,
gNB->pusch_vars[ULSCH_id]->llr,
frame_parms,
pusch_pdu,
frame_rx,
slot_rx,
harq_pid,
G);
stop_meas(&gNB->ulsch_decoding_stats);
while (gNB->nbDecode > 0) {
notifiedFIFO_elt_t *req=pullTpool(gNB->respDecode, gNB->threadPool);
nr_postDecode(gNB, req);
delNotifiedFIFO_elt(req);
}
if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations){
LOG_D(PHY, "ULSCH %d in error\n",ULSCH_id);
......
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