reworking the handling of freq_alloc_bitmap_t to make it more efficient
Co-Authored-By: @schmidtr Assisted-by: Gemini:3 Flash
This commit is contained in:
co-authored by
@schmidtr
parent
0dd1243e6e
commit
29457abe71
+46
-4
@@ -7,17 +7,59 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "assertions.h"
|
||||
|
||||
uint64_t reverse_bits(uint64_t in, int n_bits);
|
||||
void reverse_bits_u8(uint8_t const* in, size_t sz, uint8_t* out);
|
||||
|
||||
static inline int count_bits(uint8_t *arr, int sz)
|
||||
static inline int get_last_bit_index(const uint32_t *arr, int sz)
|
||||
{
|
||||
AssertFatal(sz > 0, "Invalid size %d to get the first bit of array\n", sz);
|
||||
for (int i = sz - 1; i >= 0; i--) {
|
||||
if (arr[i] != 0) {
|
||||
// 31 - clz gives the index of the highest bit (0-31)
|
||||
return (i * 32) + (31 - __builtin_clz(arr[i]));
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t bit_mask(int from_bit, int num_bits)
|
||||
{
|
||||
int total = from_bit + num_bits;
|
||||
uint32_t right_mask = total < 32 ? (0xFFFFFFFF >> (32 - total)) : 0xFFFFFFFF;
|
||||
return (0xFFFFFFFF << from_bit) & right_mask;
|
||||
}
|
||||
|
||||
static inline int get_first_bit_index_mask(const uint32_t *arr, int sz, int from_bit, int num_bits)
|
||||
{
|
||||
// start i from first_bit
|
||||
int i = from_bit / 32;
|
||||
from_bit %= 32;
|
||||
for (; i < sz && num_bits > 0; i++) {
|
||||
uint32_t a = arr[i] & bit_mask(from_bit, num_bits);
|
||||
if (a != 0) {
|
||||
// Find the first set bit in this 32-bit word
|
||||
return (i * 32) + __builtin_ctz(a);
|
||||
}
|
||||
num_bits -= 32 - from_bit;
|
||||
from_bit = 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int get_first_bit_index(const uint32_t *arr, int sz)
|
||||
{
|
||||
return get_first_bit_index_mask(arr, sz, 0, sz * 32);
|
||||
}
|
||||
|
||||
static inline int count_bits(const uint32_t *arr, int sz)
|
||||
{
|
||||
AssertFatal(sz % sizeof(int) == 0, "to implement if needed\n");
|
||||
int ret = 0;
|
||||
for (uint *ptr = (uint *)arr; (uint8_t *)ptr < arr + sz; ptr++)
|
||||
ret += __builtin_popcount(*ptr);
|
||||
// sz is the number of uint32_t elements
|
||||
for (int i = 0; i < sz; i++)
|
||||
ret += __builtin_popcount(arr[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,13 @@ static void nr_pdsch_codeword_scrambling(uint8_t *in, uint32_t size, uint8_t q,
|
||||
nr_codeword_scrambling(in, size, q, Nid, n_RNTI, out);
|
||||
}
|
||||
|
||||
static uint32_t get_block_start_sc(int block_start, int bwp_start, int symbol_sz)
|
||||
{
|
||||
return (block_start + bwp_start) * NR_NB_SC_PER_RB;
|
||||
}
|
||||
|
||||
static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
int start_sc,
|
||||
int symbol_sz,
|
||||
c16_t *txF,
|
||||
c16_t *tx_layer,
|
||||
@@ -35,10 +39,11 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
c16_t *mod_ptrs)
|
||||
{
|
||||
int ptrs_idx = 0;
|
||||
int k = start_sc;
|
||||
c16_t *in = tx_layer;
|
||||
int last_rb = freq_alloc->end[freq_alloc->num_blocks - 1];
|
||||
int first_rb = freq_alloc->start[0];
|
||||
int last_rb = freq_alloc->last_rb;
|
||||
int first_rb = freq_alloc->first_rb;
|
||||
uint32_t start_sc = get_block_start_sc(freq_alloc->first_rb, rel15->BWPStart, symbol_sz);
|
||||
int k = start_sc;
|
||||
for (int j = first_rb; j <= last_rb; j++) {
|
||||
if (check_rb_in_bitmap(freq_alloc, j)) {
|
||||
for (int i = 0; i < NR_NB_SC_PER_RB; i++) {
|
||||
@@ -222,12 +227,11 @@ static inline int dmrs_case00(c16_t *output,
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
const int16_t amp_dmrs,
|
||||
const int amp,
|
||||
int start_sc,
|
||||
int dmrs_port,
|
||||
const int dmrs_Type,
|
||||
int symbol_sz,
|
||||
int l_prime,
|
||||
uint8_t numDmrsCdmGrpsNoData)
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15)
|
||||
{
|
||||
// DMRS params for this dmrs port
|
||||
int Wt[2], Wf[2];
|
||||
@@ -235,30 +239,37 @@ static inline int dmrs_case00(c16_t *output,
|
||||
get_Wf(Wf, dmrs_port, dmrs_Type);
|
||||
const int8_t delta = get_delta(dmrs_port, dmrs_Type);
|
||||
int dmrs_idx = 0;
|
||||
uint32_t start_sc = get_block_start_sc(freq_alloc->first_rb, rel15->BWPStart, symbol_sz);
|
||||
int k = start_sc;
|
||||
c16_t *in = txl;
|
||||
uint8_t k_prime = 0;
|
||||
uint16_t n = 0;
|
||||
int rb_span = freq_alloc->end[freq_alloc->num_blocks - 1] - freq_alloc->start[0] + 1;
|
||||
int sz = rb_span * NR_NB_SC_PER_RB;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
int rb = freq_alloc->start[0] + (i / NR_NB_SC_PER_RB);
|
||||
if (check_rb_in_bitmap(freq_alloc, rb)) {
|
||||
if (k == ((start_sc + get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type)) % (symbol_sz))) {
|
||||
output[k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp_dmrs, 15);
|
||||
dmrs_idx++;
|
||||
k_prime = (k_prime + 1) & 1;
|
||||
n += (k_prime ? 0 : 1);
|
||||
} else if (allowed_xlsch_re_in_dmrs_symbol(k, start_sc, symbol_sz, numDmrsCdmGrpsNoData, dmrs_Type)) {
|
||||
/* Map PTRS Symbol */
|
||||
/* Map DATA Symbol */
|
||||
output[k] = c16mulRealShift(*in++, amp, 15);
|
||||
} else {
|
||||
/* mute RE */
|
||||
output[k] = (c16_t){0};
|
||||
int pos = freq_alloc->first_rb;
|
||||
int last_processed_rb = freq_alloc->first_rb;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, rel15->BWPSize, &pos, &block_start, &block_end)) {
|
||||
// Mute skipped RBs
|
||||
int skipped_sc = (block_start - last_processed_rb) * NR_NB_SC_PER_RB;
|
||||
memset(output + k, 0, skipped_sc * sizeof(c16_t));
|
||||
k += skipped_sc;
|
||||
for (int j = block_start; j <= block_end; j++) {
|
||||
for (int i = 0; i < NR_NB_SC_PER_RB; i++) {
|
||||
if (k == ((start_sc + get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type)) % (symbol_sz))) {
|
||||
output[k] = c16mulRealShift(mod_dmrs[dmrs_idx], Wt[l_prime] * Wf[k_prime] * amp_dmrs, 15);
|
||||
dmrs_idx++;
|
||||
k_prime = (k_prime + 1) & 1;
|
||||
n += (k_prime ? 0 : 1);
|
||||
} else if (allowed_xlsch_re_in_dmrs_symbol(k, start_sc, symbol_sz, rel15->numDmrsCdmGrpsNoData, dmrs_Type)) {
|
||||
/* Map PTRS Symbol */
|
||||
/* Map DATA Symbol */
|
||||
output[k] = c16mulRealShift(*in++, amp, 15);
|
||||
} else {
|
||||
output[k] = (c16_t){0};
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
k++;
|
||||
last_processed_rb = block_end + 1;
|
||||
} // RE loop
|
||||
return in - txl;
|
||||
}
|
||||
@@ -300,11 +311,6 @@ static inline void neg_dmrs(c16_t *in, c16_t *out, int sz)
|
||||
*out++ = i % 2 ? (c16_t){-in[i].r, -in[i].i} : in[i];
|
||||
}
|
||||
|
||||
static uint32_t get_block_start_sc(int block_start, int bwp_start, int symbol_sz)
|
||||
{
|
||||
return (block_start + bwp_start) * NR_NB_SC_PER_RB;
|
||||
}
|
||||
|
||||
static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
int slot,
|
||||
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
|
||||
@@ -323,7 +329,6 @@ static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *dmrs_start)
|
||||
{
|
||||
c16_t *txl = txl_start;
|
||||
uint32_t start_sc = get_block_start_sc(freq_alloc->start[0], rel15->BWPStart, symbol_sz);
|
||||
|
||||
/* calculate if current symbol is PTRS symbols */
|
||||
int ptrs_symbol = 0;
|
||||
@@ -339,17 +344,19 @@ static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
const uint32_t *gold =
|
||||
nr_gold_pdsch(frame_parms->N_RB_DL, frame_parms->symbols_per_slot, rel15->dlDmrsScramblingId, rel15->SCID, slot, l_symbol);
|
||||
nr_modulation(gold, n_ptrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_ptrs);
|
||||
txl += do_ptrs_symbol(rel15, freq_alloc, start_sc, symbol_sz, output, txl, amp, mod_ptrs);
|
||||
txl += do_ptrs_symbol(rel15, freq_alloc, symbol_sz, output, txl, amp, mod_ptrs);
|
||||
|
||||
} else if (rel15->dlDmrsSymbPos & (1 << l_symbol)) {
|
||||
/* Map DMRS Symbol */
|
||||
int dmrs_port = get_dmrs_port(layer, rel15->dmrsPorts);
|
||||
if (l_prime == 0 && dmrs_Type == NFAPI_NR_DMRS_TYPE1) {
|
||||
for (int i = 0; i < freq_alloc->num_blocks; i++) {
|
||||
if (i != 0)
|
||||
start_sc = get_block_start_sc(freq_alloc->start[i], rel15->BWPStart, symbol_sz);
|
||||
const int rb_span = freq_alloc->end[i] - freq_alloc->start[i] + 1;
|
||||
const int sz = rb_span * NR_NB_SC_PER_RB;
|
||||
int pos = 0;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, rel15->BWPSize, &pos, &block_start, &block_end)) {
|
||||
int start_rb = block_start;
|
||||
int nb_rb = block_end - block_start + 1;
|
||||
int start_sc = get_block_start_sc(start_rb, rel15->BWPStart, symbol_sz);
|
||||
const int sz = nb_rb * NR_NB_SC_PER_RB;
|
||||
if (rel15->numDmrsCdmGrpsNoData == 2) {
|
||||
switch (dmrs_port & 3) {
|
||||
case 0:
|
||||
@@ -398,19 +405,20 @@ static inline void do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
|
||||
freq_alloc,
|
||||
amp_dmrs,
|
||||
amp,
|
||||
start_sc,
|
||||
dmrs_port,
|
||||
dmrs_Type,
|
||||
symbol_sz,
|
||||
l_prime,
|
||||
rel15->numDmrsCdmGrpsNoData);
|
||||
rel15);
|
||||
} // generic DMRS case
|
||||
} else { // no PTRS or DMRS in this symbol
|
||||
for (int i = 0; i < freq_alloc->num_blocks; i++) {
|
||||
if (i != 0)
|
||||
start_sc = get_block_start_sc(freq_alloc->start[i], rel15->BWPStart, symbol_sz);
|
||||
const int rb_span = freq_alloc->end[i] - freq_alloc->start[i] + 1;
|
||||
const int sz = rb_span * NR_NB_SC_PER_RB;
|
||||
int pos = 0;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, rel15->BWPSize, &pos, &block_start, &block_end)) {
|
||||
int start_rb = block_start;
|
||||
int nb_rb = block_end - block_start + 1;
|
||||
int start_sc = get_block_start_sc(start_rb, rel15->BWPStart, symbol_sz);
|
||||
const int sz = nb_rb * NR_NB_SC_PER_RB;
|
||||
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, sz);
|
||||
}
|
||||
} // no DMRS/PTRS in symbol
|
||||
@@ -511,7 +519,7 @@ static void nr_pdsch_symbol_processing(void *arg)
|
||||
tx_layers[l] = rdata->tx_layers[l];
|
||||
freq_alloc_bitmap_t *freq_alloc = rdata->freq_alloc;
|
||||
const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
|
||||
const int n_dmrs = (rel15->BWPStart + freq_alloc->end[freq_alloc->num_blocks - 1] + 1) * nb_re_dmrs;
|
||||
const int n_dmrs = (rel15->BWPStart + freq_alloc->last_rb + 1) * nb_re_dmrs;
|
||||
// Loop Over OFDM symbols:
|
||||
c16_t mod_dmrs[(n_dmrs + 63) & ~63] __attribute__((aligned(64)));
|
||||
const int symbol_sz = frame_parms->ofdm_symbol_size;
|
||||
@@ -544,7 +552,7 @@ static void nr_pdsch_symbol_processing(void *arg)
|
||||
nr_modulation(gold, n_dmrs * DMRS_MOD_ORDER, DMRS_MOD_ORDER, (int16_t *)mod_dmrs);
|
||||
|
||||
}
|
||||
uint32_t dmrs_idx = freq_alloc->start[0];
|
||||
uint32_t dmrs_idx = freq_alloc->first_rb;
|
||||
if (rel15->refPoint == 0)
|
||||
dmrs_idx += rel15->BWPStart;
|
||||
dmrs_idx *= rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
|
||||
@@ -572,17 +580,19 @@ static void nr_pdsch_symbol_processing(void *arg)
|
||||
start_meas(&rdata->dlsch_precoding_stats);
|
||||
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz;
|
||||
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
|
||||
for (int b = 0; b < freq_alloc->num_blocks; b++) {
|
||||
int nb_rb_block = freq_alloc->end[b] - freq_alloc->start[b] + 1;
|
||||
int pos = 0;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, rel15->BWPSize, &pos, &block_start, &block_end)) {
|
||||
do_txdataF(txdataF,
|
||||
symbol_sz,
|
||||
txdataF_precoding,
|
||||
gNB,
|
||||
rel15,
|
||||
ant,
|
||||
freq_alloc->start[b],
|
||||
nb_rb_block,
|
||||
block_start,
|
||||
block_end - block_start + 1,
|
||||
txdataF_offset_per_symbol);
|
||||
|
||||
}
|
||||
}
|
||||
stop_meas(&rdata->dlsch_precoding_stats);
|
||||
@@ -802,8 +812,8 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
|
||||
"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbEnd %d rbsize %d\n",
|
||||
rel15->BWPStart,
|
||||
rel15->BWPSize,
|
||||
dlsch->freq_alloc.start[0],
|
||||
dlsch->freq_alloc.end[dlsch->freq_alloc.num_blocks - 1],
|
||||
dlsch->freq_alloc.first_rb,
|
||||
dlsch->freq_alloc.last_rb,
|
||||
dlsch->freq_alloc.num_rbs);
|
||||
|
||||
const int Qm = rel15->qamModOrder[0];
|
||||
|
||||
@@ -900,25 +900,30 @@ void nr_pdcch_channel_estimation(const PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *rxF,
|
||||
c16_t *pil,
|
||||
c16_t *dl_ch,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
int rb_offset,
|
||||
int nb_rb_pdsch,
|
||||
const uint8_t bitmap[36],
|
||||
delay_t *delay,
|
||||
uint32_t *nvar)
|
||||
static void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *rxF,
|
||||
c16_t *pil,
|
||||
c16_t *dl_ch,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
int nb_rb_pdsch,
|
||||
int bwpsize,
|
||||
delay_t *delay,
|
||||
uint32_t *nvar)
|
||||
{
|
||||
c16_t *dl_ch0 = dl_ch;
|
||||
int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
|
||||
c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
memset(dl_ls_est, 0, sizeof(dl_ls_est));
|
||||
int idx = 0;
|
||||
for (int rb = rb_offset; rb < rb_offset + nb_rb_pdsch; rb++) {
|
||||
bool allocated_rb = (bitmap[rb / 8] >> (rb % 8)) & 0x01;
|
||||
if (allocated_rb) {
|
||||
int pos = freq_alloc->first_rb;
|
||||
int last_processed_rb = freq_alloc->first_rb;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, bwpsize, &pos, &block_start, &block_end)) {
|
||||
int skipped_rbs = block_start - last_processed_rb;
|
||||
pil += skipped_rbs * 6;
|
||||
re_offset = (re_offset + skipped_rbs * 12) % frame_parms->ofdm_symbol_size;
|
||||
for (int rb = block_start; rb <= block_end; rb++) {
|
||||
for (int pilot_cnt = 0; pilot_cnt < 6; pilot_cnt += 2) {
|
||||
c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15);
|
||||
#ifdef DEBUG_PDSCH
|
||||
@@ -938,10 +943,8 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pil += 6;
|
||||
re_offset = (re_offset + 12) % frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
last_processed_rb = block_end + 1;
|
||||
}
|
||||
c16_t ch_estimates_time[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
nr_est_delay(frame_parms->ofdm_symbol_size, dl_ls_est, ch_estimates_time, delay);
|
||||
@@ -1071,9 +1074,9 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t *pil,
|
||||
c16_t *dl_ch,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
int rb_offset,
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
int nb_rb_pdsch,
|
||||
const uint8_t bitmap[36],
|
||||
int bwpsize,
|
||||
delay_t *delay,
|
||||
uint32_t *nvar)
|
||||
{
|
||||
@@ -1082,9 +1085,14 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
|
||||
c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
memset(dl_ls_est, 0, sizeof(dl_ls_est));
|
||||
int idx = 0;
|
||||
for (int rb = rb_offset; rb < rb_offset + nb_rb_pdsch; rb++) {
|
||||
bool allocated_rb = (bitmap[rb / 8] >> (rb % 8)) & 0x01;
|
||||
if (allocated_rb) {
|
||||
int pos = freq_alloc->first_rb;
|
||||
int last_processed_rb = freq_alloc->first_rb;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, bwpsize, &pos, &block_start, &block_end)) {
|
||||
int skipped_rbs = block_start - last_processed_rb;
|
||||
pil += skipped_rbs * 4;
|
||||
re_offset = (re_offset + skipped_rbs * 12) % frame_parms->ofdm_symbol_size;
|
||||
for (int rb = block_start; rb <= block_end; rb++) {
|
||||
for (int pilot_cnt = 0; pilot_cnt < 4; pilot_cnt += 2) {
|
||||
c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15);
|
||||
#ifdef DEBUG_PDSCH
|
||||
@@ -1104,10 +1112,8 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pil += 4;
|
||||
re_offset = (re_offset + 12) % frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
last_processed_rb = block_end + 1;
|
||||
}
|
||||
|
||||
c16_t ch_estimates_time[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
|
||||
@@ -1251,7 +1257,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
|
||||
const int ch_offset = fp->ofdm_symbol_size * symbol;
|
||||
const int symbol_offset = fp->ofdm_symbol_size * symbol;
|
||||
int bwp_start_subcarrier = fp->first_carrier_offset + (dlsch->BWPStart + freq_alloc->start[0]) * 12;
|
||||
int bwp_start_subcarrier = fp->first_carrier_offset + (dlsch->BWPStart + freq_alloc->first_rb) * 12;
|
||||
|
||||
#ifdef DEBUG_PDSCH
|
||||
printf(
|
||||
@@ -1268,8 +1274,8 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
|
||||
// generate pilot for gNB port number 1000+p
|
||||
int config_type = dlsch->dmrsConfigType;
|
||||
int rb_offset = freq_alloc->start[0] + (dlsch->refPoint ? 0 : dlsch->BWPStart);
|
||||
int nb_rb_pdsch = freq_alloc->end[freq_alloc->num_blocks - 1] - freq_alloc->start[0] + 1;
|
||||
int rb_offset = freq_alloc->first_rb + (dlsch->refPoint ? 0 : dlsch->BWPStart);
|
||||
int nb_rb_pdsch = freq_alloc->last_rb - freq_alloc->first_rb + 1;
|
||||
int8_t delta = get_delta(p, config_type);
|
||||
c16_t pilot[3280] __attribute__((aligned(16)));
|
||||
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
|
||||
@@ -1297,9 +1303,9 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
&pilot[6 * rb_offset],
|
||||
dl_ch,
|
||||
bwp_start_subcarrier,
|
||||
freq_alloc->start[0],
|
||||
freq_alloc,
|
||||
nb_rb_pdsch,
|
||||
freq_alloc->bitmap,
|
||||
dlsch->BWPSize,
|
||||
&delay,
|
||||
nvar);
|
||||
|
||||
@@ -1309,9 +1315,9 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
&pilot[4 * rb_offset],
|
||||
dl_ch,
|
||||
bwp_start_subcarrier,
|
||||
freq_alloc->start[0],
|
||||
freq_alloc,
|
||||
nb_rb_pdsch,
|
||||
freq_alloc->bitmap,
|
||||
dlsch->BWPSize,
|
||||
&delay,
|
||||
nvar);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "nr_transport_proto_ue.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
#include "T.h"
|
||||
#include "bits.h"
|
||||
#include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
@@ -276,21 +277,26 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
|
||||
int32_t dl_ch_estimates_ext[][rx_size_symbol],
|
||||
unsigned char symbol,
|
||||
uint8_t pilots,
|
||||
uint8_t config_type,
|
||||
int startBWP,
|
||||
const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config,
|
||||
const freq_alloc_bitmap_t *freq_alloc,
|
||||
uint8_t n_dmrs_cdm_groups,
|
||||
uint8_t Nl,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
uint16_t dlDmrsSymbPos,
|
||||
uint32_t csi_res_bitmap,
|
||||
int chest_time_type)
|
||||
{
|
||||
int config_type = dlsch_config->dmrsConfigType;
|
||||
int n_dmrs_cdm_groups = dlsch_config->n_dmrs_cdm_groups;
|
||||
if (config_type == NFAPI_NR_DMRS_TYPE1)
|
||||
AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n", n_dmrs_cdm_groups);
|
||||
AssertFatal(n_dmrs_cdm_groups == 1
|
||||
|| n_dmrs_cdm_groups == 2,
|
||||
"n_dmrs_cdm_groups %d is illegal\n",
|
||||
n_dmrs_cdm_groups);
|
||||
else
|
||||
AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2 || n_dmrs_cdm_groups == 3,
|
||||
"n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups);
|
||||
AssertFatal(n_dmrs_cdm_groups == 1
|
||||
|| n_dmrs_cdm_groups == 2
|
||||
|| n_dmrs_cdm_groups == 3,
|
||||
"n_dmrs_cdm_groups %d is illegal\n",
|
||||
n_dmrs_cdm_groups);
|
||||
|
||||
uint32_t dmrs_rb_bitmap = 0;
|
||||
if (pilots) {
|
||||
@@ -312,13 +318,15 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
|
||||
uint32_t dmrs_csi_overlap_odd = csi_res_odd + dmrs_rb_bitmap;
|
||||
int8_t validDmrsEst;
|
||||
if (chest_time_type == 0)
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos, symbol);
|
||||
validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlsch_config->dlDmrsSymbPos, symbol);
|
||||
else
|
||||
validDmrsEst = get_next_dmrs_symbol_in_slot(dlDmrsSymbPos, 0, 14); // get first dmrs symbol index
|
||||
validDmrsEst = get_next_dmrs_symbol_in_slot(dlsch_config->dlDmrsSymbPos, 0, 14); // get first dmrs symbol index
|
||||
|
||||
for (int b = 0; b < freq_alloc->num_blocks; b++) {
|
||||
int start_rb = freq_alloc->start[b] + startBWP;
|
||||
int nb_rb = freq_alloc->end[b] - freq_alloc->start[b] + 1;
|
||||
int pos = 0;
|
||||
int block_start, block_end;
|
||||
while (find_next_rb_block(freq_alloc->bitmap, dlsch_config->BWPSize, &pos, &block_start, &block_end)) {
|
||||
int start_rb = block_start + dlsch_config->BWPStart;
|
||||
int nb_rb = block_end - block_start + 1;
|
||||
const int start_re = (fp->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % fp->ofdm_symbol_size;
|
||||
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
|
||||
c16_t *rxF_ext = rxdataF_ext[aarx];
|
||||
@@ -1076,13 +1084,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
dl_ch_estimates_ext,
|
||||
symbol,
|
||||
pilots,
|
||||
config_type,
|
||||
dlsch_config->BWPStart,
|
||||
dlsch_config,
|
||||
freq_alloc,
|
||||
dlsch_config->n_dmrs_cdm_groups,
|
||||
nl,
|
||||
fp,
|
||||
dlsch_config->dlDmrsSymbPos,
|
||||
csi_res_bitmap,
|
||||
ue->chest_time);
|
||||
stop_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS);
|
||||
@@ -1112,13 +1117,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
uint32_t csi_re_count = 0;
|
||||
uint32_t csi_res_even = csi_res_bitmap & 0xfff;
|
||||
uint32_t csi_res_odd = (csi_res_bitmap >> 16) & 0xfff;
|
||||
int start = freq_alloc->start[0] + dlsch_config->BWPStart;
|
||||
int end = freq_alloc->end[freq_alloc->num_blocks - 1] + 1;
|
||||
uint32_t count_even = count_bits(&csi_res_even, 1);
|
||||
uint32_t count_odd = count_bits(&csi_res_odd, 1);
|
||||
int start = freq_alloc->first_rb + dlsch_config->BWPStart;
|
||||
int end = freq_alloc->last_rb + 1;
|
||||
for (int rb = start; rb < end; rb++) {
|
||||
if ((freq_alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01) {
|
||||
uint32_t rb_csi_pattern = (rb % 2 == 0) ? csi_res_even : csi_res_odd;
|
||||
csi_re_count += __builtin_popcount(rb_csi_pattern);
|
||||
}
|
||||
if ((freq_alloc->bitmap[rb / 32] >> (rb % 32)) & 0x01)
|
||||
csi_re_count += (rb % 2 == 0) ? count_even : count_odd;
|
||||
}
|
||||
nb_re_pdsch = (nb_re_pdsch > csi_re_count) ? (nb_re_pdsch - csi_re_count) : 0;
|
||||
if (csi_re_count > 0) {
|
||||
|
||||
@@ -377,13 +377,12 @@ int nr_get_ssb_start_sc(int scs,
|
||||
int ssb_sco,
|
||||
frequency_range_t freq_range);
|
||||
|
||||
#define MAX_FA_BLOCKS 10
|
||||
bool find_next_rb_block(const uint32_t *bitmap, int size, int *pos, int *start, int *end);
|
||||
typedef struct {
|
||||
int start[MAX_FA_BLOCKS];
|
||||
int end[MAX_FA_BLOCKS];
|
||||
int first_rb;
|
||||
int last_rb;
|
||||
int num_rbs;
|
||||
int num_blocks;
|
||||
uint8_t bitmap[36];
|
||||
uint32_t bitmap[9];
|
||||
} freq_alloc_bitmap_t;
|
||||
bool check_rb_in_bitmap(const freq_alloc_bitmap_t *alloc, int rb);
|
||||
freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size]);
|
||||
|
||||
@@ -430,32 +430,17 @@ void nr_scale_channel(int size, int ch_estimates_ext[][size], int symb, uint32_t
|
||||
|
||||
freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size])
|
||||
{
|
||||
freq_alloc_bitmap_t alloc = {
|
||||
.num_rbs = 0,
|
||||
.num_blocks = 0
|
||||
};
|
||||
|
||||
bool pos_bit = false;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if ((bitmap[i / 8] >> i % 8) & 0x1) {
|
||||
if (!pos_bit) {
|
||||
pos_bit = true;
|
||||
alloc.start[alloc.num_blocks] = i;
|
||||
AssertFatal(alloc.num_blocks < MAX_FA_BLOCKS, "Number of type0 PDSCH RBG exceeting %d\n", MAX_FA_BLOCKS);
|
||||
alloc.num_blocks++;
|
||||
}
|
||||
alloc.num_rbs++;
|
||||
} else {
|
||||
if (pos_bit) {
|
||||
pos_bit = false;
|
||||
alloc.end[alloc.num_blocks - 1] = i - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pos_bit)
|
||||
alloc.end[alloc.num_blocks - 1] = size - 1;
|
||||
AssertFatal(alloc.num_blocks > 0, "Frequency allocation bitmap empty\n");
|
||||
memcpy(alloc.bitmap, bitmap, alloc_size * sizeof(uint8_t));
|
||||
freq_alloc_bitmap_t alloc = {0};
|
||||
int num_words = (size + 31) / 32;
|
||||
AssertFatal(num_words <= sizeofArray(alloc.bitmap),
|
||||
"freq_alloc_bitmap.bitmap %lu words < %d\n",
|
||||
sizeofArray(alloc.bitmap),
|
||||
num_words);
|
||||
memcpy(alloc.bitmap, bitmap, alloc_size);
|
||||
alloc.num_rbs = count_bits(alloc.bitmap, num_words);
|
||||
alloc.first_rb = get_first_bit_index(alloc.bitmap, num_words);
|
||||
alloc.last_rb = get_last_bit_index(alloc.bitmap, num_words);
|
||||
AssertFatal(alloc.first_rb >= 0 && alloc.last_rb >=0 , "No valid RB set, no bit set in bitmap\n");
|
||||
return alloc;
|
||||
}
|
||||
|
||||
@@ -463,19 +448,57 @@ freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size)
|
||||
{
|
||||
freq_alloc_bitmap_t alloc = {
|
||||
.num_rbs = size,
|
||||
.num_blocks = 1,
|
||||
.start[0] = start,
|
||||
.end[0] = start + size - 1
|
||||
.first_rb = start,
|
||||
.last_rb = start + size - 1
|
||||
};
|
||||
memset(alloc.bitmap, 0, 36 * sizeof(uint8_t));
|
||||
memset(alloc.bitmap, 0, sizeof(alloc.bitmap));
|
||||
for (int i = start; i < size + start; i++)
|
||||
alloc.bitmap[i / 8] += 1 << (i % 8);
|
||||
alloc.bitmap[i / 32] |= (1U << (i % 32));
|
||||
return alloc;
|
||||
}
|
||||
|
||||
bool check_rb_in_bitmap(const freq_alloc_bitmap_t *alloc, int rb)
|
||||
{
|
||||
return (alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01;
|
||||
return (alloc->bitmap[rb / 32] >> (rb % 32)) & 0x01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the next contiguous block of set bits.
|
||||
* @param bitmap The bit buffer
|
||||
* @param size Total bits in the buffer
|
||||
* @param pos Pointer to current bit index (updated by function)
|
||||
* @param start Output: Start index of the found block
|
||||
* @param end Output: End index of the found block
|
||||
* @return true if a block was found, false if no more bits are set
|
||||
*/
|
||||
bool find_next_rb_block(const uint32_t *bitmap, int size, int *pos, int *start, int *end)
|
||||
{
|
||||
AssertFatal(*pos >= 0 && *pos <= size, "Invalid combination of bit index %d and size %d\n", *pos, size);
|
||||
const int words = (size + 31) / 32;
|
||||
|
||||
// Find start of next block
|
||||
int idx = get_first_bit_index_mask(bitmap, words, *pos, size - *pos);
|
||||
if (idx < 0)
|
||||
return false;
|
||||
*start = idx;
|
||||
|
||||
// Find end of block: first zero bit after idx
|
||||
// Reuse get_first_bit_index_from on the inverted bitmap
|
||||
idx++;
|
||||
int word_idx = idx / 32;
|
||||
int n = words - word_idx;
|
||||
uint32_t inv[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
inv[i] = ~bitmap[word_idx + i];
|
||||
if (size % 32 != 0)
|
||||
inv[n - 1] &= (1u << (size % 32)) - 1;
|
||||
|
||||
int end_off = get_first_bit_index_mask(inv, n, idx - word_idx * 32, size - idx);
|
||||
idx = (end_off < 0) ? size : word_idx * 32 + end_off;
|
||||
|
||||
*end = (idx > size) ? size - 1 : idx - 1;
|
||||
*pos = idx; // Update position for the next call
|
||||
return true;
|
||||
}
|
||||
|
||||
void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, const c16_t *rxdata_in, c16_t *rxdata_out, int size)
|
||||
|
||||
@@ -524,8 +524,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
harq_pid,
|
||||
dlsch0_harq->status,
|
||||
dlschCfg->BWPStart,
|
||||
freq_alloc.start[0],
|
||||
freq_alloc.end[freq_alloc.num_blocks - 1],
|
||||
freq_alloc.first_rb,
|
||||
freq_alloc.last_rb,
|
||||
dlschCfg->start_symbol,
|
||||
dlschCfg->number_symbols,
|
||||
dlschCfg->dlDmrsSymbPos,
|
||||
|
||||
@@ -120,8 +120,9 @@ static bool check_csi_resourceMapping_consistency(NR_CSI_RS_ResourceMapping_t re
|
||||
valid = false;
|
||||
break;
|
||||
case NR_CSI_RS_ResourceMapping__nrofPorts_p8: {
|
||||
uint8_t freq = BIT_STRING_to_uint8(&resourceMapping.frequencyDomainAllocation.choice.other);
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2 || count_bits(&freq, 1) != 4) {
|
||||
uint32_t freq32 = 0;
|
||||
freq32 = (uint32_t)BIT_STRING_to_uint8(&resourceMapping.frequencyDomainAllocation.choice.other);
|
||||
if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2 || count_bits(&freq32, 1) != 4) {
|
||||
// row 7 and 8 -> l0+1
|
||||
if (resourceMapping.firstOFDMSymbolInTimeDomain == 13)
|
||||
valid = false;
|
||||
|
||||
Reference in New Issue
Block a user