Compare commits

...

2 Commits

Author SHA1 Message Date
Bartosz Podrygajlo
ae620209a9 Fix for unit tests 2026-03-09 18:21:06 +01:00
francescomani
e8218d192e L1 gNB type0 PDSCH 2026-03-06 19:50:23 +01:00
17 changed files with 302 additions and 204 deletions

View File

@@ -0,0 +1,43 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef _NR_PARMS_H_
#define _NR_PARMS_H_
#include "fapi_nr_ue_interface.h"
#include "openair1/PHY/defs_nr_UE.h"
#ifdef __cplusplus
extern "C" {
#endif
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_params_t *cell);
int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
sl_nr_phy_config_request_t *config,
int threequarter_fs,
uint32_t ofdm_offset_divisor);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -24,19 +24,12 @@
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_UE.h"
#include "nr_parms.h"
int nr_get_ssb_start_symbol(const NR_DL_FRAME_PARMS *fp, uint8_t i_ssb);
void nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
void nr_init_frame_parms_ue_sa(NR_DL_FRAME_PARMS *frame_parms, const nrUE_cell_params_t *cell);
int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp,
sl_nr_phy_config_request_t *config,
int threequarter_fs,
uint32_t ofdm_offset_divisor);
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB);
void term_nr_ue_signal(PHY_VARS_NR_UE *ue);
void init_nr_ue_transport(PHY_VARS_NR_UE *ue);
void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms);
void phy_init_nr_gNB(PHY_VARS_gNB *gNB);
int init_codebook_gNB(PHY_VARS_gNB *gNB);
void nr_phy_config_request(NR_PHY_Config_t *gNB);

View File

@@ -23,7 +23,7 @@
extern "C" {
#include <stdlib.h>
#include "openair1/PHY/defs_nr_common.h"
#include "openair1/PHY/INIT/nr_phy_init.h"
#include "openair1/PHY/INIT/nr_parms.h"
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void)

View File

@@ -24,7 +24,6 @@
#include <stdint.h>
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#define DMRS_MOD_ORDER 2
/*Precoding matices: W[pmi][antenna_port][layer]*/

View File

@@ -20,7 +20,6 @@
*/
#include "sl_refsig_defs.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic()
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
{

View File

@@ -25,6 +25,7 @@
#define __NR_REFSIG_DEFS__H__
#include "PHY/defs_nr_UE.h"
#include "openair1/PHY/LTE_TRANSPORT/transport_proto.h" // for lte_gold_generic()
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);

View File

