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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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...)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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},\
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user