diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c index 84825747ec..36e71b2a32 100644 --- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c +++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c @@ -8,144 +8,152 @@ configmodule_interface_t *uniqCfg = NULL; int main(int argc, char *argv[]) { - time_stats_t timeEncoder,timeDecoder; - opp_enabled=1; - reset_meas(&timeEncoder); - reset_meas(&timeDecoder); - randominit(0); + time_stats_t timeEncoder, timeDecoder; + opp_enabled = 1; + reset_meas(&timeEncoder); + reset_meas(&timeDecoder); + randominit(0); - int arguments, iterations = 1000, messageLength = 11; - //int matlabDebug = 0; - uint32_t testInput, encoderOutput, codingDifference, nBitError=0, blockErrorState = 0, blockErrorCumulative=0, bitErrorCumulative=0; - uint16_t estimatedOutput; - double SNRstart = -20.0, SNRstop = 5.0, SNRinc= 0.5; //dB - double SNR, SNR_lin, sigma; - double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS]; - //int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS]; - int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS]; - unsigned char qbits=8; + int arguments, iterations = 1000, messageLength = 11; + // int matlabDebug = 0; + uint32_t testInput, encoderOutput, codingDifference, nBitError = 0, blockErrorState = 0, blockErrorCumulative = 0, + bitErrorCumulative = 0; + uint16_t estimatedOutput; + double SNRstart = -20.0, SNRstop = 5.0, SNRinc = 0.5; // dB + double SNR, SNR_lin, sigma; + double modulatedInput[NR_SMALL_BLOCK_CODED_BITS], channelOutput[NR_SMALL_BLOCK_CODED_BITS]; + // int16_t channelOutput_int16[NR_SMALL_BLOCK_CODED_BITS]; + int8_t channelOutput_int8[NR_SMALL_BLOCK_CODED_BITS]; + unsigned char qbits = 8; - while ((arguments = getopt (argc, argv, "s:d:f:l:i:mhg")) != -1) - switch (arguments) - { - case 's': - SNRstart = atof(optarg); - break; + while ((arguments = getopt(argc, argv, "s:d:f:l:i:mhg")) != -1) + switch (arguments) { + case 's': + SNRstart = atof(optarg); + break; - case 'd': - SNRinc = atof(optarg); - break; + case 'd': + SNRinc = atof(optarg); + break; - case 'f': - SNRstop = atof(optarg); - break; + case 'f': + SNRstop = atof(optarg); + break; - case 'l': - messageLength = atoi(optarg); - break; + case 'l': + messageLength = atoi(optarg); + break; - case 'i': - iterations = atoi(optarg); - break; + case 'i': + iterations = atoi(optarg); + break; - /*case 'm': - matlabDebug = 1; - //#define DEBUG_POLAR_MATLAB - break;*/ + /*case 'm': + matlabDebug = 1; + //#define DEBUG_POLAR_MATLAB + break;*/ - case 'g': - iterations = 1; - SNRstart = -6.0; - SNRstop = -6.0; - messageLength = 11; - break; + case 'g': + iterations = 1; + SNRstart = -6.0; + SNRstop = -6.0; + messageLength = 11; + break; - case 'h': - //printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations -m Matlab Debug\n"); - printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n"); - exit(-1); + case 'h': + // printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations -m Matlab Debug\n"); + printf("./smallblocktest -s SNRstart -d SNRinc -f SNRstop -l messageLength -i iterations\n"); + exit(-1); - default: - perror("[smallblocktest.c] Problem at argument parsing with getopt"); - exit(-1); - } + default: + perror("[smallblocktest.c] Problem at argument parsing with getopt"); + exit(-1); + } + uint16_t mask = 0x07ff >> (11 - messageLength); + for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { + printf("SNR %f\n", SNR); + SNR_lin = pow(10, SNR / 10.0); + sigma = 1.0 / sqrt(SNR_lin); - uint16_t mask = 0x07ff >> (11-messageLength); - for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { - printf("SNR %f\n",SNR); - SNR_lin = pow(10, SNR/10.0); - sigma = 1.0/sqrt(SNR_lin); + for (int itr = 1; itr <= iterations; itr++) { + // Generate random test input of length "messageLength" + testInput = 0; + for (int i = 1; i < messageLength; i++) { + testInput |= (((uint32_t)(rand() % 2)) & 1); + testInput <<= 1; + } + testInput |= (((uint32_t)(rand() % 2)) & 1); + // Encoding + start_meas(&timeEncoder); + encoderOutput = encodeSmallBlock(testInput, messageLength); + stop_meas(&timeEncoder); - for (int itr = 1; itr <= iterations; itr++) { + for (int i = 0; i < NR_SMALL_BLOCK_CODED_BITS; i++) { + // BPSK modulation + if ((encoderOutput >> i) & 1) { + modulatedInput[i] = -1; + } else { + modulatedInput[i] = 1; + } - //Generate random test input of length "messageLength" - testInput = 0; - for (int i = 1; i < messageLength; i++) { - testInput |= ( ((uint32_t) (rand()%2)) &1); - testInput<<=1; - } - testInput |= ( ((uint32_t) (rand()%2)) &1); - //Encoding - start_meas(&timeEncoder); - encoderOutput = encodeSmallBlock((uint16_t*)&testInput, (uint8_t)messageLength); - stop_meas(&timeEncoder); + // AWGN + channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0, 1.0) * (1 / sqrt(SNR_lin))); - for (int i=0; i>i) & 1 ) { - modulatedInput[i]=-1; - } else { - modulatedInput[i]=1; - } + // Quantization + channelOutput_int8[i] = quantize(sigma / 16.0, channelOutput[i], qbits); + } - //AWGN - channelOutput[i] = modulatedInput[i] + ( gaussdouble(0.0,1.0) * ( 1/sqrt(SNR_lin) ) ); - - //Quantization - channelOutput_int8[i] = quantize(sigma/16.0, channelOutput[i], qbits); - } - - //Decoding - start_meas(&timeDecoder); - estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength); - stop_meas(&timeDecoder); + // Decoding + start_meas(&timeDecoder); + estimatedOutput = decodeSmallBlock(channelOutput_int8, (uint8_t)messageLength); + stop_meas(&timeDecoder); #ifdef DEBUG_SMALLBLOCKTEST - printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput); - for (int i=0;i<32;i++) - printf("[smallblocktest] Input[%d] = %d, Output[%d] = %d, codingDifference[%d]=%d, Mask[%d] = %d\n", i, (testInput>>i)&1, i, (estimatedOutput>>i)&1, i, (codingDifference>>i)&1, i, (mask>>i)&1); + printf("[smallblocktest] Input = 0x%x, Output = 0x%x, DecoderOutput = 0x%x\n", testInput, encoderOutput, estimatedOutput); + for (int i = 0; i < 32; i++) + printf("[smallblocktest] Input[%d] = %d, Output[%d] = %d, codingDifference[%d]=%d, Mask[%d] = %d\n", + i, + (testInput >> i) & 1, + i, + (estimatedOutput >> i) & 1, + i, + (codingDifference >> i) & 1, + i, + (mask >> i) & 1); #endif - //Error Calculation - estimatedOutput &= mask; - codingDifference = ((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm. + // Error Calculation + estimatedOutput &= mask; + codingDifference = + ((uint32_t)estimatedOutput) ^ testInput; // Count the # of 1's in codingDifference by Brian Kernighan’s algorithm. - for (nBitError = 0; codingDifference; nBitError++) - codingDifference &= codingDifference - 1; + for (nBitError = 0; codingDifference; nBitError++) + codingDifference &= codingDifference - 1; - blockErrorState = (nBitError > 0) ? 1 : 0; + blockErrorState = (nBitError > 0) ? 1 : 0; - blockErrorCumulative+=blockErrorState; - bitErrorCumulative+=nBitError; + blockErrorCumulative += blockErrorState; + bitErrorCumulative += nBitError; - nBitError = 0; blockErrorState = 0; - } + nBitError = 0; + blockErrorState = 0; + } - //Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively. - printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n", - SNR, - ((double)bitErrorCumulative / (iterations*messageLength)), - ((double)blockErrorCumulative/iterations), - ((double)timeEncoder.diff/timeEncoder.trials)/(get_cpu_freq_GHz()), - ((double)timeDecoder.diff/timeDecoder.trials)/(get_cpu_freq_GHz()*1000.0)); + // Error statistics for the SNR; iteration times are in nanoseconds and microseconds, respectively. + printf("[smallblocktest] SNR=%+7.3f, BER=%9.6f, BLER=%9.6f, t_Encoder=%9.3fns, t_Decoder=%7.3fus\n", + SNR, + ((double)bitErrorCumulative / (iterations * messageLength)), + ((double)blockErrorCumulative / iterations), + ((double)timeEncoder.diff / timeEncoder.trials) / (get_cpu_freq_GHz()), + ((double)timeDecoder.diff / timeDecoder.trials) / (get_cpu_freq_GHz() * 1000.0)); - blockErrorCumulative=0; - bitErrorCumulative=0; - } + blockErrorCumulative = 0; + bitErrorCumulative = 0; + } - print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL); - print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL); + print_meas(&timeEncoder, "smallblock_encoder", NULL, NULL); + print_meas(&timeDecoder, "smallblock_decoder", NULL, NULL); - return (0); + return (0); } diff --git a/openair1/PHY/CODING/nrSmallBlock/encodeSmallBlock.c b/openair1/PHY/CODING/nrSmallBlock/encodeSmallBlock.c index 8358bd270b..3078243c8f 100644 --- a/openair1/PHY/CODING/nrSmallBlock/encodeSmallBlock.c +++ b/openair1/PHY/CODING/nrSmallBlock/encodeSmallBlock.c @@ -34,11 +34,12 @@ //input = [0 ... 0 c_K-1 ... c_2 c_1 c_0] //output = [d_31 d_30 ... d_2 d_1 d_0] -uint32_t encodeSmallBlock(uint16_t *in, uint8_t len){ - uint32_t out = 0; - for (uint16_t i=0; i 0) - out^=nrSmallBlockBasis[i]; +uint32_t encodeSmallBlock(int in, int len) +{ + uint32_t out = 0; + for (int i = 0; i < len; i++) + if ((in & (1 << i)) > 0) + out ^= nrSmallBlockBasis[i]; - return out; + return out; } diff --git a/openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h b/openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h index 50559aa0d2..7c8554f807 100644 --- a/openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h +++ b/openair1/PHY/CODING/nrSmallBlock/nr_small_block_defs.h @@ -43,7 +43,7 @@ #define L1d_CLS 64 -uint32_t encodeSmallBlock(uint16_t *in, uint8_t len); +uint32_t encodeSmallBlock(int in, int len); uint16_t decodeSmallBlock(int8_t *in, uint8_t len); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index 6890e52553..79b3daa212 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -42,7 +42,7 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, uint32_t n_id, - uint8_t n_hop, + int n_hop, int nr_slot_tx, uint8_t *u, uint8_t *v); diff --git a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c index cccdaed8ef..1c3d0f7008 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c @@ -32,12 +32,13 @@ #include "nr_dci.h" -void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, - uint32_t n_id, - uint8_t n_hop, - int nr_slot_tx, - uint8_t *u, - uint8_t *v) { +void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, + uint32_t n_id, + int n_hop, + int nr_slot_tx, + uint8_t *u, + uint8_t *v) +{ /* * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * The following variables are set by higher layers: diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 84232ea140..e878a3c0bb 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -158,8 +158,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; AssertFatal(pucch_pdu->bit_len_harq > 0 || pucch_pdu->sr_flag > 0, - "Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n", - pucch_pdu->bit_len_harq,pucch_pdu->sr_flag); + "Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n", + pucch_pdu->bit_len_harq, + pucch_pdu->sr_flag); NR_gNB_PHY_STATS_t *phy_stats = get_phy_stats(gNB, pucch_pdu->rnti); AssertFatal(phy_stats != NULL, "phy_stats shouldn't be NULL\n"); @@ -188,43 +189,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, int cs_ind = get_pucch0_cs_lut_index(gNB,pucch_pdu); /* * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation - * - */ - /* * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 - */ - // alpha is cyclic shift - //double alpha; - // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission - //uint8_t lnormal; - // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] - //uint8_t lprime; - - /* * in TS 38.213 Subclause 9.2.1 it is said that: * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift */ - - /* - * Implementing TS 38.211 Subclause 6.3.2.3.1, the sequence x(n) shall be generated according to: - * x(l*12+n) = r_u_v_alpha_delta(n) - */ - // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 - uint8_t u[2]={0},v[2]={0}; - - // x_n contains the sequence r_u_v_alpha_delta(n) - - int n,i; int prb_offset[2] = {pucch_pdu->bwp_start+pucch_pdu->prb_start, pucch_pdu->bwp_start+pucch_pdu->prb_start}; pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag << 1); - nr_group_sequence_hopping(pucch_GroupHopping, - pucch_pdu->hopping_id, - 0, - slot, - &u[0], - &v[0]); // calculating u and v value first hop + // the value of u,v (delta always 0 for PUCCH) has to be calculated according + // to TS 38.211 Subclause 6.3.2.2.1 + uint8_t u[2] = {0}, v[2] = {0}; + nr_group_sequence_hopping(pucch_GroupHopping, pucch_pdu->hopping_id, 0, slot, u, + v); // calculating u and v value first hop LOG_D(PHY,"pucch0: u %d, v %d\n",u[0],v[0]); if (pucch_pdu->freq_hop_flag == 1) { @@ -253,10 +230,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uint8_t index=0; int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1 - int32_t rp[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][nb_re_pucch]; - memset(rp, 0, sizeof(rp)); - int32_t *tmp_rp = NULL; - int signal_energy = 0; + int signal_energy = 0, signal_energy_ant0 = 0; for (int l=0; lnr_of_symbols; l++) { uint8_t l2 = l + pucch_pdu->start_symbol_index; @@ -266,39 +240,38 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, re_offset[l]-=frame_parms->ofdm_symbol_size; for (int aa=0;aanb_antennas_rx;aa++) { - tmp_rp = (int32_t *)&rxdataF[aa][soffset + l2*frame_parms->ofdm_symbol_size]; + c16_t rp[nb_re_pucch]; + memset(rp, 0, sizeof(rp)); + c16_t *tmp_rp = &rxdataF[aa][soffset + l2 * frame_parms->ofdm_symbol_size]; if(re_offset[l] + nb_re_pucch > frame_parms->ofdm_symbol_size) { int neg_length = frame_parms->ofdm_symbol_size-re_offset[l]; int pos_length = nb_re_pucch-neg_length; - memcpy((void*)rp[aa][l],(void*)&tmp_rp[re_offset[l]],neg_length*sizeof(int32_t)); - memcpy((void*)&rp[aa][l][neg_length],(void*)tmp_rp,pos_length*sizeof(int32_t)); + memcpy(rp, &tmp_rp[re_offset[l]], neg_length * sizeof(*tmp_rp)); + memcpy(&rp[neg_length], tmp_rp, pos_length * sizeof(*tmp_rp)); } else - memcpy((void*)rp[aa][l],(void*)&tmp_rp[re_offset[l]],nb_re_pucch*sizeof(int32_t)); + memcpy(rp, &tmp_rp[re_offset[l]], nb_re_pucch * sizeof(*tmp_rp)); - c16_t *r = (c16_t*)&rp[aa][l]; - - for (n=0;nnr_of_symbols * frame_parms->nb_antennas_rx); int pucch_power_dBtimes10 = 10 * dB_fixed(signal_energy); //int32_t no_corr = 0; int seq_index = 0; - int64_t temp; - for(i=0;inb_antennas_rx][2]; for (int aa=0;aanb_antennas_rx;aa++) { for (int l=0;lnr_of_symbols;l++) { @@ -309,7 +282,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]); #endif corr[aa][l]=(c64_t){0}; - for (n = 0; n < 12; n++) { + for (int n = 0; n < 12; n++) { corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n]; corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n]; } @@ -321,30 +294,32 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, mcs[i],seq_index,corr[0][0].r,corr[0][0].i, 10*log10((double)squaredMod(corr[0][0]))); if (pucch_pdu->nr_of_symbols==2) - LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n", - mcs[i],seq_index,corr[0][1].r,corr[0][1].i, - 10*log10((double)squaredMod(corr[0][1]))); + LOG_D(PHY, + "PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n", + mcs[i], + seq_index, + corr[0][1].r, + corr[0][1].i, + 10 * log10((double)squaredMod(corr[0][1]))); + int64_t temp = 0; if (pucch_pdu->freq_hop_flag == 0) { - if (pucch_pdu->nr_of_symbols==1) {// non-coherent correlation - temp=0; - for (int aa=0;aanb_antennas_rx;aa++) - temp+=squaredMod(corr[aa][0]); - } else { - temp=0; - for (int aa=0;aanb_antennas_rx;aa++) { - c64_t corr2; - csum(corr2, corr[aa][0], corr[aa][1]); - // coherent combining of 2 symbols and then complex modulus for single-frequency case - temp+=corr2.r*corr2.r + corr2.i*corr2.i; - } + if (pucch_pdu->nr_of_symbols == 1) { // non-coherent correlation + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) + temp += squaredMod(corr[aa][0]); + } else { + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + c64_t corr2; + csum(corr2, corr[aa][0], corr[aa][1]); + // coherent combining of 2 symbols and then complex modulus for + // single-frequency case + temp += corr2.r * corr2.r + corr2.i * corr2.i; } - } else if (pucch_pdu->freq_hop_flag == 1) { + } + } else { // full non-coherent combining of 2 symbols for frequency-hopping case - temp=0; - for (int aa=0;aanb_antennas_rx;aa++) + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]); } - else AssertFatal(1==0,"shouldn't happen\n"); if (temp>xrtmag) { xrtmag_next = xrtmag; @@ -356,11 +331,11 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, for (int aa=0;aanb_antennas_rx;aa++) { temp2 += squaredMod(corr[aa][0]); if (pucch_pdu->nr_of_symbols==2) - temp3 += squaredMod(corr[aa][1]); + temp3 += squaredMod(corr[aa][1]); } uci_stats->current_pucch0_stat0= dB_fixed64(temp2); if ( pucch_pdu->nr_of_symbols==2) - uci_stats->current_pucch0_stat1= dB_fixed64(temp3); + uci_stats->current_pucch0_stat1 = dB_fixed64(temp3); } else if (temp>xrtmag_next) xrtmag_next = temp; @@ -377,28 +352,30 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, 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 = max(gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]], - gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]); - int SNRtimes10,sigenergy=0; - for (int aa=0;aanb_antennas_rx;aa++) - sigenergy += signal_energy_nodc(rp[aa][0],12); - SNRtimes10 = pucch_power_dBtimes10 - (10 * max_n0); + int max_n0 = + max(gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]], gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]); + const int SNRtimes10 = pucch_power_dBtimes10 - (10 * max_n0); int cqi; - if (SNRtimes10 < -640) cqi=0; - else if (SNRtimes10 > 635) cqi=255; - else cqi=(640+SNRtimes10)/5; + if (SNRtimes10 < -640) + cqi = 0; + else if (SNRtimes10 > 635) + cqi = 255; + else + cqi = (640 + SNRtimes10) / 5; uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/ bool no_conf=false; if (nr_sequences>1) { if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) { no_conf=true; - LOG_D(PHY,"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n", - frame, slot, - uci_stats->pucch0_thres, - SNRtimes10, - xrtmag_dBtimes10, - xrtmag_next_dBtimes10); + LOG_D(PHY, + "%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n", + frame, + slot, + uci_stats->pucch0_thres, + SNRtimes10, + xrtmag_dBtimes10, + xrtmag_next_dBtimes10); } } gNB->bad_pucch += no_conf; @@ -408,7 +385,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->rnti = pucch_pdu->rnti; 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(sigenergy); + uci_pdu->rssi = 1280 - (10 * dB_fixed(32767 * 32767)) - dB_fixed_times10(signal_energy_ant0); if (pucch_pdu->bit_len_harq==0) { uci_pdu->sr.sr_confidence_level = SNRtimes10 < uci_stats->pucch0_thres; @@ -426,7 +403,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq.harq_confidence_level = no_conf; uci_pdu->harq.harq_list[0].harq_value = !(index&0x01); LOG_D(PHY, - "[DLSCH/PDSCH/PUCCH] %d.%d HARQ %s with confidence level %s xrt_mag %d xrt_mag_next %d pucch_power_dBtimes10 %d n0 %d (%d,%d) pucch0_thres %d, " + "[DLSCH/PDSCH/PUCCH] %d.%d HARQ %s with confidence level %s xrt_mag " + "%d xrt_mag_next %d pucch_power_dBtimes10 %d n0 %d " + "(%d,%d) pucch0_thres %d, " "cqi %d, SNRtimes10 %d, energy %f\n", frame, slot, @@ -441,7 +420,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_stats->pucch0_thres, cqi, SNRtimes10, - 10 * log10((double)sigenergy)); + 10 * log10((double)signal_energy_ant0)); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr.sr_indication = (index>1); @@ -488,10 +467,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, } //*****************************************************************// void nr_decode_pucch1(c16_t **rxdataF, - pucch_GroupHopping_t pucch_GroupHopping, - uint32_t n_id, // hoppingID higher layer parameter + pucch_GroupHopping_t pucch_GroupHopping, + uint32_t n_id, // hoppingID higher layer parameter uint64_t *payload, - NR_DL_FRAME_PARMS *frame_parms, + NR_DL_FRAME_PARMS *frame_parms, int16_t amp, int nr_tti_tx, uint8_t m0, @@ -503,33 +482,33 @@ void nr_decode_pucch1(c16_t **rxdataF, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%lp m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", - nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); + printf( + "\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d " + "payload=%lux m0=%d nrofSymbols=%d startingSymbolIndex=%d " + "startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d " + "nr_bit=%d\n", + nr_tti_tx, + *payload, + m0, + nrofSymbols, + startingSymbolIndex, + startingPRB, + startingPRB_intraSlotHopping, + timeDomainOCC, + nr_bit); #endif /* * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation * */ - int soffset = (nr_tti_tx&3)*frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; - // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): - int16_t d_re=0, d_im=0,d1_re=0,d1_im=0; -#ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] sequence modulation: payload=%lp \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); -#endif - /* - * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 - */ - // alpha is cyclic shift - double alpha; - // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission - //uint8_t lnormal = 0 ; + const int soffset = (nr_tti_tx & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] - uint8_t lprime = startingSymbolIndex; + const int lprime = startingSymbolIndex; // mcs = 0 except for PUCCH format 0 - uint8_t mcs=0; + const uint8_t mcs = 0; // r_u_v_alpha_delta_re and r_u_v_alpha_delta_im tables containing the sequence y(n) for the PUCCH, when they are multiplied by d(0) // r_u_v_alpha_delta_dmrs_re and r_u_v_alpha_delta_dmrs_im tables containing the sequence for the DM-RS. - int16_t r_u_v_alpha_delta_re[12],r_u_v_alpha_delta_im[12],r_u_v_alpha_delta_dmrs_re[12],r_u_v_alpha_delta_dmrs_im[12]; + c16_t r_u_v_alpha_delta[12], r_u_v_alpha_delta_dmrs[12]; /* * in TS 38.213 Subclause 9.2.1 it is said that: * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift @@ -540,21 +519,12 @@ void nr_decode_pucch1(c16_t **rxdataF, */ // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 uint8_t u=0,v=0;//,delta=0; - // if frequency hopping is disabled, intraSlotFrequencyHopping is not provided - // n_hop = 0 - // if frequency hopping is enabled, intraSlotFrequencyHopping is provided - // n_hop = 0 for first hop - // n_hop = 1 for second hop - uint8_t n_hop = 0; + // Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, // regardless of whether the frequency-hop distance is zero or not, // otherwise no intra-slot frequency hopping shall be assumed //uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers - uint8_t intraSlotFrequencyHopping = 0; - - if (startingPRB != startingPRB_intraSlotHopping) { - intraSlotFrequencyHopping=1; - } + const bool intraSlotFrequencyHopping = startingPRB != startingPRB_intraSlotHopping; #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n",intraSlotFrequencyHopping); @@ -562,119 +532,110 @@ void nr_decode_pucch1(c16_t **rxdataF, /* * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources */ - //int32_t *txptr; - uint32_t re_offset=0; - int i=0; #define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n - int16_t z_re_rx[MAX_SIZE_Z],z_im_rx[MAX_SIZE_Z],z_re_temp,z_im_temp; - int16_t z_dmrs_re_rx[MAX_SIZE_Z],z_dmrs_im_rx[MAX_SIZE_Z],z_dmrs_re_temp,z_dmrs_im_temp; - memset(z_re_rx,0,MAX_SIZE_Z*sizeof(int16_t)); - memset(z_im_rx,0,MAX_SIZE_Z*sizeof(int16_t)); - memset(z_dmrs_re_rx,0,MAX_SIZE_Z*sizeof(int16_t)); - memset(z_dmrs_im_rx,0,MAX_SIZE_Z*sizeof(int16_t)); - int l=0; - for(l=0;lN_RB_DL >> 1; + const bool nb_rb_is_even = (frame_parms->N_RB_DL & 1) == 0; + for (int l = 0; l < nrofSymbols; l++) { // extracting data and dmrs from rxdataF + if (intraSlotFrequencyHopping && (l < floor(nrofSymbols / 2))) { // intra-slot hopping enabled, we need + // to calculate new offset PRB startingPRB = startingPRB + startingPRB_intraSlotHopping; } + int re_offset = (l + startingSymbolIndex) * frame_parms->ofdm_symbol_size; - if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } - - if ((startingPRB >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))); - } - - if ((startingPRB < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; - } - - if ((startingPRB > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(startingPRB-(frame_parms->N_RB_DL>>1))) + 6; - } - - if ((startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*startingPRB) + frame_parms->first_carrier_offset; + if (nb_rb_is_even) { + if (startingPRB < half_nb_rb_dl) // if number RBs in bandwidth is even and + // current PRB is lower band + re_offset += 12 * startingPRB + frame_parms->first_carrier_offset; + else // if number RBs in bandwidth is even and current PRB is upper band + re_offset += 12 * (startingPRB - half_nb_rb_dl); + } else { + if (startingPRB < half_nb_rb_dl) // if number RBs in bandwidth is odd and + // current PRB is lower band + re_offset += 12 * startingPRB + frame_parms->first_carrier_offset; + else if (startingPRB > half_nb_rb_dl) // if number RBs in bandwidth is odd + // and current PRB is upper band + re_offset += 12 * (startingPRB - half_nb_rb_dl) + 6; + else // if number RBs in bandwidth is odd and current PRB contains DC + re_offset += 12 * startingPRB + frame_parms->first_carrier_offset; } for (int n=0; n<12; n++) { - if ((n==6) && (startingPRB == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + const int current_subcarrier = l * 12 + n; + if (n == 6 && startingPRB == half_nb_rb_dl && !nb_rb_is_even) { // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); } - if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 - z_re_rx[i+n] = ((int16_t *)&rxdataF[0][soffset+re_offset])[0]; - z_im_rx[i+n] = ((int16_t *)&rxdataF[0][soffset+re_offset])[1]; + if (l % 2 == 1) // mapping PUCCH or DM-RS according to TS38.211 subclause 6.4.1.3.1 + z_rx[current_subcarrier] = rxdataF[0][soffset + re_offset]; + else + z_dmrs_rx[current_subcarrier] = rxdataF[0][soffset + re_offset]; #ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", - amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, - l,n,((int16_t *)&rxdataF[0][soffset+re_offset])[0],((int16_t *)&rxdataF[0][soffset+re_offset])[1]); + printf( + "\t [nr_generate_pucch1] mapping %s to RE \t amp=%d " + "\tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d " + "\tz_pucch[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", + l % 2 ? "PUCCH" : "DM-RS", + amp, + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + frame_parms->first_carrier_offset, + current_subcarrier, + re_offset, + l, + n, + rxdataF[0][soffset + re_offset].r, + rxdataF[0][soffset + re_offset].i); #endif - } - - if (l%2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 - z_dmrs_re_rx[i+n] = ((int16_t *)&rxdataF[0][soffset+re_offset])[0]; - z_dmrs_im_rx[i+n] = ((int16_t *)&rxdataF[0][soffset+re_offset])[1]; - // printf("%d\t%d\t%d\n",l,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]); -#ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", - amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,i+n,re_offset, - l,n,((int16_t *)&rxdataF[0][soffset+re_offset])[0],((int16_t *)&rxdataF[0][soffset+re_offset])[1]); -#endif - // printf("l=%d\ti=%d\tre_offset=%d\treceived dmrs re=%d\tim=%d\n",l,i,re_offset,z_dmrs_re_rx[i+n],z_dmrs_im_rx[i+n]); - } - re_offset++; } - if (l%2 == 1) i+=12; } - int16_t y_n_re[12],y_n_im[12],y1_n_re[12],y1_n_im[12]; - memset(y_n_re,0,12*sizeof(int16_t)); - memset(y_n_im,0,12*sizeof(int16_t)); - memset(y1_n_re,0,12*sizeof(int16_t)); - memset(y1_n_im,0,12*sizeof(int16_t)); + cd_t y_n[12] = {0}, y1_n[12] = {0}; //generating transmitted sequence and dmrs - for (l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop + // if frequency hopping is disabled, intraSlotFrequencyHopping is not + // provided + // n_hop = 0 + // if frequency hopping is enabled, intraSlotFrequencyHopping is provided + // n_hop = 0 for first hop + // n_hop = 1 for second hop + const int n_hop = intraSlotFrequencyHopping && l >= nrofSymbols / 2 ? 1 : 0; #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", n_hop,nr_tti_tx); #endif nr_group_sequence_hopping(pucch_GroupHopping,n_id,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(n_id,m0,mcs,l,lprime,nr_tti_tx); - + // Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 + double alpha = nr_cyclic_shift_hopping(n_id, m0, mcs, l, lprime, nr_tti_tx); for (int n=0; n<12; n++) { // generating low papr sequences - if(l%2==1){ - r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) - - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha - r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) - + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha - } - else{ - r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) - - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha - r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) - + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha - r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_re[n]))>>15); - r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_im[n]))>>15); - } - // printf("symbol=%d\tr_u_rx_re=%d\tr_u_rx_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n], r_u_v_alpha_delta_dmrs_im[n]); - // PUCCH sequence = DM-RS sequence multiplied by d(0) - /* y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15) - - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n) - y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) - + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) */ + const c16_t angle = {lround(32767 * cos(alpha * n)), lround(32767 * sin(alpha * n))}; + const c16_t table = {table_5_2_2_2_2_Re[u][n], table_5_2_2_2_2_Im[u][n]}; + if (l % 2 == 1) + r_u_v_alpha_delta[n] = c16mulShift(angle, table, 15); + else + r_u_v_alpha_delta_dmrs[n] = c16mulRealShift(c16mulShift(angle, table, 15), amp, 15); #ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", - u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); + printf( + "\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d " + "\talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) " + "\ty_n[n=%d]=(%f,%f)\n", + u, + v, + alpha, + n, + r_u_v_alpha_delta[n].r, + r_u_v_alpha_delta[n].i, + n, + y_n[n].r, + y_n[n].i); #endif } /* @@ -691,298 +652,208 @@ void nr_decode_pucch1(c16_t **rxdataF, // the index of the orthogonal cover code is from a set determined as described in [4, TS 38.211] // and is indicated by higher layer parameter PUCCH-F1-time-domain-OCC // In the PUCCH_Config IE, the PUCCH-format1, timeDomainOCC field - uint8_t w_index = timeDomainOCC; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime_PUCCH_1; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime_PUCCH_DMRS_1; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime0_PUCCH_1; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime0_PUCCH_DMRS_1; - // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping - uint8_t mprime = 0; - - if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled + const int w_index = timeDomainOCC; + if (intraSlotFrequencyHopping == false) { // intra-slot hopping disabled #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping disabled\n", intraSlotFrequencyHopping); #endif - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) - N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) - N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) - N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) + // mprime is 0 in this not hopping case + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 + // (depending on number of PUCCH symbols nrofSymbols, mprime and + // intra-slot hopping enabled/disabled) N_SF_mprime_PUCCH_1 contains + // N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH + // symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 + // (depending on number of PUCCH symbols nrofSymbols, mprime=0 and + // intra-slot hopping enabled/disabled) N_SF_mprime_PUCCH_1 contains + // N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH + // symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot + // hopping + int N_SF_mprime_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols - 1]; // only if intra-slot hopping not enabled (PUCCH) + int N_SF_mprime_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols - 1]; // only if intra-slot hopping not enabled (DM-RS) #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); #endif + if(l%2==1){ for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { - if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){ - for (int n=0; n<12 ; n++) { - z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_re_temp; - z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]=z_im_temp; - // printf("symbol=%d\tz_re_rx=%d\tz_im_rx=%d\t",l,(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], - z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - // multiplying with conjugate of low papr sequence - z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp; - z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp; - /* if(z_re_temp<0){ - printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_re[n],z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)); - } - printf("z1_re_rx=%d\tz1_im_rx=%d\n",(int)z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); */ - } - } + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m]}; + if (l / 2 == m) { + for (int n = 0; n < 12; n++) { + c16_t *zPtr = z_rx + m * 12 + n; + *zPtr = c16MulConjShift(table, *zPtr, 15); + // multiplying with conjugate of low papr sequence + *zPtr = c16MulConjShift(r_u_v_alpha_delta[n], *zPtr, 16); + } + } } - } - - else{ + } else { for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { - if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){ - for (int n=0; n<12 ; n++) { - z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; - z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; - // printf("symbol=%d\tz_dmrs_re_rx=%d\tz_dmrs_im_rx=%d\t",l,(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], - z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays - z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - /* if(z_dmrs_re_temp<0){ - printf("\nBug detection %d\t%d\t%d\t%d\n",r_u_v_alpha_delta_dmrs_re[n],z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15),(((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15)); - }*/ - z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; - z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; - // printf("z1_dmrs_re_rx=%d\tz1_dmrs_im_rx=%d\n",(int)z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],(int)z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); - /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n]; - z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */ - } - } + const c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m]}; + if (l / 2 == m) { + for (int n = 0; n < 12; n++) { + c16_t *zDmrsPtr = z_dmrs_rx + m * 12 + n; + *zDmrsPtr = c16MulConjShift(table, *zDmrsPtr, 15); + // finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and + // z_dmrs_im_rx arrays + *zDmrsPtr = c16MulConjShift(r_u_v_alpha_delta_dmrs[n], *zDmrsPtr, 16); + } + } } } } - if (intraSlotFrequencyHopping == 1) { // intra-slot hopping enabled + if (intraSlotFrequencyHopping == true) { // intra-slot hopping enabled #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping enabled\n", intraSlotFrequencyHopping); #endif - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) - N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) - N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) - N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 + // (depending on number of PUCCH symbols nrofSymbols, mprime and + // intra-slot hopping enabled/disabled) N_SF_mprime_PUCCH_1 contains + // N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH + // symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 + // (depending on number of PUCCH symbols nrofSymbols, mprime=0 and + // intra-slot hopping enabled/disabled) N_SF_mprime_PUCCH_1 contains + // N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH + // symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot + // hopping + int N_SF_mprime_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + int N_SF_mprime_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + int N_SF_mprime0_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + int N_SF_mprime0_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) #ifdef DEBUG_NR_PUCCH_RX printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); #endif - for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1} - if(l%2==1){ - for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { - if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)){ - for (int n=0; n<12 ; n++) { - z_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp; - z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp; -#ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], - z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - z_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - + (((int32_t)(r_u_v_alpha_delta_im[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15) - - (((int32_t)(r_u_v_alpha_delta_im[n])*z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n])>>15))>>1); - z_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_re_temp; - z_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = z_im_temp; - } - } - } + for (int mprime = 0; mprime < 2; mprime++) { // mprime can get values {0,1} + if (l % 2 == 1) { + for (int m = 0; m < N_SF_mprime_PUCCH_1; m++) { + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m]}; + if (floor(l / 2) * 12 == (mprime * 12 * N_SF_mprime0_PUCCH_1) + (m * 12)) { + for (int n = 0; n < 12; n++) { + c16_t *zPtr = z_rx + (mprime * 12 * N_SF_mprime0_PUCCH_1) + (m * 12) + n; + *zPtr = c16MulConjShift(table, *zPtr, 15); + *zPtr = c16MulConjShift(r_u_v_alpha_delta[n], *zPtr, 16); + } + } + } } - else{ - for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { - if(floor(l/2)*12==(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)){ - for (int n=0; n<12 ; n++) { - z_dmrs_re_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_im_temp = (int16_t)(((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; - z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; -#ifdef DEBUG_NR_PUCCH_RX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], - z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - //finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and z_dmrs_im_rx arrays - z_dmrs_re_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - + (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_im_temp = (int16_t)(((((int32_t)(r_u_v_alpha_delta_dmrs_re[n])*z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15) - - (((int32_t)(r_u_v_alpha_delta_dmrs_im[n])*z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n])>>15))>>1); - z_dmrs_re_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_re_temp; - z_dmrs_im_rx[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = z_dmrs_im_temp; - - /* z_dmrs_re_rx[(int)(l/2)*12+n]=z_dmrs_re_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_re[n]; - z_dmrs_im_rx[(int)(l/2)*12+n]=z_dmrs_im_rx[(int)(l/2)*12+n]/r_u_v_alpha_delta_dmrs_im[n]; */ - } - } - } + else { + for (int m = 0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m]}; + if (floor(l / 2) * 12 == (mprime * 12 * N_SF_mprime0_PUCCH_DMRS_1) + (m * 12)) { + for (int n = 0; n < 12; n++) { + c16_t *zDmrsPtr = z_dmrs_rx + (mprime * 12 * N_SF_mprime0_PUCCH_DMRS_1) + (m * 12) + n; + *zDmrsPtr = c16MulConjShift(table, *zDmrsPtr, 15); + // finding channel coeffcients by dividing received dmrs with actual dmrs and storing them in z_dmrs_re_rx and + // z_dmrs_im_rx arrays + *zDmrsPtr = c16MulConjShift(r_u_v_alpha_delta_dmrs[n], *zDmrsPtr, 16); + } + } + } } - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) + N_SF_mprime_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) } } } - int16_t H_re[12],H_im[12],H1_re[12],H1_im[12]; - memset(H_re,0,12*sizeof(int16_t)); - memset(H_im,0,12*sizeof(int16_t)); - memset(H1_re,0,12*sizeof(int16_t)); - memset(H1_im,0,12*sizeof(int16_t)); - //averaging channel coefficients - for(l=0;l<=ceil(nrofSymbols/2);l++){ - if(intraSlotFrequencyHopping==0){ - for(int n=0;n<12;n++){ - H_re[n]=round(z_dmrs_re_rx[l*12+n]/ceil(nrofSymbols/2))+H_re[n]; - H_im[n]=round(z_dmrs_im_rx[l*12+n]/ceil(nrofSymbols/2))+H_im[n]; + cd_t H[12] = {0}, H1[12] = {0}; + const double half_nb_symbols = nrofSymbols / 2.0; + const double quarter_nb_symbols = nrofSymbols / 4.0; + for (int l = 0; l <= half_nb_symbols; l++) { + if (intraSlotFrequencyHopping == false) { + for (int n = 0; n < 12; n++) { + H[n].r += z_dmrs_rx[l * 12 + n].r / half_nb_symbols; + H[n].i += z_dmrs_rx[l * 12 + n].i / half_nb_symbols; + y_n[n].r += z_rx[l * 12 + n].r / half_nb_symbols; + y_n[n].i += z_rx[l * 12 + n].i / half_nb_symbols; } - } - else{ - if(l>15) + (((int32_t)(H_im[n])*y_n_im[n])>>15))>>1))/12)+d_re; - d_im = round(((int16_t)(((((int32_t)(H_re[n])*y_n_im[n])>>15) - (((int32_t)(H_im[n])*y_n_re[n])>>15))>>1))/12)+d_im; + cd_t d = {0}; + if (intraSlotFrequencyHopping == false) { + // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): + for (int n = 0; n < 12; n++) { + d.r += H[n].r * y_n[n].r + H[n].i * y_n[n].i; + d.i += H[n].r * y_n[n].i - H[n].i * y_n[n].r; } - } - else{ - for(int n=0;n<12;n++){ - d_re = round(((int16_t)(((((int32_t)(H_re[n])*y_n_re[n])>>15) + (((int32_t)(H_im[n])*y_n_im[n])>>15))>>1))/12)+d_re; - d_im = round(((int16_t)(((((int32_t)(H_re[n])*y_n_im[n])>>15) - (((int32_t)(H_im[n])*y_n_re[n])>>15))>>1))/12)+d_im; - d1_re = round(((int16_t)(((((int32_t)(H1_re[n])*y1_n_re[n])>>15) + (((int32_t)(H1_im[n])*y1_n_im[n])>>15))>>1))/12)+d1_re; - d1_im = round(((int16_t)(((((int32_t)(H1_re[n])*y1_n_im[n])>>15) - (((int32_t)(H1_im[n])*y1_n_re[n])>>15))>>1))/12)+d1_im; + } else { + for (int n = 0; n < 12; n++) { + d.r += H[n].r * y_n[n].r + H[n].i * y_n[n].i; + d.i += H[n].r * y_n[n].i - H[n].i * y_n[n].r; + d.r += H[n].r * y1_n[n].r + H[n].i * y1_n[n].i; + d.i += H[n].r * y1_n[n].i - H[n].i * y1_n[n].r; } - d_re=round(d_re/2); - d_im=round(d_im/2); - d1_re=round(d1_re/2); - d1_im=round(d1_im/2); - d_re=d_re+d1_re; - d_im=d_im+d1_im; } //Decoding QPSK or BPSK symbols to obtain payload bits - if(nr_bit==1){ - if((d_re+d_im)>0){ - *payload=0; + if (nr_bit == 1) { + if ((d.r + d.i) > 0) { + *payload = 0; + } else { + *payload = 1; } - else{ - *payload=1; - } - } - else if(nr_bit==2){ - if((d_re>0)&&(d_im>0)){ - *payload=0; - } - else if((d_re<0)&&(d_im>0)){ - *payload=1; - } - else if((d_re>0)&&(d_im<0)){ - *payload=2; - } - else{ - *payload=3; + } else if (nr_bit == 2) { + if ((d.r > 0) && (d.i > 0)) { + *payload = 0; + } else if ((d.r < 0) && (d.i > 0)) { + *payload = 1; + } else if ((d.r > 0) && (d.i < 0)) { + *payload = 2; + } else { + *payload = 3; } } } -simde__m256i pucch2_3bit[8*2]; -simde__m256i pucch2_4bit[16*2]; -simde__m256i pucch2_5bit[32*2]; -simde__m256i pucch2_6bit[64*2]; -simde__m256i pucch2_7bit[128*2]; -simde__m256i pucch2_8bit[256*2]; -simde__m256i pucch2_9bit[512*2]; -simde__m256i pucch2_10bit[1024*2]; -simde__m256i pucch2_11bit[2048*2]; +static simde__m256i pucch2_3bit[8 * 2]; +static simde__m256i pucch2_4bit[16 * 2]; +static simde__m256i pucch2_5bit[32 * 2]; +static simde__m256i pucch2_6bit[64 * 2]; +static simde__m256i pucch2_7bit[128 * 2]; +static simde__m256i pucch2_8bit[256 * 2]; +static simde__m256i pucch2_9bit[512 * 2]; +static simde__m256i pucch2_10bit[1024 * 2]; +static simde__m256i pucch2_11bit[2048 * 2]; -static simde__m256i *pucch2_lut[9]={pucch2_3bit, - pucch2_4bit, - pucch2_5bit, - pucch2_6bit, - pucch2_7bit, - pucch2_8bit, - pucch2_9bit, - pucch2_10bit, - pucch2_11bit}; +static simde__m256i *pucch2_lut[9] = + {pucch2_3bit, pucch2_4bit, pucch2_5bit, pucch2_6bit, pucch2_7bit, pucch2_8bit, pucch2_9bit, pucch2_10bit, pucch2_11bit}; simde__m64 pucch2_polar_4bit[16]; simde__m128i pucch2_polar_llr_num_lut[256],pucch2_polar_llr_den_lut[256]; @@ -993,8 +864,8 @@ void init_pucch2_luts() { int8_t bit; for (int b=3;b<12;b++) { - for (uint16_t i=0;i<(1< 0 ? -1 : 1; @@ -1082,47 +953,48 @@ void init_pucch2_luts() { simde__m128i *lut_num_i=&pucch2_polar_llr_num_lut[i]; simde__m128i *lut_den_i=&pucch2_polar_llr_den_lut[i]; bit = (i&0x1) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,0); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,0); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 0); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 0); bit = (i&0x10) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,1); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,1); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 1); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 1); bit = (i&0x2) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,2); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,2); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 2); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 2); bit = (i&0x20) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,3); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,3); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 3); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 3); bit = (i&0x4) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,4); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,4); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 4); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 4); bit = (i&0x40) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,5); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,5); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 5); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 5); bit = (i&0x8) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,6); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,6); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 6); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 6); bit = (i&0x80) > 0 ? 0 : 1; - *lut_num_i = simde_mm_insert_epi16(*lut_num_i,bit,7); - *lut_den_i = simde_mm_insert_epi16(*lut_den_i,1-bit,7); + *lut_num_i = simde_mm_insert_epi16(*lut_num_i, bit, 7); + *lut_den_i = simde_mm_insert_epi16(*lut_den_i, 1 - bit, 7); #ifdef DEBUG_NR_PUCCH_RX - printf("i %d, lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, - ((int16_t *)lut_num_i)[0], - ((int16_t *)lut_num_i)[1], - ((int16_t *)lut_num_i)[2], - ((int16_t *)lut_num_i)[3], - ((int16_t *)lut_num_i)[4], - ((int16_t *)lut_num_i)[5], - ((int16_t *)lut_num_i)[6], - ((int16_t *)lut_num_i)[7]); + printf("i %d, lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n", + i, + ((int16_t *)lut_num_i)[0], + ((int16_t *)lut_num_i)[1], + ((int16_t *)lut_num_i)[2], + ((int16_t *)lut_num_i)[3], + ((int16_t *)lut_num_i)[4], + ((int16_t *)lut_num_i)[5], + ((int16_t *)lut_num_i)[6], + ((int16_t *)lut_num_i)[7]); #endif } } @@ -1138,8 +1010,9 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; //pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); - AssertFatal(pucch_pdu->nr_of_symbols==1 || pucch_pdu->nr_of_symbols==2, - "Illegal number of symbols for PUCCH 2 %d\n",pucch_pdu->nr_of_symbols); + AssertFatal(pucch_pdu->nr_of_symbols == 1 || pucch_pdu->nr_of_symbols == 2, + "Illegal number of symbols for PUCCH 2 %d\n", + pucch_pdu->nr_of_symbols); AssertFatal((pucch_pdu->prb_start-((pucch_pdu->prb_start>>2)<<2))==0, "Current pucch2 receiver implementation requires a PRB offset multiple of 4. The one selected is %d", @@ -1147,21 +1020,26 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, //extract pucch and dmrs first - int l2=pucch_pdu->start_symbol_index; - int re_offset[2]; - re_offset[0] = 12*(pucch_pdu->prb_start+pucch_pdu->bwp_start) + frame_parms->first_carrier_offset; - int soffset=(slot&3)*frame_parms->symbols_per_slot*frame_parms->ofdm_symbol_size; + int l2 = pucch_pdu->start_symbol_index; + int soffset = (slot & 3) * frame_parms->symbols_per_slot * 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) % frame_parms->ofdm_symbol_size; 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]; + 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); + 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; // AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of2\n",pucch_pdu->prb_size); @@ -1216,7 +1094,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, // if the number of PRBs is odd // we fill the unsed part of the arrays for (int aa = 0; aa < Prx; aa++) { - for (int symb=0; symbnr_of_symbols;symb++) { + for (int symb = 0; symb < pucch_pdu->nr_of_symbols; symb++) { const int sz = pucch_pdu->prb_size; memset(r_re_ext[aa][symb] + 8 * sz, 0, 8 * sizeof(int16_t)); memset(r_im_ext[aa][symb] + 8 * sz, 0, 8 * sizeof(int16_t)); @@ -1228,7 +1106,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, for (int symb=0; symbnr_of_symbols;symb++) { // 24 REs contains 48x16-bit, so 6x8x16-bit - for (int aa=0;aaprb_size; prb++) { int16_t *r_re_ext_p = &r_re_ext[aa][symb][8 * prb]; int16_t *r_im_ext_p = &r_im_ext[aa][symb][8 * prb]; @@ -1272,7 +1150,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, reset = 0; } - for (int group=0;group>=5; + /* 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[symb][group][aa],corr32_im[symb][group][aa]); @@ -1358,7 +1235,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, sGold = lte_gold_generic(&x1, &x2, 1); uint8_t *sGold8 = (uint8_t *)&sGold; #ifdef DEBUG_NR_PUCCH_RX - printf("x2 %x, s %x\n",x2,s); + printf("x2 %x\n", x2); #endif for (int symb=0;symbnr_of_symbols;symb++) { simde__m64 c_re[4], c_im[4]; @@ -1477,9 +1354,9 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, #ifdef DEBUG_NR_PUCCH_RX printf("cw %d:",cw); for (int i=0;i<32;i+=2) { - printf("%d,%d,", - ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[i>>1], - ((int16_t*)&pucch2_lut[nb_bit-3][cw<<1])[1+(i>>1)]); + printf("%d,%d,", + ((int16_t *)&pucch2_lut[nb_bit - 3][cw << 1])[i >> 1], + ((int16_t *)&pucch2_lut[nb_bit - 3][cw << 1])[1 + (i >> 1)]); } printf("\n"); #endif @@ -1489,10 +1366,12 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, for (int group=0;group (%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], @@ -1513,7 +1392,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ((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]); -#endif +#endif prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); prod_re[aa] = simde_mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3 #ifdef DEBUG_NR_PUCCH_RX @@ -1522,7 +1401,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ((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]); -#endif +#endif prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); prod_re[aa] = simde_mm256_hadds_epi16(prod_re[aa],prod_re[aa]);// 0+1+2+3+4+5+6+7 #ifdef DEBUG_NR_PUCCH_RX @@ -1531,7 +1410,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ((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]); -#endif +#endif prod_im[aa] = simde_mm256_hadds_epi16(prod_im[aa],prod_im[aa]); } int64_t corr_re=0,corr_im=0; @@ -1542,12 +1421,16 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, corr_re = ( corr32_re[symb][group][aa]+((int16_t*)(&prod_re[aa]))[0]+((int16_t*)(&prod_re[aa]))[8]); corr_im = ( corr32_im[symb][group][aa]+((int16_t*)(&prod_im[aa]))[0]+((int16_t*)(&prod_im[aa]))[8]); #ifdef DEBUG_NR_PUCCH_RX - printf("pucch2 cw %d group %d aa %d: (%d,%d)+(%d,%d) = (%ld,%ld)\n",cw,group,aa, - corr32_re[symb][group][aa],corr32_im[symb][group][aa], - ((int16_t*)(&prod_re[aa]))[0]+((int16_t*)(&prod_re[aa]))[8], - ((int16_t*)(&prod_im[aa]))[0]+((int16_t*)(&prod_im[aa]))[8], - corr_re,corr_im - ); + printf("pucch2 cw %d group %d aa %d: (%d,%d)+(%d,%d) = (%ld,%ld)\n", + cw, + group, + aa, + corr32_re[symb][group][aa], + corr32_im[symb][group][aa], + ((int16_t *)(&prod_re[aa]))[0] + ((int16_t *)(&prod_re[aa]))[8], + ((int16_t *)(&prod_im[aa]))[0] + ((int16_t *)(&prod_im[aa]))[8], + corr_re, + corr_im); #endif @@ -1556,10 +1439,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, }// group loop } // symb loop if (corr_tmp > corr) { - corr = corr_tmp; - cw_ML=cw; + corr = corr_tmp; + cw_ML = cw; #ifdef DEBUG_NR_PUCCH_RX - printf("slot %d PUCCH2 cw_ML %d, corr %lu\n",slot,cw_ML,corr); + printf("slot %d PUCCH2 cw_ML %d, corr %lu\n", slot, cw_ML, corr); #endif } } // cw loop @@ -1592,8 +1475,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, printf("cw %d:",cw); for (int i=0;i<4;i++) { - printf("%d,", - ((int16_t*)&pucch2_polar_4bit[cw])[i>>1]); + printf("%d,", ((int16_t *)&pucch2_polar_4bit[cw])[i >> 1]); } printf("\n"); } @@ -1609,10 +1491,14 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, 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] = simde_mm_srai_pi16(simde_mm_subs_pi16(simde_mm_mullo_pi16(pucch2_polar_4bit[cw&15],rp2_im[aa][symb][half_prb]), - simde_mm_mullo_pi16(pucch2_polar_4bit[cw>>4],rp2_re[aa][symb][half_prb])),5); + prod_re[aa] = + simde_mm_srai_pi16(simde_mm_adds_pi16(simde_mm_mullo_pi16(pucch2_polar_4bit[cw & 15], rp_re[aa][symb][half_prb]), + simde_mm_mullo_pi16(pucch2_polar_4bit[cw >> 4], rp_im[aa][symb][half_prb])), + 5); + prod_im[aa] = + simde_mm_srai_pi16(simde_mm_subs_pi16(simde_mm_mullo_pi16(pucch2_polar_4bit[cw & 15], rp2_im[aa][symb][half_prb]), + simde_mm_mullo_pi16(pucch2_polar_4bit[cw >> 4], rp2_re[aa][symb][half_prb])), + 5); prod_re[aa] = simde_mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1 prod_im[aa] = simde_mm_hadds_pi16(prod_im[aa],prod_im[aa]); prod_re[aa] = simde_mm_hadds_pi16(prod_re[aa],prod_re[aa]);// 0+1+2+3 @@ -1626,63 +1512,65 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, 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, + /* + 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], - ((int16_t*)&rp_re[aa][half_prb])[2],((int16_t*)&rp_im[aa][half_prb])[2], - ((int16_t*)&rp_re[aa][half_prb])[3],((int16_t*)&rp_im[aa][half_prb])[3], - corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2),corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2), - ((int16_t*)(&prod_re[aa]))[0], - ((int16_t*)(&prod_im[aa]))[0], - corr_re, - corr_im, - corr_tmp); -*/ - } - corr16 = simde_mm_set1_epi16((int16_t)(corr_tmp>>8)); + ((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], + ((int16_t*)&rp_re[aa][half_prb])[2],((int16_t*)&rp_im[aa][half_prb])[2], + ((int16_t*)&rp_re[aa][half_prb])[3],((int16_t*)&rp_im[aa][half_prb])[3], + corr32_re[half_prb>>2][aa]/(2*nc_group_size*4/2),corr32_im[half_prb>>2][aa]/(2*nc_group_size*4/2), + ((int16_t*)(&prod_re[aa]))[0], + ((int16_t*)(&prod_im[aa]))[0], + corr_re, + corr_im, + corr_tmp); + */ + } + corr16 = simde_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); + LOG_D(PHY, "half_prb %d cw %d corr16 %d\n", half_prb, cw, corr_tmp >> 8); - llr_num = simde_mm_max_epi16(simde_mm_mullo_epi16(corr16,pucch2_polar_llr_num_lut[cw]),llr_num); - llr_den = simde_mm_max_epi16(simde_mm_mullo_epi16(corr16,pucch2_polar_llr_den_lut[cw]),llr_den); + llr_num = simde_mm_max_epi16(simde_mm_mullo_epi16(corr16, pucch2_polar_llr_num_lut[cw]), llr_num); + llr_den = simde_mm_max_epi16(simde_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], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[1], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[2], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[3], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[4], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[5], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[6], - ((int16_t*)&pucch2_polar_llr_num_lut[cw])[7]); + LOG_D(PHY, + "lut_num (%d,%d,%d,%d,%d,%d,%d,%d)\n", + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[0], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[1], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[2], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[3], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[4], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[5], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[6], + ((int16_t *)&pucch2_polar_llr_num_lut[cw])[7]); - LOG_D(PHY,"llr_num (%d,%d,%d,%d,%d,%d,%d,%d)\n", - ((int16_t*)&llr_num)[0], - ((int16_t*)&llr_num)[1], - ((int16_t*)&llr_num)[2], - ((int16_t*)&llr_num)[3], - ((int16_t*)&llr_num)[4], - ((int16_t*)&llr_num)[5], - ((int16_t*)&llr_num)[6], - ((int16_t*)&llr_num)[7]); - LOG_D(PHY,"llr_den (%d,%d,%d,%d,%d,%d,%d,%d)\n", - ((int16_t*)&llr_den)[0], - ((int16_t*)&llr_den)[1], - ((int16_t*)&llr_den)[2], - ((int16_t*)&llr_den)[3], - ((int16_t*)&llr_den)[4], - ((int16_t*)&llr_den)[5], - ((int16_t*)&llr_den)[6], - ((int16_t*)&llr_den)[7]); - - } - // compute llrs + LOG_D(PHY, + "llr_num (%d,%d,%d,%d,%d,%d,%d,%d)\n", + ((int16_t *)&llr_num)[0], + ((int16_t *)&llr_num)[1], + ((int16_t *)&llr_num)[2], + ((int16_t *)&llr_num)[3], + ((int16_t *)&llr_num)[4], + ((int16_t *)&llr_num)[5], + ((int16_t *)&llr_num)[6], + ((int16_t *)&llr_num)[7]); + LOG_D(PHY, + "llr_den (%d,%d,%d,%d,%d,%d,%d,%d)\n", + ((int16_t *)&llr_den)[0], + ((int16_t *)&llr_den)[1], + ((int16_t *)&llr_den)[2], + ((int16_t *)&llr_den)[3], + ((int16_t *)&llr_den)[4], + ((int16_t *)&llr_den)[5], + ((int16_t *)&llr_den)[6], + ((int16_t *)&llr_den)[7]); + } + // compute llrs llrs[half_prb + (symb*2*pucch_pdu->prb_size)] = simde_mm_subs_epi16(llr_num,llr_den); LOG_D(PHY,"llrs[%d] : (%d,%d,%d,%d,%d,%d,%d,%d)\n", half_prb, @@ -1712,9 +1600,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, // estimate CQI for MAC (from antenna port 0 only) // TODO this computation is wrong -> to be ignored at MAC for now - int SNRtimes10 = dB_fixed_times10(signal_energy_nodc((int32_t *)&rxdataF[0][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[0]], - 12*pucch_pdu->prb_size)) - - (10*gNB->measurements.n0_power_tot_dB); + int SNRtimes10 = + dB_fixed_times10(signal_energy_nodc((int32_t *)&rxdataF[0][soffset + (l2 * frame_parms->ofdm_symbol_size) + re_offset[0]], + 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; @@ -1739,14 +1628,12 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, int i=0; for (;iharq.harq_payload[i] = decodedPayload[0] & 255; - LOG_D(PHY,"[DLSCH/PDSCH/PUCCH2] %d.%d HARQ paylod (%d) = %d\n", - frame,slot,i,uci_pdu->harq.harq_payload[i]); + LOG_D(PHY, "[DLSCH/PDSCH/PUCCH2] %d.%d HARQ payload (%d) = %d\n", frame, slot, i, uci_pdu->harq.harq_payload[i]); decodedPayload[0]>>=8; } bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3); uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<harq.harq_payload[i]); + LOG_D(PHY, "[DLSCH/PDSCH/PUCCH2] %d.%d HARQ payload (%d) = %d\n", frame, slot, i, uci_pdu->harq.harq_payload[i]); decodedPayload[0] >>= pucch_pdu->bit_len_harq; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index b73d432f2e..19f7e89a7f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -54,7 +54,7 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, - const int16_t amp, + const int16_t amp16, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu) { @@ -72,13 +72,14 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 */ // alpha is cyclic shift - double alpha; - // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH transmission - //uint8_t lnormal; - // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] - //uint8_t lprime; + // lnormal is the OFDM symbol number in the PUCCH transmission where l=0 corresponds to the first OFDM symbol of the PUCCH + // transmission + // uint8_t lnormal; + // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the + // slot given by [5, TS 38.213] + // uint8_t lprime; // mcs is provided by TC 38.213 subclauses 9.2.3, 9.2.4, 9.2.5 FIXME! - //uint8_t mcs; + // uint8_t mcs; /* * in TS 38.213 Subclause 9.2.1 it is said that: * for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift @@ -89,7 +90,7 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, * x(l*12+n) = r_u_v_alpha_delta(n) */ // the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1 - uint8_t u[2]={0,0},v[2]={0,0}; + uint8_t u[2] = {0}, v[2] = {0}; LOG_D(PHY,"pucch0: slot %d nr_symbols %d, start_symbol %d, prb_start %d, second_hop_prb %d, group_hop_flag %d, sequence_hop_flag %d, mcs %d\n", nr_slot_tx,pucch_pdu->nr_of_symbols,pucch_pdu->start_symbol_index,pucch_pdu->prb_start,pucch_pdu->second_hop_prb,pucch_pdu->group_hop_flag,pucch_pdu->sequence_hop_flag,pucch_pdu->mcs); @@ -97,70 +98,55 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch0] sequence generation: variable initialization for test\n"); #endif - // x_n contains the sequence r_u_v_alpha_delta(n) - int16_t x_n_re[2][24],x_n_im[2][24]; - - uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start; + int startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start; pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); // we proceed to calculate alpha according to TS 38.211 Subclause 6.3.2.2.2 int prb_offset[2]={startingPRB,startingPRB}; - nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,0,nr_slot_tx,&u[0],&v[0]); // calculating u and v value + nr_group_sequence_hopping(pucch_GroupHopping, pucch_pdu->hopping_id, 0, nr_slot_tx, u, v); // calculating u and v value if (pucch_pdu->freq_hop_flag == 1) { - nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,1,nr_slot_tx,&u[1],&v[1]); // calculating u and v value + nr_group_sequence_hopping(pucch_GroupHopping, pucch_pdu->hopping_id, 1, nr_slot_tx, u + 1, v + 1); // calculating u and v value prb_offset[1] = pucch_pdu->second_hop_prb + pucch_pdu->bwp_start; } - for (int l=0; lnr_of_symbols; l++) { - alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id, - pucch_pdu->initial_cyclic_shift, - pucch_pdu->mcs,l, - pucch_pdu->start_symbol_index, - nr_slot_tx); -#ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \t(for symbol l=%d)\n",u[l],v[l],alpha,l); -#endif - - for (int n=0; n<12; n++) { - x_n_re[l][n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u[l]][n])>>15) - - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u[l]][n])>>15))); // Re part of base sequence shifted by alpha - x_n_im[l][n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u[l]][n])>>15) - + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u[l]][n])>>15))); // Im part of base sequence shifted by alpha -#ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch0] sequence generation \tu=%d \tv=%d \talpha=%lf \tx_n(l=%d,n=%d)=(%d,%d)\n", - u[l],v[l],alpha,l,n,x_n_re[l][n],x_n_im[l][n]); -#endif - } - } - /* * Implementing TS 38.211 Subclause 6.3.2.3.2 Mapping to physical resources FIXME! */ - //int32_t *txptr; - uint32_t re_offset=0; - uint8_t l2; for (int l=0; lnr_of_symbols; l++) { - l2=l+pucch_pdu->start_symbol_index; - re_offset = (12*prb_offset[l]) + frame_parms->first_carrier_offset; + const double alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id, + pucch_pdu->initial_cyclic_shift, + pucch_pdu->mcs, + l, + pucch_pdu->start_symbol_index, + nr_slot_tx); + int l2 = l + pucch_pdu->start_symbol_index; + int re_offset = (12 * prb_offset[l]) + frame_parms->first_carrier_offset; if (re_offset>= frame_parms->ofdm_symbol_size) re_offset-=frame_parms->ofdm_symbol_size; //txptr = &txdataF[0][re_offset]; #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch0] symbol %d PRB %d (%u)\n",l,prb_offset[l],re_offset); -#endif +#endif + c16_t *txdataFptr = txdataF[0] + l2 * frame_parms->ofdm_symbol_size; + const int32_t amp = amp16; for (int n=0; n<12; n++) { - - txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset].r = (int16_t)(((int32_t)(amp) * x_n_re[l][n])>>15); - txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset].i = (int16_t)(((int32_t)(amp) * x_n_im[l][n])>>15); - //((int16_t *)txptr[0][re_offset])[0] = (int16_t)((int32_t)amp * x_n_re[(12*l)+n])>>15; - //((int16_t *)txptr[0][re_offset])[1] = (int16_t)((int32_t)amp * x_n_im[(12*l)+n])>>15; - //txptr[re_offset] = (x_n_re[(12*l)+n]<<16) + x_n_im[(12*l)+n]; + const c16_t angle = {lround(32767 * cos(alpha * n)), lround(32767 * sin(alpha * n))}; + const c16_t table = {table_5_2_2_2_2_Re[u[l]][n], table_5_2_2_2_2_Im[u[l]][n]}; + txdataFptr[re_offset] = c16mulRealShift(c16mulShift(angle, table, 15), amp, 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \ttxptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", - amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, (l2 * frame_parms->ofdm_symbol_size) + re_offset, - l2, n, txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset].r, - txdataF[0][(l2*frame_parms->ofdm_symbol_size) + re_offset].i); + printf( + "\t [nr_generate_pucch0] mapping to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d " + "\ttxptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", + amp, + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + frame_parms->first_carrier_offset, + (l2 * frame_parms->ofdm_symbol_size) + re_offset, + l2, + n, + txdataFptr[re_offset].r, + txdataFptr[re_offset].i); #endif re_offset++; if (re_offset>= frame_parms->ofdm_symbol_size) @@ -172,7 +158,7 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, - const int16_t amp, + const int16_t amp16, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu) { @@ -192,37 +178,20 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, * */ // complex-valued symbol d_re, d_im containing complex-valued symbol d(0): - int16_t d_re = 0, d_im = 0; - + c16_t d = {0}; + const int32_t amp = amp16; + const int16_t baseVal = (amp * ONE_OVER_SQRT2) >> 15; + const c16_t qpskSymbols[4] = {{baseVal, baseVal}, {baseVal, -baseVal}, {-baseVal, baseVal}, {-baseVal, -baseVal}}; if (pucch_pdu->n_bit == 1) { // using BPSK if M_bit=1 according to TC 38.211 Subclause 5.1.2 - d_re = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im = (payload&1)==0 ? (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15) : -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); + d = (payload & 1) == 0 ? qpskSymbols[0] : qpskSymbols[3]; } if (pucch_pdu->n_bit == 2) { // using QPSK if M_bit=2 according to TC 38.211 Subclause 5.1.2 - if (((payload&1)==0) && (((payload>>1)&1)==0)) { - d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) - d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((payload&1)==0) && (((payload>>1)&1)==1)) { - d_re = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((payload&1)==1) && (((payload>>1)&1)==0)) { - d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((payload&1)==1) && (((payload>>1)&1)==1)) { - d_re = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } + int tmp = ((payload & 1) << 1) + ((payload >> 1) & 1); + d = qpskSymbols[tmp]; } -// printf("d_re=%d\td_im=%d\n",(int)d_re,(int)d_im); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] sequence modulation: payload=%lx \tde_re=%d \tde_im=%d\n",payload,d_re,d_im); + printf("\t [nr_generate_pucch1] sequence modulation: payload=%lx \tde_re=%d \tde_im=%d\n", payload, d.r, d.i); #endif /* * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 @@ -265,11 +234,11 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, uint32_t re_offset=0; int i=0; #define MAX_SIZE_Z 168 // this value has to be calculated from mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n - int16_t z_re[MAX_SIZE_Z],z_im[MAX_SIZE_Z]; - int16_t z_dmrs_re[MAX_SIZE_Z],z_dmrs_im[MAX_SIZE_Z]; + c16_t z[MAX_SIZE_Z]; + c16_t z_dmrs[MAX_SIZE_Z]; // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] - uint8_t lprime = startingSymbolIndex; + int lprime = startingSymbolIndex; for (int l = 0; l < nrofSymbols; l++) { #ifdef DEBUG_NR_PUCCH_TX @@ -277,7 +246,7 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, l,lprime); #endif // y_n contains the complex value d multiplied by the sequence r_u_v - int16_t y_n_re[12],y_n_im[12]; + c16_t y_n[12]; if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols / 2))) n_hop = 1; // n_hop = 1 for second hop @@ -294,28 +263,27 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, // r_u_v_alpha_delta_re and r_u_v_alpha_delta_im tables containing the sequence y(n) for the PUCCH, when they are multiplied by d(0) // r_u_v_alpha_delta_dmrs_re and r_u_v_alpha_delta_dmrs_im tables containing the sequence for the DM-RS. - int16_t r_u_v_alpha_delta_re[12], r_u_v_alpha_delta_im[12], r_u_v_alpha_delta_dmrs_re[12], r_u_v_alpha_delta_dmrs_im[12]; + c16_t r_u_v_alpha_delta[12], r_u_v_alpha_delta_dmrs[12]; for (int n = 0; n < 12; n++) { - r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) - - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of base sequence shifted by alpha - r_u_v_alpha_delta_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) - + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of base sequence shifted by alpha - r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) - - (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15))); // Re part of DMRS base sequence shifted by alpha - r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Im[u][n])>>15) - + (((int32_t)(round(32767*sin(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15))); // Im part of DMRS base sequence shifted by alpha - r_u_v_alpha_delta_dmrs_re[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_re[n]))>>15); - r_u_v_alpha_delta_dmrs_im[n] = (int16_t)(((int32_t)(amp*r_u_v_alpha_delta_dmrs_im[n]))>>15); -// printf("symbol=%d\tr_u_v_re=%d\tr_u_v_im=%d\n",l,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n]); + c16_t angle = {lround(32767 * cos(alpha * n)), lround(32767 * sin(alpha * n))}; + c16_t table = {table_5_2_2_2_2_Re[u][n], table_5_2_2_2_2_Im[u][n]}; + r_u_v_alpha_delta[n] = c16mulShift(angle, table, 15); + r_u_v_alpha_delta_dmrs[n] = c16mulRealShift(r_u_v_alpha_delta[n], amp, 15); // PUCCH sequence = DM-RS sequence multiplied by d(0) - y_n_re[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_re)>>15) - - (((int32_t)(r_u_v_alpha_delta_im[n])*d_im)>>15))); // Re part of y(n) - y_n_im[n] = (int16_t)(((((int32_t)(r_u_v_alpha_delta_re[n])*d_im)>>15) - + (((int32_t)(r_u_v_alpha_delta_im[n])*d_re)>>15))); // Im part of y(n) -// printf("symbol=%d\tr_u_v_dmrs_re=%d\tr_u_v_dmrs_im=%d\n",l,r_u_v_alpha_delta_dmrs_re[n],r_u_v_alpha_delta_dmrs_im[n]); + y_n[n] = c16mulShift(r_u_v_alpha_delta[n], d, 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) \ty_n[n=%d]=(%d,%d)\n", - u,v,alpha,n,r_u_v_alpha_delta_re[n],r_u_v_alpha_delta_im[n],n,y_n_re[n],y_n_im[n]); + printf( + "\t [nr_generate_pucch1] sequence generation \tu=%d \tv=%d \talpha=%lf \tr_u_v_alpha_delta[n=%d]=(%d,%d) " + "\ty_n[n=%d]=(%d,%d)\n", + u, + v, + alpha, + n, + r_u_v_alpha_delta[n].r, + r_u_v_alpha_delta[n].i, + n, + y_n[n].r, + y_n[n].i); #endif } @@ -333,16 +301,13 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, // the index of the orthogonal cover code is from a set determined as described in [4, TS 38.211] // and is indicated by higher layer parameter PUCCH-F1-time-domain-OCC // In the PUCCH_Config IE, the PUCCH-format1, timeDomainOCC field - uint8_t w_index = timeDomainOCC; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime_PUCCH_1; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime_PUCCH_DMRS_1; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime0_PUCCH_1; - // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) - uint8_t N_SF_mprime0_PUCCH_DMRS_1; - // mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping + const uint8_t w_index = timeDomainOCC; + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime + // and intra-slot hopping enabled/disabled) N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on + // number of PUCCH symbols nrofSymbols, mprime and intra-slot hopping enabled/disabled) N_SF_mprime_PUCCH_1 contains N_SF_mprime + // from table 6.3.2.4.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 and intra-slot hopping enabled/disabled) + // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.4.1.3.1.1-1 (depending on number of PUCCH symbols nrofSymbols, mprime=0 + // and intra-slot hopping enabled/disabled) mprime is 0 if no intra-slot hopping / mprime is {0,1} if intra-slot hopping uint8_t mprime = 0; if (intraSlotFrequencyHopping == 0) { // intra-slot hopping disabled @@ -350,46 +315,74 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping disabled\n", intraSlotFrequencyHopping); #endif - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (PUCCH) - N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled (DM-RS) - N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) - N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols-1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) + int N_SF_mprime_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols - 1]; // only if intra-slot hopping not enabled (PUCCH) + int N_SF_mprime_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols - 1]; // only if intra-slot hopping not enabled (DM-RS) + int N_SF_mprime0_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols - 1]; // only if intra-slot hopping not enabled mprime = 0 (PUCCH) + int N_SF_mprime0_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[nrofSymbols + - 1]; // only if intra-slot hopping not enabled mprime = 0 (DM-RS) #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); #endif for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { + c16_t *zPtr = z + mprime * 12 * N_SF_mprime0_PUCCH_1 + m * 12; + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m]}; for (int n=0; n<12 ; n++) { - z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); + zPtr[n] = c16mulShift(table, y_n[n], 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], - z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + printf( + "\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d " + "+ %d * %d)) = (%d,%d)\n", + mprime, + m, + n, + (mprime * 12 * N_SF_mprime0_PUCCH_1) + (m * 12) + n, + table.r, + y_n[n].r, + table.i, + y_n[n].i, + table.r, + y_n[n].i, + table.i, + y_n[n].r, + zPtr[n].r, + zPtr[n].i); #endif } } for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { + c16_t *zDmrsPtr = z_dmrs + mprime * 12 * N_SF_mprime0_PUCCH_DMRS_1 + m * 12; + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m]}; for (int n=0; n<12 ; n++) { - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); - z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); + zDmrsPtr[n] = c16mulShift(table, r_u_v_alpha_delta_dmrs[n], 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); + printf( + "\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d " + "+ %d * %d)) = (%d,%d)\n", + mprime, + m, + n, + (mprime * 12 * N_SF_mprime0_PUCCH_1) + (m * 12) + n, + table.r, + r_u_v_alpha_delta_dmrs[n].r, + table.i, + r_u_v_alpha_delta_dmrs[n].i, + table.r, + r_u_v_alpha_delta_dmrs[n].i, + table.i, + r_u_v_alpha_delta_dmrs[n].r, + zDmrsPtr[n].r, + zDmrsPtr[n].i); #endif -// printf("gNB entering l=%d\tdmrs_re=%d\tdmrs_im=%d\n",l,z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n],z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n]); - } + } } } @@ -398,10 +391,14 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, intra-slot hopping enabled\n", intraSlotFrequencyHopping); #endif - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) - N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) - N_SF_mprime0_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) - N_SF_mprime0_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + int N_SF_mprime_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + int N_SF_mprime_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) + int N_SF_mprime0_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (PUCCH) + int N_SF_mprime0_PUCCH_DMRS_1 = + table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m0Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 0 (DM-RS) #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] w_index = %d, N_SF_mprime_PUCCH_1 = %d, N_SF_mprime_PUCCH_DMRS_1 = %d, N_SF_mprime0_PUCCH_1 = %d, N_SF_mprime0_PUCCH_DMRS_1 = %d\n", w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); @@ -409,38 +406,23 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, for (mprime = 0; mprime<2; mprime++) { // mprime can get values {0,1} for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { - for (int n=0; n<12 ; n++) { - z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15)); - z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m])*y_n_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m])*y_n_re[n])>>15)); -#ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],y_n_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],y_n_re[n], - z_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - } + c16_t *zPtr = z + mprime * 12 * N_SF_mprime0_PUCCH_1 + m * 12; + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m]}; + for (int n = 0; n < 12; n++) + zPtr[n] = c16mulShift(table, y_n[n], 15); } for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { - for (int n=0; n<12 ; n++) { - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15) - - (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15)); - z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_DMRS_1)+(m*12)+n] = (int16_t)((((int32_t)(table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_im[n])>>15) - + (((int32_t)(table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m])*r_u_v_alpha_delta_dmrs_re[n])>>15)); -#ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] block-wise spread with wi(m) (mprime=%d, m=%d, n=%d) z[%d] = ((%d * %d - %d * %d), (%d * %d + %d * %d)) = (%d,%d)\n", - mprime, m, n, (mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n, - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n], - table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_im[n],table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m],r_u_v_alpha_delta_dmrs_re[n], - z_dmrs_re[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n],z_dmrs_im[(mprime*12*N_SF_mprime0_PUCCH_1)+(m*12)+n]); -#endif - } + c16_t *zDmrsPtr = z_dmrs + mprime * 12 * N_SF_mprime0_PUCCH_DMRS_1 + m * 12; + c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m], + table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m]}; + for (int n = 0; n < 12; n++) + zDmrsPtr[n] = c16mulShift(table, r_u_v_alpha_delta_dmrs[n], 15); } - N_SF_mprime_PUCCH_1 = table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) + N_SF_mprime_PUCCH_1 = + table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols - 1]; // only if intra-slot hopping enabled mprime = 1 (PUCCH) N_SF_mprime_PUCCH_DMRS_1 = table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_m1Hop[nrofSymbols-1]; // only if intra-slot hopping enabled mprime = 1 (DM-RS) } } @@ -476,8 +458,7 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, } if (l%2 == 1) { // mapping PUCCH according to TS38.211 subclause 6.4.1.3.1 - txdataF[0][re_offset].r = z_re[i+n]; - txdataF[0][re_offset].i = z_im[i+n]; + txdataF[0][re_offset] = z[i + n]; #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, i + n, re_offset, @@ -486,8 +467,7 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, } if (l % 2 == 0) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.1 - txdataF[0][re_offset].r = z_dmrs_re[i+n]; - txdataF[0][re_offset].i = z_dmrs_im[i+n]; + txdataF[0][re_offset] = z_dmrs[i + n]; #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch1] mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(x_n(l=%d,n=%d)=(%d,%d))\n", amp, frame_parms->ofdm_symbol_size, frame_parms->N_RB_DL, frame_parms->first_carrier_offset, i+n, re_offset, @@ -504,7 +484,6 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, } } -static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) __attribute__((always_inline)); static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id,uint64_t *B64,uint8_t *btilde) { uint32_t x1 = 0, x2 = 0, s = 0; int i; @@ -632,7 +611,7 @@ static void nr_uci_encoding(uint64_t payload, if (A<=11) { // procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2) // CRC bits are not attached, and coding small block lengths (subclause 5.3.3) - uint64_t b0= encodeSmallBlock((uint16_t*)&payload,A); + uint64_t b0 = encodeSmallBlock(payload, A); // repetition for rate-matching up to 16 PRB b[0] = b0 | (b0<<32); b[1] = b[0]; @@ -658,7 +637,7 @@ static void nr_uci_encoding(uint64_t payload, void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, - const int16_t amp, + const int16_t amp16, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu) { @@ -687,8 +666,8 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, * n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured * n_id = N_ID_cell if higher layer parameter not configured */ - uint8_t *btilde = calloc(M_bit, sizeof(uint8_t)); - + uint8_t btilde[M_bit]; + memset(btilde, 0, sizeof(btilde)); // rnti is given by the C-RNTI uint16_t rnti=pucch_pdu->rnti; #ifdef DEBUG_NR_PUCCH_TX @@ -717,41 +696,31 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, */ //#define ONE_OVER_SQRT2_S 23171 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) // complex-valued symbol d(0) - int16_t *d_re = calloc(M_bit, sizeof(int16_t)); - int16_t *d_im = calloc(M_bit, sizeof(int16_t)); + c16_t d[M_bit]; + memset(d, 0, sizeof(d)); uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; - + const int32_t amp = amp16; + const int16_t baseVal = (amp * ONE_OVER_SQRT2) >> 15; + c16_t qpskSymbols[4] = {{baseVal, baseVal}, {baseVal, -baseVal}, {-baseVal, baseVal}, {-baseVal, -baseVal}}; for (int i=0; i < m_symbol; i++) { // QPSK modulation subclause 5.1.3 - if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) { - d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) { - d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) { - d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) { - d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } + int tmp = (btilde[2 * i] & 1) * 2 + (btilde[(2 * i) + 1] & 1); + d[i] = qpskSymbols[tmp]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch2] modulation of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]); + printf("\t [nr_generate_pucch2] modulation of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n", + (btilde[2 * i] & 1), + (btilde[(2 * i) + 1] & 1), + m_symbol, + i, + d[i].r, + d[i].i); #endif } /* * Implementing TS 38.211 Subclause 6.3.2.5.3 Mapping to physical resources */ - //int32_t *txptr; - uint32_t re_offset=0; + // int32_t *txptr; uint32_t x1 = 0, x2 = 0, s = 0; int i=0; int m=0; @@ -773,24 +742,22 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, m = 0; for (int rb=0; rbprb_size; rb++) { //startingPRB = startingPRB + rb; - if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; - } - - if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))); - } - - if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; - } - - if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6; - } - - if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + const bool nb_rb_is_even = frame_parms->N_RB_DL & 1; + const int halfRBs = frame_parms->N_RB_DL / 2; + const int baseRB = rb + startingPRB; + int re_offset = (l + startingSymbolIndex) * frame_parms->ofdm_symbol_size + 12 * baseRB; + if (nb_rb_is_even) { + if (baseRB < halfRBs) // if number RBs in bandwidth is even and current PRB is lower band + re_offset += frame_parms->first_carrier_offset; + else + re_offset -= halfRBs; + } else { + if (baseRB < halfRBs) // if number RBs in bandwidth is odd and current PRB is lower band + re_offset += frame_parms->first_carrier_offset; + else if (baseRB > halfRBs) // if number RBs in bandwidth is odd and current PRB is upper band + re_offset += -halfRBs + 6; + else + re_offset += frame_parms->first_carrier_offset; } //txptr = &txdataF[0][re_offset]; @@ -800,14 +767,13 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, #endif for (int n=0; n<12; n++) { - if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { + if (n == 6 && baseRB == halfRBs && !nb_rb_is_even) { // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); } if (n%3 != 1) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 - ((int16_t *)&txdataF[0][re_offset])[0] = d_re[i+k]; - ((int16_t *)&txdataF[0][re_offset])[1] = d_im[i+k]; + txdataF[0][re_offset] = d[i + k]; #ifdef DEBUG_NR_PUCCH_TX printf( "\t [nr_generate_pucch2] (n=%d,i=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d " @@ -822,15 +788,15 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, re_offset, l, n, - ((int16_t *)&txdataF[0][re_offset])[0], - ((int16_t *)&txdataF[0][re_offset])[1]); + txdataF[0][re_offset].r, + txdataF[0][re_offset].i); #endif k++; } if (n%3 == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 - ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>(2*m))&1)))))>>15); - ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((int32_t)(amp*ONE_OVER_SQRT2*(1-(2*((uint8_t)((s>>((2*m)+1))&1)))))>>15); + txdataF[0][re_offset].r = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m)) & 1))))); + txdataF[0][re_offset].i = (int16_t)(baseVal * (1 - (2 * ((uint8_t)((s >> (2 * m + 1)) & 1))))); m++; #ifdef DEBUG_NR_PUCCH_TX printf( @@ -846,8 +812,8 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, re_offset, l, n, - ((int16_t *)&txdataF[0][re_offset])[0], - ((int16_t *)&txdataF[0][re_offset])[1]); + txdataF[0][re_offset].r, + txdataF[0][re_offset].i); kk++; #endif } @@ -863,15 +829,12 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, } } } - free(d_re); - free(d_im); - free(btilde); } //#if 0 void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, - const int16_t amp, + const int16_t amp16, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu) { @@ -902,7 +865,7 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, printf("\t [nr_generate_pucch3_4] intraSlotFrequencyHopping=%d \n",intraSlotFrequencyHopping); #endif } - + const int32_t amp = amp16; uint8_t nrofSymbols = pucch_pdu->nr_of_symbols; uint16_t nrofPRB = pucch_pdu->prb_size; uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start; @@ -912,11 +875,13 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, pucch_pdu->n_bit, pucch_pdu->format_type, is_pi_over_2_bpsk_enabled, - nrofSymbols,nrofPRB, + nrofSymbols, + nrofPRB, n_SF_PUCCH_s, intraSlotFrequencyHopping, add_dmrs, - &b[0],&M_bit); + b, + &M_bit); /* * Implementing TS 38.211 * Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4) @@ -929,7 +894,7 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, * n_id = {0,1,...,1023} equals the higher-layer parameter Data-scrambling-Identity if configured * n_id = N_ID_cell if higher layer parameter not configured */ - uint8_t *btilde = malloc(sizeof(int8_t)*M_bit); + uint8_t btilde[M_bit]; // rnti is given by the C-RNTI uint16_t rnti=pucch_pdu->rnti, n_id=0; #ifdef DEBUG_NR_PUCCH_TX @@ -946,35 +911,24 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, * Subclause 5.1.3 QPSK */ // complex-valued symbol d(0) - int16_t *d_re = malloc(sizeof(int16_t)*M_bit); - int16_t *d_im = malloc(sizeof(int16_t)*M_bit); + c16_t d[M_bit]; uint16_t m_symbol = (M_bit%2==0) ? M_bit/2 : floor(M_bit/2)+1; + const int16_t baseVal = (amp * ONE_OVER_SQRT2) >> 15; if (is_pi_over_2_bpsk_enabled == 0) { // using QPSK if PUCCH format 3,4 and pi/2-BPSK is not configured, according to subclause 6.3.2.6.2 + c16_t qpskSymbols[4] = {{baseVal, baseVal}, {-baseVal, baseVal}, {-baseVal, baseVal}, {-baseVal, -baseVal}}; for (int i=0; i < m_symbol; i++) { // QPSK modulation subclause 5.1.3 - if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==0)) { - d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[2*i]&1)==0) && ((btilde[(2*i)+1]&1)==1)) { - d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==0)) { - d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[2*i]&1)==1) && ((btilde[(2*i)+1]&1)==1)) { - d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - + int tmp = (btilde[2 * i] & 1) * 2 + (btilde[(2 * i) + 1] & 1); + d[i] = qpskSymbols[tmp]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] modulation QPSK of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[2*i]&1),(btilde[(2*i)+1]&1),m_symbol,i,d_re[i],d_im[i]); + printf("\t [nr_generate_pucch3_4] modulation QPSK of bit pair btilde(%d,%d), m_symbol=%d, d(%d)=(%d,%d)\n", + (btilde[2 * i] & 1), + (btilde[(2 * i) + 1] & 1), + m_symbol, + i, + d[i].r, + d[i].i); #endif } } @@ -982,30 +936,17 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, if (is_pi_over_2_bpsk_enabled == 1) { // using PI/2-BPSK if PUCCH format 3,4 and pi/2-BPSK is configured, according to subclause 6.3.2.6.2 m_symbol = M_bit; - + c16_t qpskSymbols[4] = {{baseVal, baseVal}, {-baseVal, baseVal}, {-baseVal, -baseVal}, {baseVal, -baseVal}}; for (int i=0; i>15); - d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[i]&1)==0) && (i%2 == 1)) { - d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[i]&1)==1) && (i%2 == 0)) { - d_re[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - - if (((btilde[i]&1)==1) && (i%2 == 1)) { - d_re[i] = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - d_im[i] = -(int16_t)(((int32_t)amp*ONE_OVER_SQRT2)>>15); - } - + int tmp = (btilde[i] & 1) * 2 + (i & 1); + d[i] = qpskSymbols[tmp]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] modulation PI/2-BPSK of bit btilde(%d), m_symbol=%d, d(%d)=(%d,%d)\n",(btilde[i]&1),m_symbol,i,d_re[i],d_im[i]); + printf("\t [nr_generate_pucch3_4] modulation PI/2-BPSK of bit btilde(%d), m_symbol=%d, d(%d)=(%d,%d)\n", + (btilde[i] & 1), + m_symbol, + i, + d[i].r, + d[i].i); #endif } } @@ -1020,33 +961,27 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, // number of symbols, provided by higher layers parameters PUCCH-F0-F2-number-of-symbols or PUCCH-F1-F3-F4-number-of-symbols // uint8_t nrofSymbols; // complex-valued symbol d(0) - int16_t *y_n_re = malloc(sizeof(int16_t)*4*M_bit); // 4 is the maximum number n_SF_PUCCH_s, so is the maximunm size of y_n - int16_t *y_n_im = malloc(sizeof(int16_t)*4*M_bit); + c16_t y_n[4 * M_bit]; // 4 is the maximum number n_SF_PUCCH_s, so is the maximunm size of y_n // Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1) // k={0,..11} n={0,1,2,3} // parameter PUCCH-F4-preDFT-OCC-index set of {0,1,2,3} -> n - uint16_t table_6_3_2_6_3_1_Wn_Re[2][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1} - }; + const uint16_t table_6_3_2_6_3_1_Wn_Re[2][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1}}; // Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 2 (Table 6.3.2.6.3-1) // k={0,..11} n={0,1} - uint16_t table_6_3_2_6_3_1_Wn_Im[2][12] = {{0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0,0} - }; + const uint16_t table_6_3_2_6_3_1_Wn_Im[2][12] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; // Re part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2) // k={0,..11} n={0,1,2.3} - uint16_t table_6_3_2_6_3_2_Wn_Re[4][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0}, - {1, 1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1}, - {1, 1, 1, 0, 0, 0,-1,-1,-1, 0, 0, 0} - }; + const uint16_t table_6_3_2_6_3_2_Wn_Re[4][12] = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 0, 0, 0, -1, -1, -1, 0, 0, 0}, + {1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1}, + {1, 1, 1, 0, 0, 0, -1, -1, -1, 0, 0, 0}}; // Im part orthogonal sequences w_n(k) for PUCCH format 4 when N_SF_PUCCH4 = 4 (Table 6.3.2.6.3-2) // k={0,..11} n={0,1,2,3} - uint16_t table_6_3_2_6_3_2_Wn_Im[4][12] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0,-1,-1,-1, 0, 0, 0, 1, 1, 1}, - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 1, 1, 1, 0, 0, 0,-1,-1,-1} - }; + const uint16_t table_6_3_2_6_3_2_Wn_Im[4][12] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, -1, -1, -1, 0, 0, 0, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 0, 0, 0, -1, -1, -1}}; uint8_t occ_Index = pucch_pdu->pre_dft_occ_idx; // higher layer parameter occ-Index @@ -1054,12 +989,17 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, if (pucch_pdu->format_type == 3) { // no block-wise spreading for format 3 for (int l=0; l < floor(m_symbol/(12*nrofPRB)); l++) { - for (int k=0; k < (12*nrofPRB); k++) { - y_n_re[l*(12*nrofPRB)+k] = d_re[l*(12*nrofPRB)+k]; - y_n_im[l*(12*nrofPRB)+k] = d_im[l*(12*nrofPRB)+k]; + for (int k = l * 12 * nrofPRB; k < (l + 1) * 12 * nrofPRB; k++) { + y_n[k] = d[k]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] block-wise spreading for format 3 (no block-wise spreading): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", - l,k,l*(12*nrofPRB)+k,d_re[l*(12*nrofPRB)+k],d_im[l*(12*nrofPRB)+k]); + printf( + "\t [nr_generate_pucch3_4] block-wise spreading for format 3 (no block-wise spreading): (l,k)=(%d,%d)\ty_n(%d) = " + "\t(d_re=%d, d_im=%d)\n", + l, + k, + k, + d[k].r, + d[k].i); #endif } } @@ -1070,29 +1010,37 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, for (int l=0; l < floor((n_SF_PUCCH_s*m_symbol)/(12*nrofPRB)); l++) { for (int k=0; k < (12*nrofPRB); k++) { + c16_t dVal = d[l * (12 * nrofPRB / n_SF_PUCCH_s) + k % (12 * nrofPRB / n_SF_PUCCH_s)]; + c16_t *yPtr = y_n + l * 12 * nrofPRB + k; if (n_SF_PUCCH_s == 2) { - y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Re[occ_Index][k]) - - ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Im[occ_Index][k])); - y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Re[occ_Index][k]) - + ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_1_Wn_Im[occ_Index][k])); + c16_t table = {table_6_3_2_6_3_1_Wn_Re[occ_Index][k], table_6_3_2_6_3_1_Wn_Im[occ_Index][k]}; + *yPtr = c16mulShift(table, dVal, 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 2) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", - occ_Index,l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]); - // printf("\t\t d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] = %d\n",d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)]); - // printf("\t\t d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] = %d\n",d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)]); - // printf("\t\t table_6_3_2_6_3_1_Wn_Re[%d][%d] = %d\n",occ_Index,k,table_6_3_2_6_3_1_Wn_Re[occ_Index][k]); - // printf("\t\t table_6_3_2_6_3_1_Wn_Im[%d][%d] = %d\n",occ_Index,k,table_6_3_2_6_3_1_Wn_Im[occ_Index][k]); + printf( + "\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 2) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) " + " = \t(d_re=%d, d_im=%d)\n", + occ_Index, + l, + k, + l * (12 * nrofPRB) + k, + yPtr->r, + yPtr->i); #endif } if (n_SF_PUCCH_s == 4) { - y_n_re[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Re[occ_Index][k]) - - ((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Im[occ_Index][k])); - y_n_im[l*(12*nrofPRB)+k] = (uint16_t)(((uint32_t)d_im[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Re[occ_Index][k]) - + ((uint32_t)d_re[l*(12*nrofPRB/n_SF_PUCCH_s)+k%(12*nrofPRB/n_SF_PUCCH_s)] * table_6_3_2_6_3_2_Wn_Im[occ_Index][k])); + c16_t table = {table_6_3_2_6_3_2_Wn_Re[occ_Index][k], table_6_3_2_6_3_2_Wn_Im[occ_Index][k]}; + *yPtr = c16mulShift(table, dVal, 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 4) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) = \t(d_re=%d, d_im=%d)\n", - occ_Index,l,k,l*(12*nrofPRB)+k,y_n_re[l*(12*nrofPRB)+k],y_n_im[l*(12*nrofPRB)+k]); + printf( + "\t [nr_generate_pucch3_4] block-wise spreading for format 4 (n_SF_PUCCH_s 4) (occ_Index=%d): (l,k)=(%d,%d)\ty_n(%d) " + " = \t(d_re=%d, d_im=%d)\n", + occ_Index, + l, + k, + l * 12 * nrofPRB + k, + yPtr->r, + yPtr->i); #endif } } @@ -1102,41 +1050,28 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, /* * Implementing Transform pre-coding subclause 6.3.2.6.4 */ - int16_t *z_re = malloc(sizeof(int16_t)*4*M_bit); // 4 is the maximum number n_SF_PUCCH_s - int16_t *z_im = malloc(sizeof(int16_t)*4*M_bit); + c16_t z[4 * M_bit]; // 4 is the maximum number n_SF_PUCCH_s #define M_PI 3.14159265358979323846 // pi - - //int16_t inv_sqrt_nrofPRBs = (int16_t)round(32767/sqrt(12*nrofPRB)); + const int64_t base = round(32767 / sqrt(12 * nrofPRB)); for (int l=0; l>15) - // + (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); - // z_im_tmp[m] = (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) - // - (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); - z_re[l*(12*nrofPRB)+k] = z_re[l*(12*nrofPRB)+k] - + (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) - + (((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); - z_im[l*(12*nrofPRB)+k] = z_im[l*(12*nrofPRB)+k] - + (int16_t)(((int32_t)round(32767/sqrt(12*nrofPRB))*(int16_t)((((int32_t)y_n_im[l*(12*nrofPRB)+m] * (int16_t)round(32767 * cos(2*M_PI*m*k/(12*nrofPRB))))>>15) - - (((int32_t)y_n_re[l*(12*nrofPRB)+m] * (int16_t)round(32767 * sin(2*M_PI*m*k/(12*nrofPRB))))>>15)))>>15); -#ifdef DEBUG_NR_PUCCH_TX - // printf("\t\t z_re_tmp[%d] = %d\n",m,z_re_tmp[m]); - // printf("\t\t z_im_tmp[%d] = %d\n",m,z_im_tmp[m]); - // printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k,m)=(%d,%d,%d)\tz(%d) = \t(%d, %d)\n", - // l,k,m,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]); -#endif + c16_t *yPtr = y_n + l * 12 * nrofPRB; + c16_t *zPtr = z + l * 12 * nrofPRB + k; + *zPtr = (c16_t){0}; + for (int m = l * 12 * nrofPRB; m < (l + 1) * 12 * nrofPRB; m++) { + const c16_t angle = {lround(32767 * cos(2 * M_PI * m * k / (12 * nrofPRB))), + lround(32767 * sin(2 * M_PI * m * k / (12 * nrofPRB)))}; + c16_t tmp = c16mulShift(yPtr[m], angle, 15); + csum(*zPtr, *zPtr, c16mulRealShift(tmp, base, 15)); } #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch3_4] transform precoding for formats 3 and 4: (l,k)=(%d,%d)\tz(%d) = \t(%d, %d)\n", - l,k,l*(12*nrofPRB)+k,z_re[l*(12*nrofPRB)+k],z_im[l*(12*nrofPRB)+k]); + l, + k, + l * (12 * nrofPRB) + k, + zPtr->r, + zPtr->i); #endif } } @@ -1157,10 +1092,11 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, // lprime is the index of the OFDM symbol in the slot that corresponds to the first OFDM symbol of the PUCCH transmission in the slot given by [5, TS 38.213] //uint8_t lprime = startingSymbolIndex; // m0 is the cyclic shift index calculated depending on the Orthogonal sequence index n, according to table 6.4.1.3.3.1-1 from TS 38.211 subclause 6.4.1.3.3.1 - uint8_t m0; + uint8_t m0 = 0; uint8_t mcs=0; - if (pucch_pdu->format_type == 3) m0 = 0; + if (pucch_pdu->format_type == 3) + m0 = 0; if (pucch_pdu->format_type == 4) { if (n_SF_PUCCH_s == 2) { @@ -1173,17 +1109,9 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, } double alpha; - uint8_t N_ZC = 12*nrofPRB; - int16_t *r_u_v_base_re = malloc(sizeof(int16_t)*12*nrofPRB); - int16_t *r_u_v_base_im = malloc(sizeof(int16_t)*12*nrofPRB); - //int16_t *r_u_v_alpha_delta_re = malloc(sizeof(int16_t)*12*nrofPRB); - //int16_t *r_u_v_alpha_delta_im = malloc(sizeof(int16_t)*12*nrofPRB); - // Next we proceed to mapping to physical resources according to TS 38.211, subclause 6.3.2.6.5 dor PUCCH formats 3 and 4 and subclause 6.4.1.3.3.2 for DM-RS - //int32_t *txptr; - uint32_t re_offset=0; - //uint32_t x1, x2, s=0; - // intraSlotFrequencyHopping - // uint8_t intraSlotFrequencyHopping = 0; + int N_ZC = 12 * nrofPRB; + c16_t r_u_v_base[N_ZC]; + uint32_t re_offset = 0; uint8_t table_6_4_1_3_3_2_1_dmrs_positions[11][14] = { {(intraSlotFrequencyHopping==0)?0:1,(intraSlotFrequencyHopping==0)?1:0,(intraSlotFrequencyHopping==0)?0:1,0,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 4 {1,0,0,1,0,0,0,0,0,0,0,0,0,0}, // PUCCH length = 5 @@ -1197,10 +1125,11 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, {0,(add_dmrs==0?0:1),(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0}, // PUCCH length = 13 {0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0,0,(add_dmrs==0?0:1),0,(add_dmrs==0?1:0),0,(add_dmrs==0?0:1),0} // PUCCH length = 14 }; - uint16_t k=0; + int k = 0; for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop + if ((intraSlotFrequencyHopping == 1) && (l >= (int)floor(nrofSymbols / 2))) + n_hop = 1; // n_hop = 1 for second hop pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1); nr_group_sequence_hopping(pucch_GroupHopping,pucch_pdu->hopping_id,n_hop,nr_slot_tx,&u,&v); // calculating u and v value @@ -1217,33 +1146,43 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, q = ((uint8_t)floor(2*q_base)%2 == 0 ? q+v : q-v); for (int n=0; n<(12*nrofPRB); n++) { - r_u_v_base_re[n] = (int16_t)(((int32_t)amp*(int16_t)(32767*cos(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); - r_u_v_base_im[n] = -(int16_t)(((int32_t)amp*(int16_t)(32767*sin(M_PI*q*(n%N_ZC)*((n%N_ZC)+1)/N_ZC)))>>15); + const double tmp = M_PI * q * (n % N_ZC) * ((n % N_ZC) + 1) / N_ZC; + r_u_v_base[n].r = lround(amp * 32767 * cos(tmp)) >> 15; + r_u_v_base[n].i = -lround(amp * 32767 * sin(tmp)) >> 15; #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d >= 3: r_u_v_base[n=%d]=(%d,%d)\n", - nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + nrofPRB, + n, + r_u_v_base[n].r, + r_u_v_base[n].i); #endif } } if (nrofPRB == 2) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-4) applies - for (int n=0; n<(12*nrofPRB); n++) { - r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Re[u][n])>>15); - r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_4_Im[u][n])>>15); + for (int n = 0; n < 12 * nrofPRB; n++) { + c16_t table = {table_5_2_2_2_4_Re[u][n], table_5_2_2_2_4_Im[u][n]}; + r_u_v_base[n] = c16mulRealShift(table, amp, 15); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 2: r_u_v_base[n=%d]=(%d,%d)\n", - nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + nrofPRB, + n, + r_u_v_base[n].r, + r_u_v_base[n].i); #endif } } if (nrofPRB == 1) { // TS 38.211 subclause 5.2.2.2 (Base sequences of length less than 36 using table 5.2.2.2-2) applies - for (int n=0; n<(12*nrofPRB); n++) { - r_u_v_base_re[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Re[u][n])>>15); - r_u_v_base_im[n] = (int16_t)(((int32_t)amp*table_5_2_2_2_2_Im[u][n])>>15); + for (int n = 0; n < 12 * nrofPRB; n++) { + c16_t table = {table_5_2_2_2_2_Re[u][n], table_5_2_2_2_2_Im[u][n]}; + r_u_v_base[n] = c16mulRealShift(table, amp, 15); #ifdef DEBUG_NR_PUCCH_TX printf("\t [nr_generate_pucch3_4] generation DM-RS base sequence when nrofPRB=%d == 1: r_u_v_base[n=%d]=(%d,%d)\n", - nrofPRB,n,r_u_v_base_re[n],r_u_v_base_im[n]); + nrofPRB, + n, + r_u_v_base[n].r, + r_u_v_base[n].i); #endif } } @@ -1253,76 +1192,102 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, alpha = nr_cyclic_shift_hopping(pucch_pdu->hopping_id,m0,mcs,l,startingSymbolIndex,nr_slot_tx); for (int rb=0; rbN_RB_DL & 1; + const int halfRBs = frame_parms->N_RB_DL / 2; + const int baseRB = rb + startingPRB; if ((intraSlotFrequencyHopping == 1) && (lsecond_hop_prb; } - + re_offset = ((l + startingSymbolIndex) * frame_parms->ofdm_symbol_size); //startingPRB = startingPRB + rb; - if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + if (nb_rb_is_even) { + if (baseRB < halfRBs) { // if number RBs in bandwidth is even and current PRB is lower band + re_offset += 12 * baseRB + frame_parms->first_carrier_offset; #ifdef DEBUG_NR_PUCCH_TX printf("1 "); #endif - } + } - if (((rb+startingPRB) >= (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // if number RBs in bandwidth is even and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))); + else { // if number RBs in bandwidth is even and current PRB is upper band + re_offset += 12 * (baseRB - halfRBs); #ifdef DEBUG_NR_PUCCH_TX printf("2 "); #endif - } - - if (((rb+startingPRB) < (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is lower band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + } + } else { + if (baseRB < halfRBs) { // if number RBs in bandwidth is odd and current PRB is lower band + re_offset += 12 * baseRB + frame_parms->first_carrier_offset; #ifdef DEBUG_NR_PUCCH_TX printf("3 "); #endif - } - - if (((rb+startingPRB) > (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB is upper band - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*((rb+startingPRB)-(frame_parms->N_RB_DL>>1))) + 6; + } else if (baseRB > halfRBs) { // if number RBs in bandwidth is odd and current PRB is upper band + re_offset += 12 * (baseRB - halfRBs) + 6; #ifdef DEBUG_NR_PUCCH_TX printf("4 "); #endif - } - - if (((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { // if number RBs in bandwidth is odd and current PRB contains DC - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size) + (12*(rb+startingPRB)) + frame_parms->first_carrier_offset; + } else { // if number RBs in bandwidth is odd and current PRB contains DC + re_offset += 12 * baseRB + frame_parms->first_carrier_offset; #ifdef DEBUG_NR_PUCCH_TX printf("5 "); #endif + } } #ifdef DEBUG_NR_PUCCH_TX - printf("re_offset=%u,(rb+startingPRB)=%d\n",re_offset,(rb+startingPRB)); + printf("re_offset=%u,baseRB=%d\n", re_offset, baseRB); #endif //txptr = &txdataF[0][re_offset]; for (int n=0; n<12; n++) { - if ((n==6) && ((rb+startingPRB) == (frame_parms->N_RB_DL>>1)) && ((frame_parms->N_RB_DL & 1) == 1)) { - // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second half PRB) - re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); + if ((n == 6) && baseRB == halfRBs && !nb_rb_is_even) { + // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second + // half PRB) + re_offset = ((l + startingSymbolIndex) * frame_parms->ofdm_symbol_size); } if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 0) { // mapping PUCCH according to TS38.211 subclause 6.3.2.5.3 - ((int16_t *)&txdataF[0][re_offset])[0] = z_re[n+k]; - ((int16_t *)&txdataF[0][re_offset])[1] = z_im[n+k]; + txdataF[0][re_offset] = z[n + k]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(z(l=%d,n=%d)=(%d,%d))\n", - l,rb,n,k,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+k,re_offset, - l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + printf( + "\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,k=%d) mapping PUCCH to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d " + "\tfirst_carrier_offset=%d \tz_pucch[%d]=txptr(%u)=(z(l=%d,n=%d)=(%d,%d))\n", + l, + rb, + n, + k, + amp, + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + frame_parms->first_carrier_offset, + n + k, + re_offset, + l, + n, + txdataF[0][re_offset].r, + txdataF[0][re_offset].i); #endif } - if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) { // mapping DM-RS signal according to TS38.211 subclause 6.4.1.3.2 - ((int16_t *)&txdataF[0][re_offset])[0] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15) - - (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15)); - ((int16_t *)&txdataF[0][re_offset])[1] = (int16_t)((((int32_t)(32767*cos(alpha*((n+j)%N_ZC)))*r_u_v_base_im[n+j])>>15) - + (((int32_t)(32767*sin(alpha*((n+j)%N_ZC)))*r_u_v_base_re[n+j])>>15)); + const c16_t angle = {lround(32767 * cos(alpha * ((n + j) % N_ZC))), lround(32767 * sin(alpha * ((n + j) % N_ZC)))}; + txdataF[0][re_offset] = c16mulShift(angle, r_u_v_base[n + j], 15); #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d \tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(r_u_v(l=%d,n=%d)=(%d,%d))\n", - l,rb,n,j,amp,frame_parms->ofdm_symbol_size,frame_parms->N_RB_DL,frame_parms->first_carrier_offset,n+j,re_offset, - l,n,((int16_t *)&txdataF[0][re_offset])[0],((int16_t *)&txdataF[0][re_offset])[1]); + printf( + "\t [nr_generate_pucch3_4] (l=%d,rb=%d,n=%d,j=%d) mapping DM-RS to RE \t amp=%d \tofdm_symbol_size=%d \tN_RB_DL=%d " + "\tfirst_carrier_offset=%d \tz_dm-rs[%d]=txptr(%u)=(r_u_v(l=%d,n=%d)=(%d,%d))\n", + l, + rb, + n, + j, + amp, + frame_parms->ofdm_symbol_size, + frame_parms->N_RB_DL, + frame_parms->first_carrier_offset, + n + j, + re_offset, + l, + n, + txdataF[0][re_offset].r, + txdataF[0][re_offset].i); #endif } @@ -1334,7 +1299,4 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, if (table_6_4_1_3_3_2_1_dmrs_positions[nrofSymbols-4][l] == 1) j+=12; } } - free(z_re); - free(z_im); - free(btilde); } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index e98b20b277..cd99eb497e 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -215,7 +215,8 @@ extern "C" { { return (c16_t){.r = (int16_t)((a.r * b) >> Shift), .i = (int16_t)((a.i * b) >> Shift)}; } - __attribute__((always_inline)) inline c16_t c16divShift(const c16_t a, const c16_t b, const int Shift) { + __attribute__((always_inline)) inline c16_t c16MulConjShift(const c16_t a, const c16_t b, const int Shift) + { return (c16_t) { .r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift), .i = (int16_t)((a.r * b.i - a.i * b.r) >> Shift) diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 3f99a22b71..fddb484727 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -83,64 +83,7 @@ binary_search_float_nr( return first; } -/* -void nr_generate_pucch0(int32_t **txdataF, - NR_DL_FRAME_PARMS *frame_parms, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - int16_t amp, - int nr_slot_tx, - uint8_t mcs, - uint8_t nrofSymbols, - uint8_t startingSymbolIndex, - uint16_t startingPRB); -void nr_generate_pucch1(int32_t **txdataF, - NR_DL_FRAME_PARMS *frame_parms, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - uint64_t payload, - int16_t amp, - int nr_slot_tx, - uint8_t nrofSymbols, - uint8_t startingSymbolIndex, - uint16_t startingPRB, - uint16_t startingPRB_intraSlotHopping, - uint8_t timeDomainOCC, - uint8_t nr_bit); - -void nr_generate_pucch2(int32_t **txdataF, - NR_DL_FRAME_PARMS *frame_parms, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - uint64_t payload, - int16_t amp, - int nr_slot_tx, - uint8_t nrofSymbols, - uint8_t startingSymbolIndex, - uint8_t nrofPRB, - uint16_t startingPRB, - uint8_t nr_bit); - -void nr_generate_pucch3_4(int32_t **txdataF, - NR_DL_FRAME_PARMS *frame_parms, - pucch_format_nr_t fmt, - PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, - uint64_t payload, - int16_t amp, - int nr_slot_tx, - uint8_t nrofSymbols, - uint8_t startingSymbolIndex, - uint8_t nrofPRB, - uint16_t startingPRB, - uint8_t nr_bit, - uint8_t occ_length_format4, - uint8_t occ_index_format4); -*/ -/**************** variables **************************************/ - - -/**************** functions **************************************/ - -//extern uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id); -//extern uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id); /******************************************************************* * * NAME : pucch_procedures_ue_nr