@@ -52,6 +52,7 @@ static void nr_pdsch_codeword_scrambling(uint8_t *in, uint32_t size, uint8_t q,
}
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,
@@ -62,32 +63,42 @@ static int do_ptrs_symbol(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
int ptrs_idx = 0;
int k = start_sc;
c16_t *in = tx_layer;
for (int i = 0; i < rel15->rbSize * NR_NB_SC_PER_RB; i++) {
/* check for PTRS symbol and set flag for PTRS RE */
bool is_ptrs_re =
is_ptrs_subcarrier(k, rel15->rnti, rel15->PTRSFreqDensity, rel15->rbSize, rel15->PTRSReOffset, start_sc, symbol_sz);
if (is_ptrs_re) {
/* check if cuurent RE is PTRS RE*/
uint16_t beta_ptrs = 1;
txF[k] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * amp, 15);
int last_rb = freq_alloc->end[freq_alloc->num_blocks - 1];
int first_rb = freq_alloc->start[0];
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++) {
/* check for PTRS symbol and set flag for PTRS RE */
bool is_ptrs_re =
is_ptrs_subcarrier(k, rel15->rnti, rel15->PTRSFreqDensity, freq_alloc->num_rbs, rel15->PTRSReOffset, start_sc, symbol_sz);
if (is_ptrs_re) {
/* check if cuurent RE is PTRS RE*/
uint16_t beta_ptrs = 1;
txF[k] = c16mulRealShift(mod_ptrs[ptrs_idx], beta_ptrs * amp, 15);
#ifdef DEBUG_DLSCH_MAPPING
printf("ptrs_idx %d\t \t k %d \t \t txdataF: %d %d, mod_ptrs: %d %d\n",
ptrs_idx,
k,
txF[k].r,
txF[k].i,
mod_ptrs[ptrs_idx].r,
mod_ptrs[ptrs_idx].i);
printf("ptrs_idx %d\t \t k %d \t \t txdataF: %d %d, mod_ptrs: %d %d\n",
ptrs_idx,
k,
txF[k].r,
txF[k].i,
mod_ptrs[ptrs_idx].r,
mod_ptrs[ptrs_idx].i);
#endif
ptrs_idx++;
ptrs_idx++;
} else {
txF[k] = c16mulRealShift(*in++, amp, 15);
#ifdef DEBUG_DLSCH_MAPPING
printf("k %d \t txdataF: %d %d\n", k, txF[k].r, txF[k].i);
#endif
}
if (++k >= symbol_sz)
k -= symbol_sz;
}
} else {
txF[k] = c16mulRealShift(*in++, amp, 15);
#ifdef DEBUG_DLSCH_MAPPING
printf("k %d \t txdataF: %d %d\n", k, txF[k].r, txF[k].i);
#endif
k += NR_NB_SC_PER_RB;
if (k >= symbol_sz)
k -= symbol_sz;
}
if (++k >= symbol_sz)
k -= symbol_sz;
}
return in - tx_layer;
}
@@ -258,9 +269,9 @@ static inline int interleave_signals(c16_t *output, c16_t *signal1, const int am
static inline int dmrs_case00(c16_t *output,
c16_t *txl,
c16_t *mod_dmrs,
const freq_alloc_bitmap_t *freq_alloc,
const int16_t amp_dmrs,
const int amp,
int sz,
int start_sc,
int dmrs_port,
const int dmrs_Type,
@@ -278,21 +289,24 @@ static inline int dmrs_case00(c16_t *output,
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++) {
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);
}
/* Map PTRS Symbol */
/* Map DATA Symbol */
else if (allowed_xlsch_re_in_dmrs_symbol(k, start_sc, symbol_sz, numDmrsCdmGrpsNoData, dmrs_Type)) {
output[k] = c16mulRealShift(*in++, amp, 15);
}
/* mute RE */
else {
output[k] = (c16_t){0};
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};
}
}
k = (k + 1) % symbol_sz;
} // RE loop
@@ -336,13 +350,21 @@ 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(NR_DL_FRAME_PARMS *fp, int block_start, int bwp_start, int symbol_sz)
{
uint32_t start_sc = fp->first_carrier_offset + (block_start + bwp_start) * NR_NB_SC_PER_RB;
if (start_sc >= symbol_sz)
start_sc -= symbol_sz;
return start_sc;
}
static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
int slot,
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
const freq_alloc_bitmap_t *freq_alloc,
int layer,
c16_t *output,
c16_t *txl_start,
int start_sc,
int symbol_sz,
int l_symbol,
uint16_t dlPtrsSymPos,
@@ -354,13 +376,7 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
c16_t *dmrs_start)
{
c16_t *txl = txl_start;
const uint sz = rel15->rbSize * NR_NB_SC_PER_RB;
int upper_limit = sz;
int remaining_re = 0;
if (start_sc + upper_limit > symbol_sz) {
upper_limit = symbol_sz - start_sc;
remaining_re = sz - upper_limit;
}
uint32_t start_sc = get_block_start_sc(frame_parms, freq_alloc->start[0], rel15->BWPStart, symbol_sz);
/* calculate if current symbol is PTRS symbols */
int ptrs_symbol = 0;
@@ -376,67 +392,79 @@ static inline int 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, start_sc, symbol_sz, output, txl, amp, mod_ptrs);
txl += do_ptrs_symbol(rel15, freq_alloc, start_sc, 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) {
if (rel15->numDmrsCdmGrpsNoData == 2) {
switch (dmrs_port & 3) {
case 0:
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
txl += interleave_with_0_signal_first(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break;
case 1: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, upper_limit);
txl += interleave_with_0_signal_first(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break;
case 2:
txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
txl += interleave_with_0_start_with_0(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break;
case 3: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, upper_limit);
txl += interleave_with_0_start_with_0(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break;
for (int i = 0; i < freq_alloc->num_blocks; i++) {
if (i != 0)
start_sc = get_block_start_sc(frame_parms, 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 upper_limit = sz;
int remaining_re = 0;
if (start_sc + upper_limit > symbol_sz) {
upper_limit = symbol_sz - start_sc;
remaining_re = sz - upper_limit;
}
} else if (rel15->numDmrsCdmGrpsNoData == 1) {
switch (dmrs_port & 3) {
case 0:
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, upper_limit);
txl += interleave_signals(output, txl, amp, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break;
case 1: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, upper_limit);
txl += interleave_signals(output, txl, amp, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break;
case 2:
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, upper_limit);
txl += interleave_signals(output, dmrs_start + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
break;
case 3: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, upper_limit);
txl += interleave_signals(output, dmrs + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
} break;
}
} else
AssertFatal(false, "rel15->numDmrsCdmGrpsNoData is %d\n", rel15->numDmrsCdmGrpsNoData);
if (rel15->numDmrsCdmGrpsNoData == 2) {
switch (dmrs_port & 3) {
case 0:
txl += interleave_with_0_signal_first(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
txl += interleave_with_0_signal_first(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break;
case 1: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_with_0_signal_first(output + start_sc, dmrs, amp_dmrs, upper_limit);
txl += interleave_with_0_signal_first(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break;
case 2:
txl += interleave_with_0_start_with_0(output + start_sc, dmrs_start, amp_dmrs, upper_limit);
txl += interleave_with_0_start_with_0(output, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break;
case 3: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_with_0_start_with_0(output + start_sc, dmrs, amp_dmrs, upper_limit);
txl += interleave_with_0_start_with_0(output, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break;
}
} else if (rel15->numDmrsCdmGrpsNoData == 1) {
switch (dmrs_port & 3) {
case 0:
txl += interleave_signals(output + start_sc, txl, amp, dmrs_start, amp_dmrs, upper_limit);
txl += interleave_signals(output, txl, amp, dmrs_start + upper_limit / 2, amp_dmrs, remaining_re);
break;
case 1: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_signals(output + start_sc, txl, amp, dmrs, amp_dmrs, upper_limit);
txl += interleave_signals(output, txl, amp, dmrs + upper_limit / 2, amp_dmrs, remaining_re);
} break;
case 2:
txl += interleave_signals(output + start_sc, dmrs_start, amp_dmrs, txl, amp, upper_limit);
txl += interleave_signals(output, dmrs_start + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
break;
case 3: {
c16_t dmrs[sz / 2];
neg_dmrs(dmrs_start, dmrs, sz / 2);
txl += interleave_signals(output + start_sc, dmrs, amp_dmrs, txl, amp, upper_limit);
txl += interleave_signals(output, dmrs + upper_limit / 2, amp_dmrs, txl, amp, remaining_re);
} break;
}
} else
AssertFatal(false, "rel15->numDmrsCdmGrpsNoData is %d\n", rel15->numDmrsCdmGrpsNoData);
}
} else {
txl += dmrs_case00(output,
txl,
dmrs_start,
freq_alloc,
amp_dmrs,
amp,
sz,
start_sc,
dmrs_port,
dmrs_Type,
@@ -445,8 +473,20 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms,
rel15->numDmrsCdmGrpsNoData);
} // generic DMRS case
} else { // no PTRS or DMRS in this symbol
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, upper_limit);
txl += no_ptrs_dmrs_case(output, txl, amp, remaining_re);
for (int i = 0; i < freq_alloc->num_blocks; i++) {
if (i != 0)
start_sc = get_block_start_sc(frame_parms, 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 upper_limit = sz;
int remaining_re = 0;
if (start_sc + upper_limit > symbol_sz) {
upper_limit = symbol_sz - start_sc;
remaining_re = sz - upper_limit;
}
txl += no_ptrs_dmrs_case(output + start_sc, txl, amp, upper_limit);
txl += no_ptrs_dmrs_case(output, txl, amp, remaining_re);
}
} // no DMRS/PTRS in symbol
return txl - txl_start;
}
@@ -457,24 +497,25 @@ static inline void do_txdataF(c16_t **txdataF,
PHY_VARS_gNB *gNB,
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15,
int ant,
int start_sc,
int rb_start,
int rb_size,
int txdataF_offset_per_symbol)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
int rb = 0;
uint16_t subCarrier = start_sc;
uint16_t subCarrier = get_block_start_sc(frame_parms, rb_start, rel15->BWPStart, symbol_sz);
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming;
while (rb < rel15->rbSize) {
while (rb < rb_size) {
// get pmi info
const int pmi = (pb->prg_size > 0) ? (pb->prgs_list[(int)rb / pb->prg_size].pm_idx) : 0;
const int pmi2 = (rb < (rel15->rbSize - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1;
const int pmi3 = (rb < (rel15->rbSize - 2) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 2) / pb->prg_size].pm_idx) : -1;
const int pmi4 = (rb < (rel15->rbSize - 3) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 3) / pb->prg_size].pm_idx) : -1;
const int pmi2 = (rb < (rb_size - 1) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 1) / pb->prg_size].pm_idx) : -1;
const int pmi3 = (rb < (rb_size - 2) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 2) / pb->prg_size].pm_idx) : -1;
const int pmi4 = (rb < (rb_size - 3) && pb->prg_size > 0) ? (pb->prgs_list[(int)(rb + 3) / pb->prg_size].pm_idx) : -1;
// If pmi of next RB and pmi of current RB are the same, we do 2 RB in a row
// if pmi differs, or current rb is the end (rel15->rbSize - 1), than we do 1 RB in a row
// if pmi differs, or current rb is the end (rb_size - 1), than we do 1 RB in a row
int rb_step0 = pmi == pmi2 ? 2 : 1;
const int rb_step = rb_step0==2 && pmi3==pmi && pmi4==pmi ? 4 : rb_step0;
const int rb_step = rb_step0 == 2 && pmi3 == pmi && pmi4 == pmi ? 4 : rb_step0;
const int re_cnt = NR_NB_SC_PER_RB * rb_step;
if (pmi == 0) { // unitary Precoding
if (subCarrier + re_cnt <= symbol_sz) { // RB does not cross DC
@@ -544,8 +585,9 @@ static inline void do_txdataF(c16_t **txdataF,
} // else { // non-unitary Precoding
rb += rb_step;
} // RB loop: while(rb < rel15->rbSize)
} // RB loop: while(rb < rb_size)
}
static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch, int slot)
{
const int16_t amp = gNB->TX_AMP;
@@ -553,24 +595,20 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
time_stats_t *dlsch_scrambling_stats = &gNB->dlsch_scrambling_stats;
time_stats_t *dlsch_modulation_stats = &gNB->dlsch_modulation_stats;
freq_alloc_bitmap_t *freq_alloc = &dlsch->freq_alloc;
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
const int layerSz = frame_parms->N_RB_DL * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB;
const int symbol_sz=frame_parms->ofdm_symbol_size;
const int dmrs_Type = rel15->dmrsConfigType;
const int nb_re_dmrs = rel15->numDmrsCdmGrpsNoData * (rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
const int16_t amp_dmrs = min((double)amp * sqrt(rel15->numDmrsCdmGrpsNoData), INT16_MAX); // 3GPP TS 38.214 Section 4.1: Table 4.1-1
LOG_D(PHY,
"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n",
rel15->BWPStart,
rel15->BWPSize,
rel15->rbStart,
rel15->rbSize);
const int n_dmrs = (rel15->BWPStart + rel15->rbStart + rel15->rbSize) * nb_re_dmrs;
// 3GPP TS 38.214 Section 4.1: Table 4.1-1
const int16_t amp_dmrs = min((double)amp * sqrt(rel15->numDmrsCdmGrpsNoData), INT16_MAX);
const int n_dmrs = (rel15->BWPStart + freq_alloc->end[freq_alloc->num_blocks - 1] + 1) * nb_re_dmrs;
const int dmrs_symbol_map = rel15->dlDmrsSymbPos; // single DMRS: 010000100 Double DMRS 110001100
const int xOverhead = 0;
const int nb_re =
(12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * rel15->rbSize * rel15->nrOfLayers;
(12 * rel15->NrOfSymbols - nb_re_dmrs * get_num_dmrs(rel15->dlDmrsSymbPos) - xOverhead) * freq_alloc->num_rbs * rel15->nrOfLayers;
const int Qm = rel15->qamModOrder[0];
const int encoded_length = nb_re * Qm;
@@ -583,7 +621,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
rel15->StartSymbolIndex,
1 << rel15->PTRSTimeDensity,
rel15->dlDmrsSymbPos);
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity;
n_ptrs = (freq_alloc->num_rbs + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity;
}
#ifdef DEBUG_DLSCH
@@ -641,16 +679,11 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
start_meas(&gNB->dlsch_pdsch_generation_stats);
/// Resource mapping
// Non interleaved VRB to PRB mapping
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart + rel15->BWPStart) * NR_NB_SC_PER_RB;
if (start_sc >= symbol_sz)
start_sc -= symbol_sz;
const uint32_t txdataF_offset = slot * frame_parms->samples_per_slot_wCP;
#ifdef DEBUG_DLSCH_MAPPING
printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
start_sc,
printf("PDSCH resource mapping started (start symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n",
rel15->StartSymbolIndex,
rel15->rbSize,
freq_alloc->num_rbs,
nb_re,
rel15->nrOfLayers);
#endif
@@ -727,7 +760,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
}
#endif
}
uint32_t dmrs_idx = rel15->rbStart;
uint32_t dmrs_idx = freq_alloc->start[0];
if (rel15->refPoint == 0)
dmrs_idx += rel15->BWPStart;
dmrs_idx *= dmrs_Type == NFAPI_NR_DMRS_TYPE1 ? 6 : 4;
@@ -737,10 +770,10 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
layer_sz = do_onelayer(frame_parms,
slot,
rel15,
freq_alloc,
layer,
txdataF_precoding[layer],
tx_layers[layer] + re_beginning_of_symbol,
start_sc,
symbol_sz,
l_symbol,
dlPtrsSymPos,
@@ -755,9 +788,20 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
stop_meas(&gNB->dlsch_resource_mapping_stats);
start_meas(&gNB->dlsch_precoding_stats);
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
for (int ant = 0; ant < frame_parms->nb_antennas_tx; ant++) {
const size_t txdataF_offset_per_symbol = l_symbol * symbol_sz + txdataF_offset;
do_txdataF(txdataF, symbol_sz, txdataF_precoding, gNB, rel15, ant, start_sc, txdataF_offset_per_symbol);
for (int b = 0; b < freq_alloc->num_blocks; b++) {
int nb_rb_block = freq_alloc->end[b] - freq_alloc->start[b] + 1;
do_txdataF(txdataF,
symbol_sz,
txdataF_precoding,
gNB,
rel15,
ant,
freq_alloc->start[b],
nb_rb_block,
txdataF_offset_per_symbol);
}
}
stop_meas(&gNB->dlsch_precoding_stats);
}
@@ -765,7 +809,7 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
* should remain a multiple of 8 * 64 with enough offset to fit each dlsch
*/
uint32_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
uint32_t size_output_tb = freq_alloc->num_rbs * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
return ((size_output_tb + 511) >> 9) << 6;
}
@@ -786,12 +830,19 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
NR_gNB_DLSCH_t *dlsch = &dlsch_array[i];
const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->pdsch_pdu->pdsch_pdu_rel15;
if (rel15->resourceAlloc == 0) {
int alloc_size = (rel15->BWPSize / 8) + (rel15->BWPSize % 8 > 0);
dlsch->freq_alloc = set_start_end_from_bitmap(rel15->BWPSize, alloc_size, rel15->rbBitmap);
} else {
dlsch->freq_alloc = set_bitmap_from_start_size(rel15->rbStart, rel15->rbSize);
}
LOG_D(PHY,
"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbsize %d\n",
"pdsch: BWPStart %d, BWPSize %d, rbStart %d, rbEnd %d rbsize %d\n",
rel15->BWPStart,
rel15->BWPSize,
rel15->rbStart,
rel15->rbSize);
dlsch->freq_alloc.start[0],
dlsch->freq_alloc.end[dlsch->freq_alloc.num_blocks - 1],
dlsch->freq_alloc.num_rbs);
const int Qm = rel15->qamModOrder[0];
@@ -805,7 +856,7 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
rel15->StartSymbolIndex,
1 << rel15->PTRSTimeDensity,
rel15->dlDmrsSymbPos);
n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity;
n_ptrs = (dlsch->freq_alloc.num_rbs + rel15->PTRSFreqDensity - 1) / rel15->PTRSFreqDensity;
ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, rel15->StartSymbolIndex, rel15->NrOfSymbols);
}
dlsch->unav_res = ptrsSymbPerSlot * n_ptrs;
@@ -816,7 +867,7 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
* => size_output is a sum of parts sizes rounded up to a multiple of 8 * 64
*/
size_t size_output_tb = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
size_t size_output_tb = dlsch->freq_alloc.num_rbs * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * Qm * rel15->nrOfLayers;
size_output += ceil_mod(size_output_tb, 8 * 64);
}

