diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 8fe115b23a..f7bc964cad 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -695,7 +695,7 @@ uint32_t polar_decoder_int16(int16_t *input, else if (crclen==6) crc = (uint64_t)(crc6(A64_flip,8*offset+len)>>26)&0x3f; } -#if 0 +#if 1 printf("A %llx B %llx|%llx Cprime %llx|%llx (crc %x,rxcrc %llx %d)\n", Ar, B[1],B[0],Cprime[1],Cprime[0],crc, diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c index e61b3dff9b..ddf9bd5263 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_encoder.c @@ -30,7 +30,7 @@ * \warning */ -//#define DEBUG_POLAR_ENCODER +#define DEBUG_POLAR_ENCODER //#define DEBUG_POLAR_ENCODER_DCI //#define DEBUG_POLAR_MATLAB @@ -258,10 +258,11 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void // handle rate matching with a single 128 bit word using bit shuffling // can be done with SIMD intrisics if needed if (polarParams->groupsize < 8) { - AssertFatal(polarParams->encoderLength<=128,"Need to handle groupsize<8 and N>128\n"); + AssertFatal(polarParams->encoderLength<=512,"Need to handle groupsize(%d)<8 and N(%d)>512\n",polarParams->groupsize,polarParams->encoderLength); uint128_t *out128=(uint128_t*)out; uint128_t *in128=(uint128_t*)in; - *out128=0; + for (int i=0;i<=polarParams->encoderLength>>7;i++) + out128[i]=0; uint128_t tmp0; #ifdef DEBUG_POLAR_ENCODER uint128_t tmp1; @@ -270,15 +271,21 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void #ifdef DEBUG_POLAR_ENCODER printf("%d<-%u : %llx.%llx =>",i,polarParams->rate_matching_pattern[i],((uint64_t *)out)[1],((uint64_t *)out)[0]); #endif - tmp0 = (*in128&(((uint128_t)1)<rate_matching_pattern[i])); + uint8_t pi=polarParams->rate_matching_pattern[i]; + uint8_t pi7=pi>>7; + uint8_t pimod128=pi&127; + uint8_t imod128=i&127; + uint8_t i7=i>>7; + + tmp0 = (in128[pi7]&(((uint128_t)1)<<(pimod128))); + if (tmp0!=0) { - *out128 = *out128 | ((uint128_t)1)<%llx.%llx => %llx.%llx\n", - ((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0], - ((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0], - ((uint64_t *)out)[1],((uint64_t *)out)[0]); + printf("%llx.%llx<->%llx.%llx => %llx.%llx\n", + ((uint64_t *)&tmp0)[1],((uint64_t *)&tmp0)[0], + ((uint64_t *)&tmp1)[1],((uint64_t *)&tmp1)[0], + ((uint64_t *)out)[1],((uint64_t *)out)[0]); #endif } } diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index 7cf9556fe3..ad0dffa7bc 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -101,45 +101,55 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int first_symb,int num_symb) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; NR_gNB_COMMON *common_vars = &gNB->common_vars; PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements; - uint32_t *rb_mask = gNB->rb_mask_ul; - int rb, offset, offset0, nb_rb, len; + int rb, offset, offset0, nb_symb[275], len; int32_t *ul_ch; - int32_t n0_power_tot; - int64_t n0_power_tot2; + int32_t n0_power_tot[275]; - nb_rb = 0; - n0_power_tot2=0; - for (rb=0; rbN_RB_UL; rb++) { - n0_power_tot=0; - offset0 = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; - if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe - nb_rb++; - for (int aarx=0; aarxnb_antennas_rx; aarx++) { - measurements->n0_subband_power[aarx][rb]=0; - for (int s=first_symb;s<(first_symb+num_symb);s++) { + for (int s=first_symb;s<(first_symb+num_symb);s++) { + for (rb=0; rbN_RB_UL; rb++) { - offset = offset0 + (s*frame_parms->ofdm_symbol_size); - ul_ch = &common_vars->rxdataF[aarx][offset]; - len = 12; - if (((frame_parms->N_RB_UL&1) == 1) && - (rb==(frame_parms->N_RB_UL>>1))) { - len=6; - } - AssertFatal(ul_ch, "RX signal buffer (freq) problem\n"); - measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len); - } // symbol - measurements->n0_subband_power[aarx][rb]/=num_symb; + if (s==first_symb) { + n0_power_tot[rb]=0; + nb_symb[rb]=0; + } + offset0 = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; + if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe + nb_symb[rb]++; + for (int aarx=0; aarxnb_antennas_rx; aarx++) { + if (s==first_symb) measurements->n0_subband_power[aarx][rb]=0; + offset = offset0 + (s*frame_parms->ofdm_symbol_size); + ul_ch = &common_vars->rxdataF[aarx][offset]; + len = 12; + if (((frame_parms->N_RB_UL&1) == 1) && + (rb==(frame_parms->N_RB_UL>>1))) { + len=6; + } + AssertFatal(ul_ch, "RX signal buffer (freq) problem\n"); + measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len); measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]); - n0_power_tot += measurements->n0_subband_power[aarx][rb]; - } //antenna - n0_power_tot/=frame_parms->nb_antennas_rx; - n0_power_tot2 += n0_power_tot; - measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot); + } //antenna + } + } //rb + } // symb + int nb_rb=0; + int32_t n0_subband_tot=0; + int32_t n0_subband_tot_perPRB=0; + for (int rb = 0 ; rbN_RB_UL;rb++) { + n0_subband_tot_perPRB=0; + if (nb_symb[rb] > 0) { + for (int aarx=0;aarxnb_antennas_rx;aarx++) { + measurements->n0_subband_power[aarx][rb]/=nb_symb[rb]; + n0_subband_tot_perPRB+=measurements->n0_subband_power[aarx][rb]; + } + n0_subband_tot_perPRB/=frame_parms->nb_antennas_rx; + measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_subband_tot_perPRB); measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - gNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL); + //printf("n0_subband_power_tot_dB[%d] => %d, over %d symbols\n",rb,measurements->n0_subband_power_tot_dB[rb],nb_symb[rb]); + n0_subband_tot += n0_subband_tot; + nb_rb++; } - } //rb - - if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb); + } + if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_subband_tot/nb_rb); } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 92fabe59c3..5c6af81455 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -240,7 +240,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, int prb_offset[2] = {pucch_pdu->bwp_start+pucch_pdu->prb_start, pucch_pdu->bwp_start+pucch_pdu->prb_start}; nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,0,slot,&u[0],&v[0]); // calculating u and v value first hop - LOG_I(PHY,"pucch0: u %d, v %d\n",u[0],v[0]); + LOG_I(PHY,"pucch0: cs_ind %d, u %d, v %d\n",cs_ind,u[0],v[0]); if (pucch_pdu->freq_hop_flag == 1) { @@ -249,6 +249,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, prb_offset[1] = pucch_pdu->bwp_start+pucch_pdu->second_hop_prb; } + AssertFatal(pucch_pdu->nr_of_symbols < 3,"nr_of_symbols %d not allowed\n",pucch_pdu->nr_of_symbols); uint32_t re_offset[2]={0,0}; uint8_t l2; @@ -259,12 +260,15 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, x_re[1] = table_5_2_2_2_2_Re[u[1]]; x_im[1] = table_5_2_2_2_2_Im[u[1]]; - int16_t xr[2][24] __attribute__((aligned(32))); + int16_t xr[1+frame_parms->nb_antennas_rx][1+pucch_pdu->nr_of_symbols][24] __attribute__((aligned(32))); int64_t xrtmag=0; uint8_t maxpos=0; uint8_t index=0; - memset((void*)xr[0],0,24*sizeof(int16_t)); - memset((void*)xr[1],0,24*sizeof(int16_t)); + for (l=0; lnr_of_symbols; l++) { + for (int aarx=0;aarxnb_antennas_rx;aarx++) { + memset((void*)xr[aarx][l],0,24*sizeof(int16_t)); + } + } int n2; for (l=0; lnr_of_symbols; l++) { @@ -276,72 +280,92 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n"); int16_t *r; for (int aa=0;aanb_antennas_rx;aa++) { - r=(int16_t*)&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset[l]]; + r=(int16_t*)&rxdataF[aa][(l2*frame_parms->ofdm_symbol_size)+re_offset[l]]; n2=0; for (n=0;n<12;n++,n2+=2) { - xr[l][n2] +=(int16_t)(((int32_t)x_re[l][n]*r[n2]+(int32_t)x_im[l][n]*r[n2+1])>>15); - xr[l][n2+1]+=(int16_t)(((int32_t)x_re[l][n]*r[n2+1]-(int32_t)x_im[l][n]*r[n2])>>15); + xr[aa][l][n2] +=(int16_t)(((int32_t)x_re[l][n]*r[n2]+(int32_t)x_im[l][n]*r[n2+1])>>15); + xr[aa][l][n2+1]+=(int16_t)(((int32_t)x_re[l][n]*r[n2+1]-(int32_t)x_im[l][n]*r[n2])>>15); #ifdef DEBUG_NR_PUCCH_RX printf("x (%d,%d), r%d.%d (%d,%d), xr (%d,%d)\n", - x_re[l][n],x_im[l][n],l2,re_offset[l],r[n2],r[n2+1],xr[l][n2],xr[l][n2+1]); + x_re[l][n],x_im[l][n],l2,re_offset[l],r[n2],r[n2+1],xr[aa][l][n2],xr[aa][l][n2+1]); #endif } } } - int32_t corr_re[2]; - int32_t corr_im[2]; + int32_t corr_re[1+frame_parms->nb_antennas_rx][2]; + int32_t corr_im[1+frame_parms->nb_antennas_rx][2]; //int32_t no_corr = 0; int seq_index; int64_t temp; int64_t av_corr=0; for(i=0;inr_of_symbols;l++) { - corr_re[l]=0; - corr_im[l]=0; seq_index = (pucch_pdu->initial_cyclic_shift+ mcs[i]+ gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12; #ifdef DEBUG_NR_PUCCH_RX printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]); #endif - n2=0; - for (n=0;n<12;n++,n2+=2) { - corr_re[l]+=(xr[l][n2]*idft12_re[seq_index][n]+xr[l][n2+1]*idft12_im[seq_index][n])>>15; - corr_im[l]+=(xr[l][n2]*idft12_im[seq_index][n]-xr[l][n2+1]*idft12_re[seq_index][n])>>15; + for (int aa=0;aanb_antennas_rx;aa++) { + corr_re[aa][l]=0; + corr_im[aa][l]=0; + + n2=0; + for (n=0;n<12;n++,n2+=2) { + corr_re[aa][l]+=(xr[aa][l][n2]*idft12_re[seq_index][n]+xr[aa][l][n2+1]*idft12_im[seq_index][n])>>15; + corr_im[aa][l]+=(xr[aa][l][n2]*idft12_im[seq_index][n]-xr[aa][l][n2+1]*idft12_re[seq_index][n])>>15; + } } } - -//#ifdef DEBUG_NR_PUCCH_RX - LOG_I(PHY,"PUCCH IDFT = (%d,%d)=>%f\n",corr_re[0],corr_im[0],10*log10((double)corr_re[0]*corr_re[0] + (double)corr_im[0]*corr_im[0])); - if (l>1) LOG_I(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[1],corr_im[1],10*log10((double)corr_re[1]*corr_re[1] + (double)corr_im[1]*corr_im[1])); -//#endif - if (pucch_pdu->freq_hop_flag == 0 && l==1) // non-coherent correlation - temp=(int64_t)corr_re[0]*corr_re[0] + (int64_t)corr_im[0]*corr_im[0]; - else if (pucch_pdu->freq_hop_flag == 0 && l==2) { - int64_t corr_re2 = (int64_t)corr_re[0]+corr_re[1]; - int64_t corr_im2 = (int64_t)corr_im[0]+corr_im[1]; - // coherent combining of 2 symbols and then complex modulus for single-frequency case - temp=corr_re2*corr_re2 + corr_im2*corr_im2; +#ifdef DEBUG_NR_PUCCH_RX + LOG_I(PHY,"PUCCH IDFT = (%d,%d)=>%f\n",corr_re[0][0],corr_im[0][0],10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0])); + if (l>1) LOG_I(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",mcs[i],seq_index,corr_re[0][1],corr_im[0][1],10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1])); +#endif + if (pucch_pdu->freq_hop_flag == 0 && l==1) {// non-coherent correlation + temp=0; + for (int aa=0;aanb_antennas_rx;aa++) + temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]; } - else if (pucch_pdu->freq_hop_flag == 1) + else if (pucch_pdu->freq_hop_flag == 0 && l==2) { + int64_t corr_re2=0; + int64_t corr_im2=0; + temp=0; + for (int aa=0;aanb_antennas_rx;aa++) { + corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1]; + corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1]; + // coherent combining of 2 symbols and then complex modulus for single-frequency case + temp+=corr_re2*corr_re2 + corr_im2*corr_im2; + } + } + else if (pucch_pdu->freq_hop_flag == 1) { // full non-coherent combining of 2 symbols for frequency-hopping case - temp = (int64_t)corr_re[0]*corr_re[0] + (int64_t)corr_im[0]*corr_im[0] + (int64_t)corr_re[1]*corr_re[1] + (int64_t)corr_im[1]*corr_im[1]; + temp=0; + for (int aa=0;aanb_antennas_rx;aa++) + temp += (int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0] + (int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]; + } else AssertFatal(1==0,"shouldn't happen\n"); av_corr+=temp; if (temp>xrtmag) { xrtmag=temp; maxpos=i; - uci_stats->current_pucch0_stat0 = dB_fixed64((int64_t)corr_re[0]*corr_re[0] + (int64_t)corr_im[0]*corr_im[0]); - if (l==2) uci_stats->current_pucch0_stat1 = dB_fixed64((int64_t)corr_re[1]*corr_re[1] + (int64_t)corr_im[1]*corr_im[1]); + uci_stats->current_pucch0_stat0 = 0; + int64_t temp2=0,temp3=0;; + for (int aa=0;aanb_antennas_rx;aa++) { + temp2 += ((int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]); + if (l==2) temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]); + } + uci_stats->current_pucch0_stat0= dB_fixed64(temp2); + if (l==2) uci_stats->current_pucch0_stat1= dB_fixed64(temp3); } } av_corr/=nr_sequences/l; - uint8_t xrtmag_dB = dB_fixed64(xrtmag); + uint8_t xrtmag_dB = dB_fixed64(xrtmag/frame_parms->nb_antennas_rx); #ifdef DEBUG_NR_PUCCH_RX printf("PUCCH 0 : maxpos %d\n",maxpos); @@ -350,7 +374,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, index=maxpos; uci_stats->pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]]; uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]; - + LOG_D(PHY,"n00[%d] = %d, n01[%d] = %d\n",prb_offset[0],uci_stats->pucch0_n00,prb_offset[1],uci_stats->pucch0_n01); // estimate CQI for MAC (from antenna port 0 only) int max_n0 = uci_stats->pucch0_n00>uci_stats->pucch0_n01 ? uci_stats->pucch0_n00:uci_stats->pucch0_n01; int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset[0]],12)) - (10*max_n0); @@ -392,8 +416,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq->harq_confidence_level = no_conf ? 1 : 0; uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1); uci_pdu->harq->harq_list[0].harq_value = index&0x01; - LOG_I(PHY, "Slot %d HARQ value %d with confidence level (0 is good, 1 is bad) %d xrt_mag %d n0 %d pucch0_thres %d\n", - slot,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dB,max_n0,uci_stats->pucch0_thres); + LOG_I(PHY,"Slot %d HARQ value %d, index %d with confidence level (0 is good, 1 is bad) %d xrt_mag %d n0 %d pucch0_thres %d\n", + slot,uci_pdu->harq->harq_list[0].harq_value,index,uci_pdu->harq->harq_confidence_level,xrtmag_dB,max_n0,uci_stats->pucch0_thres); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); uci_pdu->sr->sr_indication = (index>1) ? 1 : 0; @@ -1081,92 +1105,114 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, //extract pucch and dmrs first int l2=pucch_pdu->start_symbol_index; - int re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; - if (re_offset>= frame_parms->ofdm_symbol_size) - re_offset-=frame_parms->ofdm_symbol_size; - + int re_offset[2]; + re_offset[0] = 12*(pucch_pdu->prb_start+pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; + if (re_offset[0]>= frame_parms->ofdm_symbol_size) + re_offset[0]-=frame_parms->ofdm_symbol_size; + if (pucch_pdu->freq_hop_flag == 0) re_offset[1] = re_offset[0]; + else { + re_offset[1] = 12*(pucch_pdu->second_hop_prb+pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; + if (re_offset[1]>= frame_parms->ofdm_symbol_size) + re_offset[1]-=frame_parms->ofdm_symbol_size; + } AssertFatal(pucch_pdu->prb_size*pucch_pdu->nr_of_symbols > 1,"number of PRB*SYMB (%d,%d)< 2", pucch_pdu->prb_size,pucch_pdu->nr_of_symbols); int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value; int Prx2 = (Prx==1)?2:Prx; // use 2 for Nb antennas in case of single antenna to allow the following allocations - int16_t r_re_ext[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); - int16_t r_im_ext[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); - int16_t r_re_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); - int16_t r_im_ext2[Prx2][8*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); - int16_t rd_re_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); - int16_t rd_im_ext[Prx2][4*pucch_pdu->nr_of_symbols*pucch_pdu->prb_size] __attribute__((aligned(32))); + int prb_size_ext = pucch_pdu->prb_size+(pucch_pdu->prb_size&1); + int16_t r_re_ext[Prx2][2][8*prb_size_ext] __attribute__((aligned(32))); + int16_t r_im_ext[Prx2][2][8*prb_size_ext] __attribute__((aligned(32))); + int16_t r_re_ext2[Prx2][2][8*prb_size_ext] __attribute__((aligned(32))); + int16_t r_im_ext2[Prx2][2][8*prb_size_ext] __attribute__((aligned(32))); + int16_t rd_re_ext[Prx2][2][4*prb_size_ext] __attribute__((aligned(32))); + int16_t rd_im_ext[Prx2][2][4*prb_size_ext] __attribute__((aligned(32))); int16_t *r_re_ext_p,*r_im_ext_p,*rd_re_ext_p,*rd_im_ext_p; int nb_re_pucch = 12*pucch_pdu->prb_size; - int16_t rp[Prx2][nb_re_pucch*2],*tmp_rp; + int16_t rp[Prx2][2][nb_re_pucch*2],*tmp_rp; __m64 dmrs_re,dmrs_im; for (int aa=0;aaofdm_symbol_size]); - - if (re_offset + nb_re_pucch < frame_parms->ofdm_symbol_size) { - memcpy1((void*)rp[aa],(void*)&tmp_rp[re_offset*2],nb_re_pucch*sizeof(int32_t)); - } - else { - int neg_length = frame_parms->ofdm_symbol_size-re_offset; - int pos_length = nb_re_pucch-neg_length; - memcpy1((void*)rp[aa],(void*)&tmp_rp[re_offset*2],neg_length*sizeof(int32_t)); - memcpy1((void*)&rp[aa][neg_length*2],(void*)tmp_rp,pos_length*sizeof(int32_t)); + for (int symb=0;symbnr_of_symbols;symb++) { + tmp_rp = ((int16_t *)&rxdataF[aa][(l2+symb)*frame_parms->ofdm_symbol_size]); + + if (re_offset[symb] + nb_re_pucch < frame_parms->ofdm_symbol_size) { + memcpy1((void*)rp[aa][symb],(void*)&tmp_rp[re_offset[symb]*2],nb_re_pucch*sizeof(int32_t)); + } + else { + int neg_length = frame_parms->ofdm_symbol_size-re_offset[symb]; + int pos_length = nb_re_pucch-neg_length; + memcpy1((void*)rp[aa][symb],(void*)&tmp_rp[re_offset[symb]*2],neg_length*sizeof(int32_t)); + memcpy1((void*)&rp[aa][symb][neg_length*2],(void*)tmp_rp,pos_length*sizeof(int32_t)); + } } } - #ifdef DEBUG_NR_PUCCH_RX printf("Decoding pucch2 for %d symbols, %d PRB\n",pucch_pdu->nr_of_symbols,pucch_pdu->prb_size); #endif int nc_group_size=1; // 2 PRB - int ngroup = pucch_pdu->prb_size/nc_group_size/2; - int32_t corr32_re[ngroup][Prx2],corr32_im[ngroup][Prx2]; - for (int aa=0;aanr_of_symbols == 1) { - AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size); - // 24 PRBs contains 48x16-bit, so 6x8x16-bit + // AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of 2\n",pucch_pdu->prb_size); + if ((pucch_pdu->prb_size&1) > 0) { // if the number of PRBs is odd + for (int symb=0; symbnr_of_symbols;symb++) { + for (int aa=0;aaprb_size],0,8*pucch_pdu->prb_size*sizeof(int16_t)); + memset(&r_im_ext[aa][symb][8*pucch_pdu->prb_size],0,8*pucch_pdu->prb_size*sizeof(int16_t)); + memset(&rd_re_ext[aa][symb][4*pucch_pdu->prb_size],0,8*pucch_pdu->prb_size*sizeof(int16_t)); + memset(&rd_im_ext[aa][symb][4*pucch_pdu->prb_size],0,8*pucch_pdu->prb_size*sizeof(int16_t)); + } + } + } + for (int symb=0; symbnr_of_symbols;symb++) { + // 24 REs contains 48x16-bit, so 6x8x16-bit for (int prb=0;prbprb_size;prb+=2) { for (int aa=0;aa (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext_p[i],rd_im_ext_p[i]); - for (int i=0;i<16;i++) printf("Ant %d PRB %d data[%d] -> (%d,%d)\n",aa,prb+(i>>3),i,r_re_ext_p[i],r_im_ext_p[i]); + for (int i=0;i<8;i++) printf("Ant %d PRB %d dmrs[%d] -> (%d,%d)\n",aa,prb+(i>>2),i,rd_re_ext_p[i],rd_im_ext_p[i]); + for (int i=0;i<16;i++) printf("Ant %d PRB %d data[%d] -> (%d,%d)\n",aa,prb+(i>>3),i,r_re_ext_p[i],r_im_ext_p[i]); #endif } // aa } // prb - - + // first compute DMRS component + uint32_t x1, x2, s=0; - x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause + x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index+symb) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause #ifdef DEBUG_NR_PUCCH_RX - printf("slot %d, start_symbol_index %d, dmrs_scrambling_id %d\n", - slot,pucch_pdu->start_symbol_index,pucch_pdu->dmrs_scrambling_id); + printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n", + slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id); #endif int reset = 1; for (int i=0; i<=(pucch_pdu->prb_start>>2); i++) { s = lte_gold_generic(&x1, &x2, reset); reset = 0; } - + for (int group=0;group>=5; - corr32_im[group][aa]>>=5; + corr32_re[symb][group][aa]+=(rd_re_ext_p[4]*((int16_t*)&dmrs_re)[0] + rd_im_ext_p[4]*((int16_t*)&dmrs_im)[0]); + corr32_im[symb][group][aa]+=(-rd_re_ext_p[4]*((int16_t*)&dmrs_im)[0] + rd_im_ext_p[4]*((int16_t*)&dmrs_re)[0]); + corr32_re[symb][group][aa]+=(rd_re_ext_p[5]*((int16_t*)&dmrs_re)[1] + rd_im_ext_p[5]*((int16_t*)&dmrs_im)[1]); + corr32_im[symb][group][aa]+=(-rd_re_ext_p[5]*((int16_t*)&dmrs_im)[1] + rd_im_ext_p[5]*((int16_t*)&dmrs_re)[1]); + corr32_re[symb][group][aa]+=(rd_re_ext_p[6]*((int16_t*)&dmrs_re)[2] + rd_im_ext_p[6]*((int16_t*)&dmrs_im)[2]); + corr32_im[symb][group][aa]+=(-rd_re_ext_p[6]*((int16_t*)&dmrs_im)[2] + rd_im_ext_p[6]*((int16_t*)&dmrs_re)[2]); + corr32_re[symb][group][aa]+=(rd_re_ext_p[7]*((int16_t*)&dmrs_re)[3] + rd_im_ext_p[7]*((int16_t*)&dmrs_im)[3]); + corr32_im[symb][group][aa]+=(-rd_re_ext_p[7]*((int16_t*)&dmrs_im)[3] + rd_im_ext_p[7]*((int16_t*)&dmrs_re)[3]); + /* corr32_re[group][aa]>>=5; + corr32_im[group][aa]>>=5;*/ #ifdef DEBUG_NR_PUCCH_RX - printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[group][aa],corr32_im[group][aa]); + printf("Group %d: corr32 (%d,%d)\n",group,corr32_re[symb][group][aa],corr32_im[symb][group][aa]); #endif } //aa - + if ((group&1) == 1) s = lte_gold_generic(&x1, &x2, 0); } // group - } - else { // 2 symbol case - AssertFatal(1==0, "Fill in 2 symbol PUCCH2 case\n"); - } + } // symb uint32_t x1, x2, s=0; // unscrambling @@ -1253,112 +1296,114 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, #ifdef DEBUG_NR_PUCCH_RX printf("x2 %x, s %x\n",x2,s); #endif - __m64 c_re0,c_im0,c_re1,c_im1,c_re2,c_im2,c_re3,c_im3; - re_offset=0; - for (int prb=0;prbprb_size;prb+=2,re_offset+=16) { - c_re0 = byte2m64_re[((uint8_t*)&s)[0]]; - c_im0 = byte2m64_im[((uint8_t*)&s)[0]]; - c_re1 = byte2m64_re[((uint8_t*)&s)[1]]; - c_im1 = byte2m64_im[((uint8_t*)&s)[1]]; - c_re2 = byte2m64_re[((uint8_t*)&s)[2]]; - c_im2 = byte2m64_im[((uint8_t*)&s)[2]]; - c_re3 = byte2m64_re[((uint8_t*)&s)[3]]; - c_im3 = byte2m64_im[((uint8_t*)&s)[3]]; - - for (int aa=0;aanr_of_symbols;symb++) { + __m64 c_re0,c_im0,c_re1,c_im1,c_re2,c_im2,c_re3,c_im3; + int re_off=0; + for (int prb=0;prbbit_len_harq+pucch_pdu->sr_flag+pucch_pdu->bit_len_csi_part1+pucch_pdu->bit_len_csi_part2; AssertFatal(nb_bit > 2 && nb_bit< 65,"illegal length (%d : %d,%d,%d,%d)\n",nb_bit,pucch_pdu->bit_len_harq,pucch_pdu->sr_flag,pucch_pdu->bit_len_csi_part1,pucch_pdu->bit_len_csi_part2); @@ -1366,15 +1411,17 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uint8_t corr_dB; int decoderState=2; if (nb_bit < 12) { // short blocklength case - __m256i *rp_re[Prx2]; - __m256i *rp2_re[Prx2]; - __m256i *rp_im[Prx2]; - __m256i *rp2_im[Prx2]; + __m256i *rp_re[Prx2][2]; + __m256i *rp2_re[Prx2][2]; + __m256i *rp_im[Prx2][2]; + __m256i *rp2_im[Prx2][2]; for (int aa=0;aanr_of_symbols;symb++) { + rp_re[aa][symb] = (__m256i*)r_re_ext[aa][symb]; + rp_im[aa][symb] = (__m256i*)r_im_ext[aa][symb]; + rp2_re[aa][symb] = (__m256i*)r_re_ext2[aa][symb]; + rp2_im[aa][symb] = (__m256i*)r_im_ext2[aa][symb]; + } } __m256i prod_re[Prx2],prod_im[Prx2]; int64_t corr=0; @@ -1393,76 +1440,91 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, #endif int64_t corr_tmp = 0; - for (int group=0;groupnr_of_symbols;symb++) { + for (int group=0;group (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa, - ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3], - ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7], - ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11], - ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]); - printf("prod_im[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",aa, - ((int16_t*)&prod_im[aa])[0],((int16_t*)&prod_im[aa])[1],((int16_t*)&prod_im[aa])[2],((int16_t*)&prod_im[aa])[3], - ((int16_t*)&prod_im[aa])[4],((int16_t*)&prod_im[aa])[5],((int16_t*)&prod_im[aa])[6],((int16_t*)&prod_im[aa])[7], - ((int16_t*)&prod_im[aa])[8],((int16_t*)&prod_im[aa])[9],((int16_t*)&prod_im[aa])[10],((int16_t*)&prod_im[aa])[11], - ((int16_t*)&prod_im[aa])[12],((int16_t*)&prod_im[aa])[13],((int16_t*)&prod_im[aa])[14],((int16_t*)&prod_im[aa])[15]); - + printf("prod_re[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",aa, + ((int16_t*)&prod_re[aa])[0],((int16_t*)&prod_re[aa])[1],((int16_t*)&prod_re[aa])[2],((int16_t*)&prod_re[aa])[3], + ((int16_t*)&prod_re[aa])[4],((int16_t*)&prod_re[aa])[5],((int16_t*)&prod_re[aa])[6],((int16_t*)&prod_re[aa])[7], + ((int16_t*)&prod_re[aa])[8],((int16_t*)&prod_re[aa])[9],((int16_t*)&prod_re[aa])[10],((int16_t*)&prod_re[aa])[11], + ((int16_t*)&prod_re[aa])[12],((int16_t*)&prod_re[aa])[13],((int16_t*)&prod_re[aa])[14],((int16_t*)&prod_re[aa])[15]); + printf("prod_im[%d] => (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\n",aa, + ((int16_t*)&prod_im[aa])[0],((int16_t*)&prod_im[aa])[1],((int16_t*)&prod_im[aa])[2],((int16_t*)&prod_im[aa])[3], + ((int16_t*)&prod_im[aa])[4],((int16_t*)&prod_im[aa])[5],((int16_t*)&prod_im[aa])[6],((int16_t*)&prod_im[aa])[7], + ((int16_t*)&prod_im[aa])[8],((int16_t*)&prod_im[aa])[9],((int16_t*)&prod_im[aa])[10],((int16_t*)&prod_im[aa])[11], + ((int16_t*)&prod_im[aa])[12],((int16_t*)&prod_im[aa])[13],((int16_t*)&prod_im[aa])[14],((int16_t*)&prod_im[aa])[15]); + #endif - prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1 - prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]); - prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3 - prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]); - prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7 - prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]); - prod_re[aa] = _mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15 - prod_im[aa] = _mm256_hadds_epi16(prod_im[aa],prod_im[aa]); - } - int64_t corr_re=0,corr_im=0; - - - for (int aa=0;aa corr) { - corr = corr_tmp; - cw_ML=cw; + corr = corr_tmp; + cw_ML=cw; } } // cw loop corr_dB = dB_fixed64((uint64_t)corr); +#ifdef DEBUG_NR_PUCCH_RX + printf("cw_ML %d, metric %d dB\n",cw_ML,corr_dB); +#endif LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB); decodedPayload[0]=(uint64_t)cw_ML; } else { // polar coded case t_nrPolar_params *currentPtr = nr_polar_params(2,nb_bit,pucch_pdu->prb_size,1,&gNB->uci_polarParams); - __m64 *rp_re[Prx2]; - __m64 *rp2_re[Prx2]; - __m64 *rp_im[Prx2]; - __m64 *rp2_im[Prx2]; - __m128i llrs[pucch_pdu->prb_size*2]; + __m64 *rp_re[Prx2][2]; + __m64 *rp2_re[Prx2][2]; + __m64 *rp_im[Prx2][2]; + __m64 *rp2_im[Prx2][2]; + __m128i llrs[pucch_pdu->prb_size*2*pucch_pdu->nr_of_symbols]; for (int aa=0;aanr_of_symbols;symb++) { + rp_re[aa][symb] = (__m64*)r_re_ext[aa][symb]; + rp_im[aa][symb] = (__m64*)r_im_ext[aa][symb]; + rp2_re[aa][symb] = (__m64*)r_re_ext2[aa][symb]; + rp2_im[aa][symb] = (__m64*)r_im_ext2[aa][symb]; + } } __m64 prod_re[Prx2],prod_im[Prx2]; @@ -1482,35 +1544,35 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, int32_t corr_re,corr_im,corr_tmp; __m128i corr16,llr_num,llr_den; uint64_t corr = 0; - - for (int half_prb=0;half_prb<(2*pucch_pdu->prb_size);half_prb++) { - llr_num=_mm_set1_epi16(0);llr_den=_mm_set1_epi16(0); - for (int cw=0;cw<256;cw++) { - corr_tmp=0; - for (int aa=0;aa>4],rp_im[aa][half_prb])),5); - prod_im[aa] = _mm_srai_pi16(_mm_subs_pi16(_mm_mullo_pi16(pucch2_polar_4bit[cw&15],rp2_im[aa][half_prb]), - _mm_mullo_pi16(pucch2_polar_4bit[cw>>4],rp2_re[aa][half_prb])),5); - prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1 - prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]); - prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1+2+3 - prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]); - - // this is for UL CQI measurement - if (cw==0) corr += ((int64_t)corr32_re[half_prb>>2][aa]*corr32_re[half_prb>>2][aa])+ - ((int64_t)corr32_im[half_prb>>2][aa]*corr32_im[half_prb>>2][aa]); - - - corr_re = ( corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_re[aa]))[0]); - corr_im = ( corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_im[aa]))[0]); - corr_tmp += corr_re*corr_re + corr_im*corr_im; - /* - LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d) (%d,%d)+(%d,%d) = (%d,%d) => %d\n", - half_prb,cw,cw&15,cw>>4,aa, - ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0], - ((int16_t*)&pucch2_polar_4bit[cw&15])[1],((int16_t*)&pucch2_polar_4bit[cw>>4])[1], - ((int16_t*)&pucch2_polar_4bit[cw&15])[2],((int16_t*)&pucch2_polar_4bit[cw>>4])[2], + for (int symb=0;symbnr_of_symbols;symb++) { + for (int half_prb=0;half_prb<(2*pucch_pdu->prb_size);half_prb++) { + llr_num=_mm_set1_epi16(0);llr_den=_mm_set1_epi16(0); + for (int cw=0;cw<256;cw++) { + corr_tmp=0; + for (int aa=0;aa>4],rp_im[aa][symb][half_prb])),5); + prod_im[aa] = _mm_srai_pi16(_mm_subs_pi16(_mm_mullo_pi16(pucch2_polar_4bit[cw&15],rp2_im[aa][symb][half_prb]), + _mm_mullo_pi16(pucch2_polar_4bit[cw>>4],rp2_re[aa][symb][half_prb])),5); + prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1 + prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]); + prod_re[aa] = _mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1+2+3 + prod_im[aa] = _mm_hadds_pi16(prod_im[aa],prod_im[aa]); + + // this is for UL CQI measurement + if (cw==0) corr += ((int64_t)corr32_re[symb][half_prb>>2][aa]*corr32_re[symb][half_prb>>2][aa])+ + ((int64_t)corr32_im[symb][half_prb>>2][aa]*corr32_im[symb][half_prb>>2][aa]); + + + corr_re = ( corr32_re[symb][half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_re[aa]))[0]); + corr_im = ( corr32_im[symb][half_prb>>2][aa]/(2*nc_group_size*4/2)+((int16_t*)(&prod_im[aa]))[0]); + corr_tmp += corr_re*corr_re + corr_im*corr_im; + /* + LOG_D(PHY,"pucch2 half_prb %d cw %d (%d,%d) aa %d: (%d,%d,%d,%d,%d,%d,%d,%d)x(%d,%d,%d,%d,%d,%d,%d,%d) (%d,%d)+(%d,%d) = (%d,%d) => %d\n", + half_prb,cw,cw&15,cw>>4,aa, + ((int16_t*)&pucch2_polar_4bit[cw&15])[0],((int16_t*)&pucch2_polar_4bit[cw>>4])[0], + ((int16_t*)&pucch2_polar_4bit[cw&15])[1],((int16_t*)&pucch2_polar_4bit[cw>>4])[1], + ((int16_t*)&pucch2_polar_4bit[cw&15])[2],((int16_t*)&pucch2_polar_4bit[cw>>4])[2], ((int16_t*)&pucch2_polar_4bit[cw&15])[3],((int16_t*)&pucch2_polar_4bit[cw>>4])[3], ((int16_t*)&rp_re[aa][half_prb])[0],((int16_t*)&rp_im[aa][half_prb])[0], ((int16_t*)&rp_re[aa][half_prb])[1],((int16_t*)&rp_im[aa][half_prb])[1], @@ -1523,13 +1585,13 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, corr_im, corr_tmp); */ - } - corr16 = _mm_set1_epi16((int16_t)(corr_tmp>>8)); + } + corr16 = _mm_set1_epi16((int16_t)(corr_tmp>>8)); /* LOG_D(PHY,"half_prb %d cw %d corr16 %d\n",half_prb,cw,corr_tmp>>8); */ - llr_num = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_num_lut[cw]),llr_num); - llr_den = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_den_lut[cw]),llr_den); + llr_num = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_num_lut[cw]),llr_num); + llr_den = _mm_max_epi16(_mm_mullo_epi16(corr16,pucch2_polar_llr_den_lut[cw]),llr_den); /* LOG_D(PHY,"lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n", ((int16_t*)&pucch2_polar_llr_num_lut[cw])[0], @@ -1560,20 +1622,21 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ((int16_t*)&llr_den)[6], ((int16_t*)&llr_den)[7]); */ - } + } // compute llrs - llrs[half_prb] = _mm_subs_epi16(llr_num,llr_den); - LOG_D(PHY,"llrs[%d] : (%d,%d,%d,%d,%d,%d,%d,%d)\n", - half_prb, - ((int16_t*)&llrs[half_prb])[0], - ((int16_t*)&llrs[half_prb])[1], - ((int16_t*)&llrs[half_prb])[2], - ((int16_t*)&llrs[half_prb])[3], - ((int16_t*)&llrs[half_prb])[4], - ((int16_t*)&llrs[half_prb])[5], - ((int16_t*)&llrs[half_prb])[6], - ((int16_t*)&llrs[half_prb])[7]); - } // half_prb + llrs[half_prb + (symb*2*pucch_pdu->prb_size)] = _mm_subs_epi16(llr_num,llr_den); + LOG_D(PHY,"llrs[%d] : (%d,%d,%d,%d,%d,%d,%d,%d)\n", + half_prb, + ((int16_t*)&llrs[half_prb])[0], + ((int16_t*)&llrs[half_prb])[1], + ((int16_t*)&llrs[half_prb])[2], + ((int16_t*)&llrs[half_prb])[3], + ((int16_t*)&llrs[half_prb])[4], + ((int16_t*)&llrs[half_prb])[5], + ((int16_t*)&llrs[half_prb])[6], + ((int16_t*)&llrs[half_prb])[7]); + } // half_prb + } // symb // run polar decoder on llrs decoderState = polar_decoder_int16((int16_t*)llrs, decodedPayload, 0, currentPtr); LOG_D(PHY,"UCI decoderState %d, payload[0] %llu\n",decoderState,(unsigned long long)decodedPayload[0]); @@ -1582,9 +1645,9 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, LOG_D(PHY,"metric %d dB\n",corr_dB); } - re_offset = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; + int re_off = (12*pucch_pdu->prb_start) + (12*pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; // estimate CQI for MAC (from antenna port 0 only) - int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB); + int SNRtimes10 = dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_off],12*pucch_pdu->prb_size)) - (10*gNB->measurements.n0_power_tot_dB); int cqi,bit_left; if (SNRtimes10 < -640) cqi=0; else if (SNRtimes10 > 635) cqi=255; @@ -1597,7 +1660,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->pucch_format=0; uci_pdu->ul_cqi=cqi; uci_pdu->timing_advance=0xffff; // currently not valid - uci_pdu->rssi=1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_offset],12*pucch_pdu->prb_size))); + uci_pdu->rssi=1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][(l2*frame_parms->ofdm_symbol_size)+re_off],12*pucch_pdu->prb_size))); if (pucch_pdu->bit_len_harq>0) { int harq_bytes=pucch_pdu->bit_len_harq>>3; if ((pucch_pdu->bit_len_harq&7) > 0) harq_bytes++; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index c7bf459f6f..316c37741f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -59,11 +59,11 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, int16_t amp, int nr_slot_tx, uint8_t m0, - uint8_t mcs, + uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB, - uint16_t secondHopPRB) { + uint16_t secondHopPRB) { #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch0] start function at slot(nr_slot_tx)=%d\n",nr_slot_tx); #endif diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 790508a4fe..bfb76e56d1 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -798,9 +798,8 @@ typedef struct PHY_VARS_gNB_s { /// PUSCH DMRS uint32_t ****nr_gold_pusch_dmrs; - // Mask of occupied RBs - uint32_t rb_mask_ul[9]; - int ulmask_symb; + // Mask of occupied RBs, per symbol and PRB + uint32_t rb_mask_ul[14][9]; /// CSI RS sequence uint32_t ***nr_gold_csi_rs; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index eb84c0b7c5..d3140a877e 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -474,22 +474,20 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { for (int symbol=0;symbol<14;symbol++) { if (gNB->gNB_config.tdd_table.max_tdd_periodicity_list[slot_rx].max_num_of_symbol_per_slot_list[symbol].slot_config.value==1){ nb_rb = 0; - for (int m=0;m<9;m++) gNB->rb_mask_ul[m] = 0; - gNB->ulmask_symb = -1; + for (int m=0;m<9;m++) gNB->rb_mask_ul[symbol][m] = 0; for (int i=0;ipucch[i]; if (pucch) { if ((pucch->active == 1) && - (pucch->frame == frame_rx) && + (pucch->frame == frame_rx) && (pucch->slot == slot_rx) ) { - gNB->ulmask_symb = symbol; nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu; if ((symbol>=pucch_pdu->start_symbol_index) && (symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){ for (rb=0; rbprb_size; rb++) { rb2 = rb+pucch_pdu->prb_start+pucch_pdu->bwp_start; - gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31)); } nb_rb+=pucch_pdu->prb_size; } @@ -512,12 +510,11 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { (ulsch_harq->handled == 0)){ uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; - gNB->ulmask_symb = symbol; if ((symbol>=symbol_start) && (symbolulsch_pdu.rb_size; rb++) { rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start; - gNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31)); } nb_rb+=ulsch_harq->ulsch_pdu.rb_size; } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 11f5d439ea..24a104abd2 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -773,9 +773,9 @@ int main(int argc, char **argv) AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, 0, 0, NULL); + rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, NULL, 0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0,0, n_tx, n_tx, scc, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); // reset preprocessor to the one of DLSIM after it has been set during // rrc_mac_config_req_gNB gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; @@ -1248,7 +1248,7 @@ int main(int argc, char **argv) (float) n_errors / (float) n_trials); printf("*****************************************\n"); printf("\n"); - dump_pdsch_stats(gNB); + dump_pdsch_stats(stdout,gNB); printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS); printf("\n"); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 9c5fa5b8c9..f07d99ea9e 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -67,7 +67,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} int main(int argc, char **argv) { char c; - int i,aa=0;//,l; + int i;//,l; double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0; double cfo=0; uint8_t snr1set=0; @@ -101,9 +101,8 @@ int main(int argc, char **argv) uint16_t startingPRB=0,startingPRB_intraSlotHopping=0; //PRB number not sure see 9.2.1, 38.213 for more info. Should be actually present in the resource set provided uint16_t nrofPRB=2; uint8_t timeDomainOCC=0; - SCM_t channel_model=AWGN;//Rayleigh1_anticorr; - - double DS_TDL = .03; + SCM_t channel_model=TDL_C; + double DS_TDL = .3; int N_RB_DL=273,mu=1; float target_error_rate=0.001; @@ -113,7 +112,7 @@ int main(int argc, char **argv) //unsigned char frame_type = 0; int loglvl=OAILOG_WARNING; int sr_flag = 0; - + int pucch_DTX_thres = 155; cpuf = get_cpu_freq_GHz(); if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { @@ -123,7 +122,7 @@ int main(int argc, char **argv) randominit(0); logInit(); - while ((c = getopt (argc, argv, "f:hA:f:g:i:I:P:B:b:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:c")) != -1) { + while ((c = getopt (argc, argv, "f:hA:f:g:i:I:P:B:b:t:T:m:n:r:o:s:S:x:y:z:N:F:GR:IL:q:c")) != -1) { switch (c) { case 'f': //write_output_file=1; @@ -207,11 +206,11 @@ int main(int argc, char **argv) printf("Setting SNR1 to %f\n",snr1); break; - /* + case 't': - Td= atof(optarg); + pucch_DTX_thres= atoi(optarg); break; - + /* case 'p': extended_prefix_flag=1; break; @@ -251,7 +250,7 @@ int main(int argc, char **argv) case 'z': n_rx=atoi(optarg); - if ((n_rx==0) || (n_rx>2)) { + if ((n_rx==0) || (n_rx>8)) { printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -350,25 +349,27 @@ int main(int argc, char **argv) if (snr1set==0) snr1 = snr0+10; - printf("Initializing gNodeB for mu %d, N_RB_DL %d\n",mu,N_RB_DL); + printf("Initializing gNodeB for mu %d, N_RB_DL %d, n_rx %d\n",mu,N_RB_DL,n_rx); if((format!=0) && (format!=1) && (format!=2)){ printf("PUCCH format %d not supported\n",format); exit(0); } - AssertFatal(((format < 2)&&(nr_bit<3)&&(actual_payload<4)) || + AssertFatal(((format < 2)&&(nr_bit<3)&&(actual_payload<5)) || ((format == 2)&&(nr_bit>2)&&(nr_bit<65)),"illegal combination format %d, nr_bit %d\n", format,nr_bit); + int do_DTX=0; + if ((format < 2) && (actual_payload == 4)) do_DTX=1; actual_payload &= ((1<pucch0_thres = pucch_DTX_thres; frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) frame_parms->nb_antennas_tx = n_tx; frame_parms->nb_antennas_rx = n_rx; @@ -380,7 +381,7 @@ int main(int argc, char **argv) cfg->carrier_config.num_tx_ant.value = n_tx; cfg->carrier_config.num_rx_ant.value = n_rx; nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); - phy_init_nr_gNB(gNB,0,0); + phy_init_nr_gNB(gNB,0,1); double fs,bw,scs,eps; @@ -430,37 +431,34 @@ int main(int argc, char **argv) frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; - s_re = malloc(2*sizeof(double*)); - s_im = malloc(2*sizeof(double*)); - r_re = malloc(2*sizeof(double*)); - r_im = malloc(2*sizeof(double*)); - txdataF = malloc(2*sizeof(int*)); - rxdataF = malloc(2*sizeof(int*)); + s_re = malloc(n_tx*sizeof(double*)); + s_im = malloc(n_tx*sizeof(double*)); + r_re = malloc(n_rx*sizeof(double*)); + r_im = malloc(n_rx*sizeof(double*)); + txdataF = malloc(n_tx*sizeof(int*)); + rxdataF = malloc(n_rx*sizeof(int*)); gNB->common_vars.rxdataF=rxdataF; memcpy((void*)&gNB->frame_parms,(void*)frame_parms,sizeof(frame_parms)); - for (i=0; i<2; i++) { - - s_re[i] = malloc(frame_length_complex_samples*sizeof(double)); - bzero(s_re[i],frame_length_complex_samples*sizeof(double)); - s_im[i] = malloc(frame_length_complex_samples*sizeof(double)); - bzero(s_im[i],frame_length_complex_samples*sizeof(double)); - - r_re[i] = malloc(frame_length_complex_samples*sizeof(double)); - bzero(r_re[i],frame_length_complex_samples*sizeof(double)); - r_im[i] = malloc(frame_length_complex_samples*sizeof(double)); - bzero(r_im[i],frame_length_complex_samples*sizeof(double)); - - printf("Allocating %d samples for txdataF/rxdataF\n",14*frame_parms->ofdm_symbol_size); - txdataF[i] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int)); - bzero(txdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int)); - rxdataF[i] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int)); - bzero(rxdataF[i],14*frame_parms->ofdm_symbol_size*sizeof(int)); + for (int aatx=0; aatxsymbols_per_slot*frame_parms->ofdm_symbol_size); + txdataF[aatx] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int)); + bzero(txdataF[aatx],14*frame_parms->ofdm_symbol_size*sizeof(int)); } + for (int aarx=0; aarxsymbols_per_slot*frame_parms->ofdm_symbol_size); + rxdataF[aarx] = memalign(32,14*frame_parms->ofdm_symbol_size*sizeof(int)); + bzero(rxdataF[aarx],14*frame_parms->ofdm_symbol_size*sizeof(int)); + } //configure UE - UE = malloc(sizeof(PHY_VARS_NR_UE)); + UE = calloc(1,sizeof(PHY_VARS_NR_UE)); memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); + UE->frame_parms.nb_antennas_rx=2; UE->pucch_config_common_nr->hoppingId = Nid_cell; //phy_init_nr_top(UE); //called from init_nr_ue_signal @@ -496,50 +494,98 @@ int main(int argc, char **argv) } else if (format == 2 && nr_bit > 11) gNB->uci_polarParams = nr_polar_params(2, nr_bit, nrofPRB, 1, NULL); - for(SNR=snr0;SNR<=snr1;SNR=SNR+1){ + for(SNR=snr0;SNR<=snr1;SNR=SNR+0.5){ ack_nack_errors=0; sr_errors=0; n_errors = 0; for (trial=0; trialofdm_symbol_size*sizeof(int)); - if(format==0){ - nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB, 0); + for (int aatx=0;aatx<1;aatx++) + bzero(txdataF[aatx],frame_parms->ofdm_symbol_size*sizeof(int)); + if(format==0 && do_DTX==0){ + nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB, + nrofSymbols>1?(N_RB_DL-1):0); } - else if (format == 1){ + else if (format == 1 && do_DTX==0){ nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); } - else { + else if (do_DTX == 0){ nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit); } - int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size); - // printf("txlev %d (%d dB), offset %d\n",txlev,dB_fixed(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size); - - // note : this scaling - int nb_re = (format == 0 || format == 1)? 12 : 12*nrofPRB; - sigma2_dB = 10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/nb_re)-SNR; - sigma2 = pow(10,sigma2_dB/10); - - for(i=startingSymbolIndex*frame_parms->ofdm_symbol_size; i<(startingSymbolIndex+1)*frame_parms->ofdm_symbol_size; i++) { - ((int16_t*)rxdataF[aa])[i<<1] = (int16_t)(100.0*((double)(((int16_t *)txdataF[aa])[(i<<1)]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))/sqrt((double)txlev)); - ((int16_t*)rxdataF[aa])[1+(i<<1)]=(int16_t)(100.0*((double)(((int16_t *)txdataF[aa])[(i<<1)+1])+ sqrt(sigma2/2)*gaussdouble(0.0,1.0))/sqrt((double)txlev)); + // SNR Computation + // standard says: SNR = S / N, where S is the total signal energy, N is the noise energy in the transmission bandwidth (i.e. N_RB_DL resource blocks) + // txlev = S. Note: signal_energy_nodc normalizes by the length of the vector, so multiply output by ofdm_symbol_size + double txlev = do_DTX == 0 ? signal_energy_nodc(&txdataF[0][startingSymbolIndex*frame_parms->ofdm_symbol_size], + frame_parms->ofdm_symbol_size) * (double)frame_parms->ofdm_symbol_size + : 1e5; + int N_RB = (format == 0) ? 1 : nrofPRB; + // sigma2 is variance per dimension, so N/(N_RB*12) + // so, sigma2 = N/(N_RB_DL*12) => (S/SNR)/(N_RB*12) + sigma2_dB = 10*log10(txlev/(12.0*N_RB))-SNR; + sigma2 = pow(10.0,sigma2_dB/10.0); + if (n_trials==1) printf("txlev %f (%f dB), offset %d, sigma2 %f ( %f dB)\n",txlev,10*log10(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size,sigma2,sigma2_dB); + random_channel(UE2gNB,0); + freq_channel(UE2gNB,N_RB_DL,1+(N_RB_DL*12),scs/1000); + int i0; + double txr,txi,rxr,rxi,nr,ni; + for (int symb=0; symbframe_parms.symbols_per_slot;symb++) { + if (symb= startingSymbolIndex+nrofSymbols) { + i0 = symb*gNB->frame_parms.ofdm_symbol_size; + for (int re=0;reframe_parms.first_carrier_offset + re)%gNB->frame_parms.ofdm_symbol_size); + for (int aarx=0;aarxofdm_symbol_size], - frame_parms->ofdm_symbol_size); + for (int symb=0; symbframe_parms.ofdm_symbol_size; + for (int re=0;reframe_parms.first_carrier_offset + re)%gNB->frame_parms.ofdm_symbol_size); + for (int aarx=0;aarxchF[aarx][re].x - txi*UE2gNB->chF[aarx][re].y; + rxi = txr*UE2gNB->chF[aarx][re].y + txi*UE2gNB->chF[aarx][re].x; + nr = sqrt(sigma2/2)*gaussdouble(0.0,1.0); + ni = sqrt(sigma2/2)*gaussdouble(0.0,1.0); + ((int16_t*)rxdataF[aarx])[i<<1] = (int16_t)(100.0*(rxr + nr)/sqrt((double)txlev)); + ((int16_t*)rxdataF[aarx])[1+(i<<1)]= (int16_t)(100.0*(rxi + ni)/sqrt((double)txlev)); + + if (n_trials==1 && abs(txr) > 0) printf("symb %d, re %d , aarx %d : txr %f, txi %f, chr %f, chi %f, nr %f, ni %f, rxr %f, rxi %f => %d,%d\n", + symb, re, aarx, txr,txi, + UE2gNB->chF[aarx][re].x,UE2gNB->chF[aarx][re].y, + nr,ni, rxr,rxi, + ((int16_t*)rxdataF[aarx])[i<<1],((int16_t*)rxdataF[aarx])[1+(i<<1)]); + + } + } + } + int rxlev=0; + for (int aarx=0;aarxofdm_symbol_size], + frame_parms->ofdm_symbol_size); // noise measurement - gNB->ulmask_symb = startingSymbolIndex; - for (int rb=0; rbrb_mask_ul[rb2>>5] |= (1<<(rb2&31)); + + for (int s=0;ssymbols_per_slot;s++){ + if (s>=startingSymbolIndex && s<(startingSymbolIndex+nrofSymbols)) + for (int rb=0; rbrb_mask_ul[s][rb2>>5] |= (1<<(rb2&31)); + } } - gNB_I0_measurements(gNB, startingSymbolIndex, nrofSymbols); + gNB_I0_measurements(gNB, 0, gNB->frame_parms.symbols_per_slot); if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12)); if(format==0){ nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; nfapi_nr_pucch_pdu_t pucch_pdu; + gNB->uci_stats[0].rnti = 0x1234; + pucch_pdu.rnti = 0x1234; pucch_pdu.subcarrier_spacing = 1; pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; @@ -553,18 +599,27 @@ int main(int argc, char **argv) pucch_pdu.start_symbol_index = startingSymbolIndex; pucch_pdu.prb_start = startingPRB; pucch_pdu.bwp_start = 0; - pucch_pdu.freq_hop_flag = 0; + pucch_pdu.bwp_size = N_RB_DL; + if (nrofSymbols>1) { + pucch_pdu.freq_hop_flag = 1; + pucch_pdu.second_hop_prb = N_RB_DL-1; + } + else pucch_pdu.freq_hop_flag = 0; + nr_decode_pucch0(gNB, nr_frame_tx, nr_slot_tx,&uci_pdu,&pucch_pdu); if(sr_flag==1){ if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1) sr_errors+=1; } if(nr_bit>0){ - if(nr_bit==1) + if(nr_bit==1 && do_DTX == 0) ack_nack_errors+=(actual_payload^uci_pdu.harq->harq_list[0].harq_value); - else + else if (do_DTX == 0) ack_nack_errors+=(((actual_payload&1)^uci_pdu.harq->harq_list[0].harq_value)+((actual_payload>>1)^uci_pdu.harq->harq_list[1].harq_value)); - free(uci_pdu.harq->harq_list); + else if ((uci_pdu.harq->harq_confidence_level == 0 && uci_pdu.harq->harq_list[0].harq_value == 1) || + (uci_pdu.harq->harq_confidence_level == 0 && nr_bit == 2 && uci_pdu.harq->harq_list[1].harq_value==1)) + ack_nack_errors++; + free(uci_pdu.harq->harq_list); } } else if (format==1) { @@ -596,6 +651,11 @@ int main(int argc, char **argv) pucch_pdu.prb_start = startingPRB; pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id; pucch_pdu.data_scrambling_id = data_scrambling_id; + if (nrofSymbols>1) { + pucch_pdu.freq_hop_flag = 1; + pucch_pdu.second_hop_prb = N_RB_DL-1; + } + else pucch_pdu.freq_hop_flag = 0; nr_decode_pucch2(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; @@ -620,13 +680,15 @@ int main(int argc, char **argv) } } - for (i=0; i<2; i++) { - free(s_re[i]); - free(s_im[i]); - free(r_re[i]); - free(r_im[i]); - free(txdataF[i]); - free(rxdataF[i]); + for (int aatx=0; aatx>1); f<=(n_samples>>1); f++) { freq=delta_f*(double)f*1e-6;// due to the fact that delays is in mus @@ -67,14 +67,14 @@ int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { cos_lut[f+(n_samples>>1)][l] = cos(2*M_PI*freq*delay); sin_lut[f+(n_samples>>1)][l] = sin(2*M_PI*freq*delay); - //printf("values cos:%d, sin:%d\n", cos_lut[f][l], sin_lut[f][l]); + // printf("values cos:%f, sin:%f\n", cos_lut[f+(n_samples>>1)][l], sin_lut[f+(n_samples>>1)][l]); } } return(0); } -int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { +int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples,int scs) { int16_t f,f2,d; uint8_t aarx,aatx,l; double *clut,*slut; @@ -95,14 +95,14 @@ int freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples) { // if called with n_samples<12*nb_rb+1, we decimate the lut n_samples_max=12*nb_rb+1; - if (init_freq_channel(desc,nb_rb,n_samples_max)==0) + if (init_freq_channel(desc,nb_rb,n_samples_max,scs)==0) freq_channel_init=1; else return(-1); } d=(n_samples_max-1)/(n_samples-1); - //printf("no_samples=%d, n_samples_max=%d, d=%d\n",n_samples,n_samples_max,d); + // printf("no_samples=%d, n_samples_max=%d, d=%d,nb_taps %d\n",n_samples,n_samples_max,d,desc->nb_taps); start_meas(&desc->interp_freq); for (f=-n_samples_max/2,f2=-n_samples/2; fnb_rx; aarx++) { for (aatx=0; aatxnb_tx; aatx++) { + AssertFatal(n_samples/2+f2 < (2+(275*12)),"reading past chF %d (n_samples %d, f2 %d)\n",n_samples/2+f2,n_samples,f2); desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].x=0.0; desc->chF[aarx+(aatx*desc->nb_rx)][n_samples/2+f2].y=0.0; diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index d2339954bd..1f2ce99684 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -543,12 +543,12 @@ void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS chan_desc->ch[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); for (int i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); + chan_desc->chF[i] = (struct complex *) malloc((2+(275*12)) * sizeof(struct complex)); for (int i = 0; inb_taps; i++) chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); - chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); + chan_desc->R_sqrt = (struct complex **) malloc(tdl_pathsby3*sizeof(struct complex **)); if (nb_tx==2 && nb_rx==2) { for (int i = 0; i<(tdl_pathsby3); i++) @@ -1729,10 +1729,9 @@ void set_channeldesc_name(channel_desc_t *cdesc,char *modelname) { int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { double s; int i,k,l,aarx,aatx; - struct complex anew[NB_ANTENNAS_TX*NB_ANTENNAS_RX],acorr[NB_ANTENNAS_TX*NB_ANTENNAS_RX]; + struct complex anew[desc->nb_tx*desc->nb_rx],acorr[desc->nb_tx*desc->nb_rx]; struct complex phase, alpha, beta; - AssertFatal(desc->nb_tx<=NB_ANTENNAS_TX && desc->nb_rx <= NB_ANTENNAS_RX, - "random_channel.c: Error: temporary buffer for channel not big enough (%d,%d)\n",desc->nb_tx,desc->nb_rx); + start_meas(&desc->random_channel); for (i=0; i<(int)desc->nb_taps; i++) { diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 78e260b73f..f8e9221040 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -477,8 +477,8 @@ int gauss(unsigned int *gauss_LUT,unsigned char Nbits); double gaussdouble(double,double); void randominit(unsigned int seed_init); double uniformrandom(void); -int freq_channel(channel_desc_t *desc,uint16_t nb_rb, int16_t n_samples); -int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples); +int freq_channel(channel_desc_t *desc,uint16_t nb_rb, int16_t n_samples,int scs); +int init_freq_channel(channel_desc_t *desc,uint16_t nb_rb,int16_t n_samples,int scs); uint8_t multipath_channel_nosigconv(channel_desc_t *desc); void multipath_tv_channel(channel_desc_t *desc, double **tx_sig_re,