Reformat pucch_rx.c

This commit is contained in:
Robert Schmidt
2026-03-25 14:29:31 +01:00
committed by francescomani
parent ec7ad3b87c
commit 2cb96ea534
+262 -240
View File
@@ -29,7 +29,7 @@
* \note * \note
* \warning * \warning
*/ */
#include<stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <unistd.h> #include <unistd.h>
@@ -93,64 +93,63 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t
AssertFatal(found, "PUCCH list is full\n"); AssertFatal(found, "PUCCH list is full\n");
} }
int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB, nfapi_nr_pucch_pdu_t *pucch_pdu)
int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB,nfapi_nr_pucch_pdu_t* pucch_pdu) { {
int i = 0;
int i=0;
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("getting index for LUT with %d entries, Nid %d\n",gNB->pucch0_lut.nb_id, pucch_pdu->hopping_id); printf("getting index for LUT with %d entries, Nid %d\n", gNB->pucch0_lut.nb_id, pucch_pdu->hopping_id);
#endif #endif
for (i=0;i<gNB->pucch0_lut.nb_id;i++) { for (i = 0; i < gNB->pucch0_lut.nb_id; i++) {
if (gNB->pucch0_lut.Nid[i] == pucch_pdu->hopping_id) break; if (gNB->pucch0_lut.Nid[i] == pucch_pdu->hopping_id)
break;
} }
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("found index %d\n",i); printf("found index %d\n", i);
#endif #endif
if (i<gNB->pucch0_lut.nb_id) return(i); if (i < gNB->pucch0_lut.nb_id)
return (i);
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("Initializing PUCCH0 LUT index %i with Nid %d\n",i, pucch_pdu->hopping_id); printf("Initializing PUCCH0 LUT index %i with Nid %d\n", i, pucch_pdu->hopping_id);
#endif #endif
// initialize // initialize
gNB->pucch0_lut.Nid[gNB->pucch0_lut.nb_id]=pucch_pdu->hopping_id; gNB->pucch0_lut.Nid[gNB->pucch0_lut.nb_id] = pucch_pdu->hopping_id;
for (int slot=0;slot<10<<pucch_pdu->subcarrier_spacing;slot++) for (int slot = 0; slot < 10 << pucch_pdu->subcarrier_spacing; slot++)
for (int symbol=0;symbol<14;symbol++) for (int symbol = 0; symbol < 14; symbol++)
gNB->pucch0_lut.lut[gNB->pucch0_lut.nb_id][slot][symbol] = (int)floor(nr_cyclic_shift_hopping(pucch_pdu->hopping_id,0,0,symbol,0,slot)/0.5235987756); gNB->pucch0_lut.lut[gNB->pucch0_lut.nb_id][slot][symbol] =
(int)floor(nr_cyclic_shift_hopping(pucch_pdu->hopping_id, 0, 0, symbol, 0, slot) / 0.5235987756);
gNB->pucch0_lut.nb_id++; gNB->pucch0_lut.nb_id++;
return(gNB->pucch0_lut.nb_id-1); return (gNB->pucch0_lut.nb_id - 1);
} }
static const int16_t idft12_re[12][12] = {
{23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170,23170},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170,23170,-23170},
{23170,-20066,11585,0,-11585,20066,-23170,20066,-11585,0,11585,-20066},
{23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585,23170,-11585,-11585},
{23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170,0},
{23170,11585,-11585,-23170,-11585,11585,23170,11585,-11585,-23170,-11585,11585},
{23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585,0,11585,20066}
};
static const int16_t idft12_im[12][12] = { static const int16_t idft12_re[12][12] = {
{0,0,0,0,0,0,0,0,0,0,0,0}, {23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170},
{0,11585,20066,23170,20066,11585,0,-11585,-20066,-23170,-20066,-11585}, {23170, 20066, 11585, 0, -11585, -20066, -23170, -20066, -11585, 0, 11585, 20066},
{0,20066,20066,0,-20066,-20066,0,20066,20066,0,-20066,-20066}, {23170, 11585, -11585, -23170, -11585, 11585, 23170, 11585, -11585, -23170, -11585, 11585},
{0,23170,0,-23170,0,23170,0,-23170,0,23170,0,-23170}, {23170, 0, -23170, 0, 23170, 0, -23170, 0, 23170, 0, -23170, 0},
{0,20066,-20066,0,20066,-20066,0,20066,-20066,0,20066,-20066}, {23170, -11585, -11585, 23170, -11585, -11585, 23170, -11585, -11585, 23170, -11585, -11585},
{0,11585,-20066,23170,-20066,11585,0,-11585,20066,-23170,20066,-11585}, {23170, -20066, 11585, 0, -11585, 20066, -23170, 20066, -11585, 0, 11585, -20066},
{0,0,0,0,0,0,0,0,0,0,0,0}, {23170, -23170, 23170, -23170, 23170, -23170, 23170, -23170, 23170, -23170, 23170, -23170},
{0,-11585,20066,-23170,20066,-11585,0,11585,-20066,23170,-20066,11585}, {23170, -20066, 11585, 0, -11585, 20066, -23170, 20066, -11585, 0, 11585, -20066},
{0,-20066,20066,0,-20066,20066,0,-20066,20066,0,-20066,20066}, {23170, -11585, -11585, 23170, -11585, -11585, 23170, -11585, -11585, 23170, -11585, -11585},
{0,-23170,0,23170,0,-23170,0,23170,0,-23170,0,23170}, {23170, 0, -23170, 0, 23170, 0, -23170, 0, 23170, 0, -23170, 0},
{0,-20066,-20066,0,20066,20066,0,-20066,-20066,0,20066,20066}, {23170, 11585, -11585, -23170, -11585, 11585, 23170, 11585, -11585, -23170, -11585, 11585},
{0,-11585,-20066,-23170,-20066,-11585,0,11585,20066,23170,20066,11585} {23170, 20066, 11585, 0, -11585, -20066, -23170, -20066, -11585, 0, 11585, 20066}};
};
static const int16_t idft12_im[12][12] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 11585, 20066, 23170, 20066, 11585, 0, -11585, -20066, -23170, -20066, -11585},
{0, 20066, 20066, 0, -20066, -20066, 0, 20066, 20066, 0, -20066, -20066},
{0, 23170, 0, -23170, 0, 23170, 0, -23170, 0, 23170, 0, -23170},
{0, 20066, -20066, 0, 20066, -20066, 0, 20066, -20066, 0, 20066, -20066},
{0, 11585, -20066, 23170, -20066, 11585, 0, -11585, 20066, -23170, 20066, -11585},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, -11585, 20066, -23170, 20066, -11585, 0, 11585, -20066, 23170, -20066, 11585},
{0, -20066, 20066, 0, -20066, 20066, 0, -20066, 20066, 0, -20066, 20066},
{0, -23170, 0, 23170, 0, -23170, 0, 23170, 0, -23170, 0, 23170},
{0, -20066, -20066, 0, 20066, 20066, 0, -20066, -20066, 0, 20066, 20066},
{0, -11585, -20066, -23170, -20066, -11585, 0, 11585, 20066, 23170, 20066, 11585}};
//************************************************************************// //************************************************************************//
void nr_decode_pucch0(PHY_VARS_gNB *gNB, void nr_decode_pucch0(PHY_VARS_gNB *gNB,
c16_t **rxdataF, c16_t **rxdataF,
@@ -179,24 +178,32 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int nr_sequences; int nr_sequences;
const uint8_t *mcs; const uint8_t *mcs;
if(pucch_pdu->bit_len_harq==0){ if (pucch_pdu->bit_len_harq == 0) {
mcs=table1_mcs; mcs = table1_mcs;
nr_sequences=1; nr_sequences = 1;
} } else if (pucch_pdu->bit_len_harq == 1) {
else if(pucch_pdu->bit_len_harq==1){ mcs = table1_mcs;
mcs=table1_mcs; nr_sequences = 4 >> (1 - pucch_pdu->sr_flag);
nr_sequences=4>>(1-pucch_pdu->sr_flag); } else {
} mcs = table2_mcs;
else{ nr_sequences = 8 >> (1 - pucch_pdu->sr_flag);
mcs=table2_mcs;
nr_sequences=8>>(1-pucch_pdu->sr_flag);
} }
LOG_D(PHY,"pucch0: nr_symbols %d, start_symbol %d, prb_start %d, second_hop_prb %d, group_hop_flag %d, sequence_hop_flag %d, O_ACK %d, O_SR %d, mcs %d initial_cyclic_shift %d\n", LOG_D(PHY,
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->bit_len_harq, "pucch0: nr_symbols %d, start_symbol %d, prb_start %d, second_hop_prb %d, group_hop_flag %d, sequence_hop_flag %d, O_ACK "
pucch_pdu->sr_flag,mcs[0],pucch_pdu->initial_cyclic_shift); "%d, O_SR %d, mcs %d initial_cyclic_shift %d\n",
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->bit_len_harq,
pucch_pdu->sr_flag,
mcs[0],
pucch_pdu->initial_cyclic_shift);
int cs_ind = get_pucch0_cs_lut_index(gNB,pucch_pdu); int cs_ind = get_pucch0_cs_lut_index(gNB, pucch_pdu);
/* /*
* Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation * 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 * Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2
@@ -204,7 +211,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
* for PUCCH format 0 or PUCCH format 1, the index of the cyclic shift * 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 * is indicated by higher layer parameter PUCCH-F0-F1-initial-cyclic-shift
*/ */
int prb_offset[2] = {pucch_pdu->bwp_start+pucch_pdu->prb_start, pucch_pdu->bwp_start+pucch_pdu->prb_start}; 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); pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag << 1);
// the value of u,v (delta always 0 for PUCCH) has to be calculated according // the value of u,v (delta always 0 for PUCCH) has to be calculated according
@@ -212,7 +219,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
uint8_t u[2] = {0}, v[2] = {0}; uint8_t u[2] = {0}, v[2] = {0};
nr_group_sequence_hopping(pucch_GroupHopping, pucch_pdu->hopping_id, 0, slot, u, nr_group_sequence_hopping(pucch_GroupHopping, pucch_pdu->hopping_id, 0, slot, u,
v); // calculating u and v value first hop v); // calculating u and v value first hop
LOG_D(PHY,"pucch0: u %d, v %d\n",u[0],v[0]); LOG_D(PHY, "pucch0: u %d, v %d\n", u[0], v[0]);
if (pucch_pdu->freq_hop_flag == 1) { if (pucch_pdu->freq_hop_flag == 1) {
nr_group_sequence_hopping(pucch_GroupHopping, nr_group_sequence_hopping(pucch_GroupHopping,
@@ -221,47 +228,46 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
slot, slot,
&u[1], &u[1],
&v[1]); // calculating u and v value second hop &v[1]); // calculating u and v value second hop
LOG_D(PHY,"pucch0 second hop: u %d, v %d\n",u[1],v[1]); LOG_D(PHY, "pucch0 second hop: u %d, v %d\n", u[1], v[1]);
prb_offset[1] = pucch_pdu->bwp_start + pucch_pdu->second_hop_prb; prb_offset[1] = pucch_pdu->bwp_start + pucch_pdu->second_hop_prb;
} }
AssertFatal(pucch_pdu->nr_of_symbols < 3,"nr_of_symbols %d not allowed\n",pucch_pdu->nr_of_symbols); AssertFatal(pucch_pdu->nr_of_symbols < 3, "nr_of_symbols %d not allowed\n", pucch_pdu->nr_of_symbols);
uint32_t re_offset[2] = {0}; uint32_t re_offset[2] = {0};
const int16_t *x_re[2],*x_im[2]; const int16_t *x_re[2], *x_im[2];
x_re[0] = table_5_2_2_2_2_Re[u[0]]; x_re[0] = table_5_2_2_2_2_Re[u[0]];
x_im[0] = table_5_2_2_2_2_Im[u[0]]; x_im[0] = table_5_2_2_2_2_Im[u[0]];
x_re[1] = table_5_2_2_2_2_Re[u[1]]; x_re[1] = table_5_2_2_2_2_Re[u[1]];
x_im[1] = table_5_2_2_2_2_Im[u[1]]; x_im[1] = table_5_2_2_2_2_Im[u[1]];
c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32))); c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32)));
memset(xr, 0, frame_parms->nb_antennas_rx * pucch_pdu->nr_of_symbols * 12 * sizeof(c64_t)); memset(xr, 0, frame_parms->nb_antennas_rx * pucch_pdu->nr_of_symbols * 12 * sizeof(c64_t));
int64_t xrtmag=0,xrtmag_next=0; int64_t xrtmag = 0, xrtmag_next = 0;
uint8_t maxpos=0; uint8_t maxpos = 0;
uint8_t index=0; uint8_t index = 0;
int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1 int nb_re_pucch = 12 * pucch_pdu->prb_size; // prb size is 1
int64_t signal_energy = 0, signal_energy_ant0 = 0; int64_t signal_energy = 0, signal_energy_ant0 = 0;
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) { for (int l = 0; l < pucch_pdu->nr_of_symbols; l++) {
uint8_t l2 = l + pucch_pdu->start_symbol_index; uint8_t l2 = l + pucch_pdu->start_symbol_index;
re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset; re_offset[l] = (12 * prb_offset[l]) + frame_parms->first_carrier_offset;
if (re_offset[l]>= frame_parms->ofdm_symbol_size) if (re_offset[l] >= frame_parms->ofdm_symbol_size)
re_offset[l]-=frame_parms->ofdm_symbol_size; re_offset[l] -= frame_parms->ofdm_symbol_size;
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) { for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
c16_t rp[nb_re_pucch]; c16_t rp[nb_re_pucch];
memset(rp, 0, sizeof(rp)); memset(rp, 0, sizeof(rp));
c16_t *tmp_rp = &rxdataF[aa][soffset + l2 * frame_parms->ofdm_symbol_size]; 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) { if (re_offset[l] + nb_re_pucch > frame_parms->ofdm_symbol_size) {
int neg_length = frame_parms->ofdm_symbol_size-re_offset[l]; int neg_length = frame_parms->ofdm_symbol_size - re_offset[l];
int pos_length = nb_re_pucch-neg_length; int pos_length = nb_re_pucch - neg_length;
memcpy(rp, &tmp_rp[re_offset[l]], neg_length * sizeof(*tmp_rp)); memcpy(rp, &tmp_rp[re_offset[l]], neg_length * sizeof(*tmp_rp));
memcpy(&rp[neg_length], tmp_rp, pos_length * sizeof(*tmp_rp)); memcpy(&rp[neg_length], tmp_rp, pos_length * sizeof(*tmp_rp));
} } else
else
memcpy(rp, &tmp_rp[re_offset[l]], nb_re_pucch * sizeof(*tmp_rp)); memcpy(rp, &tmp_rp[re_offset[l]], nb_re_pucch * sizeof(*tmp_rp));
for (int n = 0; n < nb_re_pucch; n++) { for (int n = 0; n < nb_re_pucch; n++) {
@@ -281,20 +287,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
signal_energy_ant0 /= pucch_pdu->nr_of_symbols; signal_energy_ant0 /= pucch_pdu->nr_of_symbols;
int pucch_power_dBtimes10 = 10 * dB_fixed(signal_energy); int pucch_power_dBtimes10 = 10 * dB_fixed(signal_energy);
//int32_t no_corr = 0; // int32_t no_corr = 0;
int seq_index = 0; int seq_index = 0;
for (int i = 0; i < nr_sequences; i++) { for (int i = 0; i < nr_sequences; i++) {
c64_t corr[frame_parms->nb_antennas_rx][2]; c64_t corr[frame_parms->nb_antennas_rx][2];
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) { for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
for (int l=0;l<pucch_pdu->nr_of_symbols;l++) { for (int l = 0; l < pucch_pdu->nr_of_symbols; l++) {
seq_index = (pucch_pdu->initial_cyclic_shift+ seq_index =
mcs[i]+ (pucch_pdu->initial_cyclic_shift + mcs[i] + gNB->pucch0_lut.lut[cs_ind][slot][l + pucch_pdu->start_symbol_index]) % 12;
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]); printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n", l, i, seq_index, mcs[i]);
#endif #endif
corr[aa][l]=(c64_t){0}; corr[aa][l] = (c64_t){0};
for (int 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].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]; corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
@@ -303,10 +308,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
corr[aa][l].i >>= 31; corr[aa][l].i >>= 31;
} }
} }
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n", LOG_D(PHY,
mcs[i],seq_index,corr[0][0].r,corr[0][0].i, "PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
10*log10((double)squaredMod(corr[0][0]))); mcs[i],
if (pucch_pdu->nr_of_symbols==2) 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, LOG_D(PHY,
"PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n", "PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n",
mcs[i], mcs[i],
@@ -334,33 +343,32 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]); temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]);
} }
if (temp>xrtmag) { if (temp > xrtmag) {
xrtmag_next = xrtmag; xrtmag_next = xrtmag;
xrtmag=temp; xrtmag = temp;
LOG_D(PHY,"Sequence %d xrtmag %ld xrtmag_next %ld\n", i, xrtmag, xrtmag_next); LOG_D(PHY, "Sequence %d xrtmag %ld xrtmag_next %ld\n", i, xrtmag, xrtmag_next);
maxpos=i; maxpos = i;
uci_stats->current_pucch0_stat0 = 0; uci_stats->current_pucch0_stat0 = 0;
int64_t temp2=0,temp3=0;; int64_t temp2 = 0, temp3 = 0;
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) { for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
temp2 += squaredMod(corr[aa][0]); temp2 += squaredMod(corr[aa][0]);
if (pucch_pdu->nr_of_symbols==2) 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); uci_stats->current_pucch0_stat0 = dB_fixed64(temp2);
if ( pucch_pdu->nr_of_symbols==2) 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)
else if (temp>xrtmag_next)
xrtmag_next = temp; xrtmag_next = temp;
} }
int xrtmag_dBtimes10 = 10*(int)dB_fixed64(xrtmag/(12*pucch_pdu->nr_of_symbols)); int xrtmag_dBtimes10 = 10 * (int)dB_fixed64(xrtmag / (12 * pucch_pdu->nr_of_symbols));
int xrtmag_next_dBtimes10 = 10*(int)dB_fixed64(xrtmag_next/(12*pucch_pdu->nr_of_symbols)); int xrtmag_next_dBtimes10 = 10 * (int)dB_fixed64(xrtmag_next / (12 * pucch_pdu->nr_of_symbols));
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("PUCCH 0 : maxpos %d\n",maxpos); printf("PUCCH 0 : maxpos %d\n", maxpos);
#endif #endif
index=maxpos; index = maxpos;
int pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]]; int pucch0_n00 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]];
int pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]; int 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], pucch0_n00, prb_offset[1], pucch0_n01); LOG_D(PHY, "n00[%d] = %d, n01[%d] = %d\n", prb_offset[0], pucch0_n00, prb_offset[1], pucch0_n01);
@@ -381,10 +389,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
else else
cqi = (640 + SNRtimes10) / 5; cqi = (640 + SNRtimes10) / 5;
bool no_conf=false; bool no_conf = false;
if (nr_sequences>1) { if (nr_sequences > 1) {
if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) { if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) {
no_conf=true; no_conf = true;
LOG_D(PHY, LOG_D(PHY,
"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n", "%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n",
frame, frame,
@@ -397,28 +405,27 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
} }
gNB->bad_pucch += no_conf; gNB->bad_pucch += no_conf;
// first bit of bitmap for sr presence and second bit for acknack presence // first bit of bitmap for sr presence and second bit for acknack presence
uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1); uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq > 0) << 1);
uci_pdu->pucch_format = 0; // format 0 uci_pdu->pucch_format = 0; // format 0
uci_pdu->rnti = pucch_pdu->rnti; uci_pdu->rnti = pucch_pdu->rnti;
uci_pdu->ul_cqi = cqi; uci_pdu->ul_cqi = cqi;
uci_pdu->timing_advance = 0xffff; // currently not valid uci_pdu->timing_advance = 0xffff; // currently not valid
uci_pdu->rssi = 1280 - (10 * dB_fixed(32767 * 32767) - dB_fixed_times10(signal_energy_ant0)); uci_pdu->rssi = 1280 - (10 * dB_fixed(32767 * 32767) - dB_fixed_times10(signal_energy_ant0));
if (pucch_pdu->bit_len_harq==0) { if (pucch_pdu->bit_len_harq == 0) {
uci_pdu->sr.sr_confidence_level = SNRtimes10 < gNB->pucch0_thres; uci_pdu->sr.sr_confidence_level = SNRtimes10 < gNB->pucch0_thres;
uci_stats->pucch0_sr_trials++; uci_stats->pucch0_sr_trials++;
if (xrtmag_dBtimes10>(10*max_n0+100)) { if (xrtmag_dBtimes10 > (10 * max_n0 + 100)) {
uci_pdu->sr.sr_indication = 1; uci_pdu->sr.sr_indication = 1;
uci_stats->pucch0_positive_SR++; uci_stats->pucch0_positive_SR++;
LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR); LOG_D(PHY, "PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
} else { } else {
uci_pdu->sr.sr_indication = 0; uci_pdu->sr.sr_indication = 0;
} }
} } else if (pucch_pdu->bit_len_harq == 1) {
else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->harq.num_harq = 1; uci_pdu->harq.num_harq = 1;
uci_pdu->harq.harq_confidence_level = no_conf; uci_pdu->harq.harq_confidence_level = no_conf;
uci_pdu->harq.harq_list[0].harq_value = !(index&0x01); uci_pdu->harq.harq_list[0].harq_value = !(index & 0x01);
LOG_D(PHY, LOG_D(PHY,
"[DLSCH/PDSCH/PUCCH] %d.%d HARQ %s with confidence level %s xrt_mag " "[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 xrt_mag_next %d pucch_power_dBtimes10 %d n0 %d "
@@ -440,23 +447,23 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
10 * log10((double)signal_energy_ant0)); 10 * log10((double)signal_energy_ant0));
if (pucch_pdu->sr_flag == 1) { if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr.sr_indication = (index>1); uci_pdu->sr.sr_indication = (index > 1);
uci_pdu->sr.sr_confidence_level = no_conf; uci_pdu->sr.sr_confidence_level = no_conf;
if(uci_pdu->sr.sr_indication == 1 && uci_pdu->sr.sr_confidence_level == 0) { if (uci_pdu->sr.sr_indication == 1 && uci_pdu->sr.sr_confidence_level == 0) {
uci_stats->pucch0_positive_SR++; uci_stats->pucch0_positive_SR++;
LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR); LOG_D(PHY, "PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
} }
} }
uci_stats->pucch01_trials++; uci_stats->pucch01_trials++;
} } else {
else {
uci_pdu->harq.num_harq = 2; uci_pdu->harq.num_harq = 2;
uci_pdu->harq.harq_confidence_level = no_conf; uci_pdu->harq.harq_confidence_level = no_conf;
uci_pdu->harq.harq_list[1].harq_value = !(index&0x01); uci_pdu->harq.harq_list[1].harq_value = !(index & 0x01);
uci_pdu->harq.harq_list[0].harq_value = !((index>>1)&0x01); uci_pdu->harq.harq_list[0].harq_value = !((index >> 1) & 0x01);
LOG_D(PHY, LOG_D(PHY,
"[DLSCH/PDSCH/PUCCH] %d.%d HARQ values (%s, %s) with confidence level %s, xrt_mag %d xrt_mag_next %d pucch_power_dBtimes10 %d n0 %d (%d,%d) " "[DLSCH/PDSCH/PUCCH] %d.%d HARQ values (%s, %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\n", "pucch0_thres %d, cqi %d, SNRtimes10 %d\n",
frame, frame,
slot, slot,
@@ -473,11 +480,11 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
cqi, cqi,
SNRtimes10); SNRtimes10);
if (pucch_pdu->sr_flag == 1) { if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr.sr_indication = (index>3) ? 1 : 0; uci_pdu->sr.sr_indication = (index > 3) ? 1 : 0;
uci_pdu->sr.sr_confidence_level = no_conf; uci_pdu->sr.sr_confidence_level = no_conf;
if(uci_pdu->sr.sr_indication == 1 && uci_pdu->sr.sr_confidence_level == 0) { if (uci_pdu->sr.sr_indication == 1 && uci_pdu->sr.sr_confidence_level == 0) {
uci_stats->pucch0_positive_SR++; uci_stats->pucch0_positive_SR++;
LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR); LOG_D(PHY, "PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
} }
} }
} }
@@ -519,12 +526,13 @@ void nr_decode_pucch1(c16_t **rxdataF,
* *
*/ */
const int soffset = (nr_tti_tx % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; const int soffset = (nr_tti_tx % RU_RX_SLOT_DEPTH) * 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] // 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]
const int lprime = startingSymbolIndex; const int lprime = startingSymbolIndex;
// mcs = 0 except for PUCCH format 0 // mcs = 0 except for PUCCH format 0
const 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_re and r_u_v_alpha_delta_im tables containing the sequence y(n) for the PUCCH, when they are multiplied by
// r_u_v_alpha_delta_dmrs_re and r_u_v_alpha_delta_dmrs_im tables containing the sequence for the DM-RS. // 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.
c16_t r_u_v_alpha_delta[12], r_u_v_alpha_delta_dmrs[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: * in TS 38.213 Subclause 9.2.1 it is said that:
@@ -535,21 +543,22 @@ void nr_decode_pucch1(c16_t **rxdataF,
* the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * r_u_v_alpha_delta(n) * the complex-valued symbol d_0 shall be multiplied with a sequence r_u_v_alpha_delta(n): y(n) = d_0 * 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 // 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; uint8_t u = 0, v = 0; //,delta=0;
// Intra-slot frequency hopping shall be assumed when the higher-layer parameter intraSlotFrequencyHopping is provided, // 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, // regardless of whether the frequency-hop distance is zero or not,
// otherwise no intra-slot frequency hopping shall be assumed // otherwise no intra-slot frequency hopping shall be assumed
//uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers // uint8_t PUCCH_Frequency_Hopping = 0 ; // from higher layers
const bool intraSlotFrequencyHopping = startingPRB != startingPRB_intraSlotHopping; const bool intraSlotFrequencyHopping = startingPRB != startingPRB_intraSlotHopping;
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n",intraSlotFrequencyHopping); printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n", intraSlotFrequencyHopping);
#endif #endif
/* /*
* Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources * Implementing TS 38.211 Subclause 6.3.2.4.2 Mapping to physical resources
*/ */
#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 #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
c16_t z_rx[MAX_SIZE_Z] = {0}; c16_t z_rx[MAX_SIZE_Z] = {0};
c16_t z_dmrs_rx[MAX_SIZE_Z] = {0}; c16_t z_dmrs_rx[MAX_SIZE_Z] = {0};
const int half_nb_rb_dl = frame_parms->N_RB_DL >> 1; const int half_nb_rb_dl = frame_parms->N_RB_DL >> 1;
@@ -578,11 +587,12 @@ void nr_decode_pucch1(c16_t **rxdataF,
re_offset += 12 * startingPRB + frame_parms->first_carrier_offset; re_offset += 12 * startingPRB + frame_parms->first_carrier_offset;
} }
for (int n=0; n<12; n++) { for (int n = 0; n < 12; n++) {
const int current_subcarrier = l * 12 + n; const int current_subcarrier = l * 12 + n;
if (n == 6 && startingPRB == half_nb_rb_dl && !nb_rb_is_even) { 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) // if number RBs in bandwidth is odd and current PRB contains DC, we need to recalculate the offset when n=6 (for second
re_offset = ((l+startingSymbolIndex)*frame_parms->ofdm_symbol_size); // half PRB)
re_offset = ((l + startingSymbolIndex) * frame_parms->ofdm_symbol_size);
} }
if (l % 2 == 1) // mapping PUCCH or DM-RS according to TS38.211 subclause 6.4.1.3.1 if (l % 2 == 1) // mapping PUCCH or DM-RS according to TS38.211 subclause 6.4.1.3.1
@@ -610,11 +620,10 @@ void nr_decode_pucch1(c16_t **rxdataF,
} }
} }
cd_t y_n[12] = {0}, y1_n[12] = {0}; cd_t y_n[12] = {0}, y1_n[12] = {0};
//generating transmitted sequence and dmrs // generating transmitted sequence and dmrs
for (int l = 0; l < nrofSymbols; l++) { for (int l = 0; l < nrofSymbols; l++) {
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n", printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n", l, lprime);
l,lprime);
#endif #endif
// y_n contains the complex value d multiplied by the sequence r_u_v // y_n contains the complex value d multiplied by the sequence r_u_v
// if frequency hopping is disabled, intraSlotFrequencyHopping is not // if frequency hopping is disabled, intraSlotFrequencyHopping is not
@@ -626,13 +635,12 @@ void nr_decode_pucch1(c16_t **rxdataF,
const int n_hop = intraSlotFrequencyHopping && l >= nrofSymbols / 2 ? 1 : 0; const int n_hop = intraSlotFrequencyHopping && l >= nrofSymbols / 2 ? 1 : 0;
#ifdef DEBUG_NR_PUCCH_RX #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", 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);
n_hop,nr_tti_tx);
#endif #endif
nr_group_sequence_hopping(pucch_GroupHopping,n_id,n_hop,nr_tti_tx,&u,&v); // calculating u and v value nr_group_sequence_hopping(pucch_GroupHopping, n_id, n_hop, nr_tti_tx, &u, &v); // calculating u and v value
// Defining cyclic shift hopping TS 38.211 Subclause 6.3.2.2.2 // 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); 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 for (int n = 0; n < 12; n++) { // generating low papr sequences
const c16_t angle = {lround(32767 * cos(alpha * n)), lround(32767 * sin(alpha * 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]}; 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) if (l % 2 == 1)
@@ -660,8 +668,8 @@ void nr_decode_pucch1(c16_t **rxdataF,
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) * (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
* z(mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) * z(mprime*12*table_6_3_2_4_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n)
* *
* The block of complex-valued symbols r_u_v_alpha_dmrs_delta(n) for DM-RS shall be block-wise spread with the orthogonal sequence wi(m) * The block of complex-valued symbols r_u_v_alpha_dmrs_delta(n) for DM-RS shall be block-wise spread with the orthogonal
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im) * sequence wi(m) (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
* z(mprime*12*table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n) * z(mprime*12*table_6_4_1_3_1_1_1_N_SF_mprime_PUCCH_1_noHop[pucch_symbol_length]+m*12+n)=wi(m)*y(n)
* *
*/ */
@@ -672,8 +680,10 @@ void nr_decode_pucch1(c16_t **rxdataF,
const int w_index = timeDomainOCC; const int w_index = timeDomainOCC;
if (intraSlotFrequencyHopping == false) { // intra-slot hopping disabled if (intraSlotFrequencyHopping == false) { // intra-slot hopping disabled
#ifdef DEBUG_NR_PUCCH_RX #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", printf(
intraSlotFrequencyHopping); "\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, "
"intra-slot hopping disabled\n",
intraSlotFrequencyHopping);
#endif #endif
// mprime is 0 in this not hopping case // 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 // N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-1
@@ -693,8 +703,8 @@ void nr_decode_pucch1(c16_t **rxdataF,
int N_SF_mprime_PUCCH_DMRS_1 = 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) 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)
if(l%2==1){ if (l % 2 == 1) {
for (int m=0; m < N_SF_mprime_PUCCH_1; m++) { 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], 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]}; table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_1][w_index][m]};
if (l / 2 == m) { if (l / 2 == m) {
@@ -707,7 +717,7 @@ void nr_decode_pucch1(c16_t **rxdataF,
} }
} }
} else { } else {
for (int m=0; m < N_SF_mprime_PUCCH_DMRS_1; m++) { for (int m = 0; m < N_SF_mprime_PUCCH_DMRS_1; m++) {
const c16_t table = {table_6_3_2_4_1_2_Wi_Re[N_SF_mprime_PUCCH_DMRS_1][w_index][m], 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]}; table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m]};
if (l / 2 == m) { if (l / 2 == m) {
@@ -725,8 +735,10 @@ void nr_decode_pucch1(c16_t **rxdataF,
if (intraSlotFrequencyHopping == true) { // intra-slot hopping enabled if (intraSlotFrequencyHopping == true) { // intra-slot hopping enabled
#ifdef DEBUG_NR_PUCCH_RX #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", printf(
intraSlotFrequencyHopping); "\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, "
"intra-slot hopping enabled\n",
intraSlotFrequencyHopping);
#endif #endif
// N_SF_mprime_PUCCH_1 contains N_SF_mprime from table 6.3.2.4.1-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 and // (depending on number of PUCCH symbols nrofSymbols, mprime and
@@ -749,8 +761,14 @@ void nr_decode_pucch1(c16_t **rxdataF,
int N_SF_mprime0_PUCCH_DMRS_1 = 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) 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 #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", printf(
w_index, N_SF_mprime_PUCCH_1,N_SF_mprime_PUCCH_DMRS_1,N_SF_mprime0_PUCCH_1,N_SF_mprime0_PUCCH_DMRS_1); "\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 #endif
for (int mprime = 0; mprime < 2; mprime++) { // mprime can get values {0,1} for (int mprime = 0; mprime < 2; mprime++) { // mprime can get values {0,1}
@@ -786,7 +804,8 @@ void nr_decode_pucch1(c16_t **rxdataF,
N_SF_mprime_PUCCH_1 = 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) 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) 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)
} }
} }
} }
@@ -835,7 +854,7 @@ void nr_decode_pucch1(c16_t **rxdataF,
d.i += H[n].r * y1_n[n].i - H[n].i * y1_n[n].r; d.i += H[n].r * y1_n[n].i - H[n].i * y1_n[n].r;
} }
} }
//Decoding QPSK or BPSK symbols to obtain payload bits // Decoding QPSK or BPSK symbols to obtain payload bits
if (nr_bit == 1) { if (nr_bit == 1) {
if ((d.r + d.i) > 0) { if ((d.r + d.i) > 0) {
*payload = 0; *payload = 0;
@@ -855,18 +874,20 @@ void nr_decode_pucch1(c16_t **rxdataF,
} }
} }
typedef struct {c16_t cw[16];} cw_t; typedef struct {
static cw_t pucch2_3bit[8] __attribute__((aligned(32))); c16_t cw[16];
} cw_t;
static cw_t pucch2_3bit[8] __attribute__((aligned(32)));
static cw_t pucch2_4bit[16] __attribute__((aligned(32))); static cw_t pucch2_4bit[16] __attribute__((aligned(32)));
static cw_t pucch2_5bit[32] __attribute__((aligned(32))); static cw_t pucch2_5bit[32] __attribute__((aligned(32)));
static cw_t pucch2_6bit[64] __attribute__((aligned(32))); static cw_t pucch2_6bit[64] __attribute__((aligned(32)));
static cw_t pucch2_7bit[128] __attribute__((aligned(32))); static cw_t pucch2_7bit[128] __attribute__((aligned(32)));
static cw_t pucch2_8bit[256] __attribute__((aligned(32))); static cw_t pucch2_8bit[256] __attribute__((aligned(32)));
static cw_t pucch2_9bit[512] __attribute__((aligned(32))); static cw_t pucch2_9bit[512] __attribute__((aligned(32)));
static cw_t pucch2_10bit[1024] __attribute__((aligned(32))); static cw_t pucch2_10bit[1024] __attribute__((aligned(32)));
static cw_t pucch2_11bit[2048] __attribute__((aligned(32))); static cw_t pucch2_11bit[2048] __attribute__((aligned(32)));
static cw_t* pucch2_lut[9] = static cw_t *pucch2_lut[9] =
{pucch2_3bit, pucch2_4bit, pucch2_5bit, pucch2_6bit, pucch2_7bit, pucch2_8bit, pucch2_9bit, pucch2_10bit, pucch2_11bit}; {pucch2_3bit, pucch2_4bit, pucch2_5bit, pucch2_6bit, pucch2_7bit, pucch2_8bit, pucch2_9bit, pucch2_10bit, pucch2_11bit};
typedef struct { typedef struct {
@@ -877,12 +898,12 @@ static simde__m128i pucch2_polar_llr_num_lut[256];
void init_pucch2_luts() void init_pucch2_luts()
{ {
for (int b=3;b<12;b++) { for (int b = 3; b < 12; b++) {
for (int cw = 0; cw < (1 << b); cw++) { for (int cw = 0; cw < (1 << b); cw++) {
uint32_t out = encodeSmallBlock(cw, b); uint32_t out = encodeSmallBlock(cw, b);
uint16_t *tmp = (uint16_t *)pucch2_lut[b - 3][cw].cw; uint16_t *tmp = (uint16_t *)pucch2_lut[b - 3][cw].cw;
for (int j = 0; j < 32; j++) for (int j = 0; j < 32; j++)
*tmp++ = (out & (1U<<j)) > 0 ? -1 : 1; *tmp++ = (out & (1U << j)) > 0 ? -1 : 1;
} }
} }
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
@@ -912,22 +933,20 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
c16_t **rxdataF, c16_t **rxdataF,
int frame, int frame,
int slot, int slot,
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
nfapi_nr_pucch_pdu_t* pucch_pdu) nfapi_nr_pucch_pdu_t *pucch_pdu)
{ {
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; 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); // pucch_GroupHopping_t pucch_GroupHopping = pucch_pdu->group_hop_flag + (pucch_pdu->sequence_hop_flag<<1);
const int nb_symbols=pucch_pdu->nr_of_symbols; const int nb_symbols = pucch_pdu->nr_of_symbols;
AssertFatal(nb_symbols == 1 || nb_symbols == 2, AssertFatal(nb_symbols == 1 || nb_symbols == 2, "Illegal number of symbols for PUCCH 2 %d\n", nb_symbols);
"Illegal number of symbols for PUCCH 2 %d\n",
nb_symbols);
AssertFatal((pucch_pdu->prb_start-((pucch_pdu->prb_start>>2)<<2))==0, 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", "Current pucch2 receiver implementation requires a PRB offset multiple of 4. The one selected is %d",
pucch_pdu->prb_start); pucch_pdu->prb_start);
//extract pucch and dmrs first // extract pucch and dmrs first
int l2 = pucch_pdu->start_symbol_index; int l2 = pucch_pdu->start_symbol_index;
int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size;
@@ -941,10 +960,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
else else
re_offset[1] = re_offset[0]; re_offset[1] = re_offset[0];
} }
AssertFatal(pucch_pdu->prb_size * nb_symbols > 1, AssertFatal(pucch_pdu->prb_size * nb_symbols > 1, "number of PRB*SYMB (%d,%d)< 2", pucch_pdu->prb_size, nb_symbols);
"number of PRB*SYMB (%d,%d)< 2",
pucch_pdu->prb_size,
nb_symbols);
int Prx = gNB->gNB_config.carrier_config.num_rx_ant.value; 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); // AssertFatal((pucch_pdu->prb_size&1) == 0,"prb_size %d is not a multiple of2\n",pucch_pdu->prb_size);
@@ -954,16 +970,15 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
memset(rp, 0, sizeof(rp)); memset(rp, 0, sizeof(rp));
int64_t pucch2_lev = 0; int64_t pucch2_lev = 0;
for (int aa=0;aa<Prx;aa++){ for (int aa = 0; aa < Prx; aa++) {
for (int symb=0;symb<nb_symbols;symb++) { for (int symb = 0; symb < nb_symbols; symb++) {
c16_t *tmp_rp = ((c16_t *)&rxdataF[aa][soffset + (l2 + symb) * frame_parms->ofdm_symbol_size]); c16_t *tmp_rp = ((c16_t *)&rxdataF[aa][soffset + (l2 + symb) * frame_parms->ofdm_symbol_size]);
if (re_offset[symb] + nb_re_pucch < frame_parms->ofdm_symbol_size) { if (re_offset[symb] + nb_re_pucch < frame_parms->ofdm_symbol_size) {
memcpy(rp[aa][symb], &tmp_rp[re_offset[symb]], nb_re_pucch * sizeof(c16_t)); memcpy(rp[aa][symb], &tmp_rp[re_offset[symb]], nb_re_pucch * sizeof(c16_t));
} } else {
else { int neg_length = frame_parms->ofdm_symbol_size - re_offset[symb];
int neg_length = frame_parms->ofdm_symbol_size-re_offset[symb]; int pos_length = nb_re_pucch - neg_length;
int pos_length = nb_re_pucch-neg_length;
memcpy(rp[aa][symb], &tmp_rp[re_offset[symb]], neg_length * sizeof(c16_t)); memcpy(rp[aa][symb], &tmp_rp[re_offset[symb]], neg_length * sizeof(c16_t));
memcpy(&rp[aa][symb][neg_length], tmp_rp, pos_length * sizeof(c16_t)); memcpy(&rp[aa][symb][neg_length], tmp_rp, pos_length * sizeof(c16_t));
} }
@@ -988,8 +1003,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
scaling); scaling);
int prb_size_ext = pucch_pdu->prb_size + (pucch_pdu->prb_size & 1); int prb_size_ext = pucch_pdu->prb_size + (pucch_pdu->prb_size & 1);
int nc_group_size=1; // 2 PRB int nc_group_size = 1; // 2 PRB
int ngroup = prb_size_ext/nc_group_size/2; int ngroup = prb_size_ext / nc_group_size / 2;
c32_t corr32[nb_symbols][ngroup][Prx]; c32_t corr32[nb_symbols][ngroup][Prx];
memset(corr32, 0, sizeof(corr32)); memset(corr32, 0, sizeof(corr32));
const int nb_re_data = 8 * prb_size_ext; const int nb_re_data = 8 * prb_size_ext;
@@ -1035,13 +1050,12 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
#endif #endif
c16_t scramb_data[nb_re_data] __attribute__((aligned(32))); c16_t scramb_data[nb_re_data] __attribute__((aligned(32)));
uint32_t *sGold = gold_cache(x2, nb_symbols * nb_re_data/2); uint32_t *sGold = gold_cache(x2, nb_symbols * nb_re_data / 2);
uint8_t *sGold8 = (uint8_t *)sGold; uint8_t *sGold8 = (uint8_t *)sGold;
for (int i = 0; i < nb_re_data; i += 4) for (int i = 0; i < nb_re_data; i += 4)
*(simde__m128i *)(scramb_data + i) = byte2m128i[*sGold8++]; *(simde__m128i *)(scramb_data + i) = byte2m128i[*sGold8++];
for (int symb=0; symb<nb_symbols;symb++) { for (int symb = 0; symb < nb_symbols; symb++) {
c16_t rdmrs_ext[Prx][nb_re_dmrs] __attribute__((aligned(32))); c16_t rdmrs_ext[Prx][nb_re_dmrs] __attribute__((aligned(32)));
// extract DMRS // extract DMRS
@@ -1074,7 +1088,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
% (1U << 31); // c_init calculation according to TS38.211 subclause % (1U << 31); // c_init calculation according to TS38.211 subclause
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n", printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n",
slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id); slot,
pucch_pdu->start_symbol_index,
symb,
pucch_pdu->dmrs_scrambling_id);
#endif #endif
uint32_t *sGold = gold_cache(x2, starting_prb / 4 + ngroup / 2); uint32_t *sGold = gold_cache(x2, starting_prb / 4 + ngroup / 2);
// Compute pilot conjugate // Compute pilot conjugate
@@ -1133,22 +1150,22 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
log_dump(PHY, r_ext[aa], nb_re_data, LOG_DUMP_C16, "after delay compensation ant %d data:\n", aa); log_dump(PHY, r_ext[aa], nb_re_data, LOG_DUMP_C16, "after delay compensation ant %d data:\n", aa);
} }
#endif #endif
c16_t rdmrs_gold[Prx][nb_re_dmrs] __attribute__((aligned(32))); c16_t rdmrs_gold[Prx][nb_re_dmrs] __attribute__((aligned(32)));
for (int aa = 0; aa < Prx; aa++) for (int aa = 0; aa < Prx; aa++)
mult_complex_vectors(rdmrs_ext[aa], pil_dmrs, rdmrs_gold[aa], nb_re_dmrs, 0); mult_complex_vectors(rdmrs_ext[aa], pil_dmrs, rdmrs_gold[aa], nb_re_dmrs, 0);
for (int aa=0;aa<Prx;aa++) { for (int aa = 0; aa < Prx; aa++) {
c16_t *pil_ptr = pil_dmrs; c16_t *pil_ptr = pil_dmrs;
for (int group = 0; group < ngroup; group++) { for (int group = 0; group < ngroup; group++) {
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group // each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
// non-coherent combining across groups // non-coherent combining across groups
c16_t *rdmrs_p = &rdmrs_ext[aa][8 * group]; c16_t *rdmrs_p = &rdmrs_ext[aa][8 * group];
for (int z = 0; z < 8; z++) { for (int z = 0; z < 8; z++) {
c16_t tmp = c16mulShift(*rdmrs_p++, *pil_ptr++, scaling); c16_t tmp = c16mulShift(*rdmrs_p++, *pil_ptr++, scaling);
corr32[symb][group][aa].r += tmp.r; corr32[symb][group][aa].r += tmp.r;
corr32[symb][group][aa].i += tmp.i; corr32[symb][group][aa].i += tmp.i;
}
} }
} }
}
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
log_dump(PHY, corr32[symb][0], 8, LOG_DUMP_C32, "corr32:"); log_dump(PHY, corr32[symb][0], 8, LOG_DUMP_C32, "corr32:");
#endif #endif
@@ -1166,7 +1183,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
} }
} }
int nb_bit = pucch_pdu->bit_len_harq+pucch_pdu->sr_flag+pucch_pdu->bit_len_csi_part1+pucch_pdu->bit_len_csi_part2; int nb_bit = pucch_pdu->bit_len_harq + pucch_pdu->sr_flag + pucch_pdu->bit_len_csi_part1 + pucch_pdu->bit_len_csi_part2;
AssertFatal(nb_bit > 2 && nb_bit < 65, AssertFatal(nb_bit > 2 && nb_bit < 65,
"illegal length (%d : %d,%d,%d,%d)\n", "illegal length (%d : %d,%d,%d,%d)\n",
nb_bit, nb_bit,
@@ -1176,20 +1193,23 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
pucch_pdu->bit_len_csi_part2); pucch_pdu->bit_len_csi_part2);
uint64_t decodedPayload[nb_symbols]; uint64_t decodedPayload[nb_symbols];
memset(decodedPayload,0,sizeof(decodedPayload)); memset(decodedPayload, 0, sizeof(decodedPayload));
int8_t corr_dB; int8_t corr_dB;
int decoderState = 2; int decoderState = 2;
if (pucch2_levdB < gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10)) if (pucch2_levdB < gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10))
decoderState = 1; // assuming missed detection, only attempt to decode for polar case (with CRC) decoderState = 1; // assuming missed detection, only attempt to decode for polar case (with CRC)
LOG_D(NR_PHY, "n0+thres %d decoderState %d\n", gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10), decoderState); LOG_D(NR_PHY,
"n0+thres %d decoderState %d\n",
gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10),
decoderState);
if (nb_bit < 12 && decoderState == 2) { // short blocklength case if (nb_bit < 12 && decoderState == 2) { // short blocklength case
uint64_t corr=0; uint64_t corr = 0;
int cw_ML=0; int cw_ML = 0;
for (int cw = 0; cw < 1 << nb_bit; cw++) { for (int cw = 0; cw < 1 << nb_bit; cw++) {
uint64_t corr_tmp = 0; uint64_t corr_tmp = 0;
for (int symb=0;symb<nb_symbols;symb++) { for (int symb = 0; symb < nb_symbols; symb++) {
for (int group=0;group<ngroup;group++) { for (int group = 0; group < ngroup; group++) {
// do complex correlation // do complex correlation
for (int aa = 0; aa < Prx; aa++) { for (int aa = 0; aa < Prx; aa++) {
const simde__m256i *coeff = (simde__m256i *)&pucch2_lut[nb_bit - 3][cw].cw; const simde__m256i *coeff = (simde__m256i *)&pucch2_lut[nb_bit - 3][cw].cw;
@@ -1222,35 +1242,35 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
#endif #endif
} }
}// group loop } // group loop
} // symb loop } // symb loop
if (corr_tmp > corr) { if (corr_tmp > corr) {
corr = corr_tmp; corr = corr_tmp;
cw_ML = cw; cw_ML = cw;
#ifdef DEBUG_NR_PUCCH_RX #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 #endif
} }
} // cw loop } // cw loop
corr_dB = dB_fixed64(corr); corr_dB = dB_fixed64(corr);
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("slot %d PUCCH2 cw_ML %d, metric %d \n",slot,cw_ML,corr_dB); printf("slot %d PUCCH2 cw_ML %d, metric %d \n", slot, cw_ML, corr_dB);
#endif #endif
decodedPayload[0]=(uint64_t)cw_ML; decodedPayload[0] = (uint64_t)cw_ML;
} else if (nb_bit >= 12) { // polar coded case } else if (nb_bit >= 12) { // polar coded case
simde__m128i llrs[pucch_pdu->prb_size * 2 * nb_symbols]; simde__m128i llrs[pucch_pdu->prb_size * 2 * nb_symbols];
// non-coherent LLR computation on groups of 4 REs (half-PRBs) // non-coherent LLR computation on groups of 4 REs (half-PRBs)
uint64_t corr = 0; uint64_t corr = 0;
const simde__m128i ones = simde_mm_set1_epi16(1); const simde__m128i ones = simde_mm_set1_epi16(1);
for (int symb=0;symb<nb_symbols;symb++) { for (int symb = 0; symb < nb_symbols; symb++) {
for (int half_prb=0;half_prb<(2*pucch_pdu->prb_size);half_prb++) { for (int half_prb = 0; half_prb < (2 * pucch_pdu->prb_size); half_prb++) {
simde__m128i llr_num = simde_mm_set1_epi16(0); simde__m128i llr_num = simde_mm_set1_epi16(0);
simde__m128i llr_den = simde_mm_set1_epi16(0); simde__m128i llr_den = simde_mm_set1_epi16(0);
for (int cw=0;cw<256;cw++) { for (int cw = 0; cw < 256; cw++) {
int32_t corr_tmp=0; int32_t corr_tmp = 0;
for (int aa=0;aa<Prx;aa++) { for (int aa = 0; aa < Prx; aa++) {
simde__m128i part1 = simde_mm_set_epi64x(0ULL, *(int64_t *)&pucch2_polar_4bit[cw & 15].cw); simde__m128i part1 = simde_mm_set_epi64x(0ULL, *(int64_t *)&pucch2_polar_4bit[cw & 15].cw);
simde__m128i part2 = simde_mm_set_epi64x(0ULL, *(int64_t *)&pucch2_polar_4bit[cw >> 4].cw); simde__m128i part2 = simde_mm_set_epi64x(0ULL, *(int64_t *)&pucch2_polar_4bit[cw >> 4].cw);
simde__m128i factor = simde_mm_unpacklo_epi16(part1, part2); simde__m128i factor = simde_mm_unpacklo_epi16(part1, part2);
@@ -1280,12 +1300,13 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
} }
// compute llrs // compute llrs
llrs[half_prb + symb * 2 * pucch_pdu->prb_size] = simde_mm_subs_epi16(llr_num, llr_den); llrs[half_prb + symb * 2 * pucch_pdu->prb_size] = simde_mm_subs_epi16(llr_num, llr_den);
LOG_DDUMP(PHY, llrs+half_prb + symb * 2 * pucch_pdu->prb_size, 8, LOG_DUMP_I16, "llrs:"); LOG_DDUMP(PHY, llrs + half_prb + symb * 2 * pucch_pdu->prb_size, 8, LOG_DUMP_I16, "llrs:");
} // half_prb } // half_prb
} // symb } // symb
// run polar decoder on llrs // run polar decoder on llrs
decoderState = polar_decoder_int16((int16_t *)llrs, decodedPayload, 0, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, nb_bit, pucch_pdu->prb_size); decoderState =
polar_decoder_int16((int16_t *)llrs, decodedPayload, 0, NR_POLAR_UCI_PUCCH_MESSAGE_TYPE, nb_bit, pucch_pdu->prb_size);
// Decoder reversal // Decoder reversal
decodedPayload[0] = reverse_bits(decodedPayload[0], nb_bit); decodedPayload[0] = reverse_bits(decodedPayload[0], nb_bit);
@@ -1344,31 +1365,32 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
} }
if (pucch_pdu->sr_flag == 1) { if (pucch_pdu->sr_flag == 1) {
uci_pdu->pduBitmap|=1; uci_pdu->pduBitmap |= 1;
uci_pdu->sr.sr_bit_len = 1; uci_pdu->sr.sr_bit_len = 1;
uci_pdu->sr.sr_payload = malloc(1); uci_pdu->sr.sr_payload = malloc(1);
uci_pdu->sr.sr_payload[0] = decodedPayload[0]&1; uci_pdu->sr.sr_payload[0] = decodedPayload[0] & 1;
decodedPayload[0] = decodedPayload[0]>>1; decodedPayload[0] = decodedPayload[0] >> 1;
} }
// csi // csi
if (pucch_pdu->bit_len_csi_part1>0) { if (pucch_pdu->bit_len_csi_part1 > 0) {
uci_pdu->pduBitmap|=4; uci_pdu->pduBitmap |= 4;
uci_pdu->csi_part1.csi_part1_bit_len=pucch_pdu->bit_len_csi_part1; uci_pdu->csi_part1.csi_part1_bit_len = pucch_pdu->bit_len_csi_part1;
int csi_part1_bytes=pucch_pdu->bit_len_csi_part1>>3; int csi_part1_bytes = pucch_pdu->bit_len_csi_part1 >> 3;
if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++; if ((pucch_pdu->bit_len_csi_part1 & 7) > 0)
uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes); csi_part1_bytes++;
uci_pdu->csi_part1.csi_part1_payload = (uint8_t *)malloc(csi_part1_bytes);
uci_pdu->csi_part1.csi_part1_crc = decoderState; uci_pdu->csi_part1.csi_part1_crc = decoderState;
int i=0; int i = 0;
for (;i<csi_part1_bytes-1;i++) { for (; i < csi_part1_bytes - 1; i++) {
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255; uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & 255;
decodedPayload[0]>>=8; decodedPayload[0] >>= 8;
} }
int bit_left = pucch_pdu->bit_len_csi_part1-((csi_part1_bytes-1)<<3); int bit_left = pucch_pdu->bit_len_csi_part1 - ((csi_part1_bytes - 1) << 3);
uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1 << bit_left) - 1); uci_pdu->csi_part1.csi_part1_payload[i] = decodedPayload[0] & ((1 << bit_left) - 1);
decodedPayload[0] = pucch_pdu->bit_len_csi_part1 < 64 ? decodedPayload[0] >> bit_left : 0; decodedPayload[0] = pucch_pdu->bit_len_csi_part1 < 64 ? decodedPayload[0] >> bit_left : 0;
} }
if (pucch_pdu->bit_len_csi_part2>0) { if (pucch_pdu->bit_len_csi_part2 > 0) {
uci_pdu->pduBitmap|=8; uci_pdu->pduBitmap |= 8;
} }
} }