View File

@@ -226,7 +226,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
}
#endif
TB_parameters->nb_rb = rel15->rbSize;
int rbsize = dlsch->freq_alloc.num_rbs;
TB_parameters->nb_rb = rbsize;
TB_parameters->Qm = rel15->qamModOrder[0];
TB_parameters->mcs = rel15->mcsIndex[0];
TB_parameters->nb_layers = rel15->nrOfLayers;
@@ -234,7 +235,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
int nb_re_dmrs =
(rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? (6 * rel15->numDmrsCdmGrpsNoData) : (4 * rel15->numDmrsCdmGrpsNoData);
TB_parameters->G = nr_get_G(rel15->rbSize,
TB_parameters->G = nr_get_G(rbsize,
rel15->NrOfSymbols,
nb_re_dmrs,
get_num_dmrs(rel15->dlDmrsSymbPos),
@@ -243,7 +244,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
rel15->nrOfLayers);
TB_parameters->tbslbrm = rel15->maintenance_parms_v3.tbSizeLbrmBytes;
TB_parameters->output = &output[dlsch_offset >> 3];
TB_parameters->segments = &segments[segments_offset];
@@ -262,7 +262,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
/* output and its parts for each dlsch should be aligned on 64 bytes (or 8 * 64 bits)
* => dlsch_offset should remain a multiple of 8 * 64 with enough offset to fit each dlsch
*/
const size_t dlsch_size = rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers;
const size_t dlsch_size = rbsize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * rel15->qamModOrder[0] * rel15->nrOfLayers;
dlsch_offset += ceil_mod(dlsch_size, 8 * 64);
}

View File

@@ -22,7 +22,7 @@
#ifndef __NR_ESTIMATION_DEFS__H__
#define __NR_ESTIMATION_DEFS__H__
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
#include "PHY/defs_nr_UE.h"
/** @addtogroup _PHY_PARAMETER_ESTIMATION_BLOCKS_

View File

@@ -24,6 +24,7 @@
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/CODING/nrPolar_tools/nr_polar_psbch_defs.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/NR_REFSIG/sl_refsig_defs.h"
// #define SL_DEBUG

View File

@@ -36,7 +36,7 @@
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include <math.h>
#include "nfapi_interface.h"
#include <openair1/PHY/LTE_TRANSPORT/transport_proto.h>
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
#define NR_PUSCH_y 3 // UCI placeholder bit

View File

@@ -38,15 +38,6 @@
#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;

View File

@@ -35,6 +35,7 @@
#include "common/platform_constants.h"
#include "defs_nr_common.h"
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "PHY/impl_defs_top.h"
@@ -100,6 +101,8 @@ typedef struct {
typedef struct {
/// Nfapi DLSCH PDU
const nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu;
/// freq allocation information
freq_alloc_bitmap_t freq_alloc;
/// pointer to pdu from MAC interface (this is "a" in 36.212)
uint8_t *pdu;
/// Pointer to the payload

View File

@@ -394,4 +394,15 @@ int nr_get_ssb_start_sc(int scs,
int ssb_sco,
frequency_range_t freq_range);
#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;
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]);
freq_alloc_bitmap_t set_bitmap_from_start_size(int start, int size);
#endif

View File

@@ -444,6 +444,56 @@ 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));
return alloc;
}
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
};
memset(alloc.bitmap, 0, 36 * sizeof(uint8_t));
for (int i = start; i < size + start; i++)
alloc.bitmap[i / 8] += 1 << (i % 8);
return alloc;
}
bool check_rb_in_bitmap(const freq_alloc_bitmap_t *alloc, int rb)
{
return (alloc->bitmap[rb / 8] >> (rb % 8)) & 0x01;
}
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)
{
const double phase_inc = -fo_Hz / (samples_per_ms * 1000);

View File

@@ -515,51 +515,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
return ret;
}
static 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));
return alloc;
}
static 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
};
memset(alloc.bitmap, 0, 36 * sizeof(uint8_t));
for (int i = start; i < size + start; i++)
alloc.bitmap[i / 8] += 1 << (i % 8);
return alloc;
}
static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t dlsch[2],

View File

@@ -427,8 +427,9 @@ int main(int argc, char **argv)
dlsch_ue[0].rnti = n_rnti;
nr_init_dl_harq_processes(UE->dl_harq_processes, 8, nb_rb);
unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
NR_gNB_DLSCH_t *dlsch = &gNB->dlsch[0];
dlsch->freq_alloc = set_bitmap_from_start_size(0, nb_rb);
//time_stats_t *rm_stats, *te_stats, *i_stats;
unsigned int TBS = 8424;
uint8_t nb_re_dmrs = 6; // No data in dmrs symbol