Merge branch 'integration_2023_w36' into 'develop'

integration_2023_w36

See merge request oai/openairinterface5g!2333

* !2185 DL delay compensation
* !2255 Add condition to call or not the function nr_mac_prepare_ra_ue()
* !2301 NR UE handling MCS for retransmissions
* !2308 Heap Allocation issue: Removed Dynamic allocation
* !2317 bugfix: don't force an UE to support en-dc, respect its capabilities
* !2318 Set security for all active SRBs after NR_RRCReestablishment
* !2321 Use appropriate CMake flags to link to UHD
* !2332 T tracer: add a trace for NR SIB1
* !2322 Remove small races in ue
* !2323 NR UE fix DCI candidates
* !2328 Add SRB1 and SRB2 received bytes to statistics
This commit is contained in:
Robert Schmidt
2023-09-12 11:37:40 +00:00
52 changed files with 634 additions and 704 deletions
+1
View File
@@ -1112,6 +1112,7 @@ set(PHY_SRC_UE ${PHY_SRC_UE} ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_comp
set(PHY_NR_UE_SRC ${PHY_NR_UE_SRC} ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation_avx2.c)
add_library(PHY_COMMON ${PHY_SRC_COMMON})
target_link_libraries(PHY_COMMON PRIVATE shlib_loader)
add_dependencies(PHY_COMMON dfts)
target_link_libraries(PHY_COMMON PRIVATE asn1_lte_rrc_hdrs)
+12 -2
View File
@@ -274,6 +274,7 @@ void sr(void *_d, event e)
#define NR_NO_RNTI 0
#define NR_RA_RNTI 2
#define NR_C_RNTI 3
#define NR_SI_RNTI 4
void trace_nr(ev_data *d, int direction, int rnti_type, int rnti,
int frame, int slot, int harq_pid, void *buf, int bufsize,
@@ -346,8 +347,17 @@ void nr_dl(void *_d, event e)
{
ev_data *d = _d;
trace_nr(d, NR_DIRECTION_DOWNLINK, NR_C_RNTI, e.e[d->nr_dl_rnti].i,
e.e[d->nr_dl_frame].i, e.e[d->nr_dl_slot].i,
if (e.e[d->dl_rnti].i == 0xffff) {
if (d->no_sib) return;
if (d->max_sib && d->cur_sib == d->max_sib) return;
d->cur_sib++;
}
trace_nr(d, NR_DIRECTION_DOWNLINK,
e.e[d->dl_rnti].i != 0xffff ? NR_C_RNTI : NR_SI_RNTI,
e.e[d->nr_dl_rnti].i, e.e[d->nr_dl_frame].i, e.e[d->nr_dl_slot].i,
e.e[d->nr_dl_harq_pid].i, e.e[d->nr_dl_data].b,
e.e[d->nr_dl_data].bsize, NO_PREAMBLE);
}
+1 -1
View File
@@ -49,8 +49,8 @@
* ```
*/
#include "common/utils/LOG/log.h"
#if TRACE_ASN1C_ENC_DEC
#include "common/utils/LOG/log.h"
#define ASN_DEBUG(x...) do{ LOG_I(ASN1,x);LOG_I(ASN1,"\n"); } while(false)
#else
#define ASN_DEBUG(x...)
+87
View File
@@ -33,6 +33,7 @@
#include <stdint.h>
#include "assertions.h"
#include "nr_common.h"
#include <complex.h>
const char *duplex_mode[]={"FDD","TDD"};
@@ -738,3 +739,89 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
AssertFatal(sco % scs_scaling == 0, "ssb offset %d can create frequency offset\n", sco);
return ssb_offset_point_a;
}
int get_delay_idx(int delay, int max_delay_comp)
{
int delay_idx = max_delay_comp + delay;
// If the measured delay is less than -MAX_DELAY_COMP, a -MAX_DELAY_COMP delay is compensated.
delay_idx = max(delay_idx, 0);
// If the measured delay is greater than +MAX_DELAY_COMP, a +MAX_DELAY_COMP delay is compensated.
delay_idx = min(delay_idx, max_delay_comp << 1);
return delay_idx;
}
void init_delay_table(uint16_t ofdm_symbol_size,
int max_delay_comp,
int max_ofdm_symbol_size,
c16_t delay_table[][max_ofdm_symbol_size])
{
for (int delay = -max_delay_comp; delay <= max_delay_comp; delay++) {
for (int k = 0; k < ofdm_symbol_size; k++) {
double complex delay_cexp = cexp(I * (2.0 * M_PI * k * delay / ofdm_symbol_size));
delay_table[max_delay_comp + delay][k].r = (int16_t)round(256 * creal(delay_cexp));
delay_table[max_delay_comp + delay][k].i = (int16_t)round(256 * cimag(delay_cexp));
}
}
}
void freq2time(uint16_t ofdm_symbol_size,
int16_t *freq_signal,
int16_t *time_signal)
{
switch (ofdm_symbol_size) {
case 128:
idft(IDFT_128, freq_signal, time_signal, 1);
break;
case 256:
idft(IDFT_256, freq_signal, time_signal, 1);
break;
case 512:
idft(IDFT_512, freq_signal, time_signal, 1);
break;
case 1024:
idft(IDFT_1024, freq_signal, time_signal, 1);
break;
case 1536:
idft(IDFT_1536, freq_signal, time_signal, 1);
break;
case 2048:
idft(IDFT_2048, freq_signal, time_signal, 1);
break;
case 4096:
idft(IDFT_4096, freq_signal, time_signal, 1);
break;
case 6144:
idft(IDFT_6144, freq_signal, time_signal, 1);
break;
case 8192:
idft(IDFT_8192, freq_signal, time_signal, 1);
break;
default:
AssertFatal (1 == 0, "Invalid ofdm_symbol_size %i\n", ofdm_symbol_size);
break;
}
}
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay)
{
freq2time(ofdm_symbol_size, (int16_t *)ls_est, (int16_t *)ch_estimates_time);
int max_pos = delay->delay_max_pos;
int max_val = delay->delay_max_val;
const int sync_pos = 0;
for (int i = 0; i < ofdm_symbol_size; i++) {
int temp = c16amp2(ch_estimates_time[i]) >> 1;
if (temp > max_val) {
max_pos = i;
max_val = temp;
}
}
if (max_pos > ofdm_symbol_size / 2)
max_pos = max_pos - ofdm_symbol_size;
delay->delay_max_pos = max_pos;
delay->delay_max_val = max_val;
delay->est_delay = max_pos - sync_pos;
}
+17
View File
@@ -72,6 +72,15 @@ typedef enum frequency_range_e {
FR2
} frequency_range_t;
typedef struct {
/// Time shift in number of samples estimated based on DMRS-PDSCH/PUSCH
int est_delay;
/// Max position in OFDM symbol related to time shift estimation based on DMRS-PDSCH/PUSCH
int delay_max_pos;
/// Max value related to time shift estimation based on DMRS-PDSCH/PUSCH
int delay_max_val;
} delay_t;
extern const nr_bandentry_t nr_bandtable[];
static inline int get_num_dmrs(uint16_t dmrs_mask ) {
@@ -114,6 +123,14 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
int ssbSubcarrierSpacing,
int frequency_range);
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA);
int get_delay_idx(int delay, int max_delay_comp);
void freq2time(uint16_t ofdm_symbol_size,
int16_t *freq_signal,
int16_t *time_signal);
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay);
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
@@ -110,8 +110,6 @@
{"ulsch_ldpc_encoding_stats", &(UE->ulsch_ldpc_encoding_stats),0,1},\
{"ulsch_interleaving_stats", &(UE->ulsch_interleaving_stats),0,1},\
{"ulsch_multiplexing_stats", &(UE->ulsch_multiplexing_stats),0,1},\
{"generic_stat", &(UE->generic_stat),0,1},\
{"generic_stat_bis", &(UE->generic_stat_bis[0]),0,LTE_SLOTS_PER_SUBFRAME},\
{"ofdm_demod_stats", &(UE->ofdm_demod_stats),0,1},\
{"dlsch_rx_pdcch_stats", &(UE->dlsch_rx_pdcch_stats),0,1},\
{"rx_dft_stats", &(UE->rx_dft_stats),0,1},\
+1 -3
View File
@@ -879,7 +879,6 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap
if (req->sch_config.physical_cell_id.tl.tag == NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG) {
fp->Nid_cell = req->sch_config.physical_cell_id.value;
fp->nushift = fp->Nid_cell%6;
num_tlv++;
}
@@ -1049,8 +1048,7 @@ int nr_config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, n
}
if (req->cell_config.phy_cell_id.tl.tag == NFAPI_NR_CONFIG_PHY_CELL_ID_TAG) {
fp->Nid_cell = req->cell_config.phy_cell_id.value; //sch_config.physical_cell_id.value;
fp->nushift = fp->Nid_cell%6;
fp->Nid_cell = req->cell_config.phy_cell_id.value; // sch_config.physical_cell_id.value;
num_tlv++;
}
+3 -27
View File
@@ -778,23 +778,9 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
break;
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1;
nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1;
if (ind_pdu->sr) {
uci_ind_pdu->sr = CALLOC(1, sizeof(*uci_ind_pdu->sr));
AssertFatal(uci_ind_pdu->sr != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication.");
*uci_ind_pdu->sr = *ind_pdu->sr;
}
if (ind_pdu->harq) {
uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq));
AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication.");
*uci_ind_pdu->harq = *ind_pdu->harq;
uci_ind_pdu->harq->harq_list = CALLOC(uci_ind_pdu->harq->num_harq, sizeof(*uci_ind_pdu->harq->harq_list));
AssertFatal(uci_ind_pdu->harq->harq_list != NULL, "Memory not allocated for uci_ind_pdu->harq->harq_list in phy_nr_uci_indication.");
for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++)
uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value;
}
//nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1;
//nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1;
//Unused
break;
}
@@ -834,16 +820,6 @@ int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
{
if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE)
{
if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) {
free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list);
uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL;
free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq);
uci_ind->uci_list[i].pucch_pdu_format_0_1.harq = NULL;
}
if (uci_ind->uci_list[i].pucch_pdu_format_0_1.sr) {
free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr);
uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL;
}
}
if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE)
{
@@ -1580,7 +1580,7 @@ typedef struct
{
uint8_t num_harq;
uint8_t harq_confidence_level;
nfapi_nr_harq_t* harq_list;
nfapi_nr_harq_t harq_list[2];
} nfapi_nr_harq_pdu_0_1_t;
@@ -1628,8 +1628,8 @@ typedef struct
uint8_t ul_cqi;
uint16_t timing_advance;
uint16_t rssi;
nfapi_nr_sr_pdu_0_1_t *sr;//67
nfapi_nr_harq_pdu_0_1_t *harq;//68
nfapi_nr_sr_pdu_0_1_t sr;//67
nfapi_nr_harq_pdu_0_1_t harq;//68
}nfapi_nr_uci_pucch_pdu_format_0_1_t;
+15 -33
View File
@@ -3292,20 +3292,20 @@ static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint
if (!push16(value->rssi, ppWritePackedMsg, end))
return 0;
if (value->pduBitmap & 0x01) { //SR
if (!push8(value->sr->sr_indication, ppWritePackedMsg, end))
if (!push8(value->sr.sr_indication, ppWritePackedMsg, end))
return 0;
if (!push8(value->sr->sr_confidence_level, ppWritePackedMsg, end))
if (!push8(value->sr.sr_confidence_level, ppWritePackedMsg, end))
return 0;
}
if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
if (!push8(value->harq->num_harq, ppWritePackedMsg, end))
if (!push8(value->harq.num_harq, ppWritePackedMsg, end))
return 0;
if (!push8(value->harq->harq_confidence_level, ppWritePackedMsg, end))
if (!push8(value->harq.harq_confidence_level, ppWritePackedMsg, end))
return 0;
for (int i = 0; i < value->harq->num_harq; i++)
for (int i = 0; i < value->harq.num_harq; i++)
{
if (!push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end))
if (!push8(value->harq.harq_list[i].harq_value, ppWritePackedMsg, end))
return 0;
}
}
@@ -6075,41 +6075,23 @@ static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *valu
))
return 0;
if (value->pduBitmap & 0x01) { //SR
value->sr = nfapi_p7_allocate(sizeof(*value->sr), config);
if (value->sr == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr pdu\n", __FUNCTION__);
return 0;
}
if(!(pull8(ppReadPackedMsg, &value->sr->sr_indication, end) &&
pull8(ppReadPackedMsg, &value->sr->sr_confidence_level, end)
if(!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) &&
pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)
))
return 0;
}
if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
value->harq = nfapi_p7_allocate(sizeof(*value->harq), config);
if (value->harq == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nr_harq pdu\n", __FUNCTION__);
return 0;
}
if (!(pull8(ppReadPackedMsg, &value->harq->num_harq, end) &&
pull8(ppReadPackedMsg, &value->harq->harq_confidence_level, end)
if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) &&
pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)
))
return 0;
value->harq->harq_list = NULL;
if (value->harq->num_harq > 0) {
value->harq->harq_list = nfapi_p7_allocate(sizeof(*value->harq->harq_list) * value->harq->num_harq, config);
if (value->harq->harq_list == NULL)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n",
__FUNCTION__, value->harq->num_harq);
return 0;
}
for (int i = 0; i < value->harq->num_harq; i++) {
if (!pull8(ppReadPackedMsg, &value->harq->harq_list[i].harq_value, end)) {
if (value->harq.num_harq > 0) {
for (int i = 0; i < value->harq.num_harq; i++) {
if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
return 0;
}
}
+1 -12
View File
@@ -66,17 +66,6 @@ int l1_north_init_gNB() {
return(0);
}
void init_ul_delay_table(NR_DL_FRAME_PARMS *fp)
{
for (int delay = -MAX_UL_DELAY_COMP; delay <= MAX_UL_DELAY_COMP; delay++) {
for (int k = 0; k < fp->ofdm_symbol_size; k++) {
double complex delay_cexp = cexp(I * (2.0 * M_PI * k * delay / fp->ofdm_symbol_size));
fp->ul_delay_table[MAX_UL_DELAY_COMP + delay][k].r = (int16_t)round(256 * creal(delay_cexp));
fp->ul_delay_table[MAX_UL_DELAY_COMP + delay][k].i = (int16_t)round(256 * cimag(delay_cexp));
}
}
}
NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti)
{
NR_gNB_PHY_STATS_t *stats;
@@ -544,7 +533,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB)
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
init_codebook_gNB(gNB);
init_ul_delay_table(fp);
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
+1
View File
@@ -674,6 +674,7 @@ void init_N_TA_offset(PHY_VARS_NR_UE *ue){
void phy_init_nr_top(PHY_VARS_NR_UE *ue) {
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
init_delay_table(frame_parms->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, frame_parms->delay_table);
crcTableInit();
init_scrambling_luts();
load_dftslib();
+4
View File
@@ -56,5 +56,9 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES],
void phy_init_nr_top(PHY_VARS_NR_UE *ue);
void phy_term_nr_top(void);
void init_delay_table(uint16_t ofdm_symbol_size,
int max_delay_comp,
int max_ofdm_symbol_size,
c16_t delay_table[][max_ofdm_symbol_size]);
#endif
@@ -38,29 +38,6 @@
extern openair0_config_t openair0_cfg[MAX_CARDS];
void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms, const int32_t *ul_ch_estimates_time, NR_ULSCH_delay_t *delay)
{
int max_pos = delay->pusch_delay_max_pos;
int max_val = delay->pusch_delay_max_val;
const int sync_pos = 0;
for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) {
c16_t *sample = (c16_t *)&ul_ch_estimates_time[i];
int temp = (sample->r * sample->r / 2) + (sample->i * sample->i / 2);
if (temp > max_val) {
max_pos = i;
max_val = temp;
}
}
if (max_pos > frame_parms->ofdm_symbol_size / 2)
max_pos = max_pos - frame_parms->ofdm_symbol_size;
delay->pusch_delay_max_pos = max_pos;
delay->pusch_delay_max_val = max_val;
delay->pusch_est_delay = max_pos - sync_pos;
}
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) {
int timing_advance = 0;
@@ -42,45 +42,6 @@
#define NO_INTERP 1
#define dBc(x,y) (dB_fixed(((int32_t)(x))*(x) + ((int32_t)(y))*(y)))
void freq2time(uint16_t ofdm_symbol_size,
int16_t *freq_signal,
int16_t *time_signal) {
switch (ofdm_symbol_size) {
case 128:
idft(IDFT_128, freq_signal, time_signal, 1);
break;
case 256:
idft(IDFT_256, freq_signal, time_signal, 1);
break;
case 512:
idft(IDFT_512, freq_signal, time_signal, 1);
break;
case 1024:
idft(IDFT_1024, freq_signal, time_signal, 1);
break;
case 1536:
idft(IDFT_1536, freq_signal, time_signal, 1);
break;
case 2048:
idft(IDFT_2048, freq_signal, time_signal, 1);
break;
case 4096:
idft(IDFT_4096, freq_signal, time_signal, 1);
break;
case 6144:
idft(IDFT_6144, freq_signal, time_signal, 1);
break;
case 8192:
idft(IDFT_8192, freq_signal, time_signal, 1);
break;
default:
idft(IDFT_512, freq_signal, time_signal, 1);
break;
}
}
__attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *in1,
int *offset1,
const int step1,
@@ -103,19 +64,6 @@ __attribute__((always_inline)) inline c16_t c32x16cumulVectVectWithSteps(c16_t *
return c16x32div(cumul, N);
}
int get_delay_idx(int delay) {
int delay_idx = MAX_UL_DELAY_COMP + delay;
// If the measured delay is less than -MAX_UL_DELAY_COMP, a -MAX_UL_DELAY_COMP delay is compensated.
if (delay_idx < 0) {
delay_idx = 0;
}
// If the measured delay is greater than +MAX_UL_DELAY_COMP, a +MAX_UL_DELAY_COMP delay is compensated.
if (delay_idx > MAX_UL_DELAY_COMP<<1) {
delay_idx = MAX_UL_DELAY_COMP<<1;
}
return delay_idx;
}
int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
unsigned char Ns,
unsigned short p,
@@ -138,8 +86,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates;
const int symbolSize = gNB->frame_parms.ofdm_symbol_size;
const int soffset = (Ns&3)*gNB->frame_parms.symbols_per_slot*symbolSize;
const int nushift = (p>>1)&1;
gNB->frame_parms.nushift = nushift;
const int nushift = (p >> 1) & 1;
int ch_offset = symbolSize*symbol;
const int symbol_offset = symbolSize*symbol;
@@ -194,7 +141,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
uint64_t noise_amp2 = 0;
c16_t ul_ls_est[symbolSize] __attribute__((aligned(32)));
memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize);
NR_ULSCH_delay_t *delay = &gNB->ulsch[ul_id].delay;
delay_t *delay = &gNB->ulsch[ul_id].delay;
memset(delay, 0, sizeof(*delay));
for (int aarx=0; aarx<gNB->frame_parms.nb_antennas_rx; aarx++) {
@@ -236,15 +183,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
pilot_cnt += 2;
}
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay);
int pusch_delay = delay->pusch_est_delay;
int delay_idx = get_delay_idx(pusch_delay);
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[aarx], delay);
int delay_idx = get_delay_idx(delay->est_delay, MAX_DELAY_COMP);
c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx];
#ifdef DEBUG_PUSCH
printf("Estimated delay = %i\n", pusch_delay >> 1);
printf("Estimated delay = %i\n", delay->est_delay >> 1);
#endif
pilot_cnt = 0;
@@ -284,8 +228,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// Revert delay
pilot_cnt = 0;
ul_ch = &ul_ch_estimates[p * gNB->frame_parms.nb_antennas_rx + aarx][ch_offset];
int inv_delay_idx = get_delay_idx(-pusch_delay);
c16_t *ul_inv_delay_table = gNB->frame_parms.ul_delay_table[inv_delay_idx];
int inv_delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
c16_t *ul_inv_delay_table = gNB->frame_parms.delay_table[inv_delay_idx];
for (int n = 0; n < 3 * nb_rb_pusch; n++) {
for (int k_line = 0; k_line <= 1; k_line++) {
int k = pilot_cnt << 1;
@@ -323,11 +267,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
}
// Delay compensation
freq2time(symbolSize, (int16_t *)ul_ls_est, (int16_t *)pusch_vars->ul_ch_estimates_time[aarx]);
nr_est_timing_advance_pusch(&gNB->frame_parms, pusch_vars->ul_ch_estimates_time[aarx], delay);
int pusch_delay = delay->pusch_est_delay;
int delay_idx = get_delay_idx(-pusch_delay);
c16_t *ul_delay_table = gNB->frame_parms.ul_delay_table[delay_idx];
nr_est_delay(gNB->frame_parms.ofdm_symbol_size, ul_ls_est, (c16_t *)pusch_vars->ul_ch_estimates_time[aarx], delay);
int delay_idx = get_delay_idx(-delay->est_delay, MAX_DELAY_COMP);
c16_t *ul_delay_table = gNB->frame_parms.delay_table[delay_idx];
for (int n = 0; n < nb_rb_pusch * NR_NB_SC_PER_RB; n++) {
ul_ch[n] = c16mulShift(ul_ls_est[n], ul_delay_table[n % 6], 8);
}
@@ -60,10 +60,6 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB,
unsigned char symbol,
uint8_t nrOfLayers);
void nr_est_timing_advance_pusch(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t *ul_ch_estimates_time,
NR_ULSCH_delay_t *delay);
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]);
+23 -31
View File
@@ -146,7 +146,7 @@ static const int16_t idft12_im[12][12] = {
{0,-20066,-20066,0,20066,20066,0,-20066,-20066,0,20066,20066},
{0,-11585,-20066,-23170,-20066,-11585,0,11585,20066,23170,20066,11585}
};
//************************************************************************//
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
int frame,
int slot,
@@ -406,31 +406,27 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767))-dB_fixed_times10(sigenergy);
if (pucch_pdu->bit_len_harq==0) {
uci_pdu->harq = NULL;
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_confidence_level = SNRtimes10 < uci_stats->pucch0_thres;
uci_pdu->sr.sr_confidence_level = SNRtimes10 < uci_stats->pucch0_thres;
uci_stats->pucch0_sr_trials++;
if (xrtmag_dBtimes10>(10*max_n0+100)) {
uci_pdu->sr->sr_indication = 1;
uci_pdu->sr.sr_indication = 1;
uci_stats->pucch0_positive_SR++;
LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
} else {
uci_pdu->sr->sr_indication = 0;
uci_pdu->sr.sr_indication = 0;
}
}
else if (pucch_pdu->bit_len_harq==1) {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 1;
uci_pdu->harq->harq_confidence_level = no_conf;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(sizeof *uci_pdu->harq->harq_list);
uci_pdu->harq->harq_list[0].harq_value = !(index&0x01);
uci_pdu->harq.num_harq = 1;
uci_pdu->harq.harq_confidence_level = no_conf;
uci_pdu->harq.harq_list[0].harq_value = !(index&0x01);
LOG_D(PHY,
"[DLSCH/PDSCH/PUCCH] %d.%d HARQ %s with confidence level %s xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, "
"cqi %d, SNRtimes10 %d, energy %f\n",
frame,
slot,
uci_pdu->harq->harq_list[0].harq_value == 0 ? "ACK" : "NACK",
uci_pdu->harq->harq_confidence_level == 0 ? "good" : "bad",
uci_pdu->harq.harq_list[0].harq_value == 0 ? "ACK" : "NACK",
uci_pdu->harq.harq_confidence_level == 0 ? "good" : "bad",
xrtmag_dBtimes10,
xrtmag_next_dBtimes10,
max_n0,
@@ -442,10 +438,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
10 * log10((double)sigenergy));
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>1);
uci_pdu->sr->sr_confidence_level = no_conf;
if(uci_pdu->sr->sr_indication == 1 && uci_pdu->sr->sr_confidence_level == 0) {
uci_pdu->sr.sr_indication = (index>1);
uci_pdu->sr.sr_confidence_level = no_conf;
if(uci_pdu->sr.sr_indication == 1 && uci_pdu->sr.sr_confidence_level == 0) {
uci_stats->pucch0_positive_SR++;
LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
}
@@ -453,21 +448,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
uci_stats->pucch01_trials++;
}
else {
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
uci_pdu->harq->num_harq = 2;
uci_pdu->harq->harq_confidence_level = no_conf;
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2 * sizeof( *uci_pdu->harq->harq_list));
uci_pdu->harq.num_harq = 2;
uci_pdu->harq.harq_confidence_level = no_conf;
uci_pdu->harq->harq_list[1].harq_value = !(index&0x01);
uci_pdu->harq->harq_list[0].harq_value = !((index>>1)&0x01);
uci_pdu->harq.harq_list[1].harq_value = !(index&0x01);
uci_pdu->harq.harq_list[0].harq_value = !((index>>1)&0x01);
LOG_D(PHY,
"[DLSCH/PDSCH/PUCCH] %d.%d HARQ values (%s, %s) with confidence level %s, xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) "
"pucch0_thres %d, cqi %d, SNRtimes10 %d\n",
frame,
slot,
uci_pdu->harq->harq_list[1].harq_value == 0 ? "ACK" : "NACK",
uci_pdu->harq->harq_list[0].harq_value == 0 ? "ACK" : "NACK",
uci_pdu->harq->harq_confidence_level == 0 ? "good" : "bad",
uci_pdu->harq.harq_list[1].harq_value == 0 ? "ACK" : "NACK",
uci_pdu->harq.harq_list[0].harq_value == 0 ? "ACK" : "NACK",
uci_pdu->harq.harq_confidence_level == 0 ? "good" : "bad",
xrtmag_dBtimes10,
xrtmag_next_dBtimes10,
max_n0,
@@ -477,17 +470,16 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
cqi,
SNRtimes10);
if (pucch_pdu->sr_flag == 1) {
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
uci_pdu->sr->sr_confidence_level = no_conf;
if(uci_pdu->sr->sr_indication == 1 && uci_pdu->sr->sr_confidence_level == 0) {
uci_pdu->sr.sr_indication = (index>3) ? 1 : 0;
uci_pdu->sr.sr_confidence_level = no_conf;
if(uci_pdu->sr.sr_indication == 1 && uci_pdu->sr.sr_confidence_level == 0) {
uci_stats->pucch0_positive_SR++;
LOG_D(PHY,"PUCCH0 got positive SR. Cumulative number of positive SR %d\n", uci_stats->pucch0_positive_SR);
}
}
}
}
//*****************************************************************//
void nr_decode_pucch1(c16_t **rxdataF,
pucch_GroupHopping_t pucch_GroupHopping,
uint32_t n_id, // hoppingID higher layer parameter
@@ -635,18 +635,13 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int pilot[200] __attribute__((aligned(16)));
unsigned short k;
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF;
int symbol_offset;
uint8_t nushift;
uint8_t ssb_index=current_ssb->i_ssb;
uint8_t n_hf=current_ssb->n_hf;
nushift = ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
@@ -656,8 +651,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
k = nushift;
unsigned int k = ue->frame_parms.Nid_cell % 4;
#ifdef DEBUG_PBCH
printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
@@ -805,8 +799,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
//int slot_pbch;
uint8_t nushift;
nushift = ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift;
nushift = ue->frame_parms.Nid_cell % 4;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
@@ -1309,52 +1302,50 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
c16_t *dl_ch,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
int8_t delta)
int8_t delta,
delay_t *delay)
{
int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
c16_t *pil0 = pil;
c16_t *dl_ch0 = dl_ch;
c16_t ch = {0};
int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
const int16_t *fdcl = NULL;
const int16_t *fdcr = NULL;
const int16_t *fdclh = NULL;
const int16_t *fdcrh = NULL;
switch (delta) {
case 0: // port 0,1
fdcl = filt8_dcl0; // left DC interpolation Filter (even RB)
fdcr = filt8_dcr0; // right DC interpolation Filter (even RB)
fdclh = filt8_dcl0_h; // left DC interpolation Filter (odd RB)
fdcrh = filt8_dcr0_h; // right DC interpolation Filter (odd RB)
break;
case 1: // port2,3
fdcl = filt8_dcl1;
fdcr = filt8_dcr1;
fdclh = filt8_dcl1_h;
fdcrh = filt8_dcr1_h;
break;
default:
AssertFatal(1 == 0, "pdsch_channel_estimation: Invalid delta %i\n", delta);
break;
}
c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(dl_ls_est, 0, sizeof(dl_ls_est));
for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) {
if (pilot_cnt % 2 == 0) {
ch = c16mulShift(*pil, rxF[re_offset], 15);
c16_t ch = c16mulShift(*pil, rxF[re_offset], 15);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
ch = c16maddShift(*pil, rxF[re_offset], ch, 15);
ch = c16Shift(ch, 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;
}
}
#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.r, ch.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,
dl_ls_est[pilot_cnt << 1].r,
dl_ls_est[pilot_cnt << 1].i);
#endif
}
c16_t ch_estimates_time[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(ch_estimates_time, 0, sizeof(ch_estimates_time));
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 << 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) {
@@ -1369,45 +1360,12 @@ void NFAPI_NR_DMRS_TYPE1_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
}
}
// check if PRB crosses DC and improve estimates around DC
if ((bwp_start_subcarrier < frame_parms->ofdm_symbol_size) && (bwp_start_subcarrier + nb_rb_pdsch * 12 >= frame_parms->ofdm_symbol_size)) {
dl_ch = dl_ch0;
uint16_t idxDC = 2 * (frame_parms->ofdm_symbol_size - bwp_start_subcarrier);
uint16_t idxPil = idxDC / 4;
re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
pil = pil0;
pil += (idxPil - 1);
dl_ch += (idxDC / 2 - 2);
dl_ch = memset(dl_ch, 0, sizeof(c16_t) * 5);
re_offset = (re_offset + idxDC / 2 - 2) % frame_parms->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
ch = c16maddShift(*pil, rxF[re_offset], ch, 15);
ch = c16Shift(ch, 1);
// for proper allignment of SIMD vectors
if ((frame_parms->N_RB_DL & 1) == 0) {
c16multaddVectRealComplex(fdcl, &ch, dl_ch - 2, 8);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
ch = c16maddShift(*pil, rxF[re_offset], ch, 15);
ch = c16Shift(ch, 1);
c16multaddVectRealComplex(fdcr, &ch, dl_ch - 2, 8);
} else {
c16multaddVectRealComplex(fdclh, &ch, dl_ch, 8);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
ch = c16mulShift(*pil, rxF[re_offset], 15);
pil++;
re_offset = (re_offset + 2) % frame_parms->ofdm_symbol_size;
ch = c16maddShift(*pil, rxF[re_offset], ch, 15);
ch = c16Shift(ch, 1);
c16multaddVectRealComplex(fdcrh, &ch, dl_ch, 8);
}
// Revert delay
dl_ch = dl_ch0;
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++) {
dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8);
}
}
@@ -1503,76 +1461,64 @@ void NFAPI_NR_DMRS_TYPE2_linear_interp(NR_DL_FRAME_PARMS *frame_parms,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
int8_t delta,
unsigned short p)
unsigned short p,
delay_t *delay)
{
int re_offset = bwp_start_subcarrier % frame_parms->ofdm_symbol_size;
c16_t *dl_ch0 = dl_ch;
c16_t ch = {0};
c16_t ch_l = {0};
c16_t ch_r = {0};
c16_t dl_ls_est[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(dl_ls_est, 0, sizeof(dl_ls_est));
for (int pilot_cnt = 0; pilot_cnt < 4 * nb_rb_pdsch; pilot_cnt += 2) {
ch_l = c16mulShift(*pil, rxF[re_offset], 15);
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);
#endif
pil++;
re_offset = (re_offset + 1) % frame_parms->ofdm_symbol_size;
ch_r = c16mulShift(*pil, rxF[re_offset], 15);
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, pil->r, pil->i, rxF[re_offset].r, rxF[re_offset].i, ch_r.r, ch_r.i);
#endif
ch = c16addShift(ch_l, ch_r, 1);
if (pilot_cnt == 1) {
multadd_real_vector_complex_scalar(filt16_dl_first_type2, (int16_t *)&ch, (int16_t *)dl_ch, 16);
dl_ch += 3;
} else if (pilot_cnt == (4 * nb_rb_pdsch - 1)) {
multadd_real_vector_complex_scalar(filt16_dl_last_type2, (int16_t *)&ch, (int16_t *)dl_ch, 16);
} else {
multadd_real_vector_complex_scalar(filt16_dl_middle_type2, (int16_t *)&ch, (int16_t *)dl_ch, 16);
dl_ch += 6;
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;
}
pil++;
re_offset = (re_offset + 5) % frame_parms->ofdm_symbol_size;
}
// check if PRB crosses DC and improve estimates around DC
if ((bwp_start_subcarrier < frame_parms->ofdm_symbol_size) && (bwp_start_subcarrier + nb_rb_pdsch * 12 >= frame_parms->ofdm_symbol_size) && (p < 2)) {
dl_ch = dl_ch0;
uint16_t idxDC = 2 * (frame_parms->ofdm_symbol_size - bwp_start_subcarrier);
dl_ch += (idxDC / 2 - 4);
dl_ch = memset(dl_ch, 0, sizeof(c16_t) * 10);
c16_t ch_estimates_time[frame_parms->ofdm_symbol_size] __attribute__((aligned(32)));
memset(ch_estimates_time, 0, sizeof(ch_estimates_time));
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];
dl_ch--;
ch_r = *dl_ch;
dl_ch += 11;
ch_l = *dl_ch;
// for proper allignment of SIMD vectors
if ((frame_parms->N_RB_DL & 1) == 0) {
dl_ch -= 10;
// Interpolate fdcrl1 with ch_r
c16multaddVectRealComplex(filt8_dcrl1, &ch_r, dl_ch, 8);
// Interpolate fdclh1 with ch_l
c16multaddVectRealComplex(filt8_dclh1, &ch_l, dl_ch, 8);
dl_ch += 8;
// Interpolate fdcrh1 with ch_r
c16multaddVectRealComplex(filt8_dcrh1, &ch_r, dl_ch, 8);
// Interpolate fdcll1 with ch_l
c16multaddVectRealComplex(filt8_dcll1, &ch_l, dl_ch, 8);
} else {
dl_ch -= 14;
// Interpolate fdcrl1 with ch_r
c16multaddVectRealComplex(filt8_dcrl2, &ch_r, dl_ch, 8);
// Interpolate fdclh1 with ch_l
c16multaddVectRealComplex(filt8_dclh2, &ch_l, dl_ch, 8);
dl_ch += 8;
// Interpolate fdcrh1 with ch_r
c16multaddVectRealComplex(filt8_dcrh2, &ch_r, dl_ch, 8);
// Interpolate fdcll1 with ch_l
c16multaddVectRealComplex(filt8_dcll2, &ch_l, dl_ch, 8);
for (int pilot_cnt = 0; pilot_cnt < 6 * nb_rb_pdsch; pilot_cnt++) {
int k = (pilot_cnt / 3) * 6;
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
c16multaddVectRealComplex(filt16_ul_last, &ch, dl_ch, 16);
} else { // Treat middle pilots
c16multaddVectRealComplex(filt16_ul_middle, &ch, dl_ch, 16);
if (pilot_cnt % 2 == 0) {
dl_ch += 4;
}
}
}
// Revert delay
dl_ch = dl_ch0;
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++) {
dl_ch[k] = c16mulShift(dl_ch[k], dl_inv_delay_table[k], 8);
}
}
void NFAPI_NR_DMRS_TYPE2_average_prb(NR_DL_FRAME_PARMS *frame_parms,
@@ -1707,14 +1653,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
uint8_t nushift = 0;
if (config_type == NFAPI_NR_DMRS_TYPE1) {
nushift = (p >> 1) & 1;
if (p < 4)
ue->frame_parms.nushift = nushift;
} else { // NFAPI_NR_DMRS_TYPE2
nushift = delta;
if (p < 6)
ue->frame_parms.nushift = nushift;
}
delay_t delay = {0};
for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
#ifdef DEBUG_PDSCH
@@ -1734,7 +1678,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch,
bwp_start_subcarrier,
nb_rb_pdsch,
delta);
delta,
&delay);
} else if (config_type == NFAPI_NR_DMRS_TYPE2 && ue->chest_freq == 0) {
NFAPI_NR_DMRS_TYPE2_linear_interp(&ue->frame_parms,
@@ -1744,7 +1689,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
bwp_start_subcarrier,
nb_rb_pdsch,
delta,
p);
p,
&delay);
} else if (config_type == NFAPI_NR_DMRS_TYPE1) {
NFAPI_NR_DMRS_TYPE1_average_prb(&ue->frame_parms,
@@ -100,17 +100,23 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue,
LOG_D(PHY, "DLSCH %d in error\n", rdata->dlsch_id);
}
uint32_t tbs;
if (dlsch->dlsch_config.targetCodeRate > 0)
tbs = dlsch->dlsch_config.TBS;
else
tbs = harq_process->tb_size;
// if all segments are done
if (last) {
kpiStructure.nb_total++;
kpiStructure.blockSize = dlsch->dlsch_config.TBS;
kpiStructure.blockSize = tbs;
kpiStructure.dl_mcs = dlsch->dlsch_config.mcs;
kpiStructure.nofRBs = dlsch->dlsch_config.number_rbs;
if (*num_seg_ok == harq_process->C) {
if (harq_process->C > 1) {
/* check global CRC */
int A = dlsch->dlsch_config.TBS;
int A = tbs;
int crc_length = A > 3824 ? 3 : 2;
int crc_type = A > 3824 ? CRC24_A : CRC16;
if (!check_crc(b, A + crc_length * 8, crc_type)) {
@@ -149,9 +155,8 @@ static bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue,
}
return true; //stop
}
else
{
return false; //not last one
else {
return false; //not last one
}
}
@@ -292,7 +297,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t harq_pid,
int b_size,
uint8_t b[b_size]) {
uint32_t A,E;
uint32_t E;
uint32_t G;
uint32_t ret,offset;
uint32_t r,r_offset=0,Kr=8424,Kr_bytes;
@@ -355,7 +360,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
}
*/
nb_rb = dlsch->dlsch_config.number_rbs;
A = dlsch->dlsch_config.TBS;
uint32_t A;
if (dlsch->dlsch_config.targetCodeRate > 0) {
A = dlsch->dlsch_config.TBS;
harq_process->tb_size = A;
}
else
A = harq_process->tb_size;
ret = dlsch->max_ldpc_iterations + 1;
dlsch->last_iteration_cnt = ret;
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, dlsch->dlsch_config.qamModOrder,dlsch->Nl);
@@ -406,8 +406,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//--------------------- RBs extraction ---------------------
//----------------------------------------------------------
const int n_rx = frame_parms->nb_antennas_rx;
time_stats_t meas = {0};
const bool meas_enabled = cpumeas(CPUMEAS_GETSTATE);
start_meas(&ue->generic_stat_bis[slot]);
if (meas_enabled)
start_meas(&meas);
{
__attribute__((aligned(32))) c16_t rxdataF_ext[nbRx][rx_size_symbol];
memset(rxdataF_ext, 0, sizeof(rxdataF_ext));
@@ -429,14 +432,21 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
frame_parms,
dlsch[0].dlsch_config.dlDmrsSymbPos,
ue->chest_time);
stop_meas(&ue->generic_stat_bis[slot]);
if (meas_enabled) {
stop_meas(&meas);
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d: Pilot/Data extraction %5.2f \n",
frame,
nr_slot_rx,
slot,
symbol,
meas.p_time / (cpuf * 1000.0));
}
if (ue->phy_sim_pdsch_rxdataF_ext)
for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
int offset = ((void *)rxdataF_ext[aarx] - (void *)rxdataF_ext) + symbol * rx_size_symbol;
memcpy(ue->phy_sim_pdsch_rxdataF_ext + offset, rxdataF_ext, rx_size_symbol * sizeof(c16_t));
}
if (cpumeas(CPUMEAS_GETSTATE))
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Pilot/Data extraction %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
nb_re_pdsch = (pilots == 1)
? ((config_type == NFAPI_NR_DMRS_TYPE1) ? nb_rb_pdsch * (12 - 6 * dlsch[0].dlsch_config.n_dmrs_cdm_groups) : nb_rb_pdsch * (12 - 4 * dlsch[0].dlsch_config.n_dmrs_cdm_groups))
@@ -444,18 +454,26 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
//----------------------------------------------------------
//--------------------- Channel Scaling --------------------
//----------------------------------------------------------
start_meas(&ue->generic_stat_bis[slot]);
if (meas_enabled)
start_meas(&meas);
nr_dlsch_scale_channel(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, n_rx, symbol, pilots, nb_re_pdsch, nb_rb_pdsch);
stop_meas(&ue->generic_stat_bis[slot]);
if (meas_enabled) {
stop_meas(&meas);
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",
frame,
nr_slot_rx,
slot,
symbol,
meas.p_time / (cpuf * 1000.0));
}
if (cpumeas(CPUMEAS_GETSTATE))
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
//----------------------------------------------------------
//--------------------- Channel Level Calc. ----------------
//----------------------------------------------------------
start_meas(&ue->generic_stat_bis[slot]);
if (first_symbol_flag==1) {
//----------------------------------------------------------
//--------------------- Channel Level Calc. ----------------
//----------------------------------------------------------
if (meas_enabled)
start_meas(&meas);
if (first_symbol_flag == 1) {
nr_dlsch_channel_level(rx_size_symbol, dl_ch_estimates_ext, frame_parms, nl, avg, symbol, nb_re_pdsch, nb_rb_pdsch);
avgs = 0;
for (aatx=0;aatx<nl;aatx++)
@@ -476,45 +494,56 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
*log2_maxh = (log2_approx(avgs)/2) + 1;
//LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, log2_maxh);
LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d,%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avg[0], avgs);
}
stop_meas(&ue->generic_stat_bis[slot]);
}
if (meas_enabled) {
stop_meas(&meas);
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",
frame,
nr_slot_rx,
slot,
symbol,
first_symbol_flag,
meas.p_time / (cpuf * 1000.0));
}
#if T_TRACER
T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx),
T_INT(avg[0]), T_INT(avg[1]), T_INT(avg[2]), T_INT(avg[3]));
T(T_UE_PHY_PDSCH_ENERGY,
T_INT(gNB_id),
T_INT(0),
T_INT(frame % 1024),
T_INT(nr_slot_rx),
T_INT(avg[0]),
T_INT(avg[1]),
T_INT(avg[2]),
T_INT(avg[3]));
#endif
if (cpumeas(CPUMEAS_GETSTATE))
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",
frame, nr_slot_rx, slot, symbol, first_symbol_flag, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
//----------------------------------------------------------
//--------------------- channel compensation ---------------
//----------------------------------------------------------
// Disable correlation measurement for optimizing UE
start_meas(&ue->generic_stat_bis[slot]);
nr_dlsch_channel_compensation(rx_size_symbol,
nbRx,
rxdataF_ext,
dl_ch_estimates_ext,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
rxdataF_comp,
NULL,
frame_parms,
nl,
symbol,
nb_re_pdsch,
first_symbol_flag,
dlsch[0].dlsch_config.qamModOrder,
nb_rb_pdsch,
*log2_maxh,
measurements); // log2_maxh+I0_shift
stop_meas(&ue->generic_stat_bis[slot]);
}
if (cpumeas(CPUMEAS_GETSTATE))
//----------------------------------------------------------
//--------------------- channel compensation ---------------
//----------------------------------------------------------
// Disable correlation measurement for optimizing UE
if (meas_enabled)
start_meas(&meas);
nr_dlsch_channel_compensation(rx_size_symbol,
nbRx,
rxdataF_ext,
dl_ch_estimates_ext,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
rxdataF_comp,
NULL,
frame_parms,
nl,
symbol,
nb_re_pdsch,
first_symbol_flag,
dlsch[0].dlsch_config.qamModOrder,
nb_rb_pdsch,
*log2_maxh,
measurements); // log2_maxh+I0_shift
if (meas_enabled) {
stop_meas(&meas);
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",
frame,
@@ -522,22 +551,54 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
slot,
symbol,
*log2_maxh,
ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
meas.p_time / (cpuf * 1000.0));
}
}
start_meas(&ue->generic_stat_bis[slot]);
if (meas_enabled)
start_meas(&meas);
if (n_rx > 1) {
nr_dlsch_detection_mrc(rx_size_symbol, nl, n_rx, rxdataF_comp, NULL, dl_ch_mag, dl_ch_magb, dl_ch_magr, symbol, nb_rb_pdsch, nb_re_pdsch);
if (nl >= 2)//Apply zero forcing for 2, 3, and 4 Tx layers
nr_zero_forcing_rx(
rx_size_symbol, n_rx, nl, rxdataF_comp, dl_ch_mag, dl_ch_magb, dl_ch_magr, dl_ch_estimates_ext, nb_rb_pdsch, dlsch[0].dlsch_config.qamModOrder, *log2_maxh, symbol, nb_re_pdsch);
nr_dlsch_detection_mrc(rx_size_symbol,
nl,
n_rx,
rxdataF_comp,
NULL,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
symbol,
nb_rb_pdsch,
nb_re_pdsch);
if (nl >= 2) // Apply zero forcing for 2, 3, and 4 Tx layers
nr_zero_forcing_rx(rx_size_symbol,
n_rx,
nl,
rxdataF_comp,
dl_ch_mag,
dl_ch_magb,
dl_ch_magr,
dl_ch_estimates_ext,
nb_rb_pdsch,
dlsch[0].dlsch_config.qamModOrder,
*log2_maxh,
symbol,
nb_re_pdsch);
}
stop_meas(&ue->generic_stat_bis[slot]);
if (cpumeas(CPUMEAS_GETSTATE))
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
if (meas_enabled) {
stop_meas(&meas);
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",
frame,
nr_slot_rx,
slot,
symbol,
meas.p_time / (cpuf * 1000.0));
}
start_meas(&ue->generic_stat_bis[slot]);
if (meas_enabled)
start_meas(&meas);
/* Store the valid DL RE's */
dl_valid_re[symbol-1] = nb_re_pdsch;
@@ -652,9 +713,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#endif
}
stop_meas(&ue->generic_stat_bis[slot]);
if (cpumeas(CPUMEAS_GETSTATE))
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
if (meas_enabled) {
stop_meas(&meas);
LOG_D(PHY,
"[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",
frame,
nr_slot_rx,
slot,
symbol,
meas.p_time / (cpuf * 1000.0));
}
#if T_TRACER
T(T_UE_PHY_PDSCH_IQ,
+12 -12
View File
@@ -57,10 +57,11 @@ static uint16_t nr_pbch_extract(uint32_t rxdataF_sz,
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
uint32_t symbol,
uint32_t s_offset,
NR_DL_FRAME_PARMS *frame_parms) {
NR_DL_FRAME_PARMS *frame_parms,
int nushiftmod4)
{
uint16_t rb;
uint8_t i,j,aarx;
int nushiftmod4 = frame_parms->nushift;
uint8_t i, j, aarx;
AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n",
symbol);
@@ -395,12 +396,12 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
{
int max_h=0;
int symbol;
//uint8_t pbch_a[64];
//FT ?? cppcheck doesn't like pbch_a allocation because of line 525..and i don't get what this variable is for..
//uint8_t *pbch_a = malloc(sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
uint8_t nushift;
uint16_t M;
// uint8_t pbch_a[64];
// FT ?? cppcheck doesn't like pbch_a allocation because of line 525..and i don't get what this variable is for..
// uint8_t *pbch_a = malloc(sizeof(uint8_t) * NR_POLAR_PBCH_PAYLOAD_BITS);
uint8_t Lmax=frame_parms->Lmax;
int M = NR_POLAR_PBCH_E;
int nushift = (Lmax == 4) ? i_ssb & 3 : i_ssb & 7;
//uint16_t crc;
//unsigned short idx_demod =0;
uint32_t decoderState=0;
@@ -440,7 +441,8 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
dl_ch_estimates_ext,
symbol,
symbol_offset,
frame_parms);
frame_parms,
nushift);
#ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size );
LOG_I(PHY,"[PHY] PBCH starting channel_level\n");
@@ -496,9 +498,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
printf("pbch rx llr %d\n",*(pbch_e_rx+cnt));
#endif
//un-scrambling
M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? i_ssb&3 : i_ssb&7;
// un-scrambling
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
uint32_t pbch_a_interleaved=0;
uint32_t pbch_a_prime=0;
@@ -213,6 +213,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
uint32_t tb_size,
unsigned int G);
/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@@ -93,6 +93,8 @@ typedef struct {
uint8_t BG;
// LDPC lifting size
uint32_t Z;
// TB size
uint32_t tb_size;
} NR_UL_UE_HARQ_t;
typedef struct {
@@ -115,8 +117,6 @@ typedef struct {
uint8_t Ndi;
/// DLSCH status flag indicating
SCH_status_t status;
/// Transport block size
uint32_t TBS;
/// The payload + CRC size in bits
uint32_t B;
/// Pointers to transport block segments
@@ -144,6 +144,8 @@ typedef struct {
/// Used for computing LDPC decoder R
int llrLen;
decode_abort_t abort_decode;
// TB size
uint32_t tb_size;
} NR_DL_UE_HARQ_t;
typedef struct {
@@ -45,8 +45,9 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid,
unsigned int G) {
uint32_t tb_size,
unsigned int G)
{
start_meas(&ue->ulsch_encoding_stats);
/////////////////////////parameters and variables initialization/////////////////////////
@@ -55,7 +56,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
unsigned int crc = 1;
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
uint16_t nb_rb = ulsch->pusch_pdu.rb_size;
uint32_t A = ulsch->pusch_pdu.pusch_data.tb_size<<3;
uint32_t A = tb_size << 3;
uint32_t *pz = &harq_process->Z;
uint8_t mod_order = ulsch->pusch_pdu.qam_mod_order;
uint16_t Kr=0;
+12 -2
View File
@@ -131,6 +131,16 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
NR_UL_UE_HARQ_t *harq_process_ul_ue = &UE->ul_harq_processes[harq_pid];
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu;
uint32_t tb_size;
// MCS > limit -> retransmission
// Take TB size from previois transmission
if (pusch_pdu->target_code_rate == 0)
tb_size = harq_process_ul_ue->tb_size;
else {
tb_size = pusch_pdu->pusch_data.tb_size;
harq_process_ul_ue->tb_size = tb_size;
}
int start_symbol = pusch_pdu->start_symbol_index;
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
@@ -170,10 +180,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
trace_NRpdu(DIRECTION_UPLINK,
harq_process_ul_ue->a,
pusch_pdu->pusch_data.tb_size,
tb_size,
WS_C_RNTI, rnti, frame, slot, 0, 0);
if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G) == -1)
if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, tb_size, G) == -1)
return;
+1 -10
View File
@@ -255,15 +255,6 @@ typedef struct {
int subband_cqi_tot_dB[275];
} ulsch_measurements_gNB;
typedef struct {
/// Time shift in number of samples estimated based on DMRS-PUSCH
int pusch_est_delay;
/// Max position in OFDM symbol related to time shift estimation based on DMRS-PUSCH
int pusch_delay_max_pos;
/// Max value related to time shift estimation based on DMRS-PUSCH
int pusch_delay_max_val;
} NR_ULSCH_delay_t;
typedef struct {
uint32_t frame;
uint32_t slot;
@@ -281,7 +272,7 @@ typedef struct {
bool active;
/// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around
uint8_t handled;
NR_ULSCH_delay_t delay;
delay_t delay;
ulsch_measurements_gNB ulsch_measurements;
} NR_gNB_ULSCH_t;
-2
View File
@@ -592,8 +592,6 @@ typedef struct {
time_stats_t ulsch_interleaving_stats;
time_stats_t ulsch_multiplexing_stats;
time_stats_t generic_stat;
time_stats_t generic_stat_bis[LTE_SLOTS_PER_SUBFRAME];
time_stats_t ue_front_end_stat;
time_stats_t ue_front_end_per_slot_stat[LTE_SLOTS_PER_SUBFRAME];
time_stats_t pdcch_procedures_stat;
+3 -5
View File
@@ -95,7 +95,7 @@
#define NR_NB_NSCID 2
#define MAX_UL_DELAY_COMP 20
#define MAX_DELAY_COMP 20
typedef enum {
NR_MU_0=0,
@@ -227,10 +227,8 @@ struct NR_DL_FRAME_PARMS {
/// sequence used to compensate the phase rotation due to timeshifted OFDM symbols
/// First dimenstion is for different CP lengths
c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16)));
/// Table used to apply the delay compensation in UL
c16_t ul_delay_table[2 * MAX_UL_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE * 2];
/// shift of pilot position in one RB
uint8_t nushift;
/// Table used to apply the delay compensation in DL/UL
c16_t delay_table[2 * MAX_DELAY_COMP + 1][NR_MAX_OFDM_SYMBOL_SIZE];
/// SRS configuration from TS 38.331 RRC
SRS_NR srs_nr;
/// Power used by SSB in order to estimate signal strength and path loss
+1 -1
View File
@@ -422,7 +422,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id,
nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
// Get estimated timing advance for MAC
int sync_pos = ulsch->delay.pusch_est_delay;
int sync_pos = ulsch->delay.est_delay;
// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
uint16_t bw_scaling = 16 * gNB->frame_parms.ofdm_symbol_size / 2048;
+6 -16
View File
@@ -82,16 +82,8 @@ static void free_uci_inds(nfapi_nr_uci_indication_t *uci_ind)
{
if (uci_ind->uci_list[k].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE)
{
nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1;
free(pdu_0_1->sr);
pdu_0_1->sr = NULL;
if (pdu_0_1->harq)
{
free(pdu_0_1->harq->harq_list);
pdu_0_1->harq->harq_list = NULL;
}
free(pdu_0_1->harq);
pdu_0_1->harq = NULL;
//nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1;
// Warning: pdu_0_1 is unused
}
if (uci_ind->uci_list[k].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE)
{
@@ -259,10 +251,8 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
if (mac->nr_ue_emul_l1.num_harqs > 0) {
int harq_index = 0;
pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR
pdu_0_1->harq = CALLOC(1, sizeof(*pdu_0_1->harq));
pdu_0_1->harq->num_harq = mac->nr_ue_emul_l1.num_harqs;
pdu_0_1->harq->harq_confidence_level = 0;
pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list));
pdu_0_1->harq.num_harq = mac->nr_ue_emul_l1.num_harqs;
pdu_0_1->harq.harq_confidence_level = 0;
int harq_pid = -1;
for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
if (mac->nr_ue_emul_l1.harq[k].active &&
@@ -270,8 +260,8 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot) {
mac->nr_ue_emul_l1.harq[k].active = false;
harq_pid = k;
AssertFatal(harq_index < pdu_0_1->harq->num_harq, "Invalid harq_index %d\n", harq_index);
pdu_0_1->harq->harq_list[harq_index].harq_value = !mac->dl_harq_info[k].ack;
AssertFatal(harq_index < pdu_0_1->harq.num_harq, "Invalid harq_index %d\n", harq_index);
pdu_0_1->harq.harq_list[harq_index].harq_value = !mac->dl_harq_info[k].ack;
harq_index++;
}
}
+9 -8
View File
@@ -132,7 +132,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
dl_harq0 = &ue->dl_harq_processes[0][dlsch0->dlsch_config.harq_process_nbr];
trace_NRpdu(DIRECTION_DOWNLINK,
b,
dlsch0->dlsch_config.TBS / 8,
dl_harq0->tb_size / 8,
t,
dlsch0->rnti,
proc->frame_rx,
@@ -148,7 +148,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.harq_pid = dlsch0->dlsch_config.harq_process_nbr;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.ack_nack = dl_harq0->ack;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = b;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->dlsch_config.TBS / 8;
rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dl_harq0->tb_size / 8;
}
if(dlsch1) {
AssertFatal(1==0,"Second codeword currently not supported\n");
@@ -764,7 +764,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL);
nr_fill_rx_indication(&rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL, p_b);
LOG_D(PHY, "DL PDU length in bits: %d, in bytes: %d \n", dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8);
LOG_D(PHY, "DL PDU length in bits: %d, in bytes: %d \n", dl_harq0->tb_size, dl_harq0->tb_size / 8);
stop_meas(&ue->dlsch_decoding_stats);
if (cpumeas(CPUMEAS_GETSTATE)) {
@@ -814,7 +814,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0));
}
LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch[1].dlsch_config.TBS);
LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dl_harq1->tb_size);
}
// send to mac
@@ -1019,7 +1019,8 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
int gNB_id = proc->gNB_id;
NR_UE_DLSCH_t *dlsch = &phy_data->dlsch[0];
start_meas(&ue->generic_stat);
time_stats_t meas = {0};
start_meas(&meas);
// do procedures for C-RNTI
int ret_pdsch = 0;
@@ -1131,7 +1132,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
ue->csirs_vars[gNB_id]->active = 0;
}
start_meas(&ue->generic_stat);
start_meas(&meas);
if (nr_slot_rx==9) {
if (frame_rx % 10 == 0) {
@@ -1157,9 +1158,9 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
}
stop_meas(&ue->generic_stat);
stop_meas(&meas);
if (cpumeas(CPUMEAS_GETSTATE))
LOG_D(PHY, "after ldpc decode until end of Rx %5.2f \n", ue->generic_stat.p_time / (cpuf * 1000.0));
LOG_D(PHY, "after ldpc decode until end of Rx %5.2f \n", meas.p_time / (cpuf * 1000.0));
#ifdef EMOS
phy_procedures_emos_UE_RX(ue,slot,gNB_id);
+37 -70
View File
@@ -314,6 +314,7 @@ int main(int argc, char **argv)
//uint8_t frame_mod4,num_pdcch_symbols = 0;
SCM_t channel_model = AWGN; // AWGN Rayleigh1 Rayleigh1_anticorr;
int delay = 0;
//double pbch_sinr;
//int pbch_tx_ant;
@@ -361,7 +362,7 @@ int main(int argc, char **argv)
FILE *scg_fd=NULL;
while ((c = getopt(argc, argv, "f:hA:p:f:g:i:n:s:S:t:v:x:y:z:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y")) != -1) {
while ((c = getopt(argc, argv, "f:hA:p:f:g:i:n:s:S:t:v:x:y:z:o:M:N:F:GR:d:PI:L:a:b:e:m:w:T:U:q:X:Y")) != -1) {
switch (c) {
case 'f':
scg_fd = fopen(optarg,"r");
@@ -561,6 +562,10 @@ int main(int argc, char **argv)
slot = 0;
break;
case 'o':
delay = atoi(optarg);
break;
default:
case 'h':
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n",
@@ -574,6 +579,7 @@ int main(int argc, char **argv)
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
//printf("-t Delay spread for multipath channel\n");
printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n");
printf("-o Introduce delay in terms of number of samples\n");
printf("-y Number of TX antennas used in gNB\n");
printf("-z Number of RX antennas used in UE\n");
printf("-x Num of layer for PDSCH\n");
@@ -777,7 +783,7 @@ int main(int argc, char **argv)
0.0,
CORR_LEVEL_LOW,
0,
0,
delay,
0,
0);
@@ -788,6 +794,8 @@ int main(int argc, char **argv)
frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
//frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP*NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0);
s_re = malloc(n_tx*sizeof(double*));
s_im = malloc(n_tx*sizeof(double*));
@@ -795,22 +803,17 @@ int main(int argc, char **argv)
r_im = malloc(n_rx*sizeof(double*));
txdata = malloc(n_tx*sizeof(int*));
for (i=0; i<n_tx; i++) {
s_re[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(s_re[i],frame_length_complex_samples*sizeof(double));
s_im[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(s_im[i],frame_length_complex_samples*sizeof(double));
for (i = 0; i < n_tx; i++) {
s_re[i] = calloc(1, slot_length * sizeof(double));
s_im[i] = calloc(1, slot_length * sizeof(double));
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
bzero(txdata[i],frame_length_complex_samples*sizeof(int));
printf("Allocating %d samples for txdata\n", frame_length_complex_samples);
txdata[i] = calloc(1, frame_length_complex_samples * sizeof(int));
}
for (i=0; i<n_rx; i++) {
r_re[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(r_re[i],frame_length_complex_samples*sizeof(double));
r_im[i] = malloc(frame_length_complex_samples*sizeof(double));
bzero(r_im[i],frame_length_complex_samples*sizeof(double));
for (i = 0; i < n_rx; i++) {
r_re[i] = calloc(1, slot_length * sizeof(double));
r_im[i] = calloc(1, slot_length * sizeof(double));
}
if (pbch_file_fd!=NULL) {
@@ -1050,22 +1053,21 @@ int main(int argc, char **argv)
if (gNB->frame_parms.nb_antennas_tx>1)
LOG_M("txsigF1.m","txsF1=", &gNB->common_vars.txdataF[1][txdataF_offset+2*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1);
}
int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
if (n_trials == 1) printf("slot_offset %d, txdataF_offset %d \n", slot_offset, txdataF_offset);
//TODO: loop over slots
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
if (cyclic_prefix_type == 1) {
PHY_ofdm_mod((int *)&gNB->common_vars.txdataF[aa][txdataF_offset],
(int *)&txdata[aa][tx_offset],
(int *)&txdata[aa][slot_offset],
frame_parms->ofdm_symbol_size,
12,
frame_parms->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset],
&txdata[aa][tx_offset],
&txdata[aa][slot_offset],
14,
frame_parms,
slot);
@@ -1076,7 +1078,7 @@ int main(int argc, char **argv)
char filename[100];//LOG_M
for (aa=0;aa<n_tx;aa++) {
sprintf(filename,"txsig%d.m", aa);//LOG_M
LOG_M(filename,"txs", &txdata[aa][tx_offset+frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0],6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples),1,1);
LOG_M(filename,"txs", &txdata[aa][slot_offset +frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0],6*(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples),1,1);
}
}
if (output_fd) {
@@ -1088,19 +1090,16 @@ int main(int argc, char **argv)
int txlev_sum = 0;
int l_ofdm = 6;
for (aa=0; aa<n_tx; aa++) {
txlev[aa] = signal_energy((int32_t *)&txdata[aa][tx_offset+l_ofdm*frame_parms->ofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
txlev[aa] = signal_energy((int32_t *)&txdata[aa][slot_offset +l_ofdm*frame_parms->ofdm_symbol_size + (l_ofdm-1)*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0],
frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples);
txlev_sum += txlev[aa];
if (n_trials==1) printf("txlev[%d] = %d (%f dB) txlev_sum %d\n",aa,txlev[aa],10*log10((double)txlev[aa]),txlev_sum);
}
for (i=(frame_parms->get_samples_slot_timestamp(slot,frame_parms,0));
i<(frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0));
i++) {
for (i = 0; i < slot_length; i++) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
s_re[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)]);
s_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]);
s_re[aa][i] = ((double)(((short *)&txdata[aa][slot_offset]))[(i << 1)]);
s_im[aa][i] = ((double)(((short *)&txdata[aa][slot_offset]))[(i << 1) + 1]);
}
}
@@ -1110,50 +1109,18 @@ int main(int argc, char **argv)
sigma2 = pow(10, sigma2_dB/10);
if (n_trials==1) printf("sigma2 %f (%f dB), txlev_sum %f (factor %f)\n",sigma2,sigma2_dB,10*log10((double)txlev_sum),(double)(double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize));
for (aa=0; aa<n_rx; aa++) {
bzero(r_re[aa],frame_length_complex_samples*sizeof(double));
bzero(r_im[aa],frame_length_complex_samples*sizeof(double));
for (aa = 0; aa < n_rx; aa++) {
bzero(r_re[aa], slot_length * sizeof(double));
bzero(r_im[aa], slot_length * sizeof(double));
}
// Apply MIMO Channel
if (channel_model != AWGN) multipath_tv_channel(gNB2UE,
s_re,
s_im,
r_re,
r_im,
frame_length_complex_samples,
0);
double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0
{0.2, 1.0, 0.2, 0.1}, //rx 1
{0.1, 0.2, 1.0, 0.2}, //rx 2
{0.05, 0.1, 0.2, 1.0}};//rx 3
for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0);
i++) {
for (int aa_rx=0; aa_rx<n_rx; aa_rx++) {
if (channel_model == AWGN) {
// sum up signals from different Tx antennas
r_re[aa_rx][i] = 0;
r_im[aa_rx][i] = 0;
for (aa=0; aa<n_tx; aa++) {
r_re[aa_rx][i] += s_re[aa][i]*H_awgn_mimo[aa_rx][aa];
r_im[aa_rx][i] += s_im[aa][i]*H_awgn_mimo[aa_rx][aa];
}
}
// Add Gaussian noise
((short*) UE->common_vars.rxdata[aa_rx])[2*i] = (short) ((r_re[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
((short*) UE->common_vars.rxdata[aa_rx])[2*i+1] = (short) ((r_im[aa_rx][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)));
/* Add phase noise if enabled */
if (pdu_bit_map & 0x1) {
phase_noise(ts, &((short*) UE->common_vars.rxdata[aa_rx])[2*i],
&((short*) UE->common_vars.rxdata[aa_rx])[2*i+1]);
}
}
if (channel_model == AWGN) {
multipath_channel(gNB2UE, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0);
} else {
multipath_tv_channel(gNB2UE, s_re, s_im, r_re, r_im, slot_length, 0);
}
add_noise(UE->common_vars.rxdata, (const double **) r_re, (const double **) r_im, sigma2, slot_length, slot_offset, ts, delay, pdu_bit_map, 0x1, frame_parms->nb_antennas_rx);
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
nr_ue_scheduled_response(&scheduled_response);
-1
View File
@@ -495,7 +495,6 @@ int main(int argc, char **argv)
frame_parms->nb_antenna_ports_gNB = n_tx;
frame_parms->N_RB_DL = N_RB_DL;
frame_parms->Nid_cell = Nid_cell;
frame_parms->nushift = Nid_cell%4;
frame_parms->ssb_type = nr_ssb_type_C;
frame_parms->freq_range = mu<2 ? nr_FR1 : nr_FR2;
+3 -6
View File
@@ -663,14 +663,13 @@ int main(int argc, char **argv)
nr_decode_pucch0(gNB, nr_frame_tx, nr_slot_tx,&uci_pdu,&pucch_pdu);
if(sr_flag==1){
if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1)
if (uci_pdu.sr.sr_indication == 0 || uci_pdu.sr.sr_confidence_level == 1)
sr_errors+=1;
free(uci_pdu.sr);
}
// harq value 0 -> pass
nfapi_nr_harq_t *harq_list = uci_pdu.harq->harq_list;
nfapi_nr_harq_t *harq_list = uci_pdu.harq.harq_list;
// confidence value 0 -> good confidence
const int confidence_lvl = uci_pdu.harq->harq_confidence_level;
const int confidence_lvl = uci_pdu.harq.harq_confidence_level;
if(nr_bit>0){
if (nr_bit==1 && do_DTX == 0)
ack_nack_errors+=(actual_payload^(!harq_list[0].harq_value));
@@ -679,9 +678,7 @@ int main(int argc, char **argv)
else if ((!confidence_lvl && !harq_list[0].harq_value) ||
(!confidence_lvl && nr_bit == 2 && !harq_list[1].harq_value))
ack_nack_errors++;
free(uci_pdu.harq->harq_list);
}
free(uci_pdu.harq);
}
else if (format==1) {
nr_decode_pucch1((c16_t **)rxdataF,PUCCH_GroupHopping,hopping_id,
+1 -1
View File
@@ -522,7 +522,7 @@ int main(int argc, char **argv)
unsigned int G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, Nl);
if (input_fd == NULL) {
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G);
nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, TBS>>3, G);
}
printf("\n");
+4 -5
View File
@@ -1227,7 +1227,7 @@ int main(int argc, char **argv)
}
multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0);
add_noise(rxdata, (const double **) r_re, (const double **) r_im, sigma, slot_length, slot_offset, ts, delay, pdu_bit_map, frame_parms->nb_antennas_rx);
add_noise(rxdata, (const double **) r_re, (const double **) r_im, sigma, slot_length, slot_offset, ts, delay, pdu_bit_map, PUSCH_PDU_BITMAP_PUSCH_PTRS, frame_parms->nb_antennas_rx);
} /*End input_fd */
@@ -1299,7 +1299,6 @@ int main(int argc, char **argv)
frame_parms->ofdm_symbol_size,
1,
1);
LOG_M("chestT0.m", "chT0", &pusch_vars->ul_ch_estimates_time[0][0], frame_parms->ofdm_symbol_size, 1, 1);
LOG_M("chestF0_ext.m",
"chF0_ext",
&pusch_vars->ul_ch_estimates_ext[0][(start_symbol + 1) * (off + (NR_NB_SC_PER_RB * pusch_pdu->rb_size))],
@@ -1540,9 +1539,9 @@ int main(int argc, char **argv)
if (!crc_status)
effRate += ((double)TBS) / (double)round;
sum_pusch_delay += ulsch_gNB->delay.pusch_est_delay;
min_pusch_delay = ulsch_gNB->delay.pusch_est_delay < min_pusch_delay ? ulsch_gNB->delay.pusch_est_delay : min_pusch_delay;
max_pusch_delay = ulsch_gNB->delay.pusch_est_delay > max_pusch_delay ? ulsch_gNB->delay.pusch_est_delay : max_pusch_delay;
sum_pusch_delay += ulsch_gNB->delay.est_delay;
min_pusch_delay = min(ulsch_gNB->delay.est_delay, min_pusch_delay);
max_pusch_delay = max(ulsch_gNB->delay.est_delay, max_pusch_delay);
delay_pusch_est_count++;
} // trial loop
@@ -233,8 +233,7 @@ int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission
frame_parms->N_RB_DL = N_RB_DL; //50 for 10MHz and 25 for 5 MHz
frame_parms->N_RB_UL = N_RB_DL;
frame_parms->Ncp = extended_prefix_flag;
frame_parms->Nid_cell = Nid_cell;
frame_parms->nushift = Nid_cell%6;
frame_parms->Nid_cell = Nid_cell;
frame_parms->nb_antennas_tx = N_tx;
frame_parms->nb_antennas_rx = N_rx;
frame_parms->frame_type = frame_type;
@@ -156,6 +156,7 @@ void add_noise(c16_t **rxdata,
const double ts,
const int delay,
const uint16_t pdu_bit_map,
const uint16_t ptrs_bit_map,
const uint8_t nb_antennas_rx)
{
for (int i = 0; i < length; i++) {
@@ -164,7 +165,7 @@ void add_noise(c16_t **rxdata,
rxd->r = r_re[ap][i] + sqrt(sigma / 2) * gaussZiggurat(0.0, 1.0); // convert to fixed point
rxd->i = r_im[ap][i] + sqrt(sigma / 2) * gaussZiggurat(0.0, 1.0);
/* Add phase noise if enabled */
if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
if (pdu_bit_map & ptrs_bit_map) {
phase_noise(ts, &rxdata[ap][slot_offset + i + delay].r, &rxdata[ap][slot_offset + i + delay].i);
}
}
+1
View File
@@ -389,6 +389,7 @@ void add_noise(c16_t **rxdata,
const double ts,
const int delay,
const uint16_t pdu_bit_map,
const uint16_t ptrs_bit_map,
const uint8_t nb_antennas_rx);
/**\fn void multipath_channel(channel_desc_t *desc,
+48 -46
View File
@@ -2401,55 +2401,58 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
// the following tables contain 10 times the value reported in 214 (in line with SCF specification and to avoid fractional values)
//Table 5.1.3.1-1 of 38.214
static const uint16_t Table_51311[29][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
static const uint16_t Table_51311[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
{2, 6020}, {2, 6790}, {4, 3400}, {4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160},
{4, 6580}, {6, 4380}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7190},
{6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480}};
{6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480}, {2, 0}, {4, 0}, {6, 0}};
//Table 5.1.3.1-2 of 38.214
// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point
static const uint16_t Table_51312[28][2] = {{2, 1200}, {2, 1930}, {2, 3080}, {2, 4490}, {2, 6020}, {4, 3780}, {4, 4340},
static const uint16_t Table_51312[32][2] = {{2, 1200}, {2, 1930}, {2, 3080}, {2, 4490}, {2, 6020}, {4, 3780}, {4, 4340},
{4, 4900}, {4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670},
{6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {8, 6825},
{8, 7110}, {8, 7540}, {8, 7970}, {8, 8410}, {8, 8850}, {8, 9165}, {8, 9480}};
{8, 7110}, {8, 7540}, {8, 7970}, {8, 8410}, {8, 8850}, {8, 9165}, {8, 9480},
{2, 0}, {4, 0}, {6, 0}, {8, 0}};
//Table 5.1.3.1-3 of 38.214
static const uint16_t Table_51313[29][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200}, {2, 1570},
static const uint16_t Table_51313[32][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200}, {2, 1570},
{2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260}, {2, 6020}, {4, 3400},
{4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160}, {6, 4380}, {6, 4660}, {6, 5170},
{6, 5670}, {6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}};
{6, 5670}, {6, 6160}, {6, 6660}, {6, 7190}, {6, 7720}, {2, 0}, {4, 0}, {6, 0}};
static const uint16_t Table_61411[28][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490},
static const uint16_t Table_61411[32][2] = {{2, 1200}, {2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490},
{2, 5260}, {2, 6020}, {2, 6790}, {4, 3400}, {4, 3780}, {4, 4340}, {4, 4900},
{4, 5530}, {4, 6160}, {4, 6580}, {6, 4660}, {6, 5170}, {6, 5670}, {6, 6160},
{6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480}};
{6, 6660}, {6, 7190}, {6, 7720}, {6, 8220}, {6, 8730}, {6, 9100}, {6, 9480},
{2, 0}, {2, 0}, {4, 0}, {6, 0}};
static const uint16_t Table_61412[28][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200},
static const uint16_t Table_61412[32][2] = {{2, 300}, {2, 400}, {2, 500}, {2, 640}, {2, 780}, {2, 990}, {2, 1200},
{2, 1570}, {2, 1930}, {2, 2510}, {2, 3080}, {2, 3790}, {2, 4490}, {2, 5260},
{2, 6020}, {2, 6790}, {4, 3780}, {4, 4340}, {4, 4900}, {4, 5530}, {4, 6160},
{4, 6580}, {4, 6990}, {4, 7720}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7720}};
{4, 6580}, {4, 6990}, {4, 7720}, {6, 5670}, {6, 6160}, {6, 6660}, {6, 7720},
{2, 0}, {2, 0}, {4, 0}, {6, 0}};
uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51311[Imcs][0]);
break;
case 1:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51312[Imcs][0]);
break;
case 2:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51313[Imcs][0]);
@@ -2464,24 +2467,24 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) {
uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51311[Imcs][1]);
break;
case 1:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51312[Imcs][1]);
break;
case 2:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51313[Imcs][1]);
@@ -2496,40 +2499,40 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) {
uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51311[Imcs][0]);
break;
case 1:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51312[Imcs][0]);
break;
case 2:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51313[Imcs][0]);
break;
case 3:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_61411[Imcs][0]);
break;
case 4:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_61412[Imcs][0]);
@@ -2544,40 +2547,40 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) {
uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) {
switch(table_idx) {
case 0:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51311[Imcs][1]);
break;
case 1:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51312[Imcs][1]);
break;
case 2:
if (Imcs > 28) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_51313[Imcs][1]);
break;
case 3:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_61411[Imcs][1]);
break;
case 4:
if (Imcs > 27) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs);
if (Imcs > 31) {
LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,31])\n", Imcs);
return 0;
}
return (Table_61412[Imcs][1]);
@@ -4554,13 +4557,12 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0,
ss0->monitoringSymbolsWithinSlot->buf[0] |= ((symbols>>i)&0x01)<<(7-i);
}
const uint16_t max_agg = (type0_PDCCH_CSS_config->num_symbols*type0_PDCCH_CSS_config->num_rbs)/6;
// max values are set according to TS38.213 Section 10.1 Table 10.1-1
ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
ss0->nrofCandidates->aggregationLevel4 = (((max_agg>>2) > 4)? 4 : max_agg>>2);
ss0->nrofCandidates->aggregationLevel8 = (((max_agg>>3) > 2)? 2 : max_agg>>3);
ss0->nrofCandidates->aggregationLevel16 = (((max_agg>>4) > 1)? 1 : max_agg>>4);
ss0->nrofCandidates->aggregationLevel4 = 4;
ss0->nrofCandidates->aggregationLevel8 = 2;
ss0->nrofCandidates->aggregationLevel16 = 1;
ss0->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
}
@@ -56,7 +56,6 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss,
maxL);
if (number_of_candidates > 0) {
LOG_D(NR_MAC,"L %d, number of candidates %d, aggregation %d\n", maxL, number_of_candidates, aggregation);
rel15->number_of_candidates += number_of_candidates;
int N_cce_sym = 0; // nb of rbs of coreset per symbol
for (int f = 0; f < 6; f++) {
for (int t = 0; t < 8; t++) {
@@ -64,9 +63,12 @@ void fill_dci_search_candidates(const NR_SearchSpace_t *ss,
}
}
int N_cces = N_cce_sym * rel15->coreset.duration;
for (int j = 0; j < number_of_candidates; i++, j++) {
// limit the number of candidates to the ones fitting current configuration
int max_candidates = min(N_cces / aggregation, number_of_candidates);
rel15->number_of_candidates += max_candidates;
for (int j = 0; j < max_candidates; i++, j++) {
int first_cce = aggregation * ((Y + ((j * N_cces) / (aggregation * number_of_candidates)) + 0) % (N_cces / aggregation));
LOG_D(NR_MAC,"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n", j, number_of_candidates, first_cce, aggregation, N_cces, Y);
LOG_D(NR_MAC,"Candidate %d of %d first_cce %d (L %d N_cces %d Y %d)\n", j, max_candidates, first_cce, aggregation, N_cces, Y);
rel15->CCE[i] = first_cce;
rel15->L[i] = aggregation;
}
+16 -29
View File
@@ -683,28 +683,24 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_0->mcs_table = (pdsch_config) ? ((pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0) : 0;
/* MCS */
dlsch_config_pdu_1_0->mcs = dci->mcs;
// Basic sanity check for MCS value to check for a false or erroneous DCI
if (dlsch_config_pdu_1_0->mcs > 28) {
LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_0->mcs);
return -1;
}
dlsch_config_pdu_1_0->qamModOrder = nr_get_Qm_dl(dlsch_config_pdu_1_0->mcs, dlsch_config_pdu_1_0->mcs_table);
int R = nr_get_code_rate_dl(dlsch_config_pdu_1_0->mcs, dlsch_config_pdu_1_0->mcs_table);
dlsch_config_pdu_1_0->targetCodeRate = R;
if (dlsch_config_pdu_1_0->targetCodeRate == 0 || dlsch_config_pdu_1_0->qamModOrder == 0) {
if (dlsch_config_pdu_1_0->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
int nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
int nb_re_dmrs = ((dlsch_config_pdu_1_0->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) ? 6:4)*dlsch_config_pdu_1_0->n_dmrs_cdm_groups;
dlsch_config_pdu_1_0->TBS = nr_compute_tbs(dlsch_config_pdu_1_0->qamModOrder,
R,
dlsch_config_pdu_1_0->number_rbs,
dlsch_config_pdu_1_0->number_symbols,
nb_re_dmrs*get_num_dmrs(dlsch_config_pdu_1_0->dlDmrsSymbPos),
nb_rb_oh, 0, 1);
if (R > 0)
dlsch_config_pdu_1_0->TBS = nr_compute_tbs(dlsch_config_pdu_1_0->qamModOrder,
R,
dlsch_config_pdu_1_0->number_rbs,
dlsch_config_pdu_1_0->number_symbols,
nb_re_dmrs*get_num_dmrs(dlsch_config_pdu_1_0->dlDmrsSymbPos),
nb_rb_oh, 0, 1);
int bw_tbslbrm;
if (current_DL_BWP->initial_BWPSize > 0)
@@ -907,22 +903,12 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_1->zp_csi_rs_trigger = dci->zp_csi_rs_trigger.val;
/* MCS (for transport block 1)*/
dlsch_config_pdu_1_1->mcs = dci->mcs;
// Basic sanity check for MCS value to check for a false or erroneous DCI
if (dlsch_config_pdu_1_1->mcs > 28) {
LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->mcs);
return -1;
}
/* NDI (for transport block 1)*/
dlsch_config_pdu_1_1->ndi = dci->ndi;
/* RV (for transport block 1)*/
dlsch_config_pdu_1_1->rv = dci->rv;
/* MCS (for transport block 2)*/
dlsch_config_pdu_1_1->tb2_mcs = dci->mcs2.val;
// Basic sanity check for MCS value to check for a false or erroneous DCI
if (dlsch_config_pdu_1_1->tb2_mcs > 28) {
LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->tb2_mcs);
return -1;
}
/* NDI (for transport block 2)*/
dlsch_config_pdu_1_1->tb2_ndi = dci->ndi2.val;
/* RV (for transport block 2)*/
@@ -1108,7 +1094,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_1->qamModOrder = nr_get_Qm_dl(dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table);
int R = nr_get_code_rate_dl(dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table);
dlsch_config_pdu_1_1->targetCodeRate = R;
if (dlsch_config_pdu_1_1->targetCodeRate == 0 || dlsch_config_pdu_1_1->qamModOrder == 0) {
if (dlsch_config_pdu_1_1->qamModOrder == 0) {
LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n");
return -1;
}
@@ -1118,12 +1104,13 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
}
int nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
int nb_re_dmrs = ((dmrs_type == NULL) ? 6:4)*dlsch_config_pdu_1_1->n_dmrs_cdm_groups;
dlsch_config_pdu_1_1->TBS = nr_compute_tbs(dlsch_config_pdu_1_1->qamModOrder,
R,
dlsch_config_pdu_1_1->number_rbs,
dlsch_config_pdu_1_1->number_symbols,
nb_re_dmrs*get_num_dmrs(dlsch_config_pdu_1_1->dlDmrsSymbPos),
nb_rb_oh, 0, Nl);
if (R > 0)
dlsch_config_pdu_1_1->TBS = nr_compute_tbs(dlsch_config_pdu_1_1->qamModOrder,
R,
dlsch_config_pdu_1_1->number_rbs,
dlsch_config_pdu_1_1->number_symbols,
nb_re_dmrs*get_num_dmrs(dlsch_config_pdu_1_1->dlDmrsSymbPos),
nb_rb_oh, 0, Nl);
// TBS_LBRM according to section 5.4.2.1 of 38.212
long *maxMIMO_Layers = current_DL_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers;
+11 -16
View File
@@ -533,12 +533,6 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->bwp_start = current_UL_BWP->BWPStart;
pusch_config_pdu->bwp_size = current_UL_BWP->BWPSize;
// Basic sanity check for MCS value to check for a false or erroneous DCI
if (dci->mcs > 28) {
LOG_W(NR_MAC, "MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", dci->mcs);
return -1;
}
/* Transform precoding */
pusch_config_pdu->transform_precoding = get_transformPrecoding(current_UL_BWP, *dci_format, 0);
@@ -715,8 +709,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
pusch_config_pdu->target_code_rate = R;
pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table);
if (pusch_config_pdu->target_code_rate == 0 || pusch_config_pdu->qam_mod_order == 0) {
LOG_W(NR_MAC, "In %s: Invalid code rate or Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n", __FUNCTION__);
if (pusch_config_pdu->qam_mod_order == 0) {
LOG_W(NR_MAC, "Invalid Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n");
return -1;
}
@@ -730,14 +724,15 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
nb_dmrs_re_per_rb = ((pusch_config_pdu->dmrs_config_type == pusch_dmrs_type1) ? 6:4)*pusch_config_pdu->num_dmrs_cdm_grps_no_data;
// Compute TBS
pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
R,
pusch_config_pdu->rb_size,
pusch_config_pdu->nr_of_symbols,
nb_dmrs_re_per_rb*number_dmrs_symbols,
N_PRB_oh,
0, // TBR to verify tb scaling
pusch_config_pdu->nrOfLayers)>>3;
if (R > 0)
pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order,
R,
pusch_config_pdu->rb_size,
pusch_config_pdu->nr_of_symbols,
nb_dmrs_re_per_rb*number_dmrs_symbols,
N_PRB_oh,
0, // TBR to verify tb scaling
pusch_config_pdu->nrOfLayers)>>3;
return 0;
}
+18 -28
View File
@@ -114,7 +114,11 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE)
//process_phr_Config(sched_ctrl,mac_CellGroupConfig->phr_Config);
}
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra) {
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
}
process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList, CellGroup->rlc_BearerToReleaseList, &UE->UE_sched_ctrl);
}
@@ -597,35 +601,21 @@ bool nr_mac_prepare_ra_ue(gNB_MAC_INST *nrmac, uint32_t rnti, NR_CellGroupConfig
return false;
}
NR_RA_t *ra = &cc->ra[ra_index];
if (CellGroup->spCellConfig && CellGroup->spCellConfig->reconfigurationWithSync
&& CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated != NULL) {
if (CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
ra->cfra = true;
ra->rnti = rnti;
ra->CellGroup = CellGroup;
struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble;
ra->preambles.preamble_list = calloc(ra->preambles.num_preambles, sizeof(*ra->preambles.preamble_list));
for (int i = 0; i < cc->num_active_ssb; i++) {
for (int j = 0; j < num_preamble; j++) {
if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
// one dedicated preamble for each beam
ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
break;
}
}
ra->cfra = true;
ra->rnti = rnti;
ra->CellGroup = CellGroup;
struct NR_CFRA *cfra = CellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble;
ra->preambles.preamble_list = calloc(ra->preambles.num_preambles, sizeof(*ra->preambles.preamble_list));
for (int i = 0; i < cc->num_active_ssb; i++) {
for (int j = 0; j < num_preamble; j++) {
if (cc->ssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
// one dedicated preamble for each beam
ra->preambles.preamble_list[i] = cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
break;
}
}
} else {
ra->cfra = false;
ra->rnti = 0;
if (ra->preambles.preamble_list == NULL) {
ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
ra->preambles.preamble_list = (uint8_t *)malloc(MAX_NUM_NR_PRACH_PREAMBLES * sizeof(uint8_t));
for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
ra->preambles.preamble_list[i] = i;
}
}
LOG_I(NR_MAC, "Added new %s process for UE RNTI %04x with initial CellGroup\n", ra->cfra ? "CFRA" : "CBRA", rnti);
return true;
@@ -608,6 +608,10 @@ void schedule_nr_sib1(module_id_t module_idP,
TX_req->Slot = slotP;
type0_PDCCH_CSS_config->active = false;
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
T_INT(0xffff), T_INT(frameP), T_INT(slotP), T_INT(0 /* harq_pid */),
T_BUFFER(sib1_payload, TBS));
}
}
}
@@ -998,9 +998,9 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
if (((uci_01->pduBitmap >> 1) & 0x01)) {
// iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
for (int harq_bit = 0; harq_bit < uci_01->harq.num_harq; harq_bit++) {
const uint8_t harq_value = uci_01->harq.harq_list[harq_bit].harq_value;
const uint8_t harq_confidence = uci_01->harq.harq_confidence_level;
NR_UE_harq_t *harq = find_harq(frame, slot, UE, nrmac->dl_bler.harq_round_max);
if (!harq) {
LOG_E(NR_MAC, "UE %04x: Could not find a HARQ process at %4d.%2d!\n", UE->rnti, frame, slot);
@@ -1015,24 +1015,21 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
}
// tpc (power control) only if we received AckNack
if (uci_01->harq->harq_confidence_level==0)
if (uci_01->harq.harq_confidence_level==0)
sched_ctrl->tpc1 = nr_get_tpc(nrmac->pucch_target_snrx10, uci_01->ul_cqi, 30);
else
sched_ctrl->tpc1 = 3;
sched_ctrl->pucch_snrx10 = uci_01->ul_cqi * 5 - 640;
free(uci_01->harq->harq_list);
free(uci_01->harq);
}
// check scheduling request result, confidence_level == 0 is good
if (uci_01->pduBitmap & 0x1) {
if (uci_01->sr->sr_indication && uci_01->sr->sr_confidence_level == 0 && uci_01->ul_cqi >= 148) {
if (uci_01->sr.sr_indication && uci_01->sr.sr_confidence_level == 0 && uci_01->ul_cqi >= 148) {
// SR detected with SNR >= 10dB
sched_ctrl->SR |= true;
LOG_D(NR_MAC, "SR UE %04x ul_cqi %d\n", uci_01->rnti, uci_01->ul_cqi);
}
free(uci_01->sr);
}
NR_SCHED_UNLOCK(&nrmac->sched_lock);
}
@@ -342,6 +342,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
} else {
AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid);
}
UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len;
break;
case UL_SCH_LCID_CCCH:
+2 -2
View File
@@ -1165,8 +1165,8 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info)
continue;
fapi_nr_dci_indication_pdu_t *dci_index = dl_info->dci_ind->dci_list+i;
/* The check below filters out UL_DCIs (format 7) which are being processed as DL_DCIs. */
if (dci_index->dci_format == 7 && mac->ra.ra_state == RA_SUCCEEDED) {
/* The check below filters out UL_DCIs which are being processed as DL_DCIs. */
if (dci_index->dci_format != NR_DL_DCI_FORMAT_1_0 && dci_index->dci_format != NR_DL_DCI_FORMAT_1_1) {
LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
continue;
}
-4
View File
@@ -6835,10 +6835,6 @@ rrc_eNB_decode_dcch(
/* do NR only if at least one gNB connected */
if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0)
{
allocate_en_DC_r15(ue_context_p->ue_context.UE_Capability);
if (!is_en_dc_supported(ue_context_p->ue_context.UE_Capability)){
LOG_E(RRC, "We did not properly allocate en_DC_r15 for UE_EUTRA_Capability\n");
}
ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability);
}
else
+6 -6
View File
@@ -1069,12 +1069,12 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
uint8_t security_mode =
enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4);
nr_pdcp_config_set_security(ue_p->rrc_ue_id,
DCCH,
security_mode,
kRRCenc,
kRRCint,
kUPenc);
for (int srb_id = 1; srb_id < maxSRBs; srb_id++) {
if (ue_p->Srb[srb_id].Active) {
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc);
}
}
nr_pdcp_reestablishment(ue_p->rrc_ue_id);
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
+5
View File
@@ -359,6 +359,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a
// phytest mode: we don't set up RA, etc
ret = nr_mac_add_test_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup);
} else {
NR_CellGroupConfig_t *secondaryCellGroup = ue_context_p->ue_context.secondaryCellGroup;
DevAssert(secondaryCellGroup->spCellConfig
&& secondaryCellGroup->spCellConfig->reconfigurationWithSync
&& secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated
&& secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra);
NR_SCHED_LOCK(&RC.nrmac[rrc->module_id]->sched_lock);
ret = nr_mac_prepare_ra_ue(RC.nrmac[rrc->module_id], du_ue_id, ue_context_p->ue_context.secondaryCellGroup);
NR_SCHED_UNLOCK(&RC.nrmac[rrc->module_id]->sched_lock);
+3 -2
View File
@@ -1,9 +1,10 @@
#find_package(Boost REQUIRED)
find_package(UHD REQUIRED)
find_package(UHD REQUIRED UHD)
add_library(oai_usrpdevif MODULE usrp_lib.cpp)
#target_include_directories(oai_usrpdevif PRIVATE Boost::boost)
target_link_libraries(oai_usrpdevif PRIVATE uhd)
target_link_libraries(oai_usrpdevif PRIVATE ${UHD_LIBRARIES})
target_include_directories(oai_usrpdevif PRIVATE ${UHD_INCLUDE_DIRS})
target_link_libraries(oai_usrpdevif PRIVATE UTIL)
set_target_properties(oai_usrpdevif PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_command(TARGET oai_usrpdevif POST_BUILD