Reformat pucch_rx.c
This commit is contained in:
committed by
francescomani
parent
ec7ad3b87c
commit
2cb96ea534
@@ -29,7 +29,7 @@
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#include<stdio.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.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");
|
||||
}
|
||||
|
||||
|
||||
int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB,nfapi_nr_pucch_pdu_t* pucch_pdu) {
|
||||
|
||||
int i=0;
|
||||
int get_pucch0_cs_lut_index(PHY_VARS_gNB *gNB, nfapi_nr_pucch_pdu_t *pucch_pdu)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
#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
|
||||
|
||||
for (i=0;i<gNB->pucch0_lut.nb_id;i++) {
|
||||
if (gNB->pucch0_lut.Nid[i] == pucch_pdu->hopping_id) break;
|
||||
for (i = 0; i < gNB->pucch0_lut.nb_id; i++) {
|
||||
if (gNB->pucch0_lut.Nid[i] == pucch_pdu->hopping_id)
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("found index %d\n",i);
|
||||
printf("found index %d\n", i);
|
||||
#endif
|
||||
if (i<gNB->pucch0_lut.nb_id) return(i);
|
||||
if (i < gNB->pucch0_lut.nb_id)
|
||||
return (i);
|
||||
|
||||
#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
|
||||
// initialize
|
||||
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 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.Nid[gNB->pucch0_lut.nb_id] = pucch_pdu->hopping_id;
|
||||
for (int slot = 0; slot < 10 << pucch_pdu->subcarrier_spacing; slot++)
|
||||
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.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] = {
|
||||
{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}
|
||||
};
|
||||
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] = {{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,
|
||||
c16_t **rxdataF,
|
||||
@@ -179,24 +178,32 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
|
||||
int nr_sequences;
|
||||
const uint8_t *mcs;
|
||||
if(pucch_pdu->bit_len_harq==0){
|
||||
mcs=table1_mcs;
|
||||
nr_sequences=1;
|
||||
}
|
||||
else if(pucch_pdu->bit_len_harq==1){
|
||||
mcs=table1_mcs;
|
||||
nr_sequences=4>>(1-pucch_pdu->sr_flag);
|
||||
}
|
||||
else{
|
||||
mcs=table2_mcs;
|
||||
nr_sequences=8>>(1-pucch_pdu->sr_flag);
|
||||
if (pucch_pdu->bit_len_harq == 0) {
|
||||
mcs = table1_mcs;
|
||||
nr_sequences = 1;
|
||||
} else if (pucch_pdu->bit_len_harq == 1) {
|
||||
mcs = table1_mcs;
|
||||
nr_sequences = 4 >> (1 - pucch_pdu->sr_flag);
|
||||
} else {
|
||||
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",
|
||||
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);
|
||||
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",
|
||||
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
|
||||
* 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
|
||||
* 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);
|
||||
// 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};
|
||||
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]);
|
||||
LOG_D(PHY, "pucch0: u %d, v %d\n", u[0], v[0]);
|
||||
|
||||
if (pucch_pdu->freq_hop_flag == 1) {
|
||||
nr_group_sequence_hopping(pucch_GroupHopping,
|
||||
@@ -221,47 +228,46 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
slot,
|
||||
&u[1],
|
||||
&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;
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
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_im[0] = table_5_2_2_2_2_Im[u[0]];
|
||||
x_re[1] = table_5_2_2_2_2_Re[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));
|
||||
|
||||
int64_t xrtmag=0,xrtmag_next=0;
|
||||
uint8_t maxpos=0;
|
||||
uint8_t index=0;
|
||||
int64_t xrtmag = 0, xrtmag_next = 0;
|
||||
uint8_t maxpos = 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;
|
||||
|
||||
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;
|
||||
|
||||
re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset;
|
||||
if (re_offset[l]>= frame_parms->ofdm_symbol_size)
|
||||
re_offset[l]-=frame_parms->ofdm_symbol_size;
|
||||
re_offset[l] = (12 * prb_offset[l]) + frame_parms->first_carrier_offset;
|
||||
if (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];
|
||||
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;
|
||||
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(rp, &tmp_rp[re_offset[l]], neg_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));
|
||||
|
||||
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;
|
||||
int pucch_power_dBtimes10 = 10 * dB_fixed(signal_energy);
|
||||
|
||||
//int32_t no_corr = 0;
|
||||
// int32_t no_corr = 0;
|
||||
int seq_index = 0;
|
||||
|
||||
for (int i = 0; i < nr_sequences; i++) {
|
||||
c64_t corr[frame_parms->nb_antennas_rx][2];
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
for (int l=0;l<pucch_pdu->nr_of_symbols;l++) {
|
||||
seq_index = (pucch_pdu->initial_cyclic_shift+
|
||||
mcs[i]+
|
||||
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
|
||||
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
for (int l = 0; l < pucch_pdu->nr_of_symbols; l++) {
|
||||
seq_index =
|
||||
(pucch_pdu->initial_cyclic_shift + mcs[i] + gNB->pucch0_lut.lut[cs_ind][slot][l + pucch_pdu->start_symbol_index]) % 12;
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]);
|
||||
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};
|
||||
corr[aa][l] = (c64_t){0};
|
||||
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];
|
||||
@@ -303,10 +308,14 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
corr[aa][l].i >>= 31;
|
||||
}
|
||||
}
|
||||
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
|
||||
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 IDFT[%d/%d] = (%ld,%ld)=>%f\n",
|
||||
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],
|
||||
@@ -334,33 +343,32 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]);
|
||||
}
|
||||
|
||||
if (temp>xrtmag) {
|
||||
if (temp > xrtmag) {
|
||||
xrtmag_next = xrtmag;
|
||||
xrtmag=temp;
|
||||
LOG_D(PHY,"Sequence %d xrtmag %ld xrtmag_next %ld\n", i, xrtmag, xrtmag_next);
|
||||
maxpos=i;
|
||||
xrtmag = temp;
|
||||
LOG_D(PHY, "Sequence %d xrtmag %ld xrtmag_next %ld\n", i, xrtmag, xrtmag_next);
|
||||
maxpos = i;
|
||||
uci_stats->current_pucch0_stat0 = 0;
|
||||
int64_t temp2=0,temp3=0;;
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
int64_t temp2 = 0, temp3 = 0;
|
||||
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
temp2 += squaredMod(corr[aa][0]);
|
||||
if (pucch_pdu->nr_of_symbols==2)
|
||||
if (pucch_pdu->nr_of_symbols == 2)
|
||||
temp3 += squaredMod(corr[aa][1]);
|
||||
}
|
||||
uci_stats->current_pucch0_stat0= dB_fixed64(temp2);
|
||||
if ( pucch_pdu->nr_of_symbols==2)
|
||||
uci_stats->current_pucch0_stat0 = dB_fixed64(temp2);
|
||||
if (pucch_pdu->nr_of_symbols == 2)
|
||||
uci_stats->current_pucch0_stat1 = dB_fixed64(temp3);
|
||||
}
|
||||
else if (temp>xrtmag_next)
|
||||
} else if (temp > xrtmag_next)
|
||||
xrtmag_next = temp;
|
||||
}
|
||||
|
||||
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_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));
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("PUCCH 0 : maxpos %d\n",maxpos);
|
||||
printf("PUCCH 0 : maxpos %d\n", maxpos);
|
||||
#endif
|
||||
|
||||
index=maxpos;
|
||||
index = maxpos;
|
||||
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]];
|
||||
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
|
||||
cqi = (640 + SNRtimes10) / 5;
|
||||
|
||||
bool no_conf=false;
|
||||
if (nr_sequences>1) {
|
||||
bool no_conf = false;
|
||||
if (nr_sequences > 1) {
|
||||
if (/*xrtmag_dBtimes10 < (30+xrtmag_next_dBtimes10) ||*/ SNRtimes10 < gNB->pucch0_thres) {
|
||||
no_conf=true;
|
||||
no_conf = true;
|
||||
LOG_D(PHY,
|
||||
"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n",
|
||||
frame,
|
||||
@@ -397,28 +405,27 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
gNB->bad_pucch += no_conf;
|
||||
// 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->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(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_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_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 {
|
||||
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.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,
|
||||
"[DLSCH/PDSCH/PUCCH] %d.%d HARQ %s with confidence level %s xrt_mag "
|
||||
"%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));
|
||||
|
||||
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;
|
||||
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++;
|
||||
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++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uci_pdu->harq.num_harq = 2;
|
||||
uci_pdu->harq.harq_confidence_level = no_conf;
|
||||
|
||||
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[1].harq_value = !(index & 0x01);
|
||||
uci_pdu->harq.harq_list[0].harq_value = !((index >> 1) & 0x01);
|
||||
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",
|
||||
frame,
|
||||
slot,
|
||||
@@ -473,11 +480,11 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
||||
cqi,
|
||||
SNRtimes10);
|
||||
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;
|
||||
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++;
|
||||
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;
|
||||
// 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;
|
||||
// mcs = 0 except for PUCCH format 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.
|
||||
// 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.
|
||||
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:
|
||||
@@ -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 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,
|
||||
// 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 PUCCH_Frequency_Hopping = 0 ; // from higher layers
|
||||
const bool intraSlotFrequencyHopping = startingPRB != startingPRB_intraSlotHopping;
|
||||
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n",intraSlotFrequencyHopping);
|
||||
printf("\t [nr_generate_pucch1] intraSlotFrequencyHopping = %d \n", intraSlotFrequencyHopping);
|
||||
#endif
|
||||
/*
|
||||
* 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_dmrs_rx[MAX_SIZE_Z] = {0};
|
||||
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;
|
||||
}
|
||||
|
||||
for (int n=0; n<12; n++) {
|
||||
for (int n = 0; n < 12; n++) {
|
||||
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 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 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};
|
||||
//generating transmitted sequence and dmrs
|
||||
// generating transmitted sequence and dmrs
|
||||
for (int l = 0; l < nrofSymbols; l++) {
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n",
|
||||
l,lprime);
|
||||
printf("\t [nr_generate_pucch1] for symbol l=%d, lprime=%d\n", l, lprime);
|
||||
#endif
|
||||
// y_n contains the complex value d multiplied by the sequence r_u_v
|
||||
// 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;
|
||||
|
||||
#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);
|
||||
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
|
||||
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
|
||||
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 table = {table_5_2_2_2_2_Re[u][n], table_5_2_2_2_2_Im[u][n]};
|
||||
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)
|
||||
* 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)
|
||||
* (defined in table_6_3_2_4_1_2_Wi_Re and table_6_3_2_4_1_2_Wi_Im)
|
||||
* 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) (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)
|
||||
*
|
||||
*/
|
||||
@@ -672,8 +680,10 @@ void nr_decode_pucch1(c16_t **rxdataF,
|
||||
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);
|
||||
printf(
|
||||
"\t [nr_generate_pucch1] block-wise spread with the orthogonal sequence wi(m) if intraSlotFrequencyHopping = %d, "
|
||||
"intra-slot hopping disabled\n",
|
||||
intraSlotFrequencyHopping);
|
||||
#endif
|
||||
// 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
|
||||
@@ -693,8 +703,8 @@ void nr_decode_pucch1(c16_t **rxdataF,
|
||||
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)
|
||||
|
||||
if(l%2==1){
|
||||
for (int m=0; m < N_SF_mprime_PUCCH_1; m++) {
|
||||
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 (l / 2 == m) {
|
||||
@@ -707,7 +717,7 @@ void nr_decode_pucch1(c16_t **rxdataF,
|
||||
}
|
||||
}
|
||||
} 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],
|
||||
table_6_3_2_4_1_2_Wi_Im[N_SF_mprime_PUCCH_DMRS_1][w_index][m]};
|
||||
if (l / 2 == m) {
|
||||
@@ -725,8 +735,10 @@ void nr_decode_pucch1(c16_t **rxdataF,
|
||||
|
||||
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);
|
||||
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 contains N_SF_mprime from table 6.3.2.4.1-1
|
||||
// (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 =
|
||||
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);
|
||||
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 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 =
|
||||
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;
|
||||
}
|
||||
}
|
||||
//Decoding QPSK or BPSK symbols to obtain payload bits
|
||||
// Decoding QPSK or BPSK symbols to obtain payload bits
|
||||
if (nr_bit == 1) {
|
||||
if ((d.r + d.i) > 0) {
|
||||
*payload = 0;
|
||||
@@ -855,18 +874,20 @@ void nr_decode_pucch1(c16_t **rxdataF,
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {c16_t cw[16];} cw_t;
|
||||
static cw_t pucch2_3bit[8] __attribute__((aligned(32)));
|
||||
typedef struct {
|
||||
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_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_8bit[256] __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_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};
|
||||
|
||||
typedef struct {
|
||||
@@ -877,12 +898,12 @@ static simde__m128i pucch2_polar_llr_num_lut[256];
|
||||
|
||||
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++) {
|
||||
uint32_t out = encodeSmallBlock(cw, b);
|
||||
uint16_t *tmp = (uint16_t *)pucch2_lut[b - 3][cw].cw;
|
||||
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++) {
|
||||
@@ -912,22 +933,20 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
c16_t **rxdataF,
|
||||
int frame,
|
||||
int slot,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t* pucch_pdu)
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu)
|
||||
{
|
||||
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);
|
||||
const int nb_symbols=pucch_pdu->nr_of_symbols;
|
||||
// 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;
|
||||
|
||||
AssertFatal(nb_symbols == 1 || nb_symbols == 2,
|
||||
"Illegal number of symbols for PUCCH 2 %d\n",
|
||||
nb_symbols);
|
||||
AssertFatal(nb_symbols == 1 || nb_symbols == 2, "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",
|
||||
pucch_pdu->prb_start);
|
||||
|
||||
//extract pucch and dmrs first
|
||||
// extract pucch and dmrs first
|
||||
|
||||
int l2 = pucch_pdu->start_symbol_index;
|
||||
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
|
||||
re_offset[1] = re_offset[0];
|
||||
}
|
||||
AssertFatal(pucch_pdu->prb_size * nb_symbols > 1,
|
||||
"number of PRB*SYMB (%d,%d)< 2",
|
||||
pucch_pdu->prb_size,
|
||||
nb_symbols);
|
||||
AssertFatal(pucch_pdu->prb_size * nb_symbols > 1, "number of PRB*SYMB (%d,%d)< 2", pucch_pdu->prb_size, nb_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);
|
||||
@@ -954,16 +970,15 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
memset(rp, 0, sizeof(rp));
|
||||
|
||||
int64_t pucch2_lev = 0;
|
||||
for (int aa=0;aa<Prx;aa++){
|
||||
for (int symb=0;symb<nb_symbols;symb++) {
|
||||
for (int aa = 0; aa < Prx; aa++) {
|
||||
for (int symb = 0; symb < nb_symbols; symb++) {
|
||||
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) {
|
||||
memcpy(rp[aa][symb], &tmp_rp[re_offset[symb]], nb_re_pucch * sizeof(c16_t));
|
||||
}
|
||||
else {
|
||||
int neg_length = frame_parms->ofdm_symbol_size-re_offset[symb];
|
||||
int pos_length = nb_re_pucch-neg_length;
|
||||
} else {
|
||||
int neg_length = frame_parms->ofdm_symbol_size - re_offset[symb];
|
||||
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][neg_length], tmp_rp, pos_length * sizeof(c16_t));
|
||||
}
|
||||
@@ -988,8 +1003,8 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
scaling);
|
||||
|
||||
int prb_size_ext = pucch_pdu->prb_size + (pucch_pdu->prb_size & 1);
|
||||
int nc_group_size=1; // 2 PRB
|
||||
int ngroup = prb_size_ext/nc_group_size/2;
|
||||
int nc_group_size = 1; // 2 PRB
|
||||
int ngroup = prb_size_ext / nc_group_size / 2;
|
||||
c32_t corr32[nb_symbols][ngroup][Prx];
|
||||
memset(corr32, 0, sizeof(corr32));
|
||||
const int nb_re_data = 8 * prb_size_ext;
|
||||
@@ -1035,13 +1050,12 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
#endif
|
||||
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;
|
||||
for (int i = 0; i < nb_re_data; i += 4)
|
||||
*(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)));
|
||||
|
||||
// extract DMRS
|
||||
@@ -1074,7 +1088,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
% (1U << 31); // c_init calculation according to TS38.211 subclause
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
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
|
||||
uint32_t *sGold = gold_cache(x2, starting_prb / 4 + ngroup / 2);
|
||||
// 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);
|
||||
}
|
||||
#endif
|
||||
c16_t rdmrs_gold[Prx][nb_re_dmrs] __attribute__((aligned(32)));
|
||||
for (int aa = 0; aa < Prx; aa++)
|
||||
mult_complex_vectors(rdmrs_ext[aa], pil_dmrs, rdmrs_gold[aa], nb_re_dmrs, 0);
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
c16_t *pil_ptr = pil_dmrs;
|
||||
for (int group = 0; group < ngroup; group++) {
|
||||
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
|
||||
// non-coherent combining across groups
|
||||
c16_t *rdmrs_p = &rdmrs_ext[aa][8 * group];
|
||||
for (int z = 0; z < 8; z++) {
|
||||
c16_t tmp = c16mulShift(*rdmrs_p++, *pil_ptr++, scaling);
|
||||
corr32[symb][group][aa].r += tmp.r;
|
||||
corr32[symb][group][aa].i += tmp.i;
|
||||
}
|
||||
c16_t rdmrs_gold[Prx][nb_re_dmrs] __attribute__((aligned(32)));
|
||||
for (int aa = 0; aa < Prx; aa++)
|
||||
mult_complex_vectors(rdmrs_ext[aa], pil_dmrs, rdmrs_gold[aa], nb_re_dmrs, 0);
|
||||
for (int aa = 0; aa < Prx; aa++) {
|
||||
c16_t *pil_ptr = pil_dmrs;
|
||||
for (int group = 0; group < ngroup; group++) {
|
||||
// each group has 8*nc_group_size elements, compute 1 complex correlation with DMRS per group
|
||||
// non-coherent combining across groups
|
||||
c16_t *rdmrs_p = &rdmrs_ext[aa][8 * group];
|
||||
for (int z = 0; z < 8; z++) {
|
||||
c16_t tmp = c16mulShift(*rdmrs_p++, *pil_ptr++, scaling);
|
||||
corr32[symb][group][aa].r += tmp.r;
|
||||
corr32[symb][group][aa].i += tmp.i;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_NR_PUCCH_RX
|
||||
log_dump(PHY, corr32[symb][0], 8, LOG_DUMP_C32, "corr32:");
|
||||
#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,
|
||||
"illegal length (%d : %d,%d,%d,%d)\n",
|
||||
nb_bit,
|
||||
@@ -1176,20 +1193,23 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
pucch_pdu->bit_len_csi_part2);
|
||||
|
||||
uint64_t decodedPayload[nb_symbols];
|
||||
memset(decodedPayload,0,sizeof(decodedPayload));
|
||||
memset(decodedPayload, 0, sizeof(decodedPayload));
|
||||
int8_t corr_dB;
|
||||
int decoderState = 2;
|
||||
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)
|
||||
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
|
||||
uint64_t corr=0;
|
||||
int cw_ML=0;
|
||||
uint64_t corr = 0;
|
||||
int cw_ML = 0;
|
||||
for (int cw = 0; cw < 1 << nb_bit; cw++) {
|
||||
uint64_t corr_tmp = 0;
|
||||
for (int symb=0;symb<nb_symbols;symb++) {
|
||||
for (int group=0;group<ngroup;group++) {
|
||||
for (int symb = 0; symb < nb_symbols; symb++) {
|
||||
for (int group = 0; group < ngroup; group++) {
|
||||
// do complex correlation
|
||||
for (int aa = 0; aa < Prx; aa++) {
|
||||
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
|
||||
}
|
||||
}// group loop
|
||||
} // group loop
|
||||
} // symb loop
|
||||
if (corr_tmp > corr) {
|
||||
corr = corr_tmp;
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
} // cw loop
|
||||
corr_dB = dB_fixed64(corr);
|
||||
#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
|
||||
decodedPayload[0]=(uint64_t)cw_ML;
|
||||
|
||||
decodedPayload[0] = (uint64_t)cw_ML;
|
||||
|
||||
} else if (nb_bit >= 12) { // polar coded case
|
||||
|
||||
|
||||
simde__m128i llrs[pucch_pdu->prb_size * 2 * nb_symbols];
|
||||
// non-coherent LLR computation on groups of 4 REs (half-PRBs)
|
||||
uint64_t corr = 0;
|
||||
const simde__m128i ones = simde_mm_set1_epi16(1);
|
||||
for (int symb=0;symb<nb_symbols;symb++) {
|
||||
for (int half_prb=0;half_prb<(2*pucch_pdu->prb_size);half_prb++) {
|
||||
for (int symb = 0; symb < nb_symbols; symb++) {
|
||||
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_den = simde_mm_set1_epi16(0);
|
||||
for (int cw=0;cw<256;cw++) {
|
||||
int32_t corr_tmp=0;
|
||||
for (int aa=0;aa<Prx;aa++) {
|
||||
simde__m128i llr_den = simde_mm_set1_epi16(0);
|
||||
for (int cw = 0; cw < 256; cw++) {
|
||||
int32_t corr_tmp = 0;
|
||||
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 part2 = simde_mm_set_epi64x(0ULL, *(int64_t *)&pucch2_polar_4bit[cw >> 4].cw);
|
||||
simde__m128i factor = simde_mm_unpacklo_epi16(part1, part2);
|
||||
@@ -1280,12 +1300,13 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
// compute llrs
|
||||
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
|
||||
} // symb
|
||||
|
||||
// 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
|
||||
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) {
|
||||
uci_pdu->pduBitmap|=1;
|
||||
uci_pdu->pduBitmap |= 1;
|
||||
uci_pdu->sr.sr_bit_len = 1;
|
||||
uci_pdu->sr.sr_payload = malloc(1);
|
||||
uci_pdu->sr.sr_payload[0] = decodedPayload[0]&1;
|
||||
decodedPayload[0] = decodedPayload[0]>>1;
|
||||
uci_pdu->sr.sr_payload[0] = decodedPayload[0] & 1;
|
||||
decodedPayload[0] = decodedPayload[0] >> 1;
|
||||
}
|
||||
// csi
|
||||
if (pucch_pdu->bit_len_csi_part1>0) {
|
||||
uci_pdu->pduBitmap|=4;
|
||||
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;
|
||||
if ((pucch_pdu->bit_len_csi_part1&7) > 0) csi_part1_bytes++;
|
||||
uci_pdu->csi_part1.csi_part1_payload = (uint8_t*)malloc(csi_part1_bytes);
|
||||
if (pucch_pdu->bit_len_csi_part1 > 0) {
|
||||
uci_pdu->pduBitmap |= 4;
|
||||
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;
|
||||
if ((pucch_pdu->bit_len_csi_part1 & 7) > 0)
|
||||
csi_part1_bytes++;
|
||||
uci_pdu->csi_part1.csi_part1_payload = (uint8_t *)malloc(csi_part1_bytes);
|
||||
uci_pdu->csi_part1.csi_part1_crc = decoderState;
|
||||
int i=0;
|
||||
for (;i<csi_part1_bytes-1;i++) {
|
||||
int i = 0;
|
||||
for (; i < csi_part1_bytes - 1; i++) {
|
||||
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);
|
||||
decodedPayload[0] = pucch_pdu->bit_len_csi_part1 < 64 ? decodedPayload[0] >> bit_left : 0;
|
||||
}
|
||||
|
||||
if (pucch_pdu->bit_len_csi_part2>0) {
|
||||
uci_pdu->pduBitmap|=8;
|
||||
|
||||
if (pucch_pdu->bit_len_csi_part2 > 0) {
|
||||
uci_pdu->pduBitmap |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user