From c73353bed3da696551fbfd4a43b28cc3f1cde035 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Sun, 19 Jan 2025 17:33:28 +0100 Subject: [PATCH] comprehensive dmrs reception and better cpu efficiency --- openair1/PHY/NR_REFSIG/dmrs_nr.h | 2 +- openair1/PHY/NR_REFSIG/nr_dmrs_rx.c | 95 ++++++++++------------------- openair1/PHY/NR_REFSIG/ptrs_nr.c | 2 +- openair1/PHY/defs_nr_common.h | 1 - 4 files changed, 35 insertions(+), 65 deletions(-) diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 5a3160857a..001aae4150 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -61,7 +61,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, uint8_t numDmrsCdmGrpsNoData, uint8_t dmrs_type); -void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order); +void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, int16_t *output, int mod_order); int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol); uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb, uint8_t start); int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 1c217d8da0..01b05071a2 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -49,10 +49,21 @@ static const int wt2[12][2] = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}, {1, -1}}; // complex conjugate of mod table -static const c16_t nr_rx_mod_table[7] = - {{0, 0}, {23170, -23170}, {-23170, 23170}, {23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}}; -static const c16_t nr_rx_nmod_table[7] = - {{0, 0}, {-23170, 23170}, {23170, -23170}, {-23170, 23170}, {-23170, -23170}, {23170, 23170}, {23170, -23170}}; +static const c16_t nr_rx_mod_table[4] = {{23170, -23170}, {23170, 23170}, {-23170, -23170}, {-23170, 23170}}; + +static inline c16_t get_modulated(const uint32_t *gold_sequence, const int idx_gold, const bool inverse) +{ + const uint8_t *gold = (uint8_t *)gold_sequence; + const int swap2bits[4] = {0, 2, 1, 3}; + const uint8_t packedbyte = gold[idx_gold / 4]; + const int indexByte = (idx_gold * 2) & 7; + const int idx = swap2bits[(packedbyte >> indexByte) & 3]; + const c16_t val = nr_rx_mod_table[idx]; + if (inverse) + return val; + else + return (c16_t){-val.r, -val.i}; +} int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned int Ns, @@ -64,41 +75,27 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, uint32_t re_offset, uint8_t dmrs_type) { - int8_t w, nb_dmrs; - unsigned char idx=0; - int k; typedef int array_of_w[2]; const array_of_w *wf = (dmrs_type == pusch_dmrs_type1) ? wf1 : wf2; const array_of_w *wt = (dmrs_type == pusch_dmrs_type1) ? wt1 : wt2; - int dmrs_offset = re_offset/((dmrs_type==pusch_dmrs_type1)?2:3); - + const int dmrs_offset = re_offset / ((dmrs_type == pusch_dmrs_type1) ? 2 : 3); if (dmrs_type > 2) LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type+1); + const int nb_dmrs = dmrs_type == pusch_dmrs_type1 ? 6 : 4; + if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) { if (gNB->frame_parms.Ncp == NORMAL) { - nb_dmrs = ((dmrs_type==pusch_dmrs_type1) ? 6:4); - for (int i=dmrs_offset; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - output[k] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; + for (int k = 0; k < nb_pusch_rb * nb_dmrs; k++) { + int i = k + dmrs_offset; + int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); + output[k] = get_modulated(nr_gold_pusch, i, w == 1); #ifdef DEBUG_PUSCH printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); - printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", - i, - idx, - nr_gold_pusch[(i << 1) >> 5], - (((nr_gold_pusch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), - (((nr_gold_pusch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), - output[k].r, - output[k].i); + printf("i %d idx %d pusch mod_dmrs %d %d\n", i, idx, output[k].r, output[k].i); #endif - } } else { LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n"); @@ -119,9 +116,6 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short nb_pdsch_rb, uint8_t config_type) { - int8_t w; - unsigned char idx=0; - typedef int array_of_w[2]; const array_of_w *wf = (config_type == NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2; const array_of_w *wt = (config_type == NFAPI_NR_DMRS_TYPE1) ? wt1 : wt2; @@ -132,22 +126,13 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, if ((p >= 1000) && (p < ((config_type == NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) { if (ue->frame_parms.Ncp == NORMAL) { for (int i = 0; i < nb_pdsch_rb * ((config_type == NFAPI_NR_DMRS_TYPE1) ? 6 : 4); i++) { - w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); - const c16_t *mod_table = (w == 1) ? nr_rx_mod_table : nr_rx_nmod_table; + int w = (wf[p - 1000][i & 1]) * (wt[p - 1000][lp]); + output[i] = get_modulated(nr_gold_pdsch, i, w == 1); - idx = ((((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1) << 1) ^ (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1); - output[i] = mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; #ifdef DEBUG_PDSCH printf("nr_pdsch_dmrs_rx dmrs config type %d port %d nb_pdsch_rb %d\n", config_type, p, nb_pdsch_rb); printf("wf[%d] = %d wt[%d]= %d\n", i & 1, wf[p - 1000][i & 1], lp, wt[p - 1000][lp]); - printf("i %d idx %d pdsch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", - i, - idx, - nr_gold_pdsch[(i << 1) >> 5], - (((nr_gold_pdsch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), - (((nr_gold_pdsch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), - output[i].r, - output[i].i); + printf("i %d idx %d pdsch mod_dmrs %d %d\n", i, idx, output[i].r, output[i].i); #endif } } else { @@ -167,24 +152,12 @@ int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue, unsigned short p, unsigned short nb_rb_coreset) { - uint8_t idx=0; - //uint8_t pdcch_rb_offset =0; - //nr_gold_pdcch += ((int)floor(ue->frame_parms.ssb_start_subcarrier/12)+pdcch_rb_offset)*3/32; - if (p==2000) { for (int i=0; i<((nb_rb_coreset*6)>>1); i++) { - idx = ((((nr_gold_pdcch[(i<<1)>>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pdcch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - output[i] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; + output[i] = get_modulated(nr_gold_pdcch, i, true); #ifdef DEBUG_PDCCH if (i<8) - printf("i %d idx %d pdcch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", - i, - idx, - nr_gold_pdcch[(i << 1) >> 5], - (((nr_gold_pdcch[(i << 1) >> 5]) >> ((i << 1) & 0x1f)) & 1), - (((nr_gold_pdcch[((i << 1) + 1) >> 5]) >> (((i << 1) + 1) & 0x1f)) & 1), - output[i].r, - output[i].i); + printf("i %d idx %d pdcch mod_dmrs %d %d\n", i, idx, output[i].r, output[i].i); #endif } } @@ -194,8 +167,7 @@ int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue, void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output, bool sidelink) { - int m,m0,m1; - uint8_t idx=0; + int m0, m1; if (sidelink) { AssertFatal(symbol == 0 || (symbol >= 5 && symbol <= 12), "illegal symbol %d\n", symbol); m0 = (symbol) ? (symbol - 4) * 33 : 0; @@ -216,9 +188,8 @@ void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output } // printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1); /// QPSK modulation - for (m=m0; m>5])>>((m<<1)&0x1f))&1)<<1) ^ (((nr_gold_pbch[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1); - output[m - m0] = nr_rx_mod_table[NR_MOD_TABLE_QPSK_OFFSET + idx]; + for (int m = m0; m < m1; m++) { + output[m - m0] = get_modulated(nr_gold_pbch, m, true); #ifdef DEBUG_PBCH if (m<16) @@ -235,7 +206,7 @@ void nr_pbch_dmrs_rx(int symbol, const unsigned int *nr_gold_pbch, c16_t *output \param length is number of RE in a OFDM symbol \param *output pointer to all ptrs RE in a OFDM symbol */ -void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, uint16_t offset, int mod_order) +void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, int mod_order) { uint8_t idx, b_idx; for (int i=0; i>b_idx)&1)<<(mod_order-j-1); } - output[i] = nr_rx_mod_table[offset + idx]; + output[i] = nr_rx_mod_table[idx]; } } diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index eae3cebb01..c632585389 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -213,7 +213,7 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, c16_t dmrs_comp_p[(1 + sc_per_symbol / 4) * 4]; /* generate PTRS RE for the symbol */ - nr_gen_ref_conj_symbols(gold_seq,sc_per_symbol*2,(int16_t*)ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK + nr_gen_ref_conj_symbols(gold_seq, sc_per_symbol * 2, (int16_t *)ptrs_p, 2); // 2 for QPSK uint32_t re_cnt = 0, cnt = 0; /* loop over all sub carriers to get compensated RE on ptrs symbols*/ for (int re = 0; re < NR_NB_SC_PER_RB * nb_rb; re++) { diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index f6f18eb942..da01d7e639 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -52,7 +52,6 @@ #define NR_MOD_TABLE_SIZE_SHORT 686 #define NR_MOD_TABLE_BPSK_OFFSET 1 -#define NR_MOD_TABLE_QPSK_OFFSET 3 #define NR_MOD_TABLE_QAM16_OFFSET 7 #define NR_MOD_TABLE_QAM64_OFFSET 23 #define NR_MOD_TABLE_QAM256_OFFSET 87