From 18919576b71fa507072d1ed52ec2813a207305e0 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 4 Jan 2024 10:21:15 +0100 Subject: [PATCH] rework PUCCH codec with c16_t type, rewrite large parts of functions to make readable code. Not fixed parts that are using SIMD. No change, the code is still same block by block (variable visibility narrowed, declaration can be shifted) --- .../PHY/CODING/TESTBENCH/smallblocktest.c | 232 ++-- .../CODING/nrSmallBlock/encodeSmallBlock.c | 13 +- .../CODING/nrSmallBlock/nr_small_block_defs.h | 2 +- .../NR_TRANSPORT/nr_transport_common_proto.h | 2 +- .../PHY/NR_TRANSPORT/nr_uci_tools_common.c | 13 +- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 1041 ++++++++--------- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 784 ++++++------- openair1/PHY/TOOLS/tools_defs.h | 3 +- openair1/SCHED_NR_UE/pucch_uci_ue_nr.c | 57 - 9 files changed, 975 insertions(+), 1172 deletions(-) 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