Merge remote-tracking branch 'origin/type0_PDSCH' into integration_2025_w42 (!3495)

Type0 PDSCH frequency allocation at L1 UE
This commit is contained in:
Jaroslava Fiedlerova
2025-10-13 14:18:51 +02:00
11 changed files with 289 additions and 263 deletions
@@ -942,51 +942,57 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
c16_t *pil,
c16_t *dl_ch,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
int rb_offset,
int nb_rb_pdsch,
const uint8_t bitmap[36],
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 nest_count = 0;
uint64_t noise_amp2 = 0;
for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt += 2) {
c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15);
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) {
for (int pilot_cnt = 0; pilot_cnt < 6; pilot_cnt += 2) {
c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15);
#ifdef DEBUG_PDSCH
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i);
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i);
#endif
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15);
#ifdef DEBUG_PDSCH
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i);
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i);
#endif
c16_t ch = c16addShift(ch_l, ch_r, 1);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
for (int k = pilot_cnt << 1; k < (pilot_cnt << 1) + 4; k++) {
dl_ls_est[k] = ch;
c16_t ch = c16addShift(ch_l, ch_r, 1);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
for (int k = 0; k < 4; k++) {
dl_ls_est[idx] = ch;
idx++;
}
}
} else {
pil += 6;
re_offset = (re_offset + 12) % frame_parms->ofdm_symbol_size;
}
}
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);
int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP);
c16_t *dl_delay_table = frame_parms->delay_table[delay_idx];
for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) {
for (int pilot_cnt = 0; pilot_cnt < idx >> 1; pilot_cnt++) {
int k = pilot_cnt << 1;
c16_t ch = c16mulShift(dl_ls_est[k], dl_delay_table[k], 8);
if (pilot_cnt == 0) { // Treat first pilot
c16multaddVectRealComplex(filt16_ul_p0, &ch, dl_ch, 16);
} else if (pilot_cnt == 1 || pilot_cnt == 2) {
c16multaddVectRealComplex(filt16_ul_p1p2, &ch, dl_ch, 16);
} else if (pilot_cnt == 6 * nb_rb_pdsch - 1) { // Treat last pilot
} else if (pilot_cnt == (idx >> 1) - 1) { // Treat last pilot
c16multaddVectRealComplex(filt16_ul_last, &ch, dl_ch, 16);
} else { // Treat middle pilots
c16multaddVectRealComplex(filt16_ul_middle, &ch, dl_ch, 16);
@@ -998,9 +1004,11 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
// Revert delay
dl_ch = dl_ch0;
int nest_count = 0;
uint64_t noise_amp2 = 0;
int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
c16_t *dl_inv_delay_table = frame_parms->delay_table[inv_delay_idx];
for (int k = 0; k < 12 * nb_rb_pdsch; k++) {
for (int k = 0; k < idx; k++) {
dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8);
noise_amp2 += c16amp2(c16sub(dl_ls_est[k], dl_ch[k]));
nest_count++;
@@ -1100,51 +1108,58 @@ 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,
unsigned short nb_rb_pdsch,
int rb_offset,
int nb_rb_pdsch,
const uint8_t bitmap[36],
delay_t *delay,
uint32_t *nvar)
{
int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
c16_t *dl_ch0 = dl_ch;
c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(dl_ls_est, 0, sizeof(dl_ls_est));
int nest_count = 0;
uint64_t noise_amp2 = 0;
for (int pilot_cnt = 0; pilot_cnt < 4 * nb_rb_pdsch; pilot_cnt += 2) {
c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15);
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) {
for (int pilot_cnt = 0; pilot_cnt < 4; pilot_cnt += 2) {
c16_t ch_l = c16mulShift(*pil, rxF[re_offset], 15);
#ifdef DEBUG_PDSCH
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i);
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_l.r, ch_l.i);
#endif
pil++;
re_offset = (re_offset + 1) % frame_parms->ofdm_symbol_size;
c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15);
pil++;
re_offset = (re_offset + 1) % frame_parms->ofdm_symbol_size;
c16_t ch_r = c16mulShift(*pil, rxF[re_offset], 15);
#ifdef DEBUG_PDSCH
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i);
printf("pilot %3d: pil -> (%6d,%6d), rxF -> (%4d,%4d), ch -> (%4d,%4d) \n", pilot_cnt + 1, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i);
#endif
c16_t ch = c16addShift(ch_l, ch_r, 1);
for (int k = 3 * pilot_cnt; k < (3 * pilot_cnt) + 6; k++) {
dl_ls_est[k] = ch;
c16_t ch = c16addShift(ch_l, ch_r, 1);
pil++;
re_offset = (re_offset + 5) % frame_parms->ofdm_symbol_size;
for (int k = 0; k < 6; k++) {
dl_ls_est[idx] = ch;
idx++;
}
}
} else {
pil += 4;
re_offset = (re_offset + 12) % frame_parms->ofdm_symbol_size;
}
pil++;
re_offset = (re_offset + 5) % frame_parms->ofdm_symbol_size;
}
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);
int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP);
c16_t *dl_delay_table = frame_parms->delay_table[delay_idx];
for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) {
int k = (pilot_cnt / 3) * 6;
// kept the same as before but unclear why would it be nb_rb_pdsch / 2 and not / 3
for (int pilot_cnt = 0; pilot_cnt < idx >> 1; pilot_cnt++) {
int k = pilot_cnt << 1;
c16_t ch = c16mulShift(dl_ls_est[k], dl_delay_table[k], 8);
if (pilot_cnt == 0) { // Treat first pilot
c16multaddVectRealComplex(filt16_ul_p0, &ch, dl_ch, 16);
} else if (pilot_cnt == 1 || pilot_cnt == 2) {
c16multaddVectRealComplex(filt16_ul_p1p2, &ch, dl_ch, 16);
} else if (pilot_cnt == 6 * nb_rb_pdsch - 1) { // Treat last pilot
} else if (pilot_cnt == (idx >> 1) - 1) { // Treat last pilot
c16multaddVectRealComplex(filt16_ul_last, &ch, dl_ch, 16);
} else { // Treat middle pilots
c16multaddVectRealComplex(filt16_ul_middle, &ch, dl_ch, 16);
@@ -1156,9 +1171,11 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
// Revert delay
dl_ch = dl_ch0;
int nest_count = 0;
uint64_t noise_amp2 = 0;
int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
c16_t *dl_inv_delay_table = frame_parms->delay_table[inv_delay_idx];
for (int k = 0; k < 12 * nb_rb_pdsch; k++) {
for (int k = 0; k < idx; k++) {
dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8);
noise_amp2 += c16amp2(c16sub(dl_ls_est[k], dl_ch[k]));
nest_count++;
@@ -1253,30 +1270,25 @@ void NFAPI_NR_DMRS_TYPE2_average_prb(NR_DL_FRAME_PARMS *frame_parms,
#endif
}
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int nl,
unsigned short p,
unsigned char symbol,
unsigned char nscid,
unsigned short scrambling_id,
unsigned short BWPStart,
uint8_t config_type,
int n_dmrs_cdm_groups,
uint16_t rb_offset,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int rxdataFsize,
c16_t rxdataF[][rxdataFsize],
uint32_t *nvar)
void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch,
const freq_alloc_bitmap_t *freq_alloc,
int nl,
unsigned short p,
unsigned char symbol,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int rxdataFsize,
c16_t rxdataF[][rxdataFsize],
uint32_t *nvar)
{
// int gNB_id = proc->gNB_id;
int slot = proc->nr_slot_rx;
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;
#ifdef DEBUG_PDSCH
printf(
@@ -1292,13 +1304,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
#endif
// 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;
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
float beta_dmrs_pdsch = get_beta_dmrs(n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2);
float beta_dmrs_pdsch = get_beta_dmrs(dlsch->n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2);
int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14));
const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, scrambling_id, nscid, slot, symbol);
const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, dlsch->dlDmrsScramblingId, dlsch->nscid, slot, symbol);
nr_pdsch_dmrs_rx(ue, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling);
delay_t delay = {0};
@@ -1315,12 +1329,14 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
memset(dl_ch, 0, sizeof(*dl_ch) * fp->ofdm_symbol_size);
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) {
NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms,
NFAPI_NR_DMRS_TYPE1_linear_interp(fp,
rxF,
&pilot[6 * rb_offset],
dl_ch,
bwp_start_subcarrier,
freq_alloc->start[0],
nb_rb_pdsch,
freq_alloc->bitmap,
&delay,
nvar);
@@ -1330,14 +1346,18 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
&pilot[4 * rb_offset],
dl_ch,
bwp_start_subcarrier,
freq_alloc->start[0],
nb_rb_pdsch,
freq_alloc->bitmap,
&delay,
nvar);
} else if (config_type == NFAPI_NR_DMRS_TYPE1) {
AssertFatal(dlsch->resource_alloc == 1, "PRB average in channel estimation not supported for type0 DLSCH\n");
NFAPI_NR_DMRS_TYPE1_average_prb(fp, rxF, &pilot[6 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch);
} else {
AssertFatal(dlsch->resource_alloc == 1, "PRB average in channel estimation not supported for type0 DLSCH\n");
NFAPI_NR_DMRS_TYPE2_average_prb(fp, rxF, &pilot[4 * rb_offset], dl_ch, bwp_start_subcarrier, nb_rb_pdsch);
}
@@ -1351,7 +1371,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
}
#endif
}
return 0;
}
/*******************************************************************
@@ -1369,7 +1388,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
* uint8_t : gNB_id,
* uint8_t : nr_slot_rx,
* unsigned char : symbol,
* uint32_t : nb_re_pdsch,
* uint16_t : rnti
* RX_type_t : rx_type
* RETURN : Nothing
@@ -1392,7 +1410,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
uint8_t gNB_id,
uint8_t nr_slot_rx,
unsigned char symbol,
uint32_t nb_re_pdsch,
uint16_t rnti,
NR_UE_DLSCH_t dlsch[2])
{
+13 -20
View File
@@ -78,24 +78,18 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
bool sidelink,
uint Nid);
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int nl,
unsigned short p,
unsigned char symbol,
unsigned char nscid,
unsigned short scrambling_id,
unsigned short BWPStart,
uint8_t config_type,
int n_dmrs_cdm_groups,
uint16_t rb_offset,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int rxdataFsize,
c16_t rxdataF[][rxdataFsize],
uint32_t *nvar);
void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch,
const freq_alloc_bitmap_t *freq_alloc,
int nl,
unsigned short p,
unsigned char symbol,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
int rxdataFsize,
c16_t rxdataF[][rxdataFsize],
uint32_t *nvar);
int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
PHY_VARS_NR_UE *ue,
@@ -108,7 +102,7 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
int number_rbs,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size]);
@@ -143,7 +137,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
uint8_t gNB_id,
uint8_t nr_slot_rx,
unsigned char symbol,
uint32_t nb_re_pdsch,
uint16_t rnti,
NR_UE_DLSCH_t dlsch[2]);
@@ -48,7 +48,7 @@
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
int number_rbs,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size])
{
@@ -56,8 +56,6 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
int aarx, aatx, gNB_id = 0;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int ch_offset = frame_parms->ofdm_symbol_size*2;
int N_RB_DL = dlsch->dlsch_config.number_rbs;
ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
allocCast3D(rx_spatial_power,
@@ -85,7 +83,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.rx_power[gNB_id][aarx] = 0;
for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){
const int z=signal_energy_nodc((c16_t*)&dl_ch_estimates[gNB_id][ch_offset], N_RB_DL * NR_NB_SC_PER_RB);
const int z = signal_energy_nodc((c16_t*)&dl_ch_estimates[gNB_id][ch_offset], number_rbs * NR_NB_SC_PER_RB);
rx_spatial_power[gNB_id][aatx][aarx] = z;
if (rx_spatial_power[gNB_id][aatx][aarx] < 0)
@@ -141,11 +141,11 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
unsigned char symbol,
uint8_t pilots,
uint8_t config_type,
unsigned short start_rb,
unsigned short nb_rb_pdsch,
int startBWP,
const freq_alloc_bitmap_t *freq_alloc,
uint8_t n_dmrs_cdm_groups,
uint8_t Nl,
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_FRAME_PARMS *fp,
uint16_t dlDmrsSymbPos,
uint32_t csi_res_bitmap,
int chest_time_type);
@@ -293,6 +293,7 @@ static uint32_t build_csi_overlap_bitmap(fapi_nr_dl_config_dlsch_pdu_rel15_t *dl
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
const freq_alloc_bitmap_t *freq_alloc,
unsigned char symbol,
bool first_symbol_flag,
unsigned char harq_pid,
@@ -314,12 +315,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
uint32_t nvar,
pdsch_scope_req_t *scope_req)
{
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
const int nl = dlsch[0].Nl;
const int matrixSz = ue->frame_parms.nb_antennas_rx * nl;
const int n_rx = fp->nb_antennas_rx;
const int matrixSz = n_rx * nl;
__attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext));
__attribute__((aligned(32))) c16_t dl_ch_mag[nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol];
__attribute__((aligned(32))) c16_t dl_ch_mag[nl][n_rx][rx_size_symbol];
memset(dl_ch_mag, 0, sizeof(dl_ch_mag));
__attribute__((aligned(32))) c16_t dl_ch_magb[nl][nbRx][rx_size_symbol];
@@ -328,7 +331,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
__attribute__((aligned(32))) c16_t dl_ch_magr[nl][nbRx][rx_size_symbol];
memset(dl_ch_magr, 0, sizeof(dl_ch_magr));
NR_UE_COMMON *common_vars = &ue->common_vars;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
const int frame = proc->frame_rx;
const int nr_slot_rx = proc->nr_slot_rx;
@@ -347,7 +349,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
if (dlsch0_harq && dlsch1_harq){
LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_slot_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status);
LOG_D(PHY,
"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n",
frame,
nr_slot_rx,
symbol,
harq_pid,
dlsch0_harq->status,
dlsch1_harq->status);
if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){
codeword_TB0 = dlsch0_harq->codeword; // SV: where is this set? revisit for DL MIMO.
@@ -393,13 +402,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
DEBUG_HARQ("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1);
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config = &dlsch[0].dlsch_config;
int start_rb = dlsch_config->start_rb;
int nb_rb_pdsch = dlsch_config->number_rbs;
DevAssert(dlsch0_harq);
if (gNB_id > 2) {
LOG_E(PHY, "In %s: Illegal gNB_id %d\n", __FUNCTION__, gNB_id);
LOG_E(PHY, "Illegal gNB_id %d\n", gNB_id);
return(-1);
}
@@ -408,12 +414,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
return(-1);
}
if (!frame_parms) {
LOG_E(PHY, "dlsch_demodulation.c: Null frame_parms\n");
return(-1);
}
if(symbol > ue->frame_parms.symbols_per_slot >> 1)
if(symbol > fp->symbols_per_slot >> 1)
slot = 1;
uint8_t pilots = (dlsch_config->dlDmrsSymbPos >> symbol) & 1;
@@ -421,9 +422,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//----------------------------------------------------------
//--------------------- RBs extraction ---------------------
//----------------------------------------------------------
const int n_rx = frame_parms->nb_antennas_rx;
const bool meas_enabled = cpumeas(CPUMEAS_GETSTATE);
int nb_rb_pdsch = freq_alloc->num_rbs;
{
start_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS);
__attribute__((aligned(32))) c16_t rxdataF_ext[nbRx][rx_size_symbol];
@@ -433,7 +433,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
LOG_D(PHY, "%d.%d symbol %d csi overlap bitmap %d\n", frame, nr_slot_rx, symbol, csi_res_bitmap);
nr_dlsch_extract_rbs(ue->frame_parms.samples_per_slot_wCP,
nr_dlsch_extract_rbs(fp->samples_per_slot_wCP,
rxdataF,
rx_size_symbol,
pdsch_est_size,
@@ -443,17 +443,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
symbol,
pilots,
config_type,
start_rb + dlsch_config->BWPStart,
nb_rb_pdsch,
dlsch_config->BWPStart,
freq_alloc,
dlsch_config->n_dmrs_cdm_groups,
nl,
frame_parms,
fp,
dlsch_config->dlDmrsSymbPos,
csi_res_bitmap,
ue->chest_time);
stop_meas_nr_ue_phy(ue, DLSCH_EXTRACT_RBS_STATS);
if (scope_req->copy_chanest_to_scope) {
size_t size = sizeof(c16_t) * dlsch_config->number_rbs * NR_NB_SC_PER_RB;
size_t size = sizeof(c16_t) * nb_rb_pdsch * NR_NB_SC_PER_RB;
int copy_index = symbol - dlsch_config->start_symbol;
int offset = copy_index * size;
UEscopeCopyUnsafe(ue, pdschChanEstimates, dl_ch_estimates_ext[0], size, offset, copy_index);
@@ -478,14 +478,15 @@ 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 = start_rb + dlsch_config->BWPStart;
for (int rb = start; rb < start + nb_rb_pdsch; rb++) {
uint32_t rb_csi_pattern = (rb % 2 == 0) ? csi_res_even : csi_res_odd;
csi_re_count += __builtin_popcount(rb_csi_pattern);
int start = freq_alloc->start[0] + dlsch_config->BWPStart;
int end = freq_alloc->end[freq_alloc->num_blocks - 1] + 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);
}
}
nb_re_pdsch = (nb_re_pdsch > csi_re_count) ? (nb_re_pdsch - csi_re_count) : 0;
if (csi_re_count > 0) {
LOG_D(NR_PHY,
"[CSI OVERLAP] Frame/Slot %d.%d Symbol %d: CSI-RS overlapping PDSCH - %d CSI-RS REs skipped, %d data REs extracted\n",
@@ -507,7 +508,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//--------------------- Channel Scaling --------------------
//----------------------------------------------------------
start_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS);
nr_dlsch_scale_channel(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, n_rx, symbol, pilots, nb_re_pdsch, nb_rb_pdsch);
nr_dlsch_scale_channel(rx_size_symbol, dl_ch_estimates_ext, fp, nl, n_rx, symbol, pilots, nb_re_pdsch, nb_rb_pdsch);
stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_SCALE_STATS);
if (meas_enabled) {
LOG_D(PHY,
@@ -578,7 +579,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
dl_ch_magr,
rxdataF_comp,
NULL,
frame_parms,
fp,
nl,
symbol,
nb_re_pdsch,
@@ -603,10 +604,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
char filename[50];
snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
write_output(filename, "rxdataF0", &rxdataF[0][symbol * frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
write_output(filename, "rxdataF0", &rxdataF[0][symbol * fp->ofdm_symbol_size], fp->ofdm_symbol_size, 1, 1);
snprintf(filename, 50, "dl_ch_estimates0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
write_output(filename, "dl_ch_estimates0", &dl_ch_estimates[0][symbol * frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size, 1, 1);
write_output(filename, "dl_ch_estimates0", &dl_ch_estimates[0][symbol * fp->ofdm_symbol_size], fp->ofdm_symbol_size, 1, 1);
snprintf(filename, 50, "rxdataF_ext0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
write_output(filename, "rxdataF_ext0", &rxdataF_ext[0][0], rx_size_symbol, 1, 1);
@@ -682,13 +683,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
ptrs_re_per_slot,
rx_size_symbol,
rxdataF_comp,
frame_parms,
fp,
dlsch0_harq,
dlsch1_harq,
gNB_id,
nr_slot_rx,
symbol,
(nb_rb_pdsch * 12),
dlsch[0].rnti,
dlsch);
dl_valid_re[symbol] -= ptrs_re_per_slot[0][symbol];
@@ -759,9 +759,9 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
T_INT(frame % 1024),
T_INT(nr_slot_rx),
T_INT(nb_rb_pdsch),
T_INT(frame_parms->N_RB_UL),
T_INT(frame_parms->symbols_per_slot),
T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL * 12 * 2));
T_INT(fp->N_RB_UL),
T_INT(fp->symbols_per_slot),
T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ fp->N_RB_UL * 12 * 2));
#endif
if (ue->phy_sim_pdsch_rxdataF_comp)
@@ -778,7 +778,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
memcpy(ue->phy_sim_pdsch_dl_ch_estimates_ext + symbol * sizeof(dl_ch_estimates_ext),
dl_ch_estimates_ext,
sizeof(dl_ch_estimates_ext));
return (0);
return 0;
}
//==============================================================================================
@@ -923,7 +923,7 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_FRAME_PARMS *fp,
uint8_t n_tx,
uint8_t n_rx,
uint8_t symbol,
@@ -932,30 +932,28 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
unsigned short nb_rb)
{
short rb, ch_amp;
unsigned char aatx,aarx;
simde__m128i *dl_ch128, ch_amp128;
uint32_t nb_rb_0 = len/12 + ((len%12)?1:0);
// Determine scaling amplitude based the symbol
ch_amp = 1024*8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a));
LOG_D(PHY,"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",symbol,ch_amp,pilots,nb_rb,frame_parms->Ncp,symbol);
ch_amp = 1024 * 8; //((pilots) ? (dlsch_ue[0]->sqrt_rho_b) : (dlsch_ue[0]->sqrt_rho_a));
LOG_D(PHY,
"Scaling PDSCH Chest in OFDM symbol %d by %d, pilots %d nb_rb %d NCP %d symbol %d\n",
symbol,
ch_amp,
pilots,
nb_rb,
fp->Ncp,
symbol);
// printf("Scaling PDSCH Chest in OFDM symbol %d by %d\n",symbol_mod,ch_amp);
ch_amp128 = simde_mm_set1_epi16(ch_amp); // Q3.13
for (aatx=0; aatx<n_tx; aatx++) {
for (aarx=0; aarx<n_rx; aarx++) {
dl_ch128=(simde__m128i *)dl_ch_estimates_ext[(aatx*n_rx)+aarx];
for (rb=0;rb<nb_rb_0;rb++) {
dl_ch128[0] = simde_mm_mulhi_epi16(dl_ch128[0], ch_amp128);
dl_ch128[0] = simde_mm_slli_epi16(dl_ch128[0], 3);
@@ -965,7 +963,6 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
dl_ch128[2] = simde_mm_mulhi_epi16(dl_ch128[2], ch_amp128);
dl_ch128[2] = simde_mm_slli_epi16(dl_ch128[2], 3);
dl_ch128+=3;
}
}
}
@@ -1019,17 +1016,17 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
unsigned char symbol,
uint8_t pilots,
uint8_t config_type,
unsigned short start_rb,
unsigned short nb_rb_pdsch,
int startBWP,
const freq_alloc_bitmap_t *freq_alloc,
uint8_t n_dmrs_cdm_groups,
uint8_t Nl,
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_FRAME_PARMS *fp,
uint16_t dlDmrsSymbPos,
uint32_t csi_res_bitmap,
int chest_time_type)
{
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);
@@ -1052,61 +1049,60 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
AssertFatal((dmrs_rb_bitmap & csi_res_odd) == 0, "DMRS RE overlapping with CSI RE, it shouldn't happen\n");
uint32_t dmrs_csi_overlap_even = csi_res_even + dmrs_rb_bitmap;
uint32_t dmrs_csi_overlap_odd = csi_res_odd + dmrs_rb_bitmap;
const unsigned short start_re = (frame_parms->first_carrier_offset + start_rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
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(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(dlDmrsSymbPos, 0, 14); // get first dmrs symbol index
for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
c16_t *rxF_ext = rxdataF_ext[aarx];
c16_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
for (unsigned char l = 0; l < Nl; l++) {
int32_t *dl_ch0 = &dl_ch_estimates[(l * frame_parms->nb_antennas_rx) + aarx][validDmrsEst * frame_parms->ofdm_symbol_size];
int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx];
if (pilots == 0 && csi_res_bitmap == 0) { // data symbol only
if (l == 0) {
if (start_re + nb_rb_pdsch * NR_NB_SC_PER_RB <= frame_parms->ofdm_symbol_size) {
memcpy(rxF_ext, &rxF[start_re], nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t));
} else {
int neg_length = frame_parms->ofdm_symbol_size - start_re;
int pos_length = nb_rb_pdsch * NR_NB_SC_PER_RB - neg_length;
memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(int32_t));
memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(int32_t));
}
}
memcpy(dl_ch0_ext, dl_ch0, nb_rb_pdsch * NR_NB_SC_PER_RB * sizeof(int32_t));
}
else {
int j = 0;
int k = start_re;
for (int rb = 0; rb < nb_rb_pdsch; rb++) {
uint32_t overlap_map = rb % 2 ? dmrs_csi_overlap_odd : dmrs_csi_overlap_even;
for (int re = 0; re < 12; re++) {
if (((overlap_map >> re) & 0x01) == 0) {
// DATA RE
if (l == 0)
rxF_ext[j] = rxF[k];
dl_ch0_ext[j] = dl_ch0[re];
j++;
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;
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];
c16_t *rxF = &rxdataF[aarx][symbol * fp->ofdm_symbol_size];
for (int l = 0; l < Nl; l++) {
int32_t *dl_ch0 = &dl_ch_estimates[(l * fp->nb_antennas_rx) + aarx][validDmrsEst * fp->ofdm_symbol_size];
int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * fp->nb_antennas_rx) + aarx];
if (pilots == 0 && csi_res_bitmap == 0) { // data symbol only
if (l == 0) {
if (start_re + nb_rb * NR_NB_SC_PER_RB <= fp->ofdm_symbol_size) {
memcpy(rxF_ext, &rxF[start_re], nb_rb * NR_NB_SC_PER_RB * sizeof(int32_t));
} else {
int neg_length = fp->ofdm_symbol_size - start_re;
int pos_length = nb_rb * NR_NB_SC_PER_RB - neg_length;
memcpy(rxF_ext, &rxF[start_re], neg_length * sizeof(int32_t));
memcpy(&rxF_ext[neg_length], rxF, pos_length * sizeof(int32_t));
}
k++;
if (k >= frame_parms->ofdm_symbol_size)
k -= frame_parms->ofdm_symbol_size;
}
dl_ch0 += 12;
memcpy(dl_ch0_ext, dl_ch0, nb_rb * NR_NB_SC_PER_RB * sizeof(int32_t));
} else {
int j = 0;
int k = start_re;
for (int rb = start_rb; rb < start_rb + nb_rb; rb++) {
uint32_t overlap_map = rb % 2 ? dmrs_csi_overlap_odd : dmrs_csi_overlap_even;
for (int re = 0; re < NR_NB_SC_PER_RB; re++) {
if (((overlap_map >> re) & 0x01) == 0) {
// DATA RE
if (l == 0)
rxF_ext[j] = rxF[k];
dl_ch0_ext[j] = dl_ch0[re];
j++;
}
k++;
if (k >= fp->ofdm_symbol_size)
k -= fp->ofdm_symbol_size;
}
dl_ch0 += 12;
}
}
}
}
}
}
static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
short nl,
short n_rx,
@@ -1185,13 +1181,8 @@ void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb)
}
/* Zero Forcing Rx function: nr_element_sign()
* Compute b=sign*a
*
* */
static inline void nr_element_sign(c16_t *a, // a
c16_t *b, // b
unsigned short nb_rb,
int32_t sign)
* Compute b=sign*a */
static inline void nr_element_sign(c16_t *a, c16_t *b, unsigned short nb_rb, int32_t sign)
{
const int16_t nr_sign[8] __attribute__((aligned(16))) = {-1, -1, -1, -1, -1, -1, -1, -1};
simde__m128i *a_128,*b_128;
@@ -67,7 +67,6 @@ typedef struct pdsch_scope_req_s {
/** \brief This function initialises structures for DLSCH at UE
*/
void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations);
void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0);
/** \brief This is the alternative top-level entry point for DLSCH decoding in UE.
@@ -316,6 +315,7 @@ void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],
const freq_alloc_bitmap_t *freq_alloc,
unsigned char symbol,
bool first_symbol_flag,
unsigned char harq_pid,
@@ -38,6 +38,15 @@
#include "nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h"
#include "../NR_TRANSPORT/nr_transport_common_proto.h"
#define MAX_FA_BLOCKS 10
typedef struct {
int start[MAX_FA_BLOCKS];
int end[MAX_FA_BLOCKS];
int num_rbs;
int num_blocks;
uint8_t bitmap[36];
} freq_alloc_bitmap_t;
typedef struct {
/// Index of current HARQ round for this ULSCH
uint8_t round;