Merge remote-tracking branch 'origin/fix-ue-dlsch' into integration_2022_wk17
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
ran_build/
|
|
||||||
@@ -44,9 +44,9 @@
|
|||||||
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
||||||
do { \
|
do { \
|
||||||
if (!(cOND)) { \
|
if (!(cOND)) { \
|
||||||
fprintf(stderr, "\nAssertion ("#cOND") failed!\n" \
|
fprintf(stderr, "\nAssertion (%s) failed!\n" \
|
||||||
"In %s() %s:%d\n" fORMAT, \
|
"In %s() %s:%d\n" fORMAT, \
|
||||||
__FUNCTION__, __FILE__, __LINE__, ##aRGS); \
|
#cOND, __FUNCTION__, __FILE__, __LINE__, ##aRGS); \
|
||||||
aCTION; \
|
aCTION; \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|||||||
@@ -33,10 +33,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "PHY/defs_eNB.h"
|
#include "PHY/defs_eNB.h"
|
||||||
#include "PHY/TOOLS/dB_routines.h"
|
#include <openair1/PHY/TOOLS/tools_defs.h>
|
||||||
|
#include <openair1/SCHED/sched_common_extern.h>
|
||||||
extern int16_t hundred_times_delta_TF[100];
|
|
||||||
extern uint16_t hundred_times_log10_NPRB[100];
|
|
||||||
|
|
||||||
int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, int ncp, uint8_t use_srs)
|
int16_t estimate_ue_tx_power(int norm,uint32_t tbs, uint32_t nb_rb, uint8_t control_only, int ncp, uint8_t use_srs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -457,6 +457,7 @@ void init_gNB_Tpool(int inst) {
|
|||||||
for (int i=0; i < 2; i++) {
|
for (int i=0; i < 2; i++) {
|
||||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_out,tx_func);
|
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_out,tx_func);
|
||||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||||
|
memset(msgDataTx,0, sizeof(processingData_L1tx_t));
|
||||||
init_DLSCH_struct(gNB, msgDataTx);
|
init_DLSCH_struct(gNB, msgDataTx);
|
||||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||||
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
|
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
|
||||||
|
|||||||
@@ -245,14 +245,17 @@ nrUE_params_t *get_nrUE_params(void) {
|
|||||||
}
|
}
|
||||||
/* initialie thread pools used for NRUE processing paralleliation */
|
/* initialie thread pools used for NRUE processing paralleliation */
|
||||||
void init_tpools(uint8_t nun_dlsch_threads) {
|
void init_tpools(uint8_t nun_dlsch_threads) {
|
||||||
char *params = NULL;
|
char params[NR_RX_NB_TH*NR_NB_TH_SLOT*3+1]={0};
|
||||||
params = calloc(1,(NR_RX_NB_TH*NR_NB_TH_SLOT*3)+1);
|
|
||||||
for (int i=0; i<NR_RX_NB_TH*NR_NB_TH_SLOT; i++) {
|
for (int i=0; i<NR_RX_NB_TH*NR_NB_TH_SLOT; i++) {
|
||||||
memcpy(params+(i*3),"-1,",3);
|
memcpy(params+(i*3),"-1,",3);
|
||||||
}
|
}
|
||||||
initTpool(params, &(nrUE_params.Tpool), false);
|
if (getenv("noThreads")) {
|
||||||
free(params);
|
initTpool("n", &(nrUE_params.Tpool), false);
|
||||||
init_dlsch_tpool( nun_dlsch_threads);
|
init_dlsch_tpool(0);
|
||||||
|
} else {
|
||||||
|
initTpool(params, &(nrUE_params.Tpool), false);
|
||||||
|
init_dlsch_tpool( nun_dlsch_threads);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void get_options(void) {
|
static void get_options(void) {
|
||||||
|
|
||||||
|
|||||||
@@ -307,62 +307,76 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f)
|
|||||||
|
|
||||||
|
|
||||||
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
|
void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f)
|
||||||
{
|
{
|
||||||
|
|
||||||
int16_t *e1,*e2,*e3,*e4,*e5,*e6,*e7;
|
|
||||||
switch(Qm) {
|
switch(Qm) {
|
||||||
case 2:
|
case 2:
|
||||||
e1=e+(E/2);
|
{
|
||||||
for (int j = 0,j2=0; j< E/2; j+=2,j2+=4){
|
AssertFatal(E%2==0,"");
|
||||||
e[j] = f[j2];
|
int16_t *e1=e+(E/2);
|
||||||
e1[j] = f[j2+1];
|
int16_t *end=f+E-1;
|
||||||
e[j+1] = f[j2+2];
|
while( f<end ){
|
||||||
e1[j+1] = f[j2+3];
|
*e++ = *f++;
|
||||||
|
*e1++ = *f++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
e1=e+(E/4);
|
{
|
||||||
e2=e1+(E/4);
|
AssertFatal(E%4==0,"");
|
||||||
e3=e2+(E/4);
|
int16_t *e1=e+(E/4);
|
||||||
for (int j = 0,j2=0; j< E/4; j++,j2+=4){
|
int16_t *e2=e1+(E/4);
|
||||||
e[j] = f[j2];
|
int16_t *e3=e2+(E/4);
|
||||||
e1[j] = f[j2+1];
|
int16_t *end=f+E-3;
|
||||||
e2[j] = f[j2+2];
|
while( f<end ){
|
||||||
e3[j] = f[j2+3];
|
*e++ = *f++;
|
||||||
|
*e1++ = *f++;
|
||||||
|
*e2++ = *f++;
|
||||||
|
*e3++ = *f++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
e1=e+(E/6);
|
{
|
||||||
e2=e1+(E/6);
|
AssertFatal(E%6==0,"");
|
||||||
e3=e2+(E/6);
|
int16_t *e1=e+(E/6);
|
||||||
e4=e3+(E/6);
|
int16_t *e2=e1+(E/6);
|
||||||
e5=e4+(E/6);
|
int16_t *e3=e2+(E/6);
|
||||||
for (int j = 0,j2=0; j< E/6; j++,j2+=6){
|
int16_t *e4=e3+(E/6);
|
||||||
e[j] = f[j2];
|
int16_t *e5=e4+(E/6);
|
||||||
e1[j] = f[j2+1];
|
int16_t *end=f+E-5;
|
||||||
e2[j] = f[j2+2];
|
while( f<end ){
|
||||||
e3[j] = f[j2+3];
|
*e++ = *f++;
|
||||||
e4[j] = f[j2+4];
|
*e1++ = *f++;
|
||||||
e5[j] = f[j2+5];
|
*e2++ = *f++;
|
||||||
|
*e3++ = *f++;
|
||||||
|
*e4++ = *f++;
|
||||||
|
*e5++ = *f++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
e1=e+(E/8);
|
{
|
||||||
e2=e1+(E/8);
|
AssertFatal(E%8==0,"");
|
||||||
e3=e2+(E/8);
|
int16_t *e1=e+(E/8);
|
||||||
e4=e3+(E/8);
|
int16_t *e2=e1+(E/8);
|
||||||
e5=e4+(E/8);
|
int16_t *e3=e2+(E/8);
|
||||||
e6=e5+(E/8);
|
int16_t *e4=e3+(E/8);
|
||||||
e7=e6+(E/8);
|
int16_t *e5=e4+(E/8);
|
||||||
for (int j = 0,j2=0; j< E/8; j++,j2+=8){
|
int16_t *e6=e5+(E/8);
|
||||||
e[j] = f[j2];
|
int16_t *e7=e6+(E/8);
|
||||||
e1[j] = f[j2+1];
|
int16_t *end=f+E-7;
|
||||||
e2[j] = f[j2+2];
|
while( f<end ){
|
||||||
e3[j] = f[j2+3];
|
*e++ = *f++;
|
||||||
e4[j] = f[j2+4];
|
*e1++ = *f++;
|
||||||
e5[j] = f[j2+5];
|
*e2++ = *f++;
|
||||||
e6[j] = f[j2+6];
|
*e3++ = *f++;
|
||||||
e7[j] = f[j2+7];
|
*e4++ = *f++;
|
||||||
|
*e5++ = *f++;
|
||||||
|
*e6++ = *f++;
|
||||||
|
*e7++ = *f++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ if ((Kprime%Kb) > 0)
|
|||||||
else
|
else
|
||||||
Z = (Kprime/Kb);
|
Z = (Kprime/Kb);
|
||||||
|
|
||||||
LOG_D(PHY,"nr segmetation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
|
LOG_D(PHY,"nr segmentation B %u Bprime %u Kprime %u z %u \n", B, Bprime, Kprime, Z);
|
||||||
|
|
||||||
if (Z <= 2) {
|
if (Z <= 2) {
|
||||||
*K = 2;
|
*K = 2;
|
||||||
|
|||||||
@@ -359,6 +359,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
|
ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// RACH
|
// RACH
|
||||||
prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
|
prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
|
||||||
prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
|
prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) );
|
||||||
@@ -455,6 +456,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
|
|||||||
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||||
|
|
||||||
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
|
for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) {
|
||||||
|
|
||||||
free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
|
free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ int lte_est_freq_offset(int **dl_ch_estimates,
|
|||||||
{
|
{
|
||||||
|
|
||||||
int ch_offset, omega, dl_ch_shift;
|
int ch_offset, omega, dl_ch_shift;
|
||||||
struct complex16 omega_cpx;
|
c16_t omega_cpx;
|
||||||
double phase_offset;
|
double phase_offset;
|
||||||
int freq_offset_est;
|
int freq_offset_est;
|
||||||
unsigned char aa;
|
unsigned char aa;
|
||||||
@@ -142,8 +142,8 @@ int lte_est_freq_offset(int **dl_ch_estimates,
|
|||||||
// printf("Computing freq_offset\n");
|
// printf("Computing freq_offset\n");
|
||||||
omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
|
omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
|
||||||
//omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
|
//omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
|
||||||
omega_cpx.r = ((struct complex16*) &omega)->r;
|
omega_cpx.r = ((c16_t*) &omega)->r;
|
||||||
omega_cpx.i = ((struct complex16*) &omega)->i;
|
omega_cpx.i = ((c16_t*) &omega)->i;
|
||||||
|
|
||||||
dl_ch = (int16_t *)&dl_ch_estimates[aa][(((frame_parms->N_RB_DL/2) + 1)*12) + ch_offset];
|
dl_ch = (int16_t *)&dl_ch_estimates[aa][(((frame_parms->N_RB_DL/2) + 1)*12) + ch_offset];
|
||||||
|
|
||||||
@@ -155,8 +155,8 @@ int lte_est_freq_offset(int **dl_ch_estimates,
|
|||||||
// calculate omega = angle(conj(dl_ch)*dl_ch_prev))
|
// calculate omega = angle(conj(dl_ch)*dl_ch_prev))
|
||||||
omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
|
omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
|
||||||
|
|
||||||
omega_cpx.r += ((struct complex16*) &omega)->r;
|
omega_cpx.r += ((c16_t*) &omega)->r;
|
||||||
omega_cpx.i += ((struct complex16*) &omega)->i;
|
omega_cpx.i += ((c16_t*) &omega)->i;
|
||||||
|
|
||||||
// phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
|
// phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
|
||||||
phase_offset += atan2((double)omega_cpx.i,(double)omega_cpx.r);
|
phase_offset += atan2((double)omega_cpx.i,(double)omega_cpx.r);
|
||||||
@@ -195,7 +195,7 @@ int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
|
|||||||
{
|
{
|
||||||
|
|
||||||
int ch_offset, omega, dl_ch_shift;
|
int ch_offset, omega, dl_ch_shift;
|
||||||
struct complex16 *omega_cpx;
|
c16_t *omega_cpx;
|
||||||
double phase_offset;
|
double phase_offset;
|
||||||
int freq_offset_est;
|
int freq_offset_est;
|
||||||
unsigned char aa;
|
unsigned char aa;
|
||||||
@@ -234,7 +234,7 @@ int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
|
|||||||
// printf("Computing freq_offset\n");
|
// printf("Computing freq_offset\n");
|
||||||
omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
|
omega = dot_product(dl_ch,dl_ch_prev,(frame_parms->N_RB_DL/2 - 1)*12,dl_ch_shift);
|
||||||
//omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
|
//omega = dot_product(dl_ch,dl_ch_prev,frame_parms->ofdm_symbol_size,15);
|
||||||
omega_cpx = (struct complex16*) ω
|
omega_cpx = (c16_t*) ω
|
||||||
|
|
||||||
// printf("omega (%d,%d)\n",omega_cpx->r,omega_cpx->i);
|
// printf("omega (%d,%d)\n",omega_cpx->r,omega_cpx->i);
|
||||||
|
|
||||||
@@ -247,8 +247,8 @@ int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
|
|||||||
|
|
||||||
// calculate omega = angle(conj(dl_ch)*dl_ch_prev))
|
// calculate omega = angle(conj(dl_ch)*dl_ch_prev))
|
||||||
omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
|
omega = dot_product(dl_ch,dl_ch_prev,((frame_parms->N_RB_DL/2) - 1)*12,dl_ch_shift);
|
||||||
omega_cpx->r += ((struct complex16*) &omega)->r;
|
omega_cpx->r += ((c16_t*) &omega)->r;
|
||||||
omega_cpx->i += ((struct complex16*) &omega)->i;
|
omega_cpx->i += ((c16_t*) &omega)->i;
|
||||||
// phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
|
// phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
|
||||||
phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
|
phase_offset += atan2((double)omega_cpx->i,(double)omega_cpx->r);
|
||||||
// printf("omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
|
// printf("omega (%d,%d) -> %f\n",omega_cpx->r,omega_cpx->i,phase_offset);
|
||||||
|
|||||||
@@ -34,9 +34,9 @@
|
|||||||
// Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs)
|
// Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs)
|
||||||
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
|
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
|
||||||
|
|
||||||
static struct complex16 *primary_synch0_time __attribute__((aligned(32)));
|
static c16_t *primary_synch0_time __attribute__((aligned(32)));
|
||||||
static struct complex16 *primary_synch1_time __attribute__((aligned(32)));
|
static c16_t *primary_synch1_time __attribute__((aligned(32)));
|
||||||
static struct complex16 *primary_synch2_time __attribute__((aligned(32)));
|
static c16_t *primary_synch2_time __attribute__((aligned(32)));
|
||||||
|
|
||||||
static void doIdft(int size, short *in, short *out) {
|
static void doIdft(int size, short *in, short *out) {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
@@ -67,7 +67,7 @@ static void doIdft(int size, short *in, short *out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSize) {
|
static void copyPrimary( c16_t *out, struct complex16 *in, int ofdmSize) {
|
||||||
int k=ofdmSize-36;
|
int k=ofdmSize-36;
|
||||||
|
|
||||||
for (int i=0; i<72; i++) {
|
for (int i=0; i<72; i++) {
|
||||||
@@ -83,20 +83,20 @@ static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) { // LTE_UE_COMMON *common_vars
|
int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) { // LTE_UE_COMMON *common_vars
|
||||||
struct complex16 syncF_tmp[2048]__attribute__((aligned(32)))= {{0}};
|
c16_t syncF_tmp[2048]__attribute__((aligned(32)))= {{0}};
|
||||||
int sz=frame_parms->ofdm_symbol_size*sizeof(*primary_synch0_time);
|
int sz=frame_parms->ofdm_symbol_size*sizeof(*primary_synch0_time);
|
||||||
AssertFatal( NULL != (primary_synch0_time = (struct complex16 *)malloc16(sz)),"");
|
AssertFatal( NULL != (primary_synch0_time = (c16_t *)malloc16(sz)),"");
|
||||||
bzero(primary_synch0_time,sz);
|
bzero(primary_synch0_time,sz);
|
||||||
AssertFatal( NULL != (primary_synch1_time = (struct complex16 *)malloc16(sz)),"");
|
AssertFatal( NULL != (primary_synch1_time = (c16_t *)malloc16(sz)),"");
|
||||||
bzero(primary_synch1_time,sz);
|
bzero(primary_synch1_time,sz);
|
||||||
AssertFatal( NULL != (primary_synch2_time = (struct complex16 *)malloc16(sz)),"");
|
AssertFatal( NULL != (primary_synch2_time = (c16_t *)malloc16(sz)),"");
|
||||||
bzero(primary_synch2_time,sz);
|
bzero(primary_synch2_time,sz);
|
||||||
// generate oversampled sync_time sequences
|
// generate oversampled sync_time sequences
|
||||||
copyPrimary( syncF_tmp, (struct complex16 *) primary_synch0, frame_parms->ofdm_symbol_size);
|
copyPrimary( syncF_tmp, (c16_t *) primary_synch0, frame_parms->ofdm_symbol_size);
|
||||||
doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch0_time);
|
doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch0_time);
|
||||||
copyPrimary( syncF_tmp, (struct complex16 *) primary_synch1, frame_parms->ofdm_symbol_size);
|
copyPrimary( syncF_tmp, (c16_t *) primary_synch1, frame_parms->ofdm_symbol_size);
|
||||||
doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch1_time);
|
doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch1_time);
|
||||||
copyPrimary( syncF_tmp, (struct complex16 *) primary_synch2, frame_parms->ofdm_symbol_size);
|
copyPrimary( syncF_tmp, (c16_t *) primary_synch2, frame_parms->ofdm_symbol_size);
|
||||||
doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch2_time);
|
doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch2_time);
|
||||||
|
|
||||||
if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
|
if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
|
||||||
|
|||||||
@@ -2237,7 +2237,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
|
|||||||
int P1_SHIFT[13],P2_SHIFT[13];
|
int P1_SHIFT[13],P2_SHIFT[13];
|
||||||
int offset,nushiftmod3;
|
int offset,nushiftmod3;
|
||||||
|
|
||||||
uint8_t get_pmi_temp;
|
int get_pmi_temp;
|
||||||
|
|
||||||
MIMO_mode_t mimo_mode = -1;
|
MIMO_mode_t mimo_mode = -1;
|
||||||
uint8_t mprime=0,Ns;
|
uint8_t mprime=0,Ns;
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ uint64_t pmi2hex_2Ar1(uint32_t pmi);
|
|||||||
|
|
||||||
uint64_t pmi2hex_2Ar2(uint32_t pmi);
|
uint64_t pmi2hex_2Ar2(uint32_t pmi);
|
||||||
|
|
||||||
uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
|
uint8_t get_pmi(int N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
|
||||||
|
|
||||||
// DL power control functions
|
// DL power control functions
|
||||||
double get_pa_dB(uint8_t pa);
|
double get_pa_dB(uint8_t pa);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
|
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
|
||||||
|
|
||||||
uint8_t get_pmi(uint8_t N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb)
|
uint8_t get_pmi(int N_RB_DL, MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
MIMO_mode_t mode = dlsch_harq->mimo_mode;
|
MIMO_mode_t mode = dlsch_harq->mimo_mode;
|
||||||
|
|||||||
@@ -1550,16 +1550,6 @@ uint64_t cqi2hex(uint32_t cqi);
|
|||||||
|
|
||||||
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
|
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
|
||||||
|
|
||||||
|
|
||||||
/** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
|
|
||||||
@param N_RB_DL number of resource blocks
|
|
||||||
@param mimo_mode
|
|
||||||
@param pmi_alloc subband PMI bitmap
|
|
||||||
@param rb resource block for which to extract PMI
|
|
||||||
@returns subband PMI
|
|
||||||
*/
|
|
||||||
uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
|
|
||||||
|
|
||||||
int get_nCCE_offset_l1(int *CCE_table,
|
int get_nCCE_offset_l1(int *CCE_table,
|
||||||
const unsigned char L,
|
const unsigned char L,
|
||||||
const int nCCE,
|
const int nCCE,
|
||||||
|
|||||||
@@ -107,25 +107,20 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb
|
|||||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||||
NR_gNB_COMMON *common_vars = &gNB->common_vars;
|
NR_gNB_COMMON *common_vars = &gNB->common_vars;
|
||||||
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
|
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
|
||||||
int rb, offset, offset0, nb_symb[275], len;
|
int rb, nb_symb[275]={0};
|
||||||
int32_t *ul_ch;
|
|
||||||
|
memset(measurements->n0_subband_power, 0, sizeof(measurements->n0_subband_power));
|
||||||
LOG_D(PHY,"slot %d Doing I0 for first_symb %d, num_symb %d\n",slot,first_symb,num_symb);
|
|
||||||
for (int s=first_symb;s<(first_symb+num_symb);s++) {
|
for (int s=first_symb;s<(first_symb+num_symb);s++) {
|
||||||
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
|
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
|
||||||
|
int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) +
|
||||||
if (s==first_symb) {
|
(frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
|
||||||
nb_symb[rb]=0;
|
|
||||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx;aarx++)
|
|
||||||
measurements->n0_subband_power[aarx][rb]=0;
|
|
||||||
}
|
|
||||||
offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
|
|
||||||
if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
|
if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe
|
||||||
nb_symb[rb]++;
|
nb_symb[rb]++;
|
||||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||||
offset = offset0 + (s*frame_parms->ofdm_symbol_size);
|
int offset = offset0 + (s*frame_parms->ofdm_symbol_size);
|
||||||
ul_ch = &common_vars->rxdataF[aarx][offset];
|
int32_t *ul_ch = &common_vars->rxdataF[aarx][offset];
|
||||||
len = 12;
|
int len = 12;
|
||||||
if (((frame_parms->N_RB_UL&1) == 1) &&
|
if (((frame_parms->N_RB_UL&1) == 1) &&
|
||||||
(rb==(frame_parms->N_RB_UL>>1))) {
|
(rb==(frame_parms->N_RB_UL>>1))) {
|
||||||
len=6;
|
len=6;
|
||||||
|
|||||||
@@ -113,12 +113,6 @@ EXTERN int16_t *primary_synchro_time_nr[NUMBER_PSS_SEQUENCE]
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE]
|
|
||||||
#ifdef INIT_VARIABLES_PSS_NR_H
|
|
||||||
= { NULL, NULL, NULL}
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
/* profiling structure */
|
/* profiling structure */
|
||||||
EXTERN time_stats_t generic_time[TIME_LAST];
|
EXTERN time_stats_t generic_time[TIME_LAST];
|
||||||
|
|
||||||
|
|||||||
@@ -268,8 +268,8 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint16_t sc_per_symbol = (nb_rb + K_ptrs - 1)/K_ptrs;
|
uint16_t sc_per_symbol = (nb_rb + K_ptrs - 1)/K_ptrs;
|
||||||
struct complex16 ptrs_p[(1 + sc_per_symbol/4)*4];
|
c16_t ptrs_p[(1 + sc_per_symbol/4)*4];
|
||||||
struct complex16 dmrs_comp_p[(1 + sc_per_symbol/4)*4];
|
c16_t dmrs_comp_p[(1 + sc_per_symbol/4)*4];
|
||||||
double abs = 0.0;
|
double abs = 0.0;
|
||||||
double real = 0.0;
|
double real = 0.0;
|
||||||
double imag = 0.0;
|
double imag = 0.0;
|
||||||
@@ -422,7 +422,7 @@ void get_slope_from_estimates(uint8_t start, uint8_t end, int16_t *est_p, double
|
|||||||
/* estimate from slope */
|
/* estimate from slope */
|
||||||
void ptrs_estimate_from_slope(int16_t *error_est, double *slope_p, uint8_t start, uint8_t end)
|
void ptrs_estimate_from_slope(int16_t *error_est, double *slope_p, uint8_t start, uint8_t end)
|
||||||
{
|
{
|
||||||
struct complex16 *error=(struct complex16 *) error_est;
|
c16_t *error=(struct complex16 *) error_est;
|
||||||
for(uint8_t i = 1; i< (end -start);i++) {
|
for(uint8_t i = 1; i< (end -start);i++) {
|
||||||
error[start+i].r = error[start].r + (int16_t)(i * slope_p[0]);// real
|
error[start+i].r = error[start].r + (int16_t)(i * slope_p[0]);// real
|
||||||
error[start+i].i = error[start].i + (int16_t)(i * slope_p[1]); //imag
|
error[start+i].i = error[start].i + (int16_t)(i * slope_p[1]); //imag
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
|||||||
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI, 1,
|
polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI, 1,
|
||||||
NR_POLAR_DCI_MESSAGE_TYPE, dci_pdu->PayloadSizeBits, dci_pdu->AggregationLevel);
|
NR_POLAR_DCI_MESSAGE_TYPE, dci_pdu->PayloadSizeBits, dci_pdu->AggregationLevel);
|
||||||
#ifdef DEBUG_CHANNEL_CODING
|
#ifdef DEBUG_CHANNEL_CODING
|
||||||
|
//debug dump dci
|
||||||
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu->AggregationLevel);
|
printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu->AggregationLevel);
|
||||||
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
|
printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n",
|
||||||
((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
|
((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]);
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
|||||||
start_meas(dlsch_encoding_stats);
|
start_meas(dlsch_encoding_stats);
|
||||||
|
|
||||||
if (nr_dlsch_encoding(gNB,
|
if (nr_dlsch_encoding(gNB,
|
||||||
harq->pdu, frame, slot, dlsch, frame_parms,output,tinput,tprep,tparity,toutput,
|
frame, slot, harq, frame_parms,output,tinput,tprep,tparity,toutput,
|
||||||
dlsch_rate_matching_stats,
|
dlsch_rate_matching_stats,
|
||||||
dlsch_interleaving_stats,
|
dlsch_interleaving_stats,
|
||||||
dlsch_segmentation_stats) == -1)
|
dlsch_segmentation_stats) == -1)
|
||||||
@@ -163,6 +163,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
|||||||
rel15->dataScramblingId,
|
rel15->dataScramblingId,
|
||||||
rel15->rnti,
|
rel15->rnti,
|
||||||
scrambled_output);
|
scrambled_output);
|
||||||
|
|
||||||
#ifdef DEBUG_DLSCH
|
#ifdef DEBUG_DLSCH
|
||||||
printf("PDSCH scrambling:\n");
|
printf("PDSCH scrambling:\n");
|
||||||
for (int i=0; i<encoded_length>>8; i++) {
|
for (int i=0; i<encoded_length>>8; i++) {
|
||||||
@@ -171,6 +172,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stop_meas(dlsch_scrambling_stats);
|
stop_meas(dlsch_scrambling_stats);
|
||||||
/// Modulation
|
/// Modulation
|
||||||
start_meas(dlsch_modulation_stats);
|
start_meas(dlsch_modulation_stats);
|
||||||
|
|||||||
@@ -78,9 +78,9 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
|
|||||||
NR_gNB_SCH_STATS_t *find_nr_dlsch_stats(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
|
NR_gNB_SCH_STATS_t *find_nr_dlsch_stats(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type);
|
||||||
|
|
||||||
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||||
unsigned char *a,int frame,
|
int frame,
|
||||||
uint8_t slot,
|
uint8_t slot,
|
||||||
NR_gNB_DLSCH_t *dlsch,
|
NR_DL_gNB_HARQ_t *harq,
|
||||||
NR_DL_FRAME_PARMS* frame_parms,
|
NR_DL_FRAME_PARMS* frame_parms,
|
||||||
unsigned char * output,
|
unsigned char * output,
|
||||||
time_stats_t *tinput,
|
time_stats_t *tinput,
|
||||||
|
|||||||
@@ -286,10 +286,9 @@ void ldpc8blocks( void *p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||||
unsigned char *a,
|
|
||||||
int frame,
|
int frame,
|
||||||
uint8_t slot,
|
uint8_t slot,
|
||||||
NR_gNB_DLSCH_t *dlsch,
|
NR_DL_gNB_HARQ_t *harq,
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
unsigned char * output,
|
unsigned char * output,
|
||||||
time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
|
time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput,
|
||||||
@@ -298,13 +297,12 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
|||||||
encoder_implemparams_t impp;
|
encoder_implemparams_t impp;
|
||||||
impp.output=output;
|
impp.output=output;
|
||||||
unsigned int crc=1;
|
unsigned int crc=1;
|
||||||
NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process;
|
|
||||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
|
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15;
|
||||||
impp.Zc = &dlsch->harq_process.Z;
|
impp.Zc = &harq->Z;
|
||||||
float Coderate = 0.0;
|
float Coderate = 0.0;
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN);
|
||||||
uint32_t A = rel15->TBSize[0]<<3;
|
uint32_t A = rel15->TBSize[0]<<3;
|
||||||
|
unsigned char *a=harq->pdu;
|
||||||
if ( rel15->rnti != SI_RNTI)
|
if ( rel15->rnti != SI_RNTI)
|
||||||
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
|
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
|
||||||
|
|
||||||
@@ -317,14 +315,14 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
|||||||
stats=&gNB->dlsch_stats[i];
|
stats=&gNB->dlsch_stats[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gNB->dlsch_stats[i].rnti == dlsch->rnti) {
|
if (gNB->dlsch_stats[i].rnti == rel15->rnti) {
|
||||||
stats=&gNB->dlsch_stats[i];
|
stats=&gNB->dlsch_stats[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats) {
|
if (stats) {
|
||||||
stats->rnti = dlsch->rnti;
|
stats->rnti = rel15->rnti;
|
||||||
stats->total_bytes_tx += rel15->TBSize[0];
|
stats->total_bytes_tx += rel15->TBSize[0];
|
||||||
stats->current_RI = rel15->nrOfLayers;
|
stats->current_RI = rel15->nrOfLayers;
|
||||||
stats->current_Qm = rel15->qamModOrder[0];
|
stats->current_Qm = rel15->qamModOrder[0];
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
* x(l*12+n) = r_u_v_alpha_delta(n)
|
* x(l*12+n) = r_u_v_alpha_delta(n)
|
||||||
*/
|
*/
|
||||||
// the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
|
// the value of u,v (delta always 0 for PUCCH) has to be calculated according to TS 38.211 Subclause 6.3.2.2.1
|
||||||
uint8_t u[2]={0,0},v[2]={0,0};
|
uint8_t u[2]={0},v[2]={0};
|
||||||
|
|
||||||
// x_n contains the sequence r_u_v_alpha_delta(n)
|
// x_n contains the sequence r_u_v_alpha_delta(n)
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
|
|
||||||
|
|
||||||
AssertFatal(pucch_pdu->nr_of_symbols < 3,"nr_of_symbols %d not allowed\n",pucch_pdu->nr_of_symbols);
|
AssertFatal(pucch_pdu->nr_of_symbols < 3,"nr_of_symbols %d not allowed\n",pucch_pdu->nr_of_symbols);
|
||||||
uint32_t re_offset[2]={0,0};
|
uint32_t re_offset[2]={0};
|
||||||
uint8_t l2;
|
uint8_t l2;
|
||||||
|
|
||||||
const int16_t *x_re[2],*x_im[2];
|
const int16_t *x_re[2],*x_im[2];
|
||||||
@@ -271,16 +271,10 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
x_re[1] = table_5_2_2_2_2_Re[u[1]];
|
x_re[1] = table_5_2_2_2_2_Re[u[1]];
|
||||||
x_im[1] = table_5_2_2_2_2_Im[u[1]];
|
x_im[1] = table_5_2_2_2_2_Im[u[1]];
|
||||||
|
|
||||||
int16_t xr[1+frame_parms->nb_antennas_rx][1+pucch_pdu->nr_of_symbols][24] __attribute__((aligned(32)));
|
c64_t xr[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][12] __attribute__((aligned(32)));
|
||||||
int64_t xrtmag=0,xrtmag_next=0;
|
int64_t xrtmag=0,xrtmag_next=0;
|
||||||
uint8_t maxpos=0;
|
uint8_t maxpos=0;
|
||||||
uint8_t index=0;
|
uint8_t index=0;
|
||||||
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
|
||||||
for (int aarx=0;aarx<frame_parms->nb_antennas_rx;aarx++) {
|
|
||||||
memset((void*)xr[aarx][l],0,24*sizeof(int16_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int n2;
|
|
||||||
|
|
||||||
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
|
||||||
l2 = l+pucch_pdu->start_symbol_index;
|
l2 = l+pucch_pdu->start_symbol_index;
|
||||||
@@ -289,75 +283,68 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
re_offset[l]-=frame_parms->ofdm_symbol_size;
|
re_offset[l]-=frame_parms->ofdm_symbol_size;
|
||||||
|
|
||||||
AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
|
AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n");
|
||||||
int16_t *r;
|
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||||
r=(int16_t*)&rxdataF[aa][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[l]];
|
c16_t *r=(c16_t*)&rxdataF[aa][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[l]];
|
||||||
n2=0;
|
for (n=0;n<12;n++) {
|
||||||
for (n=0;n<12;n++,n2+=2) {
|
xr[aa][l][n].r = (int32_t)x_re[l][n] * r[n].r + (int32_t)x_im[l][n] * r[n].i;
|
||||||
xr[aa][l][n2] +=(int16_t)(((int32_t)x_re[l][n]*r[n2]+(int32_t)x_im[l][n]*r[n2+1])>>15);
|
xr[aa][l][n].i = (int32_t)x_re[l][n] * r[n].i - (int32_t)x_im[l][n] * r[n].r;
|
||||||
xr[aa][l][n2+1]+=(int16_t)(((int32_t)x_re[l][n]*r[n2+1]-(int32_t)x_im[l][n]*r[n2])>>15);
|
|
||||||
#ifdef DEBUG_NR_PUCCH_RX
|
#ifdef DEBUG_NR_PUCCH_RX
|
||||||
printf("x (%d,%d), r%d.%d (%d,%d), xr (%d,%d)\n",
|
printf("x (%d,%d), r%d.%d (%d,%d), xr (%lld,%lld)\n",
|
||||||
x_re[l][n],x_im[l][n],l2,re_offset[l],r[n2],r[n2+1],xr[aa][l][n2],xr[aa][l][n2+1]);
|
x_re[l][n],x_im[l][n],l2,re_offset[l],r[n].r,r[n].i,xr[aa][l][n].r,xr[aa][l][n].i);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t corr_re[1+frame_parms->nb_antennas_rx][2];
|
|
||||||
int32_t corr_im[1+frame_parms->nb_antennas_rx][2];
|
|
||||||
//int32_t no_corr = 0;
|
//int32_t no_corr = 0;
|
||||||
int seq_index = 0;
|
int seq_index = 0;
|
||||||
int64_t temp;
|
int64_t temp;
|
||||||
|
|
||||||
for(i=0;i<nr_sequences;i++){
|
for(i=0;i<nr_sequences;i++){
|
||||||
|
c64_t corr[frame_parms->nb_antennas_rx][2];
|
||||||
for (int l=0;l<pucch_pdu->nr_of_symbols;l++) {
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||||
seq_index = (pucch_pdu->initial_cyclic_shift+
|
for (int l=0;l<pucch_pdu->nr_of_symbols;l++) {
|
||||||
mcs[i]+
|
seq_index = (pucch_pdu->initial_cyclic_shift+
|
||||||
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
|
mcs[i]+
|
||||||
|
gNB->pucch0_lut.lut[cs_ind][slot][l+pucch_pdu->start_symbol_index])%12;
|
||||||
#ifdef DEBUG_NR_PUCCH_RX
|
#ifdef DEBUG_NR_PUCCH_RX
|
||||||
printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]);
|
printf("PUCCH symbol %d seq %d, seq_index %d, mcs %d\n",l,i,seq_index,mcs[i]);
|
||||||
#endif
|
#endif
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
corr[aa][l]=(c64_t){0};
|
||||||
corr_re[aa][l]=0;
|
for (n = 0; n < 12; n++) {
|
||||||
corr_im[aa][l]=0;
|
corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n];
|
||||||
|
corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n];
|
||||||
n2=0;
|
|
||||||
for (n=0;n<12;n++,n2+=2) {
|
|
||||||
corr_re[aa][l]+=(xr[aa][l][n2]*idft12_re[seq_index][n]+xr[aa][l][n2+1]*idft12_im[seq_index][n])>>15;
|
|
||||||
corr_im[aa][l]+=(xr[aa][l][n2]*idft12_im[seq_index][n]-xr[aa][l][n2+1]*idft12_re[seq_index][n])>>15;
|
|
||||||
}
|
}
|
||||||
|
corr[aa][l].r >>= 31;
|
||||||
|
corr[aa][l].i >>= 31;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%d,%d)=>%f\n",
|
LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n",
|
||||||
mcs[i],seq_index,corr_re[0][0],corr_im[0][0],
|
mcs[i],seq_index,corr[0][0].r,corr[0][0].i,
|
||||||
10*log10((double)corr_re[0][0]*corr_re[0][0] + (double)corr_im[0][0]*corr_im[0][0]));
|
10*log10((double)squaredMod(corr[0][0])));
|
||||||
if (pucch_pdu->nr_of_symbols==2)
|
if (pucch_pdu->nr_of_symbols==2)
|
||||||
LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%d,%d)=>%f\n",
|
LOG_D(PHY,"PUCCH 2nd symbol IDFT[%d/%d] = (%ld,%ld)=>%f\n",
|
||||||
mcs[i],seq_index,corr_re[0][1],corr_im[0][1],
|
mcs[i],seq_index,corr[0][1].r,corr[0][1].i,
|
||||||
10*log10((double)corr_re[0][1]*corr_re[0][1] + (double)corr_im[0][1]*corr_im[0][1]));
|
10*log10((double)squaredMod(corr[0][1])));
|
||||||
if (pucch_pdu->freq_hop_flag == 0) {
|
if (pucch_pdu->freq_hop_flag == 0) {
|
||||||
if (pucch_pdu->nr_of_symbols==1) {// non-coherent correlation
|
if (pucch_pdu->nr_of_symbols==1) {// non-coherent correlation
|
||||||
temp=0;
|
temp=0;
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
||||||
temp+=(int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0];
|
temp+=squaredMod(corr[aa][0]);
|
||||||
} else {
|
} else {
|
||||||
int64_t corr_re2=0;
|
|
||||||
int64_t corr_im2=0;
|
|
||||||
temp=0;
|
temp=0;
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||||
corr_re2 = (int64_t)corr_re[aa][0]+corr_re[aa][1];
|
c64_t corr2;
|
||||||
corr_im2 = (int64_t)corr_im[aa][0]+corr_im[aa][1];
|
csum(corr2, corr[aa][0], corr[aa][1]);
|
||||||
// coherent combining of 2 symbols and then complex modulus for single-frequency case
|
// coherent combining of 2 symbols and then complex modulus for single-frequency case
|
||||||
temp+=corr_re2*corr_re2 + corr_im2*corr_im2;
|
temp+=corr2.r*corr2.r + corr2.i*corr2.i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (pucch_pdu->freq_hop_flag == 1) {
|
} else if (pucch_pdu->freq_hop_flag == 1) {
|
||||||
// full non-coherent combining of 2 symbols for frequency-hopping case
|
// full non-coherent combining of 2 symbols for frequency-hopping case
|
||||||
temp=0;
|
temp=0;
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
||||||
temp += (int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0] + (int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1];
|
temp += squaredMod(corr[aa][0]) + squaredMod(corr[aa][1]);
|
||||||
}
|
}
|
||||||
else AssertFatal(1==0,"shouldn't happen\n");
|
else AssertFatal(1==0,"shouldn't happen\n");
|
||||||
|
|
||||||
@@ -369,9 +356,9 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
uci_stats->current_pucch0_stat0 = 0;
|
uci_stats->current_pucch0_stat0 = 0;
|
||||||
int64_t temp2=0,temp3=0;;
|
int64_t temp2=0,temp3=0;;
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||||
temp2 += ((int64_t)corr_re[aa][0]*corr_re[aa][0] + (int64_t)corr_im[aa][0]*corr_im[aa][0]);
|
temp2 += squaredMod(corr[aa][0]);
|
||||||
if (pucch_pdu->nr_of_symbols==2)
|
if (pucch_pdu->nr_of_symbols==2)
|
||||||
temp3 += ((int64_t)corr_re[aa][1]*corr_re[aa][1] + (int64_t)corr_im[aa][1]*corr_im[aa][1]);
|
temp3 += squaredMod(corr[aa][1]);
|
||||||
}
|
}
|
||||||
uci_stats->current_pucch0_stat0= dB_fixed64(temp2);
|
uci_stats->current_pucch0_stat0= dB_fixed64(temp2);
|
||||||
if ( pucch_pdu->nr_of_symbols==2)
|
if ( pucch_pdu->nr_of_symbols==2)
|
||||||
@@ -392,7 +379,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]];
|
uci_stats->pucch0_n01 = gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]];
|
||||||
LOG_D(PHY,"n00[%d] = %d, n01[%d] = %d\n",prb_offset[0],uci_stats->pucch0_n00,prb_offset[1],uci_stats->pucch0_n01);
|
LOG_D(PHY,"n00[%d] = %d, n01[%d] = %d\n",prb_offset[0],uci_stats->pucch0_n00,prb_offset[1],uci_stats->pucch0_n01);
|
||||||
// estimate CQI for MAC (from antenna port 0 only)
|
// estimate CQI for MAC (from antenna port 0 only)
|
||||||
int max_n0 = uci_stats->pucch0_n00>uci_stats->pucch0_n01 ? uci_stats->pucch0_n00:uci_stats->pucch0_n01;
|
int max_n0 = max(gNB->measurements.n0_subband_power_tot_dB[prb_offset[0]],
|
||||||
|
gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]);
|
||||||
int SNRtimes10,sigenergy=0;
|
int SNRtimes10,sigenergy=0;
|
||||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++)
|
||||||
sigenergy += signal_energy_nodc(&rxdataF[aa][soffset+
|
sigenergy += signal_energy_nodc(&rxdataF[aa][soffset+
|
||||||
@@ -407,8 +395,15 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/
|
uci_stats->pucch0_thres = gNB->pucch0_thres; /* + (10*max_n0);*/
|
||||||
bool no_conf=false;
|
bool no_conf=false;
|
||||||
if (nr_sequences>1) {
|
if (nr_sequences>1) {
|
||||||
if (xrtmag_dBtimes10 < (50+xrtmag_next_dBtimes10) || SNRtimes10 < uci_stats->pucch0_thres)
|
if (xrtmag_dBtimes10 < (50+xrtmag_next_dBtimes10) || SNRtimes10 < gNB->pucch0_thres) {
|
||||||
no_conf=true;
|
no_conf=true;
|
||||||
|
LOG_D(PHY,"%d.%d PUCCH bad confidence: %d threshold, %d, %d, %d\n",
|
||||||
|
frame, slot,
|
||||||
|
uci_stats->pucch0_thres,
|
||||||
|
SNRtimes10,
|
||||||
|
xrtmag_dBtimes10,
|
||||||
|
xrtmag_next_dBtimes10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gNB->bad_pucch += no_conf;
|
gNB->bad_pucch += no_conf;
|
||||||
// first bit of bitmap for sr presence and second bit for acknack presence
|
// first bit of bitmap for sr presence and second bit for acknack presence
|
||||||
@@ -422,7 +417,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
if (pucch_pdu->bit_len_harq==0) {
|
if (pucch_pdu->bit_len_harq==0) {
|
||||||
uci_pdu->harq = NULL;
|
uci_pdu->harq = NULL;
|
||||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||||
uci_pdu->sr->sr_confidence_level = no_conf ? 1 : 0;
|
uci_pdu->sr->sr_confidence_level = no_conf;
|
||||||
uci_stats->pucch0_sr_trials++;
|
uci_stats->pucch0_sr_trials++;
|
||||||
if (xrtmag_dBtimes10>(10*gNB->measurements.n0_power_tot_dB)) {
|
if (xrtmag_dBtimes10>(10*gNB->measurements.n0_power_tot_dB)) {
|
||||||
uci_pdu->sr->sr_indication = 1;
|
uci_pdu->sr->sr_indication = 1;
|
||||||
@@ -434,17 +429,19 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
else if (pucch_pdu->bit_len_harq==1) {
|
else if (pucch_pdu->bit_len_harq==1) {
|
||||||
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
|
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
|
||||||
uci_pdu->harq->num_harq = 1;
|
uci_pdu->harq->num_harq = 1;
|
||||||
uci_pdu->harq->harq_confidence_level = no_conf ? 1 : 0;
|
uci_pdu->harq->harq_confidence_level = no_conf;
|
||||||
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1);
|
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->harq_list[0].harq_value = !(index&0x01);
|
||||||
LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ value %d (0 pass, 1 fail) with confidence level %d (0 is good, 1 is bad) xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d, energy %f, sync_pos %d\n",
|
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, sync_pos %d\n",
|
||||||
frame,slot,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10,10*log10((double)sigenergy),gNB->ulsch_stats[0].sync_pos);
|
frame,slot,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,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10,10*log10((double)sigenergy),gNB->ulsch_stats[0].sync_pos);
|
||||||
|
|
||||||
if (pucch_pdu->sr_flag == 1) {
|
if (pucch_pdu->sr_flag == 1) {
|
||||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||||
uci_pdu->sr->sr_indication = (index>1) ? 1 : 0;
|
uci_pdu->sr->sr_indication = (index>1);
|
||||||
uci_pdu->sr->sr_confidence_level = no_conf ? 1 : 0;
|
uci_pdu->sr->sr_confidence_level = no_conf;
|
||||||
uci_stats->pucch0_positive_SR++;
|
uci_stats->pucch0_positive_SR++;
|
||||||
}
|
}
|
||||||
uci_stats->pucch01_trials++;
|
uci_stats->pucch01_trials++;
|
||||||
@@ -452,17 +449,23 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
|
|||||||
else {
|
else {
|
||||||
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
|
uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq));
|
||||||
uci_pdu->harq->num_harq = 2;
|
uci_pdu->harq->num_harq = 2;
|
||||||
uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0;
|
uci_pdu->harq->harq_confidence_level = no_conf;
|
||||||
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2);
|
uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2 * sizeof( *uci_pdu->harq->harq_list));
|
||||||
|
|
||||||
uci_pdu->harq->harq_list[1].harq_value = !(index&0x01);
|
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[0].harq_value = !((index>>1)&0x01);
|
||||||
LOG_D(PHY, "[DLSCH/PDSCH/PUCCH] %d.%d HARQ values %d and %d (0 pass, 1 fail) with confidence level %d (0 is good, 1 is bad), xrt_mag %d xrt_mag_next %d n0 %d (%d,%d) pucch0_thres %d, cqi %d, SNRtimes10 %d,sync_pos %d\n",
|
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,sync_pos %d\n",
|
||||||
frame,slot,uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level,xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,SNRtimes10,gNB->ulsch_stats[0].sync_pos);
|
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",
|
||||||
|
xrtmag_dBtimes10,xrtmag_next_dBtimes10,max_n0,
|
||||||
|
uci_stats->pucch0_n00,uci_stats->pucch0_n01,uci_stats->pucch0_thres,cqi,
|
||||||
|
SNRtimes10,gNB->ulsch_stats[0].sync_pos);
|
||||||
if (pucch_pdu->sr_flag == 1) {
|
if (pucch_pdu->sr_flag == 1) {
|
||||||
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr));
|
||||||
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
|
uci_pdu->sr->sr_indication = (index>3) ? 1 : 0;
|
||||||
uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0;
|
uci_pdu->sr->sr_confidence_level = no_conf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ char nr_dci_format_string[8][30] = {
|
|||||||
//static const int16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
|
//static const int16_t conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
|
||||||
|
|
||||||
|
|
||||||
void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
static void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
||||||
uint32_t *z,
|
uint32_t *e_rx,
|
||||||
uint8_t coreset_time_dur,
|
uint8_t coreset_time_dur,
|
||||||
uint8_t start_symbol,
|
uint8_t start_symbol,
|
||||||
uint32_t coreset_nbr_rb,
|
uint32_t coreset_nbr_rb,
|
||||||
@@ -187,10 +187,10 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
|
|||||||
index_z = data_sc * rb_count;
|
index_z = data_sc * rb_count;
|
||||||
index_llr = (uint16_t) (f*B_rb + rb + symbol_idx * coreset_nbr_rb) * data_sc;
|
index_llr = (uint16_t) (f*B_rb + rb + symbol_idx * coreset_nbr_rb) * data_sc;
|
||||||
for (int i = 0; i < data_sc; i++) {
|
for (int i = 0; i < data_sc; i++) {
|
||||||
z[index_z + i] = llr[index_llr + i];
|
e_rx[index_z + i] = llr[index_llr + i];
|
||||||
#ifdef NR_PDCCH_DCI_DEBUG
|
#ifdef NR_PDCCH_DCI_DEBUG
|
||||||
LOG_I(PHY,"[candidate=%d,symbol_idx=%d,cce=%d,REG bundle=%d,PRB=%d] z[%d]=(%d,%d) <-> \t llr[%d]=(%d,%d) \n",
|
LOG_I(PHY,"[candidate=%d,symbol_idx=%d,cce=%d,REG bundle=%d,PRB=%d] z[%d]=(%d,%d) <-> \t llr[%d]=(%d,%d) \n",
|
||||||
c_id,symbol_idx,cce_count,k,f*B_rb + rb,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]),
|
c_id,symbol_idx,cce_count,k,f*B_rb + rb,(index_z + i),*(int16_t *) &e_rx[index_z + i],*(1 + (int16_t *) &e_rx[index_z + i]),
|
||||||
(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i]));
|
(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i]));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -798,7 +798,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void nr_pdcch_unscrambling(int16_t *z,
|
void nr_pdcch_unscrambling(int16_t *e_rx,
|
||||||
uint16_t scrambling_RNTI,
|
uint16_t scrambling_RNTI,
|
||||||
uint32_t length,
|
uint32_t length,
|
||||||
uint16_t pdcch_DMRS_scrambling_id,
|
uint16_t pdcch_DMRS_scrambling_id,
|
||||||
@@ -821,8 +821,10 @@ void nr_pdcch_unscrambling(int16_t *z,
|
|||||||
reset = 0;
|
reset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((s >> (i % 32)) & 1) == 1) z2[i] = -z[i];
|
if (((s >> (i % 32)) & 1) == 1)
|
||||||
else z2[i]=z[i];
|
z2[i] = -e_rx[i];
|
||||||
|
else
|
||||||
|
z2[i]=e_rx[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,6 +877,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
|||||||
int L = rel15->L[j];
|
int L = rel15->L[j];
|
||||||
|
|
||||||
// Loop over possible DCI lengths
|
// Loop over possible DCI lengths
|
||||||
|
|
||||||
for (int k = 0; k < rel15->num_dci_options; k++) {
|
for (int k = 0; k < rel15->num_dci_options; k++) {
|
||||||
// skip this candidate if we've already found one with the
|
// skip this candidate if we've already found one with the
|
||||||
// same rnti and format at a different aggregation level
|
// same rnti and format at a different aggregation level
|
||||||
@@ -893,10 +896,11 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
|||||||
LOG_D(PHY, "(%i.%i) Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d, length %d, format %s\n",
|
LOG_D(PHY, "(%i.%i) Trying DCI candidate %d of %d number of candidates, CCE %d (%d), L %d, length %d, format %s\n",
|
||||||
proc->frame_rx, proc->nr_slot_rx, j, rel15->number_of_candidates, CCEind, e_rx_cand_idx, L, dci_length, nr_dci_format_string[rel15->dci_format_options[k]]);
|
proc->frame_rx, proc->nr_slot_rx, j, rel15->number_of_candidates, CCEind, e_rx_cand_idx, L, dci_length, nr_dci_format_string[rel15->dci_format_options[k]]);
|
||||||
|
|
||||||
|
|
||||||
nr_pdcch_unscrambling(&pdcch_e_rx[e_rx_cand_idx], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
|
nr_pdcch_unscrambling(&pdcch_e_rx[e_rx_cand_idx], rel15->coreset.scrambling_rnti, L*108, rel15->coreset.pdcch_dmrs_scrambling_id, tmp_e);
|
||||||
|
|
||||||
#ifdef DEBUG_DCI_DECODING
|
#ifdef DEBUG_DCI_DECODING
|
||||||
uint32_t *z = (uint32_t *) &pdcch_vars->e_rx[e_rx_cand_idx];
|
uint32_t *z = (uint32_t *) &e_rx[e_rx_cand_idx];
|
||||||
for (int index_z = 0; index_z < L*6; index_z++){
|
for (int index_z = 0; index_z < L*6; index_z++){
|
||||||
for (int i=0; i<9; i++) {
|
for (int i=0; i<9; i++) {
|
||||||
LOG_I(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[9*index_z + i],*(1 + (int16_t *) &z[9*index_z + i]));
|
LOG_I(PHY,"z[%d]=(%d,%d) \n", (9*index_z + i), *(int16_t *) &z[9*index_z + i],*(1 + (int16_t *) &z[9*index_z + i]));
|
||||||
@@ -909,8 +913,8 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
|||||||
NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
|
NR_POLAR_DCI_MESSAGE_TYPE, dci_length, L);
|
||||||
|
|
||||||
n_rnti = rel15->rnti;
|
n_rnti = rel15->rnti;
|
||||||
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d)\n",
|
LOG_D(PHY, "(%i.%i) dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx )\n",
|
||||||
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length);
|
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length, *(unsigned long long*)dci_estimation);
|
||||||
if (crc == n_rnti) {
|
if (crc == n_rnti) {
|
||||||
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
|
LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %s,n_CCE %d,payloadSize %d,payload %llx)\n",
|
||||||
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
|
proc->frame_rx, proc->nr_slot_rx,n_rnti,nr_dci_format_string[rel15->dci_format_options[k]],CCEind,dci_length,*(unsigned long long*)dci_estimation);
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
|
|||||||
memset(dlsch->harq_processes[i]->d[r],0,5*8448);
|
memset(dlsch->harq_processes[i]->d[r],0,5*8448);
|
||||||
else
|
else
|
||||||
exit_flag=2;
|
exit_flag=2;
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exit_flag=1;
|
exit_flag=1;
|
||||||
@@ -221,7 +222,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
|
|||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
||||||
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
||||||
harq_process->status = SCH_IDLE;
|
harq_process->status = SCH_IDLE;
|
||||||
harq_process->round = 0;
|
harq_process->DLround = 0;
|
||||||
harq_process->ack = 1;
|
harq_process->ack = 1;
|
||||||
|
|
||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n",
|
||||||
@@ -236,9 +237,9 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
|
|||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
||||||
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
||||||
harq_process->ack = 0;
|
harq_process->ack = 0;
|
||||||
if (harq_process->round >= dlsch->Mlimit) {
|
if (harq_process->DLround >= dlsch->Mlimit) {
|
||||||
harq_process->status = SCH_IDLE;
|
harq_process->status = SCH_IDLE;
|
||||||
harq_process->round = 0;
|
harq_process->DLround = 0;
|
||||||
phy_vars_ue->dl_stats[4]++;
|
phy_vars_ue->dl_stats[4]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,14 +296,14 @@ void nr_processDLSegment(void* arg) {
|
|||||||
K_bits_F = Kr-harq_process->F;
|
K_bits_F = Kr-harq_process->F;
|
||||||
|
|
||||||
t_nrLDPC_time_stats procTime = {0};
|
t_nrLDPC_time_stats procTime = {0};
|
||||||
t_nrLDPC_time_stats* p_procTime = &procTime ;
|
|
||||||
|
|
||||||
int16_t w[5*8448];
|
|
||||||
memset(w,0,(5*8448)*sizeof(short));
|
|
||||||
|
|
||||||
start_meas(&rdata->ts_deinterleave);
|
start_meas(&rdata->ts_deinterleave);
|
||||||
|
|
||||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
|
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_IN);
|
||||||
|
int16_t w[E];
|
||||||
|
memset(w, 0, sizeof(w));
|
||||||
nr_deinterleaving_ldpc(E,
|
nr_deinterleaving_ldpc(E,
|
||||||
Qm,
|
Qm,
|
||||||
w, // [hna] w is e
|
w, // [hna] w is e
|
||||||
@@ -389,12 +390,12 @@ void nr_processDLSegment(void* arg) {
|
|||||||
no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
|
no_iteration_ldpc = nrLDPC_decoder(p_decoderParms,
|
||||||
(int8_t *)&pl[0],
|
(int8_t *)&pl[0],
|
||||||
llrProcBuf,
|
llrProcBuf,
|
||||||
p_procTime);
|
&procTime);
|
||||||
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
|
//VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_LDPC, VCD_FUNCTION_OUT);
|
||||||
|
|
||||||
// Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
|
// Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int
|
||||||
if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
|
if (check_crc((uint8_t *)llrProcBuf,length_dec,harq_process->F,crc_type)) {
|
||||||
LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
|
LOG_D(PHY,"Segment %u CRC OK\n",r);
|
||||||
|
|
||||||
if (r==0) {
|
if (r==0) {
|
||||||
for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
|
for (int i=0; i<10; i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t *)llrProcBuf)[i]);
|
||||||
@@ -404,7 +405,7 @@ void nr_processDLSegment(void* arg) {
|
|||||||
no_iteration_ldpc = dlsch->max_ldpc_iterations;
|
no_iteration_ldpc = dlsch->max_ldpc_iterations;
|
||||||
rdata->decodeIterations = no_iteration_ldpc;
|
rdata->decodeIterations = no_iteration_ldpc;
|
||||||
} else {
|
} else {
|
||||||
LOG_D(PHY,"CRC NOT OK\n\033[0m");
|
LOG_D(PHY,"CRC NOT OK\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
nb_total_decod++;
|
nb_total_decod++;
|
||||||
@@ -447,8 +448,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HARQ stats
|
// HARQ stats
|
||||||
phy_vars_ue->dl_stats[harq_process->round]++;
|
phy_vars_ue->dl_stats[harq_process->DLround]++;
|
||||||
LOG_D(PHY,"Round %d RV idx %d\n",harq_process->round,harq_process->rvidx);
|
LOG_D(PHY,"Round %d RV idx %d\n",harq_process->DLround,harq_process->rvidx);
|
||||||
uint8_t kc;
|
uint8_t kc;
|
||||||
uint32_t Tbslbrm;// = 950984;
|
uint32_t Tbslbrm;// = 950984;
|
||||||
uint16_t nb_rb;// = 30;
|
uint16_t nb_rb;// = 30;
|
||||||
@@ -501,7 +502,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
nb_rb = harq_process->nb_rb;
|
nb_rb = harq_process->nb_rb;
|
||||||
harq_process->trials[harq_process->round]++;
|
harq_process->trials[harq_process->DLround]++;
|
||||||
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
|
uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs
|
||||||
harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
|
harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl);
|
||||||
A = harq_process->TBS;
|
A = harq_process->TBS;
|
||||||
|
|||||||
@@ -117,7 +117,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
|
|||||||
unsigned char first_symbol_flag,
|
unsigned char first_symbol_flag,
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
unsigned short nb_rb,
|
unsigned short nb_rb,
|
||||||
unsigned short round,
|
|
||||||
int32_t codeword_TB0,
|
int32_t codeword_TB0,
|
||||||
int32_t codeword_TB1,
|
int32_t codeword_TB1,
|
||||||
uint32_t len,
|
uint32_t len,
|
||||||
@@ -154,7 +153,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
|
|
||||||
unsigned char aatx=0,aarx=0;
|
unsigned char aatx=0,aarx=0;
|
||||||
|
|
||||||
unsigned short round;
|
|
||||||
int avgs = 0;// rb;
|
int avgs = 0;// rb;
|
||||||
NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
|
NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
|
||||||
|
|
||||||
@@ -278,8 +276,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
nb_rb_pdsch = dlsch0_harq->nb_rb;
|
nb_rb_pdsch = dlsch0_harq->nb_rb;
|
||||||
|
|
||||||
DevAssert(dlsch0_harq);
|
DevAssert(dlsch0_harq);
|
||||||
round = dlsch0_harq->round;
|
|
||||||
//printf("round = %d\n", round);
|
|
||||||
|
|
||||||
if (gNB_id > 2) {
|
if (gNB_id > 2) {
|
||||||
LOG_W(PHY, "In %s: Illegal gNB_id %d\n", __FUNCTION__, gNB_id);
|
LOG_W(PHY, "In %s: Illegal gNB_id %d\n", __FUNCTION__, gNB_id);
|
||||||
@@ -522,7 +519,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
rx_type, harq_pid,
|
rx_type, harq_pid,
|
||||||
gNB_id, gNB_id_i,
|
gNB_id, gNB_id_i,
|
||||||
first_symbol_flag,
|
first_symbol_flag,
|
||||||
i, nb_rb_pdsch, round,
|
i, nb_rb_pdsch,
|
||||||
codeword_TB0, codeword_TB1,
|
codeword_TB0, codeword_TB1,
|
||||||
pdsch_vars[gNB_id]->dl_valid_re[i-1],
|
pdsch_vars[gNB_id]->dl_valid_re[i-1],
|
||||||
nr_slot_rx, beamforming_mode);
|
nr_slot_rx, beamforming_mode);
|
||||||
@@ -2479,7 +2476,6 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
|
|||||||
unsigned char first_symbol_flag,
|
unsigned char first_symbol_flag,
|
||||||
unsigned char symbol,
|
unsigned char symbol,
|
||||||
unsigned short nb_rb,
|
unsigned short nb_rb,
|
||||||
unsigned short round,
|
|
||||||
int32_t codeword_TB0,
|
int32_t codeword_TB0,
|
||||||
int32_t codeword_TB1,
|
int32_t codeword_TB1,
|
||||||
uint32_t len,
|
uint32_t len,
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int freq_offset_sss = 0;
|
int freq_offset_sss = 0;
|
||||||
rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
|
ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
|
||||||
|
|
||||||
accumulated_freq_offset += freq_offset_sss;
|
accumulated_freq_offset += freq_offset_sss;
|
||||||
|
|
||||||
@@ -336,8 +336,10 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_gold_pbch(ue);
|
if (ret==0) { //we got sss channel
|
||||||
ret = nr_pbch_detection(proc, ue, 1, &phy_pdcch_config); // start pbch detection at first symbol after pss
|
nr_gold_pbch(ue);
|
||||||
|
ret = nr_pbch_detection(proc, ue, 1, &phy_pdcch_config); // start pbch detection at first symbol after pss
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
// sync at symbol ue->symbol_offset
|
// sync at symbol ue->symbol_offset
|
||||||
|
|||||||
@@ -1456,16 +1456,6 @@ uint64_t cqi2hex(uint32_t cqi);
|
|||||||
|
|
||||||
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
|
uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
|
||||||
|
|
||||||
|
|
||||||
/** \brief This routine extracts a single subband PMI from a bitmap coming from UCI or the pmi_extend function
|
|
||||||
@param N_RB_DL number of resource blocks
|
|
||||||
@param mimo_mode
|
|
||||||
@param pmi_alloc subband PMI bitmap
|
|
||||||
@param rb resource block for which to extract PMI
|
|
||||||
@returns subband PMI
|
|
||||||
*/
|
|
||||||
uint8_t get_pmi(uint8_t N_RB_DL,MIMO_mode_t mode, uint32_t pmi_alloc,uint16_t rb);
|
|
||||||
|
|
||||||
int get_nCCE_offset_l1(int *CCE_table,
|
int get_nCCE_offset_l1(int *CCE_table,
|
||||||
const unsigned char L,
|
const unsigned char L,
|
||||||
const int nCCE,
|
const int nCCE,
|
||||||
|
|||||||
@@ -181,9 +181,10 @@ typedef struct {
|
|||||||
/// Pointers to transport block segments
|
/// Pointers to transport block segments
|
||||||
uint8_t **c;
|
uint8_t **c;
|
||||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||||
|
/// Accumulates the soft bits for each round to increase decoding success (HARQ)
|
||||||
int16_t **d;
|
int16_t **d;
|
||||||
/// Index of current HARQ round for this DLSCH
|
/// Index of current HARQ round for this DLSCH
|
||||||
uint8_t round;
|
uint8_t DLround;
|
||||||
/// MCS table for this DLSCH
|
/// MCS table for this DLSCH
|
||||||
uint8_t mcs_table;
|
uint8_t mcs_table;
|
||||||
/// MCS format for this DLSCH
|
/// MCS format for this DLSCH
|
||||||
|
|||||||
@@ -381,7 +381,6 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
|||||||
int sizePss = LENGTH_PSS_NR * IQ_SIZE; /* complex value i & q signed 16 bits */
|
int sizePss = LENGTH_PSS_NR * IQ_SIZE; /* complex value i & q signed 16 bits */
|
||||||
int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
|
int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
|
||||||
int16_t *p = NULL;
|
int16_t *p = NULL;
|
||||||
int64_t *q = NULL;
|
|
||||||
|
|
||||||
AssertFatal(ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
|
AssertFatal(ofdm_symbol_size > 127, "illegal ofdm_symbol_size %d\n",ofdm_symbol_size);
|
||||||
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
|
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
|
||||||
@@ -410,17 +409,6 @@ void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = sizeof(int64_t)*(frame_parms_ue->samples_per_frame + (2*ofdm_symbol_size));
|
|
||||||
q = (int64_t*)malloc16(size);
|
|
||||||
if (q != NULL) {
|
|
||||||
pss_corr_ue[i] = q;
|
|
||||||
bzero( pss_corr_ue[i], size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_E(PHY,"Fatal memory allocation problem \n");
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_pss_nr(frame_parms_ue,i);
|
generate_pss_nr(frame_parms_ue,i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,7 +431,6 @@ void free_context_pss_nr(void)
|
|||||||
free_and_zero(primary_synchro_nr[i]);
|
free_and_zero(primary_synchro_nr[i]);
|
||||||
free_and_zero(primary_synchro_nr2[i]);
|
free_and_zero(primary_synchro_nr2[i]);
|
||||||
free_and_zero(primary_synchro_time_nr[i]);
|
free_and_zero(primary_synchro_time_nr[i]);
|
||||||
free_and_zero(pss_corr_ue[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,7 +788,6 @@ static inline double angle64(int64_t x)
|
|||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#define DOT_PRODUCT_SCALING_SHIFT (17)
|
#define DOT_PRODUCT_SCALING_SHIFT (17)
|
||||||
|
|
||||||
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||||
NR_DL_FRAME_PARMS *frame_parms,
|
NR_DL_FRAME_PARMS *frame_parms,
|
||||||
int fo_flag,
|
int fo_flag,
|
||||||
@@ -812,7 +798,7 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
unsigned int n, ar, peak_position, pss_source;
|
unsigned int n, ar, peak_position, pss_source;
|
||||||
int64_t peak_value;
|
int64_t peak_value;
|
||||||
int64_t result;
|
int64_t result;
|
||||||
int64_t avg[NUMBER_PSS_SEQUENCE];
|
int64_t avg[NUMBER_PSS_SEQUENCE]={0};
|
||||||
double ffo_est=0;
|
double ffo_est=0;
|
||||||
|
|
||||||
// performing the correlation on a frame length plus one symbol for the first of the two frame
|
// performing the correlation on a frame length plus one symbol for the first of the two frame
|
||||||
@@ -823,9 +809,8 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
else
|
else
|
||||||
length = frame_parms->samples_per_frame;
|
length = frame_parms->samples_per_frame;
|
||||||
|
|
||||||
AssertFatal(length>0,"illegal length %d\n",length);
|
|
||||||
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) AssertFatal(pss_corr_ue[i] != NULL,"pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
|
|
||||||
|
|
||||||
|
AssertFatal(length>0,"illegal length %d\n",length);
|
||||||
peak_value = 0;
|
peak_value = 0;
|
||||||
peak_position = 0;
|
peak_position = 0;
|
||||||
pss_source = 0;
|
pss_source = 0;
|
||||||
@@ -846,47 +831,41 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
|
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
|
||||||
|
|
||||||
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
|
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
|
||||||
avg[pss_index]=0;
|
|
||||||
memset(pss_corr_ue[pss_index],0,length*sizeof(int64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (n=0; n < length; n+=4) { //
|
for (n=0; n < length; n+=4) { //
|
||||||
|
|
||||||
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
|
int64_t pss_corr_ue=0;
|
||||||
|
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n]
|
||||||
|
* (ar=0..nb_ant_rx) and store the sum in temp[n]; */
|
||||||
|
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
|
||||||
|
|
||||||
if ( n < (length - frame_parms->ofdm_symbol_size)) {
|
/* perform correlation of rx data and pss sequence ie it is a dot product */
|
||||||
|
result = dot_product64((short*)primary_synchro_time_nr[pss_index],
|
||||||
|
(short*)&(rxdata[ar][n+is*frame_parms->samples_per_frame]),
|
||||||
|
frame_parms->ofdm_symbol_size,
|
||||||
|
shift);
|
||||||
|
pss_corr_ue += abs64(result);
|
||||||
|
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
|
||||||
|
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
|
||||||
|
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
|
||||||
|
//((short*)&synchro_out)[1] += ((int*) &result)[1]; /* imaginary part */
|
||||||
|
|
||||||
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; */
|
|
||||||
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
|
|
||||||
|
|
||||||
/* perform correlation of rx data and pss sequence ie it is a dot product */
|
|
||||||
result = dot_product64((short*)primary_synchro_time_nr[pss_index],
|
|
||||||
(short*)&(rxdata[ar][n+is*frame_parms->samples_per_frame]),
|
|
||||||
frame_parms->ofdm_symbol_size,
|
|
||||||
shift);
|
|
||||||
pss_corr_ue[pss_index][n] += abs64(result);
|
|
||||||
//((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
|
|
||||||
//((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
|
|
||||||
//((short*)&synchro_out)[0] += ((int*) &result)[0]; /* real part */
|
|
||||||
//((short*)&synchro_out)[1] += ((int*) &result)[1]; /* imaginary part */
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the absolute value of sync_corr[n] */
|
/* calculate the absolute value of sync_corr[n] */
|
||||||
avg[pss_index]+=pss_corr_ue[pss_index][n];
|
avg[pss_index]+=pss_corr_ue;
|
||||||
if (pss_corr_ue[pss_index][n] > peak_value) {
|
if (pss_corr_ue > peak_value) {
|
||||||
peak_value = pss_corr_ue[pss_index][n];
|
peak_value = pss_corr_ue;
|
||||||
peak_position = n;
|
peak_position = n;
|
||||||
pss_source = pss_index;
|
pss_source = pss_index;
|
||||||
|
|
||||||
#ifdef DEBUG_PSS_NR
|
#ifdef DEBUG_PSS_NR
|
||||||
printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[pss_index][n]);
|
printf("pss_index %d: n %6u peak_value %15llu\n", pss_index, n, (unsigned long long)pss_corr_ue[n]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fo_flag){
|
if (fo_flag){
|
||||||
|
|
||||||
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
|
// fractional frequency offset computation according to Cross-correlation Synchronization Algorithm Using PSS
|
||||||
@@ -922,7 +901,8 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
// computing absolute value of frequency offset
|
// computing absolute value of frequency offset
|
||||||
*f_off = ffo_est*frame_parms->subcarrier_spacing;
|
*f_off = ffo_est*frame_parms->subcarrier_spacing;
|
||||||
|
|
||||||
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) avg[pss_index]/=(length/4);
|
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++)
|
||||||
|
avg[pss_index]/=(length/4);
|
||||||
|
|
||||||
*eNB_id = pss_source;
|
*eNB_id = pss_source;
|
||||||
|
|
||||||
@@ -937,9 +917,6 @@ int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
|||||||
static int debug_cnt = 0;
|
static int debug_cnt = 0;
|
||||||
|
|
||||||
if (debug_cnt == 0) {
|
if (debug_cnt == 0) {
|
||||||
LOG_M("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,6);
|
|
||||||
LOG_M("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,6);
|
|
||||||
LOG_M("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,6);
|
|
||||||
if (is)
|
if (is)
|
||||||
LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1);
|
LOG_M("rxdata1.m","rxd0",rxdata[frame_parms->samples_per_frame],length,1,1);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -563,6 +563,10 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
|
|||||||
|
|
||||||
int re = 0;
|
int re = 0;
|
||||||
int im = 0;
|
int im = 0;
|
||||||
|
if (Nid1 == N_ID_1_NUMBER) {
|
||||||
|
LOG_I(PHY,"Failled to detect SSS after PSS\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||||
for(i = 0; i<LENGTH_SSS_NR; i++) {
|
for(i = 0; i<LENGTH_SSS_NR; i++) {
|
||||||
re += d[i]*sss[2*i];
|
re += d[i]*sss[2*i];
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#include "costable.h"
|
#include "costable.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
unsigned int angle(struct complex16 perror)
|
unsigned int angle(c16_t perror)
|
||||||
{
|
{
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ main ()
|
|||||||
short output[256] __attribute__((aligned(16)));
|
short output[256] __attribute__((aligned(16)));
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
struct complex16 alpha;
|
c16_t alpha;
|
||||||
|
|
||||||
Zero_Buffer(output,256*2);
|
Zero_Buffer(output,256*2);
|
||||||
|
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ main ()
|
|||||||
short output[256] __attribute__((aligned(16)));
|
short output[256] __attribute__((aligned(16)));
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
struct complex16 alpha;
|
c16_t alpha;
|
||||||
|
|
||||||
Zero_Buffer(output,256*2);
|
Zero_Buffer(output,256*2);
|
||||||
|
|
||||||
|
|||||||
@@ -305,15 +305,15 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
openair0_device_load(&rfdevice,&openair0_cfg);
|
openair0_device_load(&rfdevice,&openair0_cfg);
|
||||||
|
|
||||||
void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
|
void ** samplesRx = (void **)malloc16(antennas* sizeof(c16_t *) );
|
||||||
void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
|
void ** samplesTx = (void **)malloc16(antennas* sizeof(c16_t *) );
|
||||||
|
|
||||||
int fd=open(getenv("rftestInputFile"),O_RDONLY);
|
int fd=open(getenv("rftestInputFile"),O_RDONLY);
|
||||||
AssertFatal(fd>=0,"%s",strerror(errno));
|
AssertFatal(fd>=0,"%s",strerror(errno));
|
||||||
|
|
||||||
for (int i=0; i<antennas; i++) {
|
for (int i=0; i<antennas; i++) {
|
||||||
samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
|
samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(c16_t) );
|
||||||
samplesTx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) );
|
samplesTx[i] = (int32_t *)malloc16_clear( DFT*sizeof(c16_t) );
|
||||||
}
|
}
|
||||||
|
|
||||||
CalibrationInitScope(samplesRx, &rfdevice);
|
CalibrationInitScope(samplesRx, &rfdevice);
|
||||||
@@ -322,7 +322,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
while(!oai_exit) {
|
while(!oai_exit) {
|
||||||
for (int i=0; i<antennas; i++)
|
for (int i=0; i<antennas; i++)
|
||||||
read(fd, samplesTx[i], DFT*sizeof(struct complex16));
|
read(fd, samplesTx[i], DFT*sizeof(c16_t));
|
||||||
int readBlockSize = rfdevice.trx_read_func(&rfdevice,
|
int readBlockSize = rfdevice.trx_read_func(&rfdevice,
|
||||||
×tamp,
|
×tamp,
|
||||||
samplesRx,
|
samplesRx,
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
||||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.openairinterface.org/?page_id=698
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*-------------------------------------------------------------------------------
|
|
||||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
||||||
* contact@openairinterface.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dB_routines.h
|
|
||||||
*
|
|
||||||
* Created on: Nov 12, 2013
|
|
||||||
* Author: winckel
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DB_ROUTINES_H_
|
|
||||||
#define DB_ROUTINES_H_
|
|
||||||
|
|
||||||
int16_t dB_fixed_times10(uint32_t x);
|
|
||||||
int16_t dB_fixed_x10(uint32_t x);
|
|
||||||
|
|
||||||
#endif /* DB_ROUTINES_H_ */
|
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
|
const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
|
||||||
const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
|
const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
|
||||||
|
|
||||||
typedef struct complex16 scopeSample_t;
|
typedef c16_t scopeSample_t;
|
||||||
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
|
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -39,26 +39,33 @@ extern "C" {
|
|||||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||||
|
|
||||||
struct complexd {
|
typedef struct complexd {
|
||||||
double r;
|
double r;
|
||||||
double i;
|
double i;
|
||||||
};
|
} cd_t;
|
||||||
|
|
||||||
struct complexf {
|
typedef struct complexf {
|
||||||
float r;
|
float r;
|
||||||
float i;
|
float i;
|
||||||
};
|
} cf_t;
|
||||||
|
|
||||||
struct complex16 {
|
typedef struct complex16 {
|
||||||
int16_t r;
|
int16_t r;
|
||||||
int16_t i;
|
int16_t i;
|
||||||
};
|
} c16_t;
|
||||||
|
|
||||||
struct complex32 {
|
typedef struct complex32 {
|
||||||
int32_t r;
|
int32_t r;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
};
|
} c32_t;
|
||||||
|
|
||||||
|
typedef struct complex64 {
|
||||||
|
int64_t r;
|
||||||
|
int64_t i;
|
||||||
|
} c64_t;
|
||||||
|
|
||||||
|
#define squaredMod(a) ((a).r*(a).r+(a).i*(a).i)
|
||||||
|
#define csum(res, i1, i2) (res).r=(i1).r+(i2).r ; (res).i=(i1).i+(i2).i
|
||||||
//cmult_sv.h
|
//cmult_sv.h
|
||||||
|
|
||||||
/*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
|
/*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
|
|
||||||
/*used for the resource mapping*/
|
/*used for the resource mapping*/
|
||||||
#define NR_MAX_PDCCH_DMRS_LENGTH 576 // 16(L)*2(QPSK)*3(3 DMRS symbs per REG)*6(REG per CCE)
|
#define NR_MAX_PDCCH_DMRS_LENGTH 576 // 16(L)*2(QPSK)*3(3 DMRS symbs per REG)*6(REG per CCE)
|
||||||
|
#define NR_MAX_PDCCH_SIZE 8192 // It seems it is the max polar coded block size
|
||||||
|
|
||||||
#define NR_MAX_DCI_PAYLOAD_SIZE 64
|
#define NR_MAX_DCI_PAYLOAD_SIZE 64
|
||||||
#define NR_MAX_DCI_SIZE 1728 //16(L)*2(QPSK)*9(12 RE per REG - 3(DMRS))*6(REG per CCE)
|
#define NR_MAX_DCI_SIZE 1728 //16(L)*2(QPSK)*9(12 RE per REG - 3(DMRS))*6(REG per CCE)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <openair1/SCHED/sched_common_extern.h>
|
||||||
|
|
||||||
|
|
||||||
// This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25
|
// This is the formula from Section 5.1.1.1 in 36.213 100*10*log10((2^(MPR*Ks)-1)), where MPR is in the range [0,6] and Ks=1.25
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
|
|||||||
{
|
{
|
||||||
dl_harq->status = SCH_IDLE;
|
dl_harq->status = SCH_IDLE;
|
||||||
dl_harq->first_rx = 1;
|
dl_harq->first_rx = 1;
|
||||||
dl_harq->round = 0;
|
dl_harq->DLround = 0;
|
||||||
dl_harq->DCINdi = 1;
|
dl_harq->DCINdi = 1;
|
||||||
dl_harq->ack = DL_ACKNACK_NO_SET;
|
dl_harq->ack = DL_ACKNACK_NO_SET;
|
||||||
}
|
}
|
||||||
@@ -334,60 +334,38 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int
|
|||||||
if (rnti_type == _SI_RNTI_ ||
|
if (rnti_type == _SI_RNTI_ ||
|
||||||
rnti_type == _P_RNTI_ ||
|
rnti_type == _P_RNTI_ ||
|
||||||
rnti_type == _RA_RNTI_) {
|
rnti_type == _RA_RNTI_) {
|
||||||
dl_harq->round = 0;
|
dl_harq->DLround = 0;
|
||||||
dl_harq->status = ACTIVE;
|
dl_harq->status = ACTIVE;
|
||||||
dl_harq->first_rx = 1;
|
dl_harq->first_rx = 1;
|
||||||
}
|
} else {
|
||||||
else{
|
LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n",
|
||||||
switch(rv){
|
dl_harq, harq_pid, rv, ndi, rnti_type, dl_harq->DCINdi != ndi ? "yes":"no");
|
||||||
case 0:
|
AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv);
|
||||||
dl_harq->round = 0;
|
|
||||||
dl_harq->status = ACTIVE;
|
if (ndi!=dl_harq->DCINdi) {
|
||||||
dl_harq->first_rx = 1;
|
if (dl_harq->ack == DL_NACK)
|
||||||
if (dl_harq->DCINdi == ndi)
|
LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid);
|
||||||
LOG_E(PHY,"Warning! rv %d indicates new transmission but new ndi %d is the same as old ndi %d\n",rv,ndi,dl_harq->DCINdi);
|
else
|
||||||
dl_harq->DCINdi = ndi;
|
LOG_D(PHY,"Starting new transmission on a harq pid (%d)\n", harq_pid);
|
||||||
break;
|
} else {
|
||||||
case 1:
|
if (dl_harq->ack != DL_NACK)
|
||||||
dl_harq->round = 3;
|
LOG_D(PHY,"gNB asked for retransmission even if we sent ACK\n");
|
||||||
dl_harq->status = ACTIVE;
|
else
|
||||||
dl_harq->first_rx = 0;
|
LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv);
|
||||||
if (dl_harq->DCINdi != ndi) {
|
|
||||||
LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
|
|
||||||
dl_harq->first_rx = 1;
|
|
||||||
dl_harq->DCINdi = ndi;
|
|
||||||
}
|
|
||||||
else if (dl_harq->ack == 1)
|
|
||||||
dl_harq->status = SCH_IDLE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
dl_harq->round = 1;
|
|
||||||
dl_harq->status = ACTIVE;
|
|
||||||
dl_harq->first_rx = 0;
|
|
||||||
if (dl_harq->DCINdi != ndi) {
|
|
||||||
LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
|
|
||||||
dl_harq->first_rx = 1;
|
|
||||||
dl_harq->DCINdi = ndi;
|
|
||||||
}
|
|
||||||
else if (dl_harq->ack == 1)
|
|
||||||
dl_harq->status = SCH_IDLE;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
dl_harq->round = 2;
|
|
||||||
dl_harq->status = ACTIVE;
|
|
||||||
dl_harq->first_rx = 0;
|
|
||||||
if (dl_harq->DCINdi != ndi) {
|
|
||||||
LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
|
|
||||||
dl_harq->first_rx = 1;
|
|
||||||
dl_harq->DCINdi = ndi;
|
|
||||||
}
|
|
||||||
else if (dl_harq->ack == 1)
|
|
||||||
dl_harq->status = SCH_IDLE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AssertFatal(1==0,"Invalid value for rv %d\n",rv);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ndi!=dl_harq->DCINdi) {
|
||||||
|
dl_harq->first_rx = true;
|
||||||
|
dl_harq->DLround = 0;
|
||||||
|
} else {
|
||||||
|
dl_harq->first_rx = false;
|
||||||
|
dl_harq->DLround++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl_harq->status = ACTIVE;
|
||||||
|
|
||||||
|
dl_harq->DCINdi = ndi;
|
||||||
|
//dl_harq->status = SCH_IDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
|
|||||||
start_meas(&ue->dlsch_rx_pdcch_stats);
|
start_meas(&ue->dlsch_rx_pdcch_stats);
|
||||||
|
|
||||||
/// PDCCH/DCI e-sequence (input to rate matching).
|
/// PDCCH/DCI e-sequence (input to rate matching).
|
||||||
int32_t pdcch_e_rx_size = 2*4*100*12;
|
int32_t pdcch_e_rx_size = NR_MAX_PDCCH_SIZE;
|
||||||
int16_t pdcch_e_rx[pdcch_e_rx_size];
|
int16_t pdcch_e_rx[pdcch_e_rx_size];
|
||||||
|
|
||||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
|
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
|
||||||
|
|||||||
@@ -478,14 +478,11 @@ int main(int argc, char **argv)
|
|||||||
harq_process->n_dmrs_cdm_groups = 1;
|
harq_process->n_dmrs_cdm_groups = 1;
|
||||||
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
|
printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch);
|
||||||
|
|
||||||
unsigned char *test_input;
|
unsigned char *test_input=dlsch->harq_process.pdu;
|
||||||
test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8);
|
|
||||||
//unsigned char test_input[TBS / 8] __attribute__ ((aligned(16)));
|
//unsigned char test_input[TBS / 8] __attribute__ ((aligned(16)));
|
||||||
for (i = 0; i < TBS / 8; i++)
|
for (i = 0; i < TBS / 8; i++)
|
||||||
test_input[i] = (unsigned char) rand();
|
test_input[i] = (unsigned char) rand();
|
||||||
|
|
||||||
//estimated_output = harq_process->b;
|
|
||||||
|
|
||||||
#ifdef DEBUG_NR_DLSCHSIM
|
#ifdef DEBUG_NR_DLSCHSIM
|
||||||
for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]);
|
for (i = 0; i < TBS / 8; i++) printf("test_input[i]=%hhu \n",test_input[i]);
|
||||||
#endif
|
#endif
|
||||||
@@ -498,7 +495,7 @@ int main(int argc, char **argv)
|
|||||||
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
|
unsigned char output[rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS] __attribute__((aligned(32)));
|
||||||
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
bzero(output,rel15->rbSize * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS);
|
||||||
if (input_fd == NULL) {
|
if (input_fd == NULL) {
|
||||||
nr_dlsch_encoding(gNB, test_input, frame, slot, dlsch, frame_parms,output,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
nr_dlsch_encoding(gNB, frame, slot, &dlsch->harq_process, frame_parms,output,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
for (SNR = snr0; SNR < snr1; SNR += snr_step) {
|
||||||
@@ -618,8 +615,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
free(test_input);
|
|
||||||
|
|
||||||
free_channel_desc_scm(gNB2UE);
|
free_channel_desc_scm(gNB2UE);
|
||||||
|
|
||||||
reset_DLSCH_struct(gNB, &msgDataTx);
|
reset_DLSCH_struct(gNB, &msgDataTx);
|
||||||
|
|||||||
@@ -1089,7 +1089,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
UE_harq_process->ack = 0;
|
UE_harq_process->ack = 0;
|
||||||
round = 0;
|
round = 0;
|
||||||
UE_harq_process->round = round;
|
UE_harq_process->DLround = round;
|
||||||
UE_harq_process->first_rx = 1;
|
UE_harq_process->first_rx = 1;
|
||||||
|
|
||||||
while ((round<num_rounds) && (UE_harq_process->ack==0)) {
|
while ((round<num_rounds) && (UE_harq_process->ack==0)) {
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if (n_trials==1) printf("txlev %d (%f dB), offset %d, sigma2 %f ( %f dB)\n",txlev,10*log10(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size,sigma2,sigma2_dB);
|
if (n_trials==1) printf("txlev %d (%f dB), offset %d, sigma2 %f ( %f dB)\n",txlev,10*log10(txlev),startingSymbolIndex*frame_parms->ofdm_symbol_size,sigma2,sigma2_dB);
|
||||||
|
|
||||||
struct complex16 **rxdataF = (struct complex16 **)gNB->common_vars.rxdataF;
|
c16_t **rxdataF = (struct complex16 **)gNB->common_vars.rxdataF;
|
||||||
for (int symb=0; symb<gNB->frame_parms.symbols_per_slot;symb++) {
|
for (int symb=0; symb<gNB->frame_parms.symbols_per_slot;symb++) {
|
||||||
if (symb<startingSymbolIndex || symb >= startingSymbolIndex+nrofSymbols) {
|
if (symb<startingSymbolIndex || symb >= startingSymbolIndex+nrofSymbols) {
|
||||||
int i0 = symb*gNB->frame_parms.ofdm_symbol_size;
|
int i0 = symb*gNB->frame_parms.ofdm_symbol_size;
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int Nid_cell[] = {(3*0+0)};
|
int Nid_cell[] = {(3*0+0)};
|
||||||
VOID_PARAMETER argc;
|
VOID_PARAMETER argc;
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int Nid_cell[] = {(3*0+0)};
|
int Nid_cell[] = {(3*0+0)};
|
||||||
VOID_PARAMETER argc;
|
VOID_PARAMETER argc;
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int decoded_pbch = -1;
|
int decoded_pbch = -1;
|
||||||
int Nid1, Nid2;
|
int Nid1, Nid2;
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint16_t Nid_cell=123;
|
uint16_t Nid_cell=123;
|
||||||
uint8_t frame_type=FDD;
|
uint8_t frame_type=FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag=NORMAL;
|
lte_prefix_type_t extended_prefix_flag=NORMAL;
|
||||||
const char *name_test = "PSS NR";
|
const char *name_test = "PSS NR";
|
||||||
test_t test = { name_test, 0, 0, 0, 0};
|
test_t test = { name_test, 0, 0, 0, 0};
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ void undefined_function(const char *function) {
|
|||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
|
int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
|
||||||
unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell, uint8_t N_RB_DL) {
|
unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell, int N_RB_DL) {
|
||||||
(void) transmission_mode;
|
(void) transmission_mode;
|
||||||
NR_DL_FRAME_PARMS *frame_parms;
|
NR_DL_FRAME_PARMS *frame_parms;
|
||||||
int log_level = OAILOG_TRACE;
|
int log_level = OAILOG_TRACE;
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ int set_pss_in_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int p
|
|||||||
|
|
||||||
int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
|
int init_test(unsigned char N_tx, unsigned char N_rx, unsigned char transmission_mode,
|
||||||
unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell,
|
unsigned char extended_prefix_flag, uint8_t frame_type, uint16_t Nid_cell,
|
||||||
uint8_t N_RB_DL);
|
int N_RB_DL);
|
||||||
|
|
||||||
void display_test_configuration_pss(int position, int pss_sequence_number);
|
void display_test_configuration_pss(int position, int pss_sequence_number);
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ int main(int argc, char *argv[]) {
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=106;
|
int N_RB_DL=106;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int Nid_cell[] = {(3*1+3)};
|
int Nid_cell[] = {(3*1+3)};
|
||||||
VOID_PARAMETER argc;
|
VOID_PARAMETER argc;
|
||||||
|
|||||||
@@ -1239,7 +1239,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int Nid_cell[] = {(3*1+3)};
|
int Nid_cell[] = {(3*1+3)};
|
||||||
VOID_PARAMETER argc;
|
VOID_PARAMETER argc;
|
||||||
|
|||||||
@@ -442,7 +442,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int Nid_cell[] = {(3*0+0)};
|
int Nid_cell[] = {(3*0+0)};
|
||||||
VOID_PARAMETER argc;
|
VOID_PARAMETER argc;
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ int main(int argc, char *argv[])
|
|||||||
uint8_t nb_antennas_tx = 1;
|
uint8_t nb_antennas_tx = 1;
|
||||||
uint8_t nb_antennas_rx = 1;
|
uint8_t nb_antennas_rx = 1;
|
||||||
uint8_t frame_type = FDD;
|
uint8_t frame_type = FDD;
|
||||||
uint8_t N_RB_DL=100;
|
int N_RB_DL=100;
|
||||||
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
lte_prefix_type_t extended_prefix_flag = NORMAL;
|
||||||
int phase;
|
int phase;
|
||||||
int Nid1, Nid2;
|
int Nid1, Nid2;
|
||||||
|
|||||||
@@ -58,11 +58,6 @@ extern int l2_init_eNB(void);
|
|||||||
extern void mac_top_init_eNB(void);
|
extern void mac_top_init_eNB(void);
|
||||||
extern void mac_init_cell_params(int Mod_idP,int CC_idP);
|
extern void mac_init_cell_params(int Mod_idP,int CC_idP);
|
||||||
|
|
||||||
|
|
||||||
int32_t **rxdata;
|
|
||||||
int32_t **txdata;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct eutra_bandentry_s {
|
typedef struct eutra_bandentry_s {
|
||||||
int16_t band;
|
int16_t band;
|
||||||
uint32_t ul_min;
|
uint32_t ul_min;
|
||||||
|
|||||||
@@ -107,11 +107,10 @@ typedef struct {
|
|||||||
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT;
|
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_SHORT;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t LCID: 6; // octet 1 [5:0]
|
uint8_t LCID: 6;
|
||||||
uint8_t F: 1; // octet 1 [6]
|
uint8_t F: 1;
|
||||||
uint8_t R: 1; // octet 1 [7]
|
uint8_t R: 1;
|
||||||
uint8_t L1: 8; // octet 2 [7:0]
|
uint16_t L: 16;
|
||||||
uint8_t L2: 8; // octet 3 [7:0]
|
|
||||||
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG;
|
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_LONG;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -119,6 +118,23 @@ typedef struct {
|
|||||||
uint8_t R: 2; // octet 1 [7:6]
|
uint8_t R: 2; // octet 1 [7:6]
|
||||||
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
|
} __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED;
|
||||||
|
|
||||||
|
static inline int get_mac_len(uint8_t* pdu, int pdu_len, uint16_t *mac_ce_len, uint16_t *mac_subheader_len) {
|
||||||
|
if ( pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
||||||
|
return false;
|
||||||
|
NR_MAC_SUBHEADER_SHORT *s = (NR_MAC_SUBHEADER_SHORT*) pdu;
|
||||||
|
NR_MAC_SUBHEADER_LONG *l = (NR_MAC_SUBHEADER_LONG*) pdu;
|
||||||
|
if (s->F && pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
||||||
|
return false;
|
||||||
|
if (s->F) {
|
||||||
|
*mac_subheader_len = sizeof(*l);
|
||||||
|
*mac_ce_len = ntohs(l->L);
|
||||||
|
} else {
|
||||||
|
*mac_subheader_len = sizeof(*s);
|
||||||
|
*mac_ce_len = s->L;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// BSR MAC CEs
|
// BSR MAC CEs
|
||||||
// TS 38.321 ch. 6.1.3.1
|
// TS 38.321 ch. 6.1.3.1
|
||||||
// Short BSR for a specific logical channel group ID
|
// Short BSR for a specific logical channel group ID
|
||||||
|
|||||||
@@ -2137,6 +2137,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
|
|||||||
pucch->is_common = current_harq->is_common;
|
pucch->is_common = current_harq->is_common;
|
||||||
current_harq->active = false;
|
current_harq->active = false;
|
||||||
current_harq->ack_received = false;
|
current_harq->ack_received = false;
|
||||||
|
LOG_D(PHY,"%4d.%2d Sent %d ack on harq pid %d\n", frame, slot, current_harq->ack, dl_harq_pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3370,10 +3371,6 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment,
|
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment,
|
||||||
int pdu_id){
|
int pdu_id){
|
||||||
|
|
||||||
uint8_t rx_lcid;
|
|
||||||
uint16_t mac_ce_len;
|
|
||||||
uint16_t mac_subheader_len;
|
|
||||||
uint16_t mac_sdu_len;
|
|
||||||
module_id_t module_idP = dl_info->module_id;
|
module_id_t module_idP = dl_info->module_id;
|
||||||
frame_t frameP = dl_info->frame;
|
frame_t frameP = dl_info->frame;
|
||||||
int slot = dl_info->slot;
|
int slot = dl_info->slot;
|
||||||
@@ -3392,139 +3389,100 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus);
|
LOG_D(MAC, "In %s [%d.%d]: processing PDU %d (with length %d) of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, pdu_len, dl_info->rx_ind->number_pdus);
|
||||||
|
|
||||||
while (!done && pdu_len > 0){
|
while (!done && pdu_len > 0){
|
||||||
mac_ce_len = 0x0000;
|
uint16_t mac_len = 0x0000;
|
||||||
mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
|
uint16_t mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct
|
||||||
mac_sdu_len = 0x0000;
|
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||||
rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
|
||||||
|
|
||||||
LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len);
|
LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len);
|
||||||
|
bool ret;
|
||||||
switch(rx_lcid){
|
switch(rx_lcid){
|
||||||
// MAC CE
|
// MAC CE
|
||||||
case DL_SCH_LCID_CCCH:
|
case DL_SCH_LCID_CCCH:
|
||||||
// MSG4 RRC Setup 38.331
|
// MSG4 RRC Setup 38.331
|
||||||
// variable length
|
// variable length
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
ret=get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len);
|
||||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
|
AssertFatal(ret, "The mac_len (%d) has an invalid size. PDU len = %d! \n",
|
||||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
|
mac_len, pdu_len);
|
||||||
mac_subheader_len = 3;
|
|
||||||
} else {
|
|
||||||
mac_sdu_len = ((NR_MAC_SUBHEADER_SHORT *) pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssertFatal(pdu_len > mac_sdu_len, "The mac_sdu_len (%d) has an invalid size. PDU len = %d! \n",
|
|
||||||
mac_sdu_len, pdu_len);
|
|
||||||
|
|
||||||
// Check if it is a valid CCCH message, we get all 00's messages very often
|
// Check if it is a valid CCCH message, we get all 00's messages very often
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
|
for(i=0; i<(mac_subheader_len+mac_len); i++) {
|
||||||
if(pduP[i] != 0) {
|
if(pduP[i] != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == (mac_subheader_len+mac_sdu_len)) {
|
if (i == (mac_subheader_len+mac_len)) {
|
||||||
LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len);
|
LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len);
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mac_sdu_len > 0 ) {
|
if ( mac_len > 0 ) {
|
||||||
LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len);
|
LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_len);
|
||||||
for (int i = 0; i < mac_subheader_len; i++) {
|
for (int i = 0; i < mac_subheader_len; i++) {
|
||||||
LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]);
|
LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mac_sdu_len; i++) {
|
for (int i = 0; i < mac_len; i++) {
|
||||||
LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]);
|
LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]);
|
||||||
}
|
}
|
||||||
nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len);
|
nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_len);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
|
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
|
||||||
|
case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL:
|
||||||
|
case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT:
|
||||||
|
case DL_SCH_LCID_SP_SRS_ACTIVATION:
|
||||||
|
|
||||||
// 38.321 Ch6.1.3.14
|
// 38.321 Ch6.1.3.14
|
||||||
// varialbe length
|
// varialbe length
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len);
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL:
|
|
||||||
// 38.321 Ch6.1.3.13
|
|
||||||
// varialbe length
|
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT:
|
|
||||||
// 38.321 Ch6.1.3.12
|
|
||||||
// varialbe length
|
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DL_SCH_LCID_SP_SRS_ACTIVATION:
|
|
||||||
// 38.321 Ch6.1.3.17
|
|
||||||
// varialbe length
|
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DL_SCH_LCID_RECOMMENDED_BITRATE:
|
case DL_SCH_LCID_RECOMMENDED_BITRATE:
|
||||||
// 38.321 Ch6.1.3.20
|
// 38.321 Ch6.1.3.20
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT:
|
case DL_SCH_LCID_SP_ZP_CSI_RS_RES_SET_ACT:
|
||||||
// 38.321 Ch6.1.3.19
|
// 38.321 Ch6.1.3.19
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT:
|
case DL_SCH_LCID_PUCCH_SPATIAL_RELATION_ACT:
|
||||||
// 38.321 Ch6.1.3.18
|
// 38.321 Ch6.1.3.18
|
||||||
mac_ce_len = 3;
|
mac_len = 3;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT:
|
case DL_SCH_LCID_SP_CSI_REP_PUCCH_ACT:
|
||||||
// 38.321 Ch6.1.3.16
|
// 38.321 Ch6.1.3.16
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH:
|
case DL_SCH_LCID_TCI_STATE_IND_UE_SPEC_PDCCH:
|
||||||
// 38.321 Ch6.1.3.15
|
// 38.321 Ch6.1.3.15
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_DUPLICATION_ACT:
|
case DL_SCH_LCID_DUPLICATION_ACT:
|
||||||
// 38.321 Ch6.1.3.11
|
// 38.321 Ch6.1.3.11
|
||||||
mac_ce_len = 1;
|
mac_len = 1;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_SCell_ACT_4_OCT:
|
case DL_SCH_LCID_SCell_ACT_4_OCT:
|
||||||
// 38.321 Ch6.1.3.10
|
// 38.321 Ch6.1.3.10
|
||||||
mac_ce_len = 4;
|
mac_len = 4;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_SCell_ACT_1_OCT:
|
case DL_SCH_LCID_SCell_ACT_1_OCT:
|
||||||
// 38.321 Ch6.1.3.10
|
// 38.321 Ch6.1.3.10
|
||||||
mac_ce_len = 1;
|
mac_len = 1;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_L_DRX:
|
case DL_SCH_LCID_L_DRX:
|
||||||
// 38.321 Ch6.1.3.6
|
// 38.321 Ch6.1.3.6
|
||||||
// fixed length but not yet specify.
|
// fixed length but not yet specify.
|
||||||
mac_ce_len = 0;
|
mac_len = 0;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_DRX:
|
case DL_SCH_LCID_DRX:
|
||||||
// 38.321 Ch6.1.3.5
|
// 38.321 Ch6.1.3.5
|
||||||
// fixed length but not yet specify.
|
// fixed length but not yet specify.
|
||||||
mac_ce_len = 0;
|
mac_len = 0;
|
||||||
break;
|
break;
|
||||||
case DL_SCH_LCID_TA_COMMAND:
|
case DL_SCH_LCID_TA_COMMAND:
|
||||||
// 38.321 Ch6.1.3.4
|
// 38.321 Ch6.1.3.4
|
||||||
mac_ce_len = 1;
|
mac_len = 1;
|
||||||
|
|
||||||
/*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
/*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND;
|
||||||
uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/
|
uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/
|
||||||
@@ -3546,14 +3504,14 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
// Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
|
// Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
|
||||||
// MAC Header: 1 byte (R/R/LCID)
|
// MAC Header: 1 byte (R/R/LCID)
|
||||||
// MAC SDU: 6 bytes (UE Contention Resolution Identity)
|
// MAC SDU: 6 bytes (UE Contention Resolution Identity)
|
||||||
mac_ce_len = 6;
|
mac_len = 6;
|
||||||
|
|
||||||
if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) {
|
if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) {
|
||||||
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
|
LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
|
||||||
module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
|
module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
|
||||||
|
|
||||||
bool ra_success = true;
|
bool ra_success = true;
|
||||||
for(int i = 0; i<mac_ce_len; i++) {
|
for(int i = 0; i<mac_len; i++) {
|
||||||
if(ra->cont_res_id[i] != pduP[i+1]) {
|
if(ra->cont_res_id[i] != pduP[i+1]) {
|
||||||
ra_success = false;
|
ra_success = false;
|
||||||
break;
|
break;
|
||||||
@@ -3581,25 +3539,9 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
// check if LCID is valid at current time.
|
// check if LCID is valid at current time.
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// check if LCID is valid at current time.
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
return;
|
||||||
return;
|
LOG_D(NR_MAC, "[UE %d] %4d.%2d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, slot, rx_lcid, gNB_index, mac_len);
|
||||||
NR_MAC_SUBHEADER_SHORT *shs = (NR_MAC_SUBHEADER_SHORT *)pduP;
|
|
||||||
if (shs->F) {
|
|
||||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
|
||||||
return;
|
|
||||||
NR_MAC_SUBHEADER_LONG *shl = (NR_MAC_SUBHEADER_LONG *)pduP;
|
|
||||||
mac_sdu_len = ((uint16_t)(shl->L1 & 0x7f) << 8) | (uint16_t)(shl->L2 & 0xff);
|
|
||||||
} else {
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
|
||||||
return;
|
|
||||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len);
|
|
||||||
|
|
||||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||||
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
|
||||||
@@ -3620,7 +3562,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
MBMS_FLAG_NO,
|
MBMS_FLAG_NO,
|
||||||
rx_lcid,
|
rx_lcid,
|
||||||
(char *) (pduP + mac_subheader_len),
|
(char *) (pduP + mac_subheader_len),
|
||||||
mac_sdu_len,
|
mac_len,
|
||||||
1,
|
1,
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
@@ -3631,8 +3573,8 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
pduP += ( mac_subheader_len + mac_len );
|
||||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
pdu_len -= ( mac_subheader_len + mac_len );
|
||||||
if (pdu_len < 0)
|
if (pdu_len < 0)
|
||||||
LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len);
|
LOG_E(MAC, "[UE %d][%d.%d] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", module_idP, frameP, slot, pdu_len);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3143,8 +3143,7 @@ uint8_t nr_ue_get_sdu(module_id_t module_idP,
|
|||||||
header->R = 0;
|
header->R = 0;
|
||||||
header->F = 1;
|
header->F = 1;
|
||||||
header->LCID = lcid;
|
header->LCID = lcid;
|
||||||
header->L1 = ((unsigned short) sdu_length >> 8) & 0x7f;
|
header->L = htons(sdu_length);
|
||||||
header->L2 = (unsigned short) sdu_length & 0xff;
|
|
||||||
|
|
||||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||||
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
|
LOG_I(NR_MAC, "In %s: dumping MAC sub-header with length %d: \n", __FUNCTION__, sh_size);
|
||||||
|
|||||||
@@ -1622,7 +1622,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
|||||||
harq->feedback_slot = pucch->ul_slot;
|
harq->feedback_slot = pucch->ul_slot;
|
||||||
harq->feedback_frame = pucch->frame;
|
harq->feedback_frame = pucch->frame;
|
||||||
|
|
||||||
uint8_t *buf = (uint8_t *) harq->tb;
|
uint8_t *buf = (uint8_t *) harq->transportBlock;
|
||||||
// Bytes to be transmitted
|
// Bytes to be transmitted
|
||||||
if (harq->round == 0) {
|
if (harq->round == 0) {
|
||||||
if (ra->msg3_dcch_dtch) {
|
if (ra->msg3_dcch_dtch) {
|
||||||
@@ -1870,11 +1870,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
|||||||
}
|
}
|
||||||
|
|
||||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
|
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
|
||||||
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->tb, harq->tb_size));
|
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size));
|
||||||
|
|
||||||
// DL TX request
|
// DL TX request
|
||||||
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
||||||
memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size);
|
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size);
|
||||||
tx_req->PDU_length = harq->tb_size;
|
tx_req->PDU_length = harq->tb_size;
|
||||||
tx_req->PDU_index = pduindex;
|
tx_req->PDU_index = pduindex;
|
||||||
tx_req->num_TLV = 1;
|
tx_req->num_TLV = 1;
|
||||||
|
|||||||
@@ -53,10 +53,10 @@
|
|||||||
#define WORD 32
|
#define WORD 32
|
||||||
//#define SIZE_OF_POINTER sizeof (void *)
|
//#define SIZE_OF_POINTER sizeof (void *)
|
||||||
|
|
||||||
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp)
|
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp) {
|
||||||
{
|
|
||||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||||
const int bwp_id = bwp ? bwp->bwp_Id : 0;
|
const int bwp_id = bwp ? bwp->bwp_Id : 0;
|
||||||
|
|
||||||
if (nrmac->preferred_dl_tda[bwp_id])
|
if (nrmac->preferred_dl_tda[bwp_id])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -65,27 +65,27 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
|||||||
lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
|
lte_frame_type_t frame_type = nrmac->common_channels->frame_type;
|
||||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||||
|
|
||||||
int symb_dlMixed = 0;
|
int symb_dlMixed = 0;
|
||||||
int nr_mix_slots = 0;
|
int nr_mix_slots = 0;
|
||||||
int nr_slots_period = n;
|
int nr_slots_period = n;
|
||||||
|
|
||||||
if (tdd) {
|
if (tdd) {
|
||||||
symb_dlMixed = (1 << tdd->nrofDownlinkSymbols) - 1;
|
symb_dlMixed = (1 << tdd->nrofDownlinkSymbols) - 1;
|
||||||
nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
|
nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
|
||||||
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
// if TDD configuration is not present and the band is not FDD, it means it is a dynamic TDD configuration
|
// if TDD configuration is not present and the band is not FDD, it means it is a dynamic TDD configuration
|
||||||
AssertFatal(nrmac->common_channels->frame_type == FDD,"Dynamic TDD not handled yet\n");
|
AssertFatal(nrmac->common_channels->frame_type == FDD,"Dynamic TDD not handled yet\n");
|
||||||
|
|
||||||
int target_ss;
|
int target_ss;
|
||||||
|
|
||||||
if (bwp) {
|
if (bwp) {
|
||||||
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
target_ss = NR_SearchSpace__searchSpaceType_PR_common;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NR_SIB1_t *sib1 = nrmac->common_channels[0].sib1 ? nrmac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
const NR_SIB1_t *sib1 = nrmac->common_channels[0].sib1 ? nrmac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||||
NR_SearchSpace_t *search_space = get_searchspace(sib1,
|
NR_SearchSpace_t *search_space = get_searchspace(sib1,
|
||||||
scc,
|
scc,
|
||||||
@@ -113,9 +113,9 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
|||||||
// here we assume that the coreset is scheduled every slot (which it
|
// here we assume that the coreset is scheduled every slot (which it
|
||||||
// currently is) and starting at symbol 0
|
// currently is) and starting at symbol 0
|
||||||
AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n");
|
AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n");
|
||||||
|
|
||||||
/* check that TDA index 1 fits into DL part of mixed slot, if it exists */
|
/* check that TDA index 1 fits into DL part of mixed slot, if it exists */
|
||||||
int tdaMi = -1;
|
int tdaMi = -1;
|
||||||
|
|
||||||
if (frame_type == TDD && tdaList->list.count > 1) {
|
if (frame_type == TDD && tdaList->list.count > 1) {
|
||||||
const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
|
const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
|
||||||
AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0,
|
AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0,
|
||||||
@@ -124,6 +124,7 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
|||||||
int start, len;
|
int start, len;
|
||||||
SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
|
SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
|
||||||
const uint16_t symb_tda = ((1 << len) - 1) << start;
|
const uint16_t symb_tda = ((1 << len) - 1) << start;
|
||||||
|
|
||||||
// check whether coreset and TDA overlap: then, we cannot use it. Also,
|
// check whether coreset and TDA overlap: then, we cannot use it. Also,
|
||||||
// check whether TDA is entirely within mixed slot DL. Note that
|
// check whether TDA is entirely within mixed slot DL. Note that
|
||||||
// here we assume that the coreset is scheduled every slot (which it
|
// here we assume that the coreset is scheduled every slot (which it
|
||||||
@@ -143,10 +144,12 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
|||||||
|
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
nrmac->preferred_dl_tda[bwp_id][i] = -1;
|
nrmac->preferred_dl_tda[bwp_id][i] = -1;
|
||||||
|
|
||||||
if (frame_type == FDD || i % nr_slots_period < tdd->nrofDownlinkSlots)
|
if (frame_type == FDD || i % nr_slots_period < tdd->nrofDownlinkSlots)
|
||||||
nrmac->preferred_dl_tda[bwp_id][i] = 0;
|
nrmac->preferred_dl_tda[bwp_id][i] = 0;
|
||||||
else if (nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots)
|
else if (nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots)
|
||||||
nrmac->preferred_dl_tda[bwp_id][i] = tdaMi;
|
nrmac->preferred_dl_tda[bwp_id][i] = tdaMi;
|
||||||
|
|
||||||
LOG_D(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]);
|
LOG_D(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,8 +160,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
|||||||
const NR_UE_sched_ctrl_t *ue_sched_ctl,
|
const NR_UE_sched_ctrl_t *ue_sched_ctl,
|
||||||
unsigned char *mac_pdu,
|
unsigned char *mac_pdu,
|
||||||
unsigned char drx_cmd,
|
unsigned char drx_cmd,
|
||||||
unsigned char *ue_cont_res_id)
|
unsigned char *ue_cont_res_id) {
|
||||||
{
|
|
||||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||||
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
|
NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu;
|
||||||
uint8_t last_size = 0;
|
uint8_t last_size = 0;
|
||||||
@@ -201,8 +203,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
|||||||
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
|
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
|
||||||
ce_ptr += mac_ce_size;
|
ce_ptr += mac_ce_size;
|
||||||
mac_pdu_ptr += (unsigned char) mac_ce_size;
|
mac_pdu_ptr += (unsigned char) mac_ce_size;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contention resolution fixed subheader and MAC CE
|
// Contention resolution fixed subheader and MAC CE
|
||||||
@@ -399,18 +399,18 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
|||||||
|
|
||||||
#define BLER_UPDATE_FRAME 10
|
#define BLER_UPDATE_FRAME 10
|
||||||
#define BLER_FILTER 0.9f
|
#define BLER_FILTER 0.9f
|
||||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table)
|
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table) {
|
||||||
{
|
|
||||||
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
||||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||||
|
|
||||||
int max_allowed_mcs = (mcs_table == 1) ? 27 : 28;
|
int max_allowed_mcs = (mcs_table == 1) ? 27 : 28;
|
||||||
int max_mcs = nrmac->dl_max_mcs;
|
int max_mcs = nrmac->dl_max_mcs;
|
||||||
|
|
||||||
if (nrmac->dl_max_mcs>max_allowed_mcs)
|
if (nrmac->dl_max_mcs>max_allowed_mcs)
|
||||||
max_mcs = max_allowed_mcs;
|
max_mcs = max_allowed_mcs;
|
||||||
|
|
||||||
NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
|
NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
|
||||||
|
|
||||||
/* first call: everything is zero. Initialize to sensible default */
|
/* first call: everything is zero. Initialize to sensible default */
|
||||||
if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
|
if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
|
||||||
bler_stats->last_frame_slot = frame * n + slot;
|
bler_stats->last_frame_slot = frame * n + slot;
|
||||||
@@ -418,13 +418,16 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
|||||||
bler_stats->bler = (nrmac->dl_bler_target_lower + nrmac->dl_bler_target_upper) / 2;
|
bler_stats->bler = (nrmac->dl_bler_target_lower + nrmac->dl_bler_target_upper) / 2;
|
||||||
bler_stats->rd2_bler = nrmac->dl_rd2_bler_threshold;
|
bler_stats->rd2_bler = nrmac->dl_rd2_bler_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int now = frame * n + slot;
|
const int now = frame * n + slot;
|
||||||
int diff = now - bler_stats->last_frame_slot;
|
int diff = now - bler_stats->last_frame_slot;
|
||||||
|
|
||||||
if (diff < 0) // wrap around
|
if (diff < 0) // wrap around
|
||||||
diff += 1024 * n;
|
diff += 1024 * n;
|
||||||
|
|
||||||
const uint8_t old_mcs = bler_stats->mcs;
|
const uint8_t old_mcs = bler_stats->mcs;
|
||||||
const NR_mac_stats_t *stats = &nrmac->UE_info.mac_stats[UE_id];
|
const NR_mac_stats_t *stats = &nrmac->UE_info.mac_stats[UE_id];
|
||||||
|
|
||||||
// TODO put back this condition when relevant
|
// TODO put back this condition when relevant
|
||||||
/*const int dret3x = stats->dlsch_rounds[3] - bler_stats->dlsch_rounds[3];
|
/*const int dret3x = stats->dlsch_rounds[3] - bler_stats->dlsch_rounds[3];
|
||||||
if (dret3x > 0) {
|
if (dret3x > 0) {
|
||||||
@@ -447,8 +450,8 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
|||||||
const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler;
|
const float rd2_bler_wnd = dtx > 0 ? (float) dretx2 / dtx : bler_stats->rd2_bler;
|
||||||
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
|
bler_stats->bler = BLER_FILTER * bler_stats->bler + (1 - BLER_FILTER) * bler_window;
|
||||||
bler_stats->rd2_bler = BLER_FILTER / 4 * bler_stats->rd2_bler + (1 - BLER_FILTER / 4) * rd2_bler_wnd;
|
bler_stats->rd2_bler = BLER_FILTER / 4 * bler_stats->rd2_bler + (1 - BLER_FILTER / 4) * rd2_bler_wnd;
|
||||||
|
|
||||||
int new_mcs = old_mcs;
|
int new_mcs = old_mcs;
|
||||||
|
|
||||||
// TODO put back this condition when relevant
|
// TODO put back this condition when relevant
|
||||||
/* first ensure that number of 2nd retx is below threshold. If this is the
|
/* first ensure that number of 2nd retx is below threshold. If this is the
|
||||||
* case, use 1st retx to adjust faster
|
* case, use 1st retx to adjust faster
|
||||||
@@ -459,9 +462,8 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
|||||||
new_mcs += 1;
|
new_mcs += 1;
|
||||||
else if (bler_stats->bler > nrmac->dl_bler_target_upper && old_mcs > 6)
|
else if (bler_stats->bler > nrmac->dl_bler_target_upper && old_mcs > 6)
|
||||||
new_mcs -= 1;
|
new_mcs -= 1;
|
||||||
|
|
||||||
// else we are within threshold boundaries
|
// else we are within threshold boundaries
|
||||||
|
|
||||||
|
|
||||||
bler_stats->last_frame_slot = now;
|
bler_stats->last_frame_slot = now;
|
||||||
bler_stats->mcs = new_mcs;
|
bler_stats->mcs = new_mcs;
|
||||||
memcpy(bler_stats->dlsch_rounds, stats->dlsch_rounds, sizeof(stats->dlsch_rounds));
|
memcpy(bler_stats->dlsch_rounds, stats->dlsch_rounds, sizeof(stats->dlsch_rounds));
|
||||||
@@ -473,11 +475,9 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
|||||||
void nr_store_dlsch_buffer(module_id_t module_id,
|
void nr_store_dlsch_buffer(module_id_t module_id,
|
||||||
frame_t frame,
|
frame_t frame,
|
||||||
sub_frame_t slot) {
|
sub_frame_t slot) {
|
||||||
|
|
||||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||||
|
|
||||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||||
sched_ctrl->num_total_bytes = 0;
|
sched_ctrl->num_total_bytes = 0;
|
||||||
sched_ctrl->dl_pdus_total = 0;
|
sched_ctrl->dl_pdus_total = 0;
|
||||||
@@ -485,21 +485,20 @@ void nr_store_dlsch_buffer(module_id_t module_id,
|
|||||||
/* loop over all activated logical channels */
|
/* loop over all activated logical channels */
|
||||||
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
|
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
|
||||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
||||||
|
|
||||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
const int lcid = sched_ctrl->dl_lc_ids[i];
|
||||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||||
LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid);
|
LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid);
|
||||||
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||||
rnti,
|
rnti,
|
||||||
module_id,
|
module_id,
|
||||||
frame,
|
frame,
|
||||||
slot,
|
slot,
|
||||||
ENB_FLAG_YES,
|
ENB_FLAG_YES,
|
||||||
MBMS_FLAG_NO,
|
MBMS_FLAG_NO,
|
||||||
lcid,
|
lcid,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
stop_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||||
|
|
||||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||||
@@ -531,6 +530,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
int UE_id,
|
int UE_id,
|
||||||
int current_harq_pid) {
|
int current_harq_pid) {
|
||||||
|
|
||||||
|
|
||||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||||
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
|
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
|
||||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||||
@@ -558,30 +558,34 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
|
|
||||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||||
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||||
|
|
||||||
int rbStart = 0; // start wrt BWPstart
|
int rbStart = 0; // start wrt BWPstart
|
||||||
|
|
||||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||||
|
|
||||||
int rbSize = 0;
|
int rbSize = 0;
|
||||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||||
|
|
||||||
if (tda == retInfo->time_domain_allocation) {
|
if (tda == retInfo->time_domain_allocation) {
|
||||||
/* Check that there are enough resources for retransmission */
|
/* Check that there are enough resources for retransmission */
|
||||||
while (rbSize < retInfo->rbSize) {
|
while (rbSize < retInfo->rbSize) {
|
||||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||||
rbSize = 0;
|
rbSize = 0;
|
||||||
|
|
||||||
while (rbStart < bwpSize &&
|
while (rbStart < bwpSize &&
|
||||||
!(rballoc_mask[rbStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)))
|
!(rballoc_mask[rbStart]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)))
|
||||||
rbStart++;
|
rbStart++;
|
||||||
|
|
||||||
if (rbStart >= bwpSize) {
|
if (rbStart >= bwpSize) {
|
||||||
LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
|
LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (rbStart + rbSize < bwpSize &&
|
while (rbStart + rbSize < bwpSize &&
|
||||||
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) &&
|
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols)) &&
|
||||||
rbSize < retInfo->rbSize)
|
rbSize < retInfo->rbSize)
|
||||||
rbSize++;
|
rbSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether we need to switch the TDA allocation since the last
|
/* check whether we need to switch the TDA allocation since the last
|
||||||
* (re-)transmission */
|
* (re-)transmission */
|
||||||
if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
||||||
@@ -599,8 +603,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
} else {
|
} else {
|
||||||
/* the retransmission will use a different time domain allocation, check
|
/* the retransmission will use a different time domain allocation, check
|
||||||
* that we have enough resources */
|
* that we have enough resources */
|
||||||
|
|
||||||
NR_pdsch_semi_static_t temp_ps = *ps;
|
NR_pdsch_semi_static_t temp_ps = *ps;
|
||||||
|
|
||||||
nr_set_pdsch_semi_static(sib1,
|
nr_set_pdsch_semi_static(sib1,
|
||||||
scc,
|
scc,
|
||||||
UE_info->CellGroup[UE_id],
|
UE_info->CellGroup[UE_id],
|
||||||
@@ -613,6 +617,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
while (rbStart < bwpSize &&
|
while (rbStart < bwpSize &&
|
||||||
!(rballoc_mask[rbStart]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
!(rballoc_mask[rbStart]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
||||||
rbStart++;
|
rbStart++;
|
||||||
|
|
||||||
while (rbStart + rbSize < bwpSize &&
|
while (rbStart + rbSize < bwpSize &&
|
||||||
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
(rballoc_mask[rbStart + rbSize]&SL_to_bitmap(temp_ps.startSymbolIndex, temp_ps.nrOfSymbols)))
|
||||||
rbSize++;
|
rbSize++;
|
||||||
@@ -629,10 +634,12 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
rbSize,
|
rbSize,
|
||||||
&new_tbs,
|
&new_tbs,
|
||||||
&new_rbSize);
|
&new_rbSize);
|
||||||
|
|
||||||
if (!success || new_tbs != retInfo->tb_size) {
|
if (!success || new_tbs != retInfo->tb_size) {
|
||||||
LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
|
LOG_D(MAC, "new TBsize %d of new TDA does not match old TBS %d\n", new_tbs, retInfo->tb_size);
|
||||||
return false; /* the maximum TBsize we might have is smaller than what we need */
|
return false; /* the maximum TBsize we might have is smaller than what we need */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we can allocate it. Overwrite the time_domain_allocation, the number
|
/* we can allocate it. Overwrite the time_domain_allocation, the number
|
||||||
* of RBs, and the new TB size. The rest is done below */
|
* of RBs, and the new TB size. The rest is done below */
|
||||||
retInfo->tb_size = new_tbs;
|
retInfo->tb_size = new_tbs;
|
||||||
@@ -645,12 +652,14 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||||
uint8_t nr_of_candidates;
|
uint8_t nr_of_candidates;
|
||||||
|
|
||||||
for (int i=0; i<5; i++) {
|
for (int i=0; i<5; i++) {
|
||||||
// for now taking the lowest value among the available aggregation levels
|
// for now taking the lowest value among the available aggregation levels
|
||||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||||
&nr_of_candidates,
|
&nr_of_candidates,
|
||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
1<<i);
|
1<<i);
|
||||||
|
|
||||||
if(nr_of_candidates>0) break;
|
if(nr_of_candidates>0) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,12 +679,12 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
|
|
||||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||||
* allocation after CCE alloc fail would be more complex) */
|
* allocation after CCE alloc fail would be more complex) */
|
||||||
|
|
||||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||||
if (alloc<0) {
|
if (alloc<0) {
|
||||||
LOG_D(MAC,
|
LOG_D(MAC,
|
||||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
"could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||||
__func__,
|
|
||||||
UE_id,
|
UE_id,
|
||||||
UE_info->rnti[UE_id],
|
UE_info->rnti[UE_id],
|
||||||
frame,
|
frame,
|
||||||
@@ -685,23 +694,21 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sched_ctrl->cce_index = CCEIndex;
|
sched_ctrl->cce_index = CCEIndex;
|
||||||
|
|
||||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||||
/* CC_id = */ 0,
|
/* CC_id = */ 0,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
CCEIndex,
|
CCEIndex,
|
||||||
sched_ctrl->aggregation_level);
|
sched_ctrl->aggregation_level);
|
||||||
|
|
||||||
/* just reuse from previous scheduling opportunity, set new start RB */
|
/* just reuse from previous scheduling opportunity, set new start RB */
|
||||||
sched_ctrl->sched_pdsch = *retInfo;
|
sched_ctrl->sched_pdsch = *retInfo;
|
||||||
sched_ctrl->sched_pdsch.rbStart = rbStart;
|
sched_ctrl->sched_pdsch.rbStart = rbStart;
|
||||||
|
|
||||||
sched_ctrl->sched_pdsch.pucch_allocation = alloc;
|
sched_ctrl->sched_pdsch.pucch_allocation = alloc;
|
||||||
|
|
||||||
/* retransmissions: directly allocate */
|
/* retransmissions: directly allocate */
|
||||||
*n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
|
*n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
|
||||||
|
|
||||||
for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
|
for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
|
||||||
rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] ^= SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,7 +722,6 @@ void pf_dl(module_id_t module_id,
|
|||||||
int max_num_ue,
|
int max_num_ue,
|
||||||
int n_rb_sched,
|
int n_rb_sched,
|
||||||
uint16_t *rballoc_mask) {
|
uint16_t *rballoc_mask) {
|
||||||
|
|
||||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||||
NR_UE_info_t *UE_info = &mac->UE_info;
|
NR_UE_info_t *UE_info = &mac->UE_info;
|
||||||
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
||||||
@@ -728,15 +734,16 @@ void pf_dl(module_id_t module_id,
|
|||||||
/* Loop UE_info->list to check retransmission */
|
/* Loop UE_info->list to check retransmission */
|
||||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
if (UE_info->Msg4_ACKed[UE_id] != true) continue;
|
if (UE_info->Msg4_ACKed[UE_id] != true) continue;
|
||||||
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||||
|
|
||||||
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
||||||
|
|
||||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||||
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||||
|
|
||||||
layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
|
layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
|
||||||
|
|
||||||
/* Calculate Throughput */
|
/* Calculate Throughput */
|
||||||
const float a = 0.0005f; // corresponds to 200ms window
|
const float a = 0.0005f; // corresponds to 200ms window
|
||||||
const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes;
|
const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes;
|
||||||
@@ -746,13 +753,16 @@ void pf_dl(module_id_t module_id,
|
|||||||
if (sched_pdsch->dl_harq_pid >= 0) {
|
if (sched_pdsch->dl_harq_pid >= 0) {
|
||||||
/* Allocate retransmission */
|
/* Allocate retransmission */
|
||||||
bool r = allocate_dl_retransmission(
|
bool r = allocate_dl_retransmission(
|
||||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
|
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
|
LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||||
max_num_ue--;
|
max_num_ue--;
|
||||||
|
|
||||||
if (max_num_ue < 0) return;
|
if (max_num_ue < 0) return;
|
||||||
} else {
|
} else {
|
||||||
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
|
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
|
||||||
@@ -782,18 +792,21 @@ void pf_dl(module_id_t module_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int min_rbSize = 5;
|
const int min_rbSize = 5;
|
||||||
|
|
||||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||||
while (max_num_ue > 0 && n_rb_sched >= min_rbSize && UE_sched.head >= 0) {
|
while (max_num_ue > 0 && n_rb_sched >= min_rbSize && UE_sched.head >= 0) {
|
||||||
|
|
||||||
/* Find max coeff from UE_sched*/
|
/* Find max coeff from UE_sched*/
|
||||||
int *max = &UE_sched.head; /* assume head is max */
|
int *max = &UE_sched.head; /* assume head is max */
|
||||||
int *p = &UE_sched.next[*max];
|
int *p = &UE_sched.next[*max];
|
||||||
|
|
||||||
while (*p >= 0) {
|
while (*p >= 0) {
|
||||||
/* if the current one has larger coeff, save for later */
|
/* if the current one has larger coeff, save for later */
|
||||||
if (coeff_ue[*p] > coeff_ue[*max])
|
if (coeff_ue[*p] > coeff_ue[*max])
|
||||||
max = p;
|
max = p;
|
||||||
|
|
||||||
p = &UE_sched.next[*p];
|
p = &UE_sched.next[*p];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the max one: do not use remove_nr_list() it goes through the
|
/* remove the max one: do not use remove_nr_list() it goes through the
|
||||||
* whole list every time. Note that UE_sched.tail might not be set
|
* whole list every time. Note that UE_sched.tail might not be set
|
||||||
* correctly anymore */
|
* correctly anymore */
|
||||||
@@ -803,6 +816,7 @@ void pf_dl(module_id_t module_id,
|
|||||||
*p = -1;
|
*p = -1;
|
||||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||||
|
|
||||||
|
|
||||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||||
cg &&
|
cg &&
|
||||||
cg->spCellConfig &&
|
cg->spCellConfig &&
|
||||||
@@ -837,12 +851,14 @@ void pf_dl(module_id_t module_id,
|
|||||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||||
uint8_t nr_of_candidates;
|
uint8_t nr_of_candidates;
|
||||||
|
|
||||||
for (int i=0; i<5; i++) {
|
for (int i=0; i<5; i++) {
|
||||||
// for now taking the lowest value among the available aggregation levels
|
// for now taking the lowest value among the available aggregation levels
|
||||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||||
&nr_of_candidates,
|
&nr_of_candidates,
|
||||||
sched_ctrl->search_space,
|
sched_ctrl->search_space,
|
||||||
1<<i);
|
1<<i);
|
||||||
|
|
||||||
if(nr_of_candidates>0) break;
|
if(nr_of_candidates>0) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,12 +877,13 @@ void pf_dl(module_id_t module_id,
|
|||||||
|
|
||||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||||
* allocation after CCE alloc fail would be more complex) */
|
* allocation after CCE alloc fail would be more complex) */
|
||||||
|
|
||||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||||
|
|
||||||
if (alloc<0) {
|
if (alloc<0) {
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
"could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||||
__func__,
|
|
||||||
UE_id,
|
UE_id,
|
||||||
rnti,
|
rnti,
|
||||||
frame,
|
frame,
|
||||||
@@ -879,21 +896,18 @@ void pf_dl(module_id_t module_id,
|
|||||||
* and PUCCH */
|
* and PUCCH */
|
||||||
max_num_ue--;
|
max_num_ue--;
|
||||||
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
|
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
|
||||||
|
|
||||||
sched_ctrl->cce_index = CCEIndex;
|
sched_ctrl->cce_index = CCEIndex;
|
||||||
|
|
||||||
fill_pdcch_vrb_map(mac,
|
fill_pdcch_vrb_map(mac,
|
||||||
/* CC_id = */ 0,
|
/* CC_id = */ 0,
|
||||||
&sched_ctrl->sched_pdcch,
|
&sched_ctrl->sched_pdcch,
|
||||||
CCEIndex,
|
CCEIndex,
|
||||||
sched_ctrl->aggregation_level);
|
sched_ctrl->aggregation_level);
|
||||||
|
|
||||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||||
max_num_ue--;
|
max_num_ue--;
|
||||||
|
|
||||||
if (max_num_ue < 0) return;
|
if (max_num_ue < 0) return;
|
||||||
|
|
||||||
/* MCS has been set above */
|
/* MCS has been set above */
|
||||||
|
|
||||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||||
@@ -913,12 +927,14 @@ void pf_dl(module_id_t module_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||||
|
|
||||||
// Freq-demain allocation
|
// Freq-demain allocation
|
||||||
while (rbStart < bwpSize &&
|
while (rbStart < bwpSize &&
|
||||||
!(rballoc_mask[rbStart]&slbitmap))
|
!(rballoc_mask[rbStart]&slbitmap))
|
||||||
rbStart++;
|
rbStart++;
|
||||||
|
|
||||||
uint16_t max_rbSize = 1;
|
uint16_t max_rbSize = 1;
|
||||||
|
|
||||||
while (rbStart + max_rbSize < bwpSize &&
|
while (rbStart + max_rbSize < bwpSize &&
|
||||||
(rballoc_mask[rbStart + max_rbSize]&slbitmap))
|
(rballoc_mask[rbStart + max_rbSize]&slbitmap))
|
||||||
max_rbSize++;
|
max_rbSize++;
|
||||||
@@ -947,39 +963,41 @@ void pf_dl(module_id_t module_id,
|
|||||||
sched_pdsch->rbSize = rbSize;
|
sched_pdsch->rbSize = rbSize;
|
||||||
sched_pdsch->rbStart = rbStart;
|
sched_pdsch->rbStart = rbStart;
|
||||||
sched_pdsch->tb_size = TBS;
|
sched_pdsch->tb_size = TBS;
|
||||||
|
|
||||||
/* transmissions: directly allocate */
|
/* transmissions: directly allocate */
|
||||||
n_rb_sched -= sched_pdsch->rbSize;
|
n_rb_sched -= sched_pdsch->rbSize;
|
||||||
|
|
||||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||||
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
|
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) {
|
||||||
{
|
|
||||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||||
|
|
||||||
if (UE_info->num_UEs == 0)
|
if (UE_info->num_UEs == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||||
const int CC_id = 0;
|
const int CC_id = 0;
|
||||||
|
|
||||||
/* Get bwpSize and TDAfrom the first UE */
|
/* Get bwpSize and TDAfrom the first UE */
|
||||||
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
||||||
int UE_id = UE_info->list.head;
|
int UE_id = UE_info->list.head;
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||||
const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
|
const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
|
||||||
|
|
||||||
if (!RC.nrmac[module_id]->preferred_dl_tda[bwp_id])
|
if (!RC.nrmac[module_id]->preferred_dl_tda[bwp_id])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[bwp_id][slot];
|
const int tda = RC.nrmac[module_id]->preferred_dl_tda[bwp_id][slot];
|
||||||
int startSymbolIndex, nrOfSymbols;
|
int startSymbolIndex, nrOfSymbols;
|
||||||
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ?
|
const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ?
|
||||||
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList :
|
||||||
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||||
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
|
||||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||||
|
|
||||||
|
|
||||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||||
@@ -1000,19 +1018,20 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
|||||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||||
uint16_t rballoc_mask[bwpSize];
|
uint16_t rballoc_mask[bwpSize];
|
||||||
int n_rb_sched = 0;
|
int n_rb_sched = 0;
|
||||||
|
|
||||||
for (int i = 0; i < bwpSize; i++) {
|
for (int i = 0; i < bwpSize; i++) {
|
||||||
// calculate mask: init with "NOT" vrb_map:
|
// calculate mask: init with "NOT" vrb_map:
|
||||||
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
// if any RB in vrb_map is blocked (1), the current RBG will be 0
|
||||||
rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols
|
rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols
|
||||||
|
|
||||||
// if all the pdsch symbols are free
|
// if all the pdsch symbols are free
|
||||||
if((rballoc_mask[i]&slbitmap) ==
|
if((rballoc_mask[i]&slbitmap) ==
|
||||||
slbitmap)
|
slbitmap)
|
||||||
n_rb_sched++;
|
n_rb_sched++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve amount of data to send for this UE */
|
/* Retrieve amount of data to send for this UE */
|
||||||
nr_store_dlsch_buffer(module_id, frame, slot);
|
nr_store_dlsch_buffer(module_id, frame, slot);
|
||||||
|
|
||||||
/* proportional fair scheduling algorithm */
|
/* proportional fair scheduling algorithm */
|
||||||
pf_dl(module_id,
|
pf_dl(module_id,
|
||||||
frame,
|
frame,
|
||||||
@@ -1023,8 +1042,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
|||||||
rballoc_mask);
|
rballoc_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
|
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) {
|
||||||
{
|
|
||||||
/* in the PF algorithm, we have to use the TBsize to compute the coefficient.
|
/* in the PF algorithm, we have to use the TBsize to compute the coefficient.
|
||||||
* This would include the number of DMRS symbols, which in turn depends on
|
* This would include the number of DMRS symbols, which in turn depends on
|
||||||
* the time domain allocation. In case we are in a mixed slot, we do not want
|
* the time domain allocation. In case we are in a mixed slot, we do not want
|
||||||
@@ -1034,16 +1052,17 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
|
|||||||
for (int mcs = 0; mcs < 29; ++mcs) {
|
for (int mcs = 0; mcs < 29; ++mcs) {
|
||||||
if (mcs > 27 && mcsTableIdx == 1)
|
if (mcs > 27 && mcsTableIdx == 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
|
const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
|
||||||
const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
|
const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
|
||||||
pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
|
pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
|
||||||
R,
|
R,
|
||||||
1, /* rbSize */
|
1, /* rbSize */
|
||||||
10, /* hypothetical number of slots */
|
10, /* hypothetical number of slots */
|
||||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||||
0 /* tb_scaling */,
|
0 /* tb_scaling */,
|
||||||
1 /* nrOfLayers */)
|
1 /* nrOfLayers */)
|
||||||
>> 3;
|
>> 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1055,22 +1074,23 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
frame_t frame,
|
frame_t frame,
|
||||||
sub_frame_t slot) {
|
sub_frame_t slot) {
|
||||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||||
|
|
||||||
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* PREPROCESSOR */
|
/* PREPROCESSOR */
|
||||||
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
||||||
|
|
||||||
const int CC_id = 0;
|
const int CC_id = 0;
|
||||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||||
|
|
||||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||||
|
|
||||||
NR_list_t *UE_list = &UE_info->list;
|
NR_list_t *UE_list = &UE_info->list;
|
||||||
|
|
||||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||||
|
|
||||||
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
||||||
|
|
||||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
|
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
|
||||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||||
@@ -1085,7 +1105,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
* Possible improvement: take the periodicity from input file.
|
* Possible improvement: take the periodicity from input file.
|
||||||
* If such UE is not scheduled now, it will be by the preprocessor later.
|
* If such UE is not scheduled now, it will be by the preprocessor later.
|
||||||
* If we add the CE, ta_apply will be reset */
|
* If we add the CE, ta_apply will be reset */
|
||||||
if (frame == (sched_ctrl->ta_frame + 10) % 1024){
|
if (frame == (sched_ctrl->ta_frame + 10) % 1024) {
|
||||||
sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
|
sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
|
||||||
LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
|
LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
|
||||||
}
|
}
|
||||||
@@ -1094,19 +1114,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const rnti_t rnti = UE_info->rnti[UE_id];
|
const rnti_t rnti = UE_info->rnti[UE_id];
|
||||||
|
|
||||||
/* pre-computed PDSCH values that only change if time domain
|
/* pre-computed PDSCH values that only change if time domain
|
||||||
* allocation/DMRS parameters change. Updated in the preprocessor through
|
* allocation/DMRS parameters change. Updated in the preprocessor through
|
||||||
* nr_set_pdsch_semi_static() */
|
* nr_set_pdsch_semi_static() */
|
||||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||||
|
|
||||||
/* POST processing */
|
/* POST processing */
|
||||||
const uint8_t nrOfLayers = ps->nrOfLayers;
|
const uint8_t nrOfLayers = ps->nrOfLayers;
|
||||||
const uint16_t R = sched_pdsch->R;
|
const uint16_t R = sched_pdsch->R;
|
||||||
const uint8_t Qm = sched_pdsch->Qm;
|
const uint8_t Qm = sched_pdsch->Qm;
|
||||||
const uint32_t TBS = sched_pdsch->tb_size;
|
const uint32_t TBS = sched_pdsch->tb_size;
|
||||||
|
|
||||||
int8_t current_harq_pid = sched_pdsch->dl_harq_pid;
|
int8_t current_harq_pid = sched_pdsch->dl_harq_pid;
|
||||||
|
|
||||||
if (current_harq_pid < 0) {
|
if (current_harq_pid < 0) {
|
||||||
/* PP has not selected a specific HARQ Process, get a new one */
|
/* PP has not selected a specific HARQ Process, get a new one */
|
||||||
current_harq_pid = sched_ctrl->available_dl_harq.head;
|
current_harq_pid = sched_ctrl->available_dl_harq.head;
|
||||||
@@ -1124,6 +1142,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
else
|
else
|
||||||
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
|
remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||||
DevAssert(!harq->is_waiting);
|
DevAssert(!harq->is_waiting);
|
||||||
add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
|
add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
|
||||||
@@ -1132,8 +1151,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
harq->feedback_slot = pucch->ul_slot;
|
harq->feedback_slot = pucch->ul_slot;
|
||||||
harq->is_waiting = true;
|
harq->is_waiting = true;
|
||||||
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
|
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
|
||||||
|
LOG_D(NR_MAC,
|
||||||
LOG_D(NR_MAC,"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
|
"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
|
||||||
frame,
|
frame,
|
||||||
slot,
|
slot,
|
||||||
UE_id,
|
UE_id,
|
||||||
@@ -1156,8 +1175,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
pucch->ul_slot,
|
pucch->ul_slot,
|
||||||
sched_pdsch->pucch_allocation,
|
sched_pdsch->pucch_allocation,
|
||||||
sched_ctrl->tpc1);
|
sched_ctrl->tpc1);
|
||||||
|
|
||||||
NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp;
|
NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp;
|
||||||
|
|
||||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(bwp,
|
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(bwp,
|
||||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||||
@@ -1170,6 +1189,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
|
|
||||||
/* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */
|
/* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */
|
||||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid];
|
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid];
|
||||||
|
|
||||||
if (!pdcch_pdu) {
|
if (!pdcch_pdu) {
|
||||||
LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
|
LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n");
|
||||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||||
@@ -1190,7 +1210,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
|
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
|
||||||
dl_req->nPDUs += 1;
|
dl_req->nPDUs += 1;
|
||||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||||
|
|
||||||
pdsch_pdu->pduBitmap = 0;
|
pdsch_pdu->pduBitmap = 0;
|
||||||
pdsch_pdu->rnti = rnti;
|
pdsch_pdu->rnti = rnti;
|
||||||
/* SCF222: PDU index incremented for each PDSCH PDU sent in TX control
|
/* SCF222: PDU index incremented for each PDSCH PDU sent in TX control
|
||||||
@@ -1208,9 +1227,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
|
pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing;
|
||||||
|
|
||||||
pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
|
pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
|
||||||
|
|
||||||
// Codeword information
|
// Codeword information
|
||||||
pdsch_pdu->NrOfCodewords = 1;
|
pdsch_pdu->NrOfCodewords = 1;
|
||||||
pdsch_pdu->targetCodeRate[0] = R;
|
pdsch_pdu->targetCodeRate[0] = R;
|
||||||
@@ -1221,12 +1238,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
AssertFatal(harq->round<4,"%d",harq->round);
|
AssertFatal(harq->round<4,"%d",harq->round);
|
||||||
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
|
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
|
||||||
pdsch_pdu->TBSize[0] = TBS;
|
pdsch_pdu->TBSize[0] = TBS;
|
||||||
|
|
||||||
pdsch_pdu->dataScramblingId = *scc->physCellId;
|
pdsch_pdu->dataScramblingId = *scc->physCellId;
|
||||||
pdsch_pdu->nrOfLayers = nrOfLayers;
|
pdsch_pdu->nrOfLayers = nrOfLayers;
|
||||||
pdsch_pdu->transmissionScheme = 0;
|
pdsch_pdu->transmissionScheme = 0;
|
||||||
pdsch_pdu->refPoint = 0; // Point A
|
pdsch_pdu->refPoint = 0; // Point A
|
||||||
|
|
||||||
// DMRS
|
// DMRS
|
||||||
pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos;
|
pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos;
|
||||||
pdsch_pdu->dmrsConfigType = ps->dmrsConfigType;
|
pdsch_pdu->dmrsConfigType = ps->dmrsConfigType;
|
||||||
@@ -1234,18 +1249,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
pdsch_pdu->SCID = 0;
|
pdsch_pdu->SCID = 0;
|
||||||
pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData;
|
pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData;
|
||||||
pdsch_pdu->dmrsPorts = (1<<nrOfLayers)-1; // FIXME with a better implementation
|
pdsch_pdu->dmrsPorts = (1<<nrOfLayers)-1; // FIXME with a better implementation
|
||||||
|
|
||||||
// Pdsch Allocation in frequency domain
|
// Pdsch Allocation in frequency domain
|
||||||
pdsch_pdu->resourceAlloc = 1;
|
pdsch_pdu->resourceAlloc = 1;
|
||||||
pdsch_pdu->rbStart = sched_pdsch->rbStart;
|
pdsch_pdu->rbStart = sched_pdsch->rbStart;
|
||||||
pdsch_pdu->rbSize = sched_pdsch->rbSize;
|
pdsch_pdu->rbSize = sched_pdsch->rbSize;
|
||||||
pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
|
pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
|
||||||
|
|
||||||
// Resource Allocation in time domain
|
// Resource Allocation in time domain
|
||||||
pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex;
|
pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex;
|
||||||
pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
|
pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
|
||||||
|
|
||||||
NR_PDSCH_Config_t *pdsch_Config=NULL;
|
NR_PDSCH_Config_t *pdsch_Config=NULL;
|
||||||
|
|
||||||
if (bwp &&
|
if (bwp &&
|
||||||
bwp->bwp_Dedicated &&
|
bwp->bwp_Dedicated &&
|
||||||
bwp->bwp_Dedicated->pdsch_Config &&
|
bwp->bwp_Dedicated->pdsch_Config &&
|
||||||
@@ -1254,18 +1267,20 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
|
|
||||||
/* Check and validate PTRS values */
|
/* Check and validate PTRS values */
|
||||||
struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS =
|
struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS =
|
||||||
pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
|
pdsch_Config ? pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS : NULL;
|
||||||
|
|
||||||
if (phaseTrackingRS) {
|
if (phaseTrackingRS) {
|
||||||
bool valid_ptrs_setup = set_dl_ptrs_values(phaseTrackingRS->choice.setup,
|
bool valid_ptrs_setup = set_dl_ptrs_values(phaseTrackingRS->choice.setup,
|
||||||
pdsch_pdu->rbSize,
|
pdsch_pdu->rbSize,
|
||||||
pdsch_pdu->mcsIndex[0],
|
pdsch_pdu->mcsIndex[0],
|
||||||
pdsch_pdu->mcsTable[0],
|
pdsch_pdu->mcsTable[0],
|
||||||
&pdsch_pdu->PTRSFreqDensity,
|
&pdsch_pdu->PTRSFreqDensity,
|
||||||
&pdsch_pdu->PTRSTimeDensity,
|
&pdsch_pdu->PTRSTimeDensity,
|
||||||
&pdsch_pdu->PTRSPortIndex,
|
&pdsch_pdu->PTRSPortIndex,
|
||||||
&pdsch_pdu->nEpreRatioOfPDSCHToPTRS,
|
&pdsch_pdu->nEpreRatioOfPDSCHToPTRS,
|
||||||
&pdsch_pdu->PTRSReOffset,
|
&pdsch_pdu->PTRSReOffset,
|
||||||
pdsch_pdu->NrOfSymbols);
|
pdsch_pdu->NrOfSymbols);
|
||||||
|
|
||||||
if (valid_ptrs_setup)
|
if (valid_ptrs_setup)
|
||||||
pdsch_pdu->pduBitmap |= 0x1; // Bit 0: pdschPtrs - Indicates PTRS included (FR2)
|
pdsch_pdu->pduBitmap |= 0x1; // Bit 0: pdschPtrs - Indicates PTRS included (FR2)
|
||||||
}
|
}
|
||||||
@@ -1275,6 +1290,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
|
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
|
||||||
pdcch_pdu->numDlDci++;
|
pdcch_pdu->numDlDci++;
|
||||||
dci_pdu->RNTI = rnti;
|
dci_pdu->RNTI = rnti;
|
||||||
|
|
||||||
if (sched_ctrl->coreset &&
|
if (sched_ctrl->coreset &&
|
||||||
sched_ctrl->search_space &&
|
sched_ctrl->search_space &&
|
||||||
sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
|
sched_ctrl->coreset->pdcch_DMRS_ScramblingID &&
|
||||||
@@ -1285,27 +1301,28 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
dci_pdu->ScramblingId = *scc->physCellId;
|
dci_pdu->ScramblingId = *scc->physCellId;
|
||||||
dci_pdu->ScramblingRNTI = 0;
|
dci_pdu->ScramblingRNTI = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dci_pdu->AggregationLevel = sched_ctrl->aggregation_level;
|
dci_pdu->AggregationLevel = sched_ctrl->aggregation_level;
|
||||||
dci_pdu->CceIndex = sched_ctrl->cce_index;
|
dci_pdu->CceIndex = sched_ctrl->cce_index;
|
||||||
dci_pdu->beta_PDCCH_1_0 = 0;
|
dci_pdu->beta_PDCCH_1_0 = 0;
|
||||||
dci_pdu->powerControlOffsetSS = 1;
|
dci_pdu->powerControlOffsetSS = 1;
|
||||||
|
|
||||||
/* DCI payload */
|
/* DCI payload */
|
||||||
dci_pdu_rel15_t dci_payload;
|
dci_pdu_rel15_t dci_payload;
|
||||||
memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
|
memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t));
|
||||||
// bwp indicator
|
// bwp indicator
|
||||||
const int n_dl_bwp = bwp ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0;
|
const int n_dl_bwp = bwp ? UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0;
|
||||||
AssertFatal(n_dl_bwp <= 1, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp);
|
AssertFatal(n_dl_bwp <= 1, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp);
|
||||||
|
|
||||||
// as per table 7.3.1.1.2-1 in 38.212
|
// as per table 7.3.1.1.2-1 in 38.212
|
||||||
dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0;
|
dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0;
|
||||||
|
|
||||||
if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
|
if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1,
|
||||||
"Only frequency resource allocation type 1 is currently supported\n");
|
"Only frequency resource allocation type 1 is currently supported\n");
|
||||||
|
|
||||||
dci_payload.frequency_domain_assignment.val =
|
dci_payload.frequency_domain_assignment.val =
|
||||||
PRBalloc_to_locationandbandwidth0(
|
PRBalloc_to_locationandbandwidth0(
|
||||||
pdsch_pdu->rbSize,
|
pdsch_pdu->rbSize,
|
||||||
pdsch_pdu->rbStart,
|
pdsch_pdu->rbStart,
|
||||||
pdsch_pdu->BWPSize);
|
pdsch_pdu->BWPSize);
|
||||||
dci_payload.format_indicator = 1;
|
dci_payload.format_indicator = 1;
|
||||||
dci_payload.time_domain_assignment.val = ps->time_domain_allocation;
|
dci_payload.time_domain_assignment.val = ps->time_domain_allocation;
|
||||||
dci_payload.mcs = sched_pdsch->mcs;
|
dci_payload.mcs = sched_pdsch->mcs;
|
||||||
@@ -1336,11 +1353,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
dci_payload.tpc,
|
dci_payload.tpc,
|
||||||
pucch->timing_indicator);
|
pucch->timing_indicator);
|
||||||
|
|
||||||
|
|
||||||
int dci_format = ss && ss->searchSpaceType && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ?
|
int dci_format = ss && ss->searchSpaceType && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ?
|
||||||
NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
|
NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0;
|
||||||
|
|
||||||
const int rnti_type = NR_RNTI_C;
|
const int rnti_type = NR_RNTI_C;
|
||||||
|
|
||||||
fill_dci_pdu_rel15(scc,
|
fill_dci_pdu_rel15(scc,
|
||||||
UE_info->CellGroup[UE_id],
|
UE_info->CellGroup[UE_id],
|
||||||
dci_pdu,
|
dci_pdu,
|
||||||
@@ -1359,7 +1376,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
|
|
||||||
if (harq->round != 0) { /* retransmission */
|
if (harq->round != 0) { /* retransmission */
|
||||||
/* we do not have to do anything, since we do not require to get data
|
/* we do not have to do anything, since we do not require to get data
|
||||||
* from RLC or encode MAC CEs. The TX_req structure is filled below
|
* from RLC or encode MAC CEs. The TX_req structure is filled below
|
||||||
* or copy data to FAPI structures */
|
* or copy data to FAPI structures */
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
|
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
|
||||||
@@ -1370,20 +1387,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
current_harq_pid,
|
current_harq_pid,
|
||||||
harq->round,
|
harq->round,
|
||||||
harq->ndi);
|
harq->ndi);
|
||||||
|
|
||||||
AssertFatal(harq->sched_pdsch.tb_size == TBS,
|
AssertFatal(harq->sched_pdsch.tb_size == TBS,
|
||||||
"UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
"UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
||||||
UE_id,
|
UE_id,
|
||||||
current_harq_pid);
|
current_harq_pid);
|
||||||
|
|
||||||
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->tb, TBS));
|
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
|
||||||
} else { /* initial transmission */
|
} else { /* initial transmission */
|
||||||
|
|
||||||
LOG_D(NR_MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
|
LOG_D(NR_MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
|
||||||
|
uint8_t *buf = (uint8_t *) harq->transportBlock;
|
||||||
uint8_t *buf = (uint8_t *) harq->tb;
|
|
||||||
|
|
||||||
/* first, write all CEs that might be there */
|
/* first, write all CEs that might be there */
|
||||||
int written = nr_write_ce_dlsch_pdu(module_id,
|
int written = nr_write_ce_dlsch_pdu(module_id,
|
||||||
sched_ctrl,
|
sched_ctrl,
|
||||||
@@ -1391,32 +1403,30 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
255, // no drx
|
255, // no drx
|
||||||
NULL); // contention res id
|
NULL); // contention res id
|
||||||
buf += written;
|
buf += written;
|
||||||
int size = TBS - written;
|
uint8_t *bufEnd = buf + TBS - written;
|
||||||
DevAssert(size >= 0);
|
DevAssert(TBS > written);
|
||||||
|
int dlsch_total_bytes = 0;
|
||||||
/* next, get RLC data */
|
/* next, get RLC data */
|
||||||
|
|
||||||
start_meas(&gNB_mac->rlc_data_req);
|
start_meas(&gNB_mac->rlc_data_req);
|
||||||
if (sched_ctrl->num_total_bytes > 0) {
|
|
||||||
|
|
||||||
|
if (sched_ctrl->num_total_bytes > 0) {
|
||||||
/* loop over all activated logical channels */
|
/* loop over all activated logical channels */
|
||||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
||||||
|
|
||||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
const int lcid = sched_ctrl->dl_lc_ids[i];
|
||||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
|
||||||
continue; // no data for this LC
|
|
||||||
|
|
||||||
int dlsch_total_bytes = 0;
|
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||||
while (size > 3) {
|
continue; // no data for this LC tbs_size_t len = 0;
|
||||||
|
|
||||||
|
int lcid_bytes=0;
|
||||||
|
while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) {
|
||||||
// we do not know how much data we will get from RLC, i.e., whether it
|
// we do not know how much data we will get from RLC, i.e., whether it
|
||||||
// will be longer than 256B or not. Therefore, reserve space for long header, then
|
// will be longer than 256B or not. Therefore, reserve space for long header, then
|
||||||
// fetch data, then fill real length
|
// fetch data, then fill real length
|
||||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||||
buf += 3;
|
|
||||||
size -= 3;
|
|
||||||
|
|
||||||
/* limit requested number of bytes to what preprocessor specified, or
|
/* limit requested number of bytes to what preprocessor specified, or
|
||||||
* such that TBS is full */
|
* such that TBS is full */
|
||||||
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, size);
|
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||||
|
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||||
tbs_size_t len = mac_rlc_data_req(module_id,
|
tbs_size_t len = mac_rlc_data_req(module_id,
|
||||||
rnti,
|
rnti,
|
||||||
module_id,
|
module_id,
|
||||||
@@ -1425,12 +1435,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
MBMS_FLAG_NO,
|
MBMS_FLAG_NO,
|
||||||
lcid,
|
lcid,
|
||||||
ndata,
|
ndata,
|
||||||
(char *)buf,
|
(char *)buf+sizeof(NR_MAC_SUBHEADER_LONG),
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
LOG_D(NR_MAC,
|
LOG_D(NR_MAC,
|
||||||
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %d)\n",
|
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n",
|
||||||
frame,
|
frame,
|
||||||
slot,
|
slot,
|
||||||
rnti,
|
rnti,
|
||||||
@@ -1438,64 +1447,56 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
lcid < 4 ? "DCCH" : "DTCH",
|
lcid < 4 ? "DCCH" : "DTCH",
|
||||||
lcid,
|
lcid,
|
||||||
ndata,
|
ndata,
|
||||||
size);
|
bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG));
|
||||||
if (len == 0) {
|
|
||||||
/* RLC did not have data anymore, mark buffer as unused */
|
if (len == 0)
|
||||||
buf -= 3;
|
|
||||||
size += 3;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
header->R = 0;
|
header->R = 0;
|
||||||
header->F = 1;
|
header->F = 1;
|
||||||
header->LCID = lcid;
|
header->LCID = lcid;
|
||||||
header->L1 = (len >> 8) & 0xff;
|
header->L = htons(len);
|
||||||
header->L2 = len & 0xff;
|
buf += len+sizeof(NR_MAC_SUBHEADER_LONG);
|
||||||
size -= len;
|
|
||||||
buf += len;
|
|
||||||
dlsch_total_bytes += len;
|
dlsch_total_bytes += len;
|
||||||
|
lcid_bytes += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
|
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += lcid_bytes;
|
||||||
}
|
}
|
||||||
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
|
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
|
||||||
/* we will need the large header, phy-test typically allocates all
|
/* we will need the large header, phy-test typically allocates all
|
||||||
* resources and fills to the last byte below */
|
* resources and fills to the last byte below */
|
||||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d of random data\n", frame, slot, TBS);
|
||||||
buf += 3;
|
|
||||||
size -= 3;
|
if (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) ) {
|
||||||
DevAssert(size > 0);
|
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||||
LOG_D(NR_MAC, "Configuring DL_TX in %d.%d: TBS %d with %d B of random data\n", frame, slot, TBS, size);
|
// fill dlsch_buffer with random data
|
||||||
// fill dlsch_buffer with random data
|
header->R = 0;
|
||||||
for (int i = 0; i < size; i++)
|
header->F = 1;
|
||||||
buf[i] = lrand48() & 0xff;
|
header->LCID = DL_SCH_LCID_PADDING;
|
||||||
header->R = 0;
|
buf += sizeof(NR_MAC_SUBHEADER_LONG);
|
||||||
header->F = 1;
|
header->L = htons(bufEnd-buf);
|
||||||
header->LCID = DL_SCH_LCID_PADDING;
|
dlsch_total_bytes += bufEnd-buf;
|
||||||
header->L1 = (size >> 8) & 0xff;
|
|
||||||
header->L2 = size & 0xff;
|
for (; buf < bufEnd; buf++)
|
||||||
size -= size;
|
*buf = lrand48() & 0xff;
|
||||||
buf += size;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_meas(&gNB_mac->rlc_data_req);
|
stop_meas(&gNB_mac->rlc_data_req);
|
||||||
|
|
||||||
// Add padding header and zero rest out if there is space left
|
// Add padding header and zero rest out if there is space left
|
||||||
if (size > 0) {
|
if (bufEnd-buf > 0) {
|
||||||
NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf;
|
NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf;
|
||||||
padding->R = 0;
|
padding->R = 0;
|
||||||
padding->LCID = DL_SCH_LCID_PADDING;
|
padding->LCID = DL_SCH_LCID_PADDING;
|
||||||
size -= 1;
|
|
||||||
buf += 1;
|
buf += 1;
|
||||||
while (size > 0) {
|
memset(buf,0,bufEnd-buf);
|
||||||
*buf = 0;
|
buf=bufEnd;
|
||||||
buf += 1;
|
|
||||||
size -= 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
|
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
|
||||||
|
|
||||||
/* save retransmission information */
|
/* save retransmission information */
|
||||||
harq->sched_pdsch = *sched_pdsch;
|
harq->sched_pdsch = *sched_pdsch;
|
||||||
/* save which time allocation has been used, to be used on
|
/* save which time allocation has been used, to be used on
|
||||||
@@ -1514,7 +1515,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->tb, TBS));
|
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS));
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||||
@@ -1523,11 +1524,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
|||||||
tx_req->PDU_index = pduindex;
|
tx_req->PDU_index = pduindex;
|
||||||
tx_req->num_TLV = 1;
|
tx_req->num_TLV = 1;
|
||||||
tx_req->TLVs[0].length = TBS + 2;
|
tx_req->TLVs[0].length = TBS + 2;
|
||||||
memcpy(tx_req->TLVs[0].value.direct, harq->tb, TBS);
|
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS);
|
||||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||||
gNB_mac->TX_req[CC_id].SFN = frame;
|
gNB_mac->TX_req[CC_id].SFN = frame;
|
||||||
gNB_mac->TX_req[CC_id].Slot = slot;
|
gNB_mac->TX_req[CC_id].Slot = slot;
|
||||||
|
|
||||||
/* mark UE as scheduled */
|
/* mark UE as scheduled */
|
||||||
sched_pdsch->rbSize = 0;
|
sched_pdsch->rbSize = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
|||||||
&RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
|
&RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
|
||||||
AssertFatal(future_ul_tti_req->SFN == pucch->frame
|
AssertFatal(future_ul_tti_req->SFN == pucch->frame
|
||||||
&& future_ul_tti_req->Slot == pucch->ul_slot,
|
&& future_ul_tti_req->Slot == pucch->ul_slot,
|
||||||
"future UL_tti_req's frame.slot %d.%d does not match PUCCH %d.%d\n",
|
"future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n",
|
||||||
future_ul_tti_req->SFN,
|
future_ul_tti_req->SFN,
|
||||||
future_ul_tti_req->Slot,
|
future_ul_tti_req->Slot,
|
||||||
pucch->frame,
|
pucch->frame,
|
||||||
@@ -84,7 +84,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
|||||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||||
|
|
||||||
LOG_D(NR_MAC,"%d.%d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %d.%d\n",
|
LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
|
||||||
frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
|
frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
|
||||||
|
|
||||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||||
@@ -161,7 +161,7 @@ void nr_schedule_pucch(int Mod_idP,
|
|||||||
|| frameP != curr_pucch->frame
|
|| frameP != curr_pucch->frame
|
||||||
|| slotP != curr_pucch->ul_slot)
|
|| slotP != curr_pucch->ul_slot)
|
||||||
continue;
|
continue;
|
||||||
LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %d.%d O_ack %d\n",i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack);
|
LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %4d.%2d O_ack %d\n",i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack);
|
||||||
nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id);
|
nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id);
|
||||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||||
}
|
}
|
||||||
@@ -820,6 +820,7 @@ static void handle_dl_harq(module_id_t mod_id,
|
|||||||
stats->dlsch_errors++;
|
stats->dlsch_errors++;
|
||||||
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
|
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
|
||||||
} else {
|
} else {
|
||||||
|
LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id);
|
||||||
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
|
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
|
||||||
harq->round++;
|
harq->round++;
|
||||||
}
|
}
|
||||||
@@ -1398,7 +1399,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
|
|||||||
while (harq->feedback_frame != frame
|
while (harq->feedback_frame != frame
|
||||||
|| (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
|
|| (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
|
||||||
LOG_W(NR_MAC,
|
LOG_W(NR_MAC,
|
||||||
"expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the past)\n",
|
"expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the past)\n",
|
||||||
pid,
|
pid,
|
||||||
harq->feedback_frame,
|
harq->feedback_frame,
|
||||||
harq->feedback_slot,
|
harq->feedback_slot,
|
||||||
@@ -1414,7 +1415,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
|
|||||||
/* feedbacks that we wait for in the future: don't do anything */
|
/* feedbacks that we wait for in the future: don't do anything */
|
||||||
if (harq->feedback_slot > slot) {
|
if (harq->feedback_slot > slot) {
|
||||||
LOG_W(NR_MAC,
|
LOG_W(NR_MAC,
|
||||||
"expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the future)\n",
|
"expected HARQ pid %d feedback at %4d.%2d, but is at %4d.%2d instead (HARQ feedback is in the future)\n",
|
||||||
pid,
|
pid,
|
||||||
harq->feedback_frame,
|
harq->feedback_frame,
|
||||||
harq->feedback_slot,
|
harq->feedback_slot,
|
||||||
@@ -1451,7 +1452,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
|||||||
DevAssert(harq->is_waiting);
|
DevAssert(harq->is_waiting);
|
||||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||||
LOG_D(NR_MAC,"bit %d pid %d ack/nack %d\n",harq_bit,pid,harq_value);
|
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
||||||
handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0);
|
handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0);
|
||||||
if (harq_confidence == 1) UE_info->mac_stats[UE_id].pucch0_DTX++;
|
if (harq_confidence == 1) UE_info->mac_stats[UE_id].pucch0_DTX++;
|
||||||
}
|
}
|
||||||
@@ -1635,7 +1636,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||||
|
|
||||||
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
|
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
|
||||||
LOG_D(NR_MAC, "In %s: %d.%d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c);
|
LOG_D(NR_MAC, "In %s: %4d.%2d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c);
|
||||||
|
|
||||||
pucch->r_pucch=r_pucch;
|
pucch->r_pucch=r_pucch;
|
||||||
AssertFatal(pucch->csi_bits == 0,
|
AssertFatal(pucch->csi_bits == 0,
|
||||||
@@ -1649,7 +1650,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
* the same slot again */
|
* the same slot again */
|
||||||
const int f = pucch->frame;
|
const int f = pucch->frame;
|
||||||
const int s = pucch->ul_slot;
|
const int s = pucch->ul_slot;
|
||||||
LOG_D(NR_MAC, "In %s: %d.%d DAI = 2 pucch currently in %d.%d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
|
LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
|
||||||
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
||||||
memset(pucch, 0, sizeof(*pucch));
|
memset(pucch, 0, sizeof(*pucch));
|
||||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||||
@@ -1676,7 +1677,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c);
|
LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c);
|
||||||
|
|
||||||
// this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP
|
// this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP
|
||||||
NR_BWP_UplinkDedicated_t *ubwpd=NULL;
|
NR_BWP_UplinkDedicated_t *ubwpd=NULL;
|
||||||
@@ -1696,7 +1697,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
int max_fb_time = 0;
|
int max_fb_time = 0;
|
||||||
get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
|
get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: 1b. DL %d.%d, UL_ACK %d.%d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
|
LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
|
||||||
/* there is a HARQ. Check whether we can use it for this ACKNACK */
|
/* there is a HARQ. Check whether we can use it for this ACKNACK */
|
||||||
if (pucch->dai_c > 0) {
|
if (pucch->dai_c > 0) {
|
||||||
/* this UE already has a PUCCH occasion */
|
/* this UE already has a PUCCH occasion */
|
||||||
@@ -1716,7 +1717,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
const int f = pucch->frame;
|
const int f = pucch->frame;
|
||||||
const int s = pucch->ul_slot;
|
const int s = pucch->ul_slot;
|
||||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||||
LOG_D(NR_MAC, "In %s: %d.%d DAI > 0, cannot reach timing for pucch in %d.%d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s);
|
LOG_D(NR_MAC, "In %s: %4d.%2d DAI > 0, cannot reach timing for pucch in %4d.%2d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s);
|
||||||
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
||||||
memset(pucch, 0, sizeof(*pucch));
|
memset(pucch, 0, sizeof(*pucch));
|
||||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||||
@@ -1730,11 +1731,11 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
pucch->timing_indicator = i;
|
pucch->timing_indicator = i;
|
||||||
pucch->dai_c++;
|
pucch->dai_c++;
|
||||||
// retain old resource indicator, and we are good
|
// retain old resource indicator, and we are good
|
||||||
LOG_D(NR_MAC, "In %s: %d.%d. DAI > 0, pucch allocated for %d.%d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
LOG_D(NR_MAC, "In %s: %4d.%2d. DAI > 0, pucch allocated for %4d.%2d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: %d.%d DAI = 0, looking for new pucch occasion\n", __FUNCTION__, frame, slot);
|
LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 0, looking for new pucch occasion\n", __FUNCTION__, frame, slot);
|
||||||
/* we need to find a new PUCCH occasion */
|
/* we need to find a new PUCCH occasion */
|
||||||
|
|
||||||
/*(Re)Inizialization of timing information*/
|
/*(Re)Inizialization of timing information*/
|
||||||
@@ -1837,7 +1838,7 @@ int nr_acknack_scheduling(int mod_id,
|
|||||||
|
|
||||||
pucch->timing_indicator = ind_found; // index in the list of timing indicators
|
pucch->timing_indicator = ind_found; // index in the list of timing indicators
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: 2. DAI 0 DL %d.%d, UL_ACK %d.%d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
LOG_D(NR_MAC, "In %s: 2. DAI 0 DL %4d.%2d, UL_ACK %4d.%2d (index %d)\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->timing_indicator);
|
||||||
|
|
||||||
pucch->dai_c++;
|
pucch->dai_c++;
|
||||||
pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
|
pucch->resource_indicator = 0; // each UE has dedicated PUCCH resources
|
||||||
|
|||||||
@@ -213,11 +213,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
int pdu_len)
|
int pdu_len)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint8_t rx_lcid;
|
|
||||||
uint8_t done = 0;
|
uint8_t done = 0;
|
||||||
uint16_t mac_ce_len;
|
|
||||||
uint16_t mac_subheader_len;
|
|
||||||
uint16_t mac_sdu_len;
|
|
||||||
|
|
||||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||||
@@ -231,10 +228,9 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (!done && pdu_len > 0){
|
while (!done && pdu_len > 0){
|
||||||
mac_ce_len = 0;
|
uint16_t mac_len=0;
|
||||||
mac_subheader_len = sizeof(NR_MAC_SUBHEADER_FIXED);
|
uint16_t mac_subheader_len=sizeof(NR_MAC_SUBHEADER_FIXED);
|
||||||
mac_sdu_len = 0;
|
uint8_t rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
||||||
rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID;
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len);
|
LOG_D(NR_MAC, "In %s: received UL-SCH sub-PDU with LCID 0x%x in %d.%d (remaining PDU length %d)\n", __func__, rx_lcid, frameP, slot, pdu_len);
|
||||||
|
|
||||||
@@ -249,7 +245,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
#endif*/
|
#endif*/
|
||||||
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
|
case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY:
|
||||||
// 38.321 Ch6.1.3.20
|
// 38.321 Ch6.1.3.20
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
break;
|
break;
|
||||||
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
|
case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION:
|
||||||
// 38.321 Ch6.1.3.7
|
// 38.321 Ch6.1.3.7
|
||||||
@@ -259,7 +255,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
case UL_SCH_LCID_S_TRUNCATED_BSR:
|
case UL_SCH_LCID_S_TRUNCATED_BSR:
|
||||||
//38.321 section 6.1.3.1
|
//38.321 section 6.1.3.1
|
||||||
//fixed length
|
//fixed length
|
||||||
mac_ce_len =1;
|
mac_len =1;
|
||||||
/* Extract short BSR value */
|
/* Extract short BSR value */
|
||||||
ce_ptr = &pduP[mac_subheader_len];
|
ce_ptr = &pduP[mac_subheader_len];
|
||||||
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
|
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
|
||||||
@@ -284,16 +280,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
to be a partial PDU at the end of this buffer, so here
|
to be a partial PDU at the end of this buffer, so here
|
||||||
we gracefully ignore that by returning 0. See:
|
we gracefully ignore that by returning 0. See:
|
||||||
https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues/534 */
|
https://gitlab.eurecom.fr/oai/openairinterface5g/-/issues/534 */
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
return 0;
|
return 0;
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
|
||||||
return 0;
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
/* Extract long BSR value */
|
/* Extract long BSR value */
|
||||||
ce_ptr = &pduP[mac_subheader_len];
|
ce_ptr = &pduP[mac_subheader_len];
|
||||||
NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
|
NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr;
|
||||||
@@ -339,14 +327,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
|
|
||||||
//38.321 section 6.1.3.2
|
//38.321 section 6.1.3.2
|
||||||
//fixed length
|
//fixed length
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
/* Extract CRNTI value */
|
/* Extract CRNTI value */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
case UL_SCH_LCID_SINGLE_ENTRY_PHR:
|
||||||
//38.321 section 6.1.3.8
|
//38.321 section 6.1.3.8
|
||||||
//fixed length
|
//fixed length
|
||||||
mac_ce_len = 2;
|
mac_len = 2;
|
||||||
/* Extract SINGLE ENTRY PHR elements for PHR calculation */
|
/* Extract SINGLE ENTRY PHR elements for PHR calculation */
|
||||||
ce_ptr = &pduP[mac_subheader_len];
|
ce_ptr = &pduP[mac_subheader_len];
|
||||||
NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
|
NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
|
||||||
@@ -367,32 +355,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
|
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
|
||||||
//38.321 section 6.1.3.9
|
//38.321 section 6.1.3.9
|
||||||
// varialbe length
|
// varialbe length
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
return 0;
|
return 0;
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
|
||||||
return 0;
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
/* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */
|
/* Extract MULTI ENTRY PHR elements from single octet bitmap for PHR calculation */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
|
case UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT:
|
||||||
//38.321 section 6.1.3.9
|
//38.321 section 6.1.3.9
|
||||||
// varialbe length
|
// varialbe length
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
return 0;
|
return 0;
|
||||||
mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
|
||||||
return 0;
|
|
||||||
mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
}
|
|
||||||
/* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */
|
/* Extract MULTI ENTRY PHR elements from four octets bitmap for PHR calculation */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -403,27 +375,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
|
|
||||||
case UL_SCH_LCID_SRB1:
|
case UL_SCH_LCID_SRB1:
|
||||||
case UL_SCH_LCID_SRB2:
|
case UL_SCH_LCID_SRB2:
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
return 0;
|
return 0;
|
||||||
if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
|
|
||||||
//mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
|
||||||
return 0;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
|
|
||||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
|
|
||||||
} else {
|
|
||||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
rnti_t crnti = UE_info->rnti[UE_id];
|
rnti_t crnti = UE_info->rnti[UE_id];
|
||||||
int UE_idx = UE_id;
|
int UE_idx = UE_id;
|
||||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) {
|
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) {
|
||||||
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_sdu_len;
|
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
|
||||||
if ((pduP[mac_subheader_len+mac_sdu_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
||||||
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
||||||
UE_idx = find_nr_UE_id(module_idP, crnti);
|
UE_idx = find_nr_UE_id(module_idP, crnti);
|
||||||
break;
|
break;
|
||||||
@@ -432,7 +393,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (UE_info->CellGroup[UE_idx]) {
|
if (UE_info->CellGroup[UE_idx]) {
|
||||||
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, crnti);
|
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_len, crnti);
|
||||||
mac_rlc_data_ind(module_idP,
|
mac_rlc_data_ind(module_idP,
|
||||||
crnti,
|
crnti,
|
||||||
module_idP,
|
module_idP,
|
||||||
@@ -441,7 +402,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
MBMS_FLAG_NO,
|
MBMS_FLAG_NO,
|
||||||
rx_lcid,
|
rx_lcid,
|
||||||
(char *) (pduP + mac_subheader_len),
|
(char *) (pduP + mac_subheader_len),
|
||||||
mac_sdu_len,
|
mac_len,
|
||||||
1,
|
1,
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
@@ -459,23 +420,23 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
|
|
||||||
if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
|
if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
|
||||||
// RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
|
// RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
|
||||||
mac_sdu_len = 8;
|
mac_len = 8;
|
||||||
|
|
||||||
// Check if it is a valid CCCH1 message, we get all 00's messages very often
|
// Check if it is a valid CCCH1 message, we get all 00's messages very often
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
|
for(i=0; i<(mac_subheader_len+mac_len); i++) {
|
||||||
if(pduP[i] != 0) {
|
if(pduP[i] != 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == (mac_subheader_len+mac_sdu_len)) {
|
if (i == (mac_subheader_len+mac_len)) {
|
||||||
LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
|
LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// fixed length of 6 bytes
|
// fixed length of 6 bytes
|
||||||
mac_sdu_len = 6;
|
mac_len = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_mac_rrc_data_ind(module_idP,
|
nr_mac_rrc_data_ind(module_idP,
|
||||||
@@ -486,26 +447,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
UE_info->rnti[UE_id],
|
UE_info->rnti[UE_id],
|
||||||
CCCH,
|
CCCH,
|
||||||
pduP + mac_subheader_len,
|
pduP + mac_subheader_len,
|
||||||
mac_sdu_len,
|
mac_len,
|
||||||
0);
|
0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UL_SCH_LCID_DTCH:
|
case UL_SCH_LCID_DTCH:
|
||||||
// check if LCID is valid at current time.
|
// check if LCID is valid at current time.
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT))
|
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||||
return 0;
|
return 0;
|
||||||
if (((NR_MAC_SUBHEADER_SHORT *)pduP)->F) {
|
|
||||||
// mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
|
|
||||||
if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG))
|
|
||||||
return 0;
|
|
||||||
mac_subheader_len = 3;
|
|
||||||
mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L1 & 0x7f) << 8)
|
|
||||||
| ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pduP)->L2 & 0xff);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
|
|
||||||
mac_subheader_len = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_D(NR_MAC, "In %s: [UE %d] %d.%d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
|
LOG_D(NR_MAC, "In %s: [UE %d] %d.%d : ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
|
||||||
__func__,
|
__func__,
|
||||||
@@ -515,8 +464,8 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
rx_lcid<4?"DCCH":"DTCH",
|
rx_lcid<4?"DCCH":"DTCH",
|
||||||
rx_lcid,
|
rx_lcid,
|
||||||
module_idP,
|
module_idP,
|
||||||
mac_sdu_len);
|
mac_len);
|
||||||
UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
|
UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_len;
|
||||||
|
|
||||||
mac_rlc_data_ind(module_idP,
|
mac_rlc_data_ind(module_idP,
|
||||||
UE_info->rnti[UE_id],
|
UE_info->rnti[UE_id],
|
||||||
@@ -526,13 +475,13 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
MBMS_FLAG_NO,
|
MBMS_FLAG_NO,
|
||||||
rx_lcid,
|
rx_lcid,
|
||||||
(char *)(pduP + mac_subheader_len),
|
(char *)(pduP + mac_subheader_len),
|
||||||
mac_sdu_len,
|
mac_len,
|
||||||
1,
|
1,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* Updated estimated buffer when receiving data */
|
/* Updated estimated buffer when receiving data */
|
||||||
if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
|
if (sched_ctrl->estimated_ul_buffer >= mac_len)
|
||||||
sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
|
sched_ctrl->estimated_ul_buffer -= mac_len;
|
||||||
else
|
else
|
||||||
sched_ctrl->estimated_ul_buffer = 0;
|
sched_ctrl->estimated_ul_buffer = 0;
|
||||||
break;
|
break;
|
||||||
@@ -547,16 +496,16 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
|||||||
if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) {
|
if (rx_lcid < 45 || rx_lcid == 52 || rx_lcid == 63) {
|
||||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid);
|
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU sub-header with length %d (LCID = 0x%02x):\n", __func__, mac_subheader_len, rx_lcid);
|
||||||
log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n");
|
log_dump(NR_MAC, pduP, mac_subheader_len, LOG_DUMP_CHAR, "\n");
|
||||||
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_sdu_len, rx_lcid);
|
LOG_I(NR_MAC, "In %s: dumping UL MAC SDU with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
||||||
log_dump(NR_MAC, pduP + mac_subheader_len, mac_sdu_len, LOG_DUMP_CHAR, "\n");
|
log_dump(NR_MAC, pduP + mac_subheader_len, mac_len, LOG_DUMP_CHAR, "\n");
|
||||||
} else {
|
} else {
|
||||||
LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_ce_len, rx_lcid);
|
LOG_I(NR_MAC, "In %s: dumping UL MAC CE with length %d (LCID = 0x%02x):\n", __func__, mac_len, rx_lcid);
|
||||||
log_dump(NR_MAC, pduP + mac_subheader_len + mac_sdu_len, mac_ce_len, LOG_DUMP_CHAR, "\n");
|
log_dump(NR_MAC, pduP + mac_subheader_len + mac_len, mac_len, LOG_DUMP_CHAR, "\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
pduP += ( mac_subheader_len + mac_len );
|
||||||
pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len );
|
pdu_len -= ( mac_subheader_len + mac_len );
|
||||||
|
|
||||||
if (pdu_len < 0) {
|
if (pdu_len < 0) {
|
||||||
LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len);
|
LOG_E(NR_MAC, "In %s: residual UL MAC PDU in %d.%d with length < 0!, pdu_len %d \n", __func__, frameP, slot, pdu_len);
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ typedef struct NR_UE_harq {
|
|||||||
|
|
||||||
/* Transport block to be sent using this HARQ process, its size is in
|
/* Transport block to be sent using this HARQ process, its size is in
|
||||||
* sched_pdsch */
|
* sched_pdsch */
|
||||||
uint32_t tb[16384];
|
uint32_t transportBlock[16384];
|
||||||
uint32_t tb_size;
|
uint32_t tb_size;
|
||||||
|
|
||||||
/// sched_pdsch keeps information on MCS etc used for the initial transmission
|
/// sched_pdsch keeps information on MCS etc used for the initial transmission
|
||||||
|
|||||||
@@ -89,13 +89,13 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
|
|||||||
int sd = socket(server_address.sin_family, SOCK_DGRAM, 0);
|
int sd = socket(server_address.sin_family, SOCK_DGRAM, 0);
|
||||||
if (sd < 0)
|
if (sd < 0)
|
||||||
{
|
{
|
||||||
LOG_E(MAC, "Socket creation error standalone PNF\n");
|
LOG_E(NR_MAC, "Socket creation error standalone PNF\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inet_pton(server_address.sin_family, stub_eth_params.remote_addr, &server_address.sin_addr) <= 0)
|
if (inet_pton(server_address.sin_family, stub_eth_params.remote_addr, &server_address.sin_addr) <= 0)
|
||||||
{
|
{
|
||||||
LOG_E(MAC, "Invalid standalone PNF Address\n");
|
LOG_E(NR_MAC, "Invalid standalone PNF Address\n");
|
||||||
close(sd);
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
|
|||||||
// Using connect to use send() instead of sendto()
|
// Using connect to use send() instead of sendto()
|
||||||
if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
||||||
{
|
{
|
||||||
LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
LOG_E(NR_MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||||
close(sd);
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ void nrue_init_standalone_socket(int tx_port, int rx_port)
|
|||||||
|
|
||||||
if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0)
|
||||||
{
|
{
|
||||||
LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
LOG_E(NR_MAC, "Connection to standalone PNF failed: %s\n", strerror(errno));
|
||||||
close(sd);
|
close(sd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -634,6 +634,7 @@ static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, n
|
|||||||
AssertFatal(num_pdus >= 0, "Invalid ul_tti_request number of PDUS\n");
|
AssertFatal(num_pdus >= 0, "Invalid ul_tti_request number of PDUS\n");
|
||||||
AssertFatal(num_pdus <= sizeof(ul_tti_req->pdus_list) / sizeof(ul_tti_req->pdus_list[0]),
|
AssertFatal(num_pdus <= sizeof(ul_tti_req->pdus_list) / sizeof(ul_tti_req->pdus_list[0]),
|
||||||
"Too many pdus %d in ul_tti_req\n", num_pdus);
|
"Too many pdus %d in ul_tti_req\n", num_pdus);
|
||||||
|
|
||||||
if (!send_crc_ind_and_rx_ind(sfn_slot))
|
if (!send_crc_ind_and_rx_ind(sfn_slot))
|
||||||
{
|
{
|
||||||
LOG_T(NR_MAC, "CRC_RX ind not sent\n");
|
LOG_T(NR_MAC, "CRC_RX ind not sent\n");
|
||||||
@@ -1045,7 +1046,7 @@ void *nrue_standalone_pnf_task(void *context)
|
|||||||
|
|
||||||
if (sem_post(&sfn_slot_semaphore) != 0)
|
if (sem_post(&sfn_slot_semaphore) != 0)
|
||||||
{
|
{
|
||||||
LOG_E(MAC, "sem_post() error\n");
|
LOG_E(NR_MAC, "sem_post() error\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1125,13 +1126,13 @@ void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nac
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//shouldn't get here
|
//shouldn't get here
|
||||||
LOG_E(MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
|
LOG_E(NR_MAC, "Trying to process acknack for an inactive harq process (%d)\n", harq_pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
|
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
|
||||||
|
|
||||||
NR_UE_L2_STATE_t ret;
|
NR_UE_L2_STATE_t ret=0;
|
||||||
module_id_t module_id = ul_info->module_id;
|
module_id_t module_id = ul_info->module_id;
|
||||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||||
|
|
||||||
@@ -1183,6 +1184,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
|||||||
} else {
|
} else {
|
||||||
// UL indication after reception of DCI or DL PDU
|
// UL indication after reception of DCI or DL PDU
|
||||||
if (dl_info && dl_info->dci_ind && dl_info->dci_ind->number_of_dcis) {
|
if (dl_info && dl_info->dci_ind && dl_info->dci_ind->number_of_dcis) {
|
||||||
|
|
||||||
LOG_T(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
|
LOG_T(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n");
|
||||||
for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) {
|
for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) {
|
||||||
LOG_T(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
|
LOG_T(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis);
|
||||||
@@ -1198,8 +1200,8 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
|||||||
|
|
||||||
/* The check below filters out UL_DCIs (format 7) which are being processed as DL_DCIs. */
|
/* 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) {
|
if (dci_index->dci_format == 7 && mac->ra.ra_state == RA_SUCCEEDED) {
|
||||||
LOG_T(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
|
LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n");
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format];
|
dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format];
|
||||||
g_harq_pid = def_dci_pdu_rel15->harq_pid;
|
g_harq_pid = def_dci_pdu_rel15->harq_pid;
|
||||||
@@ -1222,7 +1224,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
|
|||||||
|
|
||||||
for (int i=0; i<dl_info->rx_ind->number_pdus; ++i) {
|
for (int i=0; i<dl_info->rx_ind->number_pdus; ++i) {
|
||||||
|
|
||||||
LOG_T(MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
|
LOG_D(NR_MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
dl_info->rx_ind->rx_indication_body[i].pdu_type,
|
dl_info->rx_ind->rx_indication_body[i].pdu_type,
|
||||||
dl_info->rx_ind->number_pdus);
|
dl_info->rx_ind->number_pdus);
|
||||||
|
|||||||
@@ -969,9 +969,9 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
|
|||||||
uint16_t ue_initial_id;
|
uint16_t ue_initial_id;
|
||||||
uint32_t gNB_ue_ngap_id;
|
uint32_t gNB_ue_ngap_id;
|
||||||
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
rrc_gNB_ue_context_t *ue_context_p = NULL;
|
||||||
protocol_ctxt_t ctxt;
|
protocol_ctxt_t ctxt={0};
|
||||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req;
|
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
|
||||||
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp;
|
gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
|
||||||
uint8_t pdu_sessions_done;
|
uint8_t pdu_sessions_done;
|
||||||
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
uint8_t inde_list[NR_NB_RB_MAX - 3]= {0};
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) {
|
|||||||
size += 10;
|
size += 10;
|
||||||
|
|
||||||
// encode the message
|
// encode the message
|
||||||
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
|
initialNasMsg->data = malloc16_clear(size * sizeof(Byte_t));
|
||||||
registration_request_buf = initialNasMsg->data;
|
registration_request_buf = initialNasMsg->data;
|
||||||
|
|
||||||
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
|
||||||
|
|||||||
@@ -52,7 +52,8 @@
|
|||||||
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
|
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
|
||||||
legacy: we regenerate each sub frame in UL, and each frame only in DL
|
legacy: we regenerate each sub frame in UL, and each frame only in DL
|
||||||
*/
|
*/
|
||||||
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
|
void rxAddInput( const c16_t *input_sig,
|
||||||
|
c16_t *after_channel_sig,
|
||||||
int rxAnt,
|
int rxAnt,
|
||||||
channel_desc_t *channelDesc,
|
channel_desc_t *channelDesc,
|
||||||
int nbSamples,
|
int nbSamples,
|
||||||
@@ -73,7 +74,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
|
|||||||
const int nbTx=channelDesc->nb_tx;
|
const int nbTx=channelDesc->nb_tx;
|
||||||
|
|
||||||
for (int i=0; i<((int)nbSamples-dd); i++) {
|
for (int i=0; i<((int)nbSamples-dd); i++) {
|
||||||
struct complex16 *out_ptr=after_channel_sig+dd+i;
|
c16_t *out_ptr=after_channel_sig+dd+i;
|
||||||
struct complexd rx_tmp= {0};
|
struct complexd rx_tmp= {0};
|
||||||
|
|
||||||
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
||||||
@@ -87,7 +88,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
|
|||||||
// but it is not very usefull
|
// but it is not very usefull
|
||||||
// it would be better to split out each antenna in a separate flow
|
// it would be better to split out each antenna in a separate flow
|
||||||
// that will allow to mix ru antennas freely
|
// that will allow to mix ru antennas freely
|
||||||
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
|
c16_t tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
|
||||||
rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
|
rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
|
||||||
rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
|
rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
|
||||||
} //l
|
} //l
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
#define __RFSIMULATOR_H
|
#define __RFSIMULATOR_H
|
||||||
double gaussZiggurat(double mean, double variance);
|
double gaussZiggurat(double mean, double variance);
|
||||||
void tableNor(unsigned long seed);
|
void tableNor(unsigned long seed);
|
||||||
void rxAddInput( struct complex16 *input_sig,
|
void rxAddInput( const c16_t *input_sig,
|
||||||
struct complex16 *after_channel_sig,
|
c16_t *after_channel_sig,
|
||||||
int rxAnt,
|
int rxAnt,
|
||||||
channel_desc_t *channelDesc,
|
channel_desc_t *channelDesc,
|
||||||
int nbSamples,
|
int nbSamples,
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ static telnetshell_vardef_t rfsimu_vardef[] = {
|
|||||||
};
|
};
|
||||||
pthread_mutex_t Sockmutex;
|
pthread_mutex_t Sockmutex;
|
||||||
|
|
||||||
typedef struct complex16 sample_t; // 2*16 bits complex number
|
typedef c16_t sample_t; // 2*16 bits complex number
|
||||||
|
|
||||||
typedef struct buffer_s {
|
typedef struct buffer_s {
|
||||||
int conn_sock;
|
int conn_sock;
|
||||||
@@ -495,7 +495,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
|||||||
setblocking(conn_sock, notBlocking);
|
setblocking(conn_sock, notBlocking);
|
||||||
allocCirBuf(t, conn_sock);
|
allocCirBuf(t, conn_sock);
|
||||||
LOG_I(HW,"A client connected, sending the current time\n");
|
LOG_I(HW,"A client connected, sending the current time\n");
|
||||||
struct complex16 v= {0};
|
c16_t v= {0};
|
||||||
void *samplesVoid[t->tx_num_channels];
|
void *samplesVoid[t->tx_num_channels];
|
||||||
|
|
||||||
for ( int i=0; i < t->tx_num_channels; i++)
|
for ( int i=0; i < t->tx_num_channels; i++)
|
||||||
@@ -665,7 +665,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
|
|||||||
// We send timestamp for nb samples required
|
// We send timestamp for nb samples required
|
||||||
// assuming this should have been done earlier if a Tx would exist
|
// assuming this should have been done earlier if a Tx would exist
|
||||||
pthread_mutex_unlock(&Sockmutex);
|
pthread_mutex_unlock(&Sockmutex);
|
||||||
struct complex16 v= {0};
|
c16_t v= {0};
|
||||||
void *dummyS[t->tx_num_channels];
|
void *dummyS[t->tx_num_channels];
|
||||||
|
|
||||||
for ( int i=0; i < t->tx_num_channels; i++)
|
for ( int i=0; i < t->tx_num_channels; i++)
|
||||||
@@ -728,7 +728,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest
|
|||||||
|
|
||||||
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
|
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
|
||||||
if ( ptr->channel_model != NULL ) // apply a channel model
|
if ( ptr->channel_model != NULL ) // apply a channel model
|
||||||
rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
|
rxAddInput( ptr->circularBuf, (c16_t *) samplesVoid[a],
|
||||||
a,
|
a,
|
||||||
ptr->channel_model,
|
ptr->channel_model,
|
||||||
nsamps,
|
nsamps,
|
||||||
|
|||||||
@@ -93,9 +93,6 @@ extern uint16_t sf_ahead;
|
|||||||
|
|
||||||
void ue_stub_rx_handler(unsigned int, char *);
|
void ue_stub_rx_handler(unsigned int, char *);
|
||||||
|
|
||||||
int32_t **rxdata;
|
|
||||||
int32_t **txdata;
|
|
||||||
|
|
||||||
int timer_subframe = 0;
|
int timer_subframe = 0;
|
||||||
int timer_frame = 0;
|
int timer_frame = 0;
|
||||||
SF_ticking *phy_stub_ticking = NULL;
|
SF_ticking *phy_stub_ticking = NULL;
|
||||||
@@ -1938,7 +1935,7 @@ void write_dummy(PHY_VARS_UE *UE, openair0_timestamp timestamp) {
|
|||||||
// we have to write to tell explicitly to the eNB, else it will wait for us forever
|
// we have to write to tell explicitly to the eNB, else it will wait for us forever
|
||||||
// we write the next subframe (always write in future of what we received)
|
// we write the next subframe (always write in future of what we received)
|
||||||
//
|
//
|
||||||
struct complex16 v= {0};
|
c16_t v= {0};
|
||||||
void *samplesVoid[UE->frame_parms.nb_antennas_tx];
|
void *samplesVoid[UE->frame_parms.nb_antennas_tx];
|
||||||
|
|
||||||
for ( int i=0; i < UE->frame_parms.nb_antennas_tx; i++)
|
for ( int i=0; i < UE->frame_parms.nb_antennas_tx; i++)
|
||||||
@@ -2486,23 +2483,18 @@ int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue,
|
|||||||
AssertFatal( phy_vars_ue[CC_id] !=0, "");
|
AssertFatal( phy_vars_ue[CC_id] !=0, "");
|
||||||
frame_parms = &(phy_vars_ue[CC_id]->frame_parms);
|
frame_parms = &(phy_vars_ue[CC_id]->frame_parms);
|
||||||
// replace RX signal buffers with mmaped HW versions
|
// replace RX signal buffers with mmaped HW versions
|
||||||
rxdata = (int32_t **)malloc16( frame_parms->nb_antennas_rx*sizeof(int32_t *) );
|
|
||||||
txdata = (int32_t **)malloc16( frame_parms->nb_antennas_tx*sizeof(int32_t *) );
|
|
||||||
|
|
||||||
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
|
for (i=0; i<frame_parms->nb_antennas_rx; i++) {
|
||||||
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %lu on card %d, chain %d\n",
|
LOG_I(PHY, "Mapping UE CC_id %d, rx_ant %d, freq %lu on card %d, chain %d\n",
|
||||||
CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
|
CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
|
||||||
free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
|
free( phy_vars_ue[CC_id]->common_vars.rxdata[i] );
|
||||||
rxdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
|
phy_vars_ue[CC_id]->common_vars.rxdata[i] = malloc16_clear( 307200*sizeof(int32_t) ); // what about the "-N_TA_offset" ? // N_TA offset for TDD
|
||||||
phy_vars_ue[CC_id]->common_vars.rxdata[i] = rxdata[i]; // what about the "-N_TA_offset" ? // N_TA offset for TDD
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
|
for (i=0; i<frame_parms->nb_antennas_tx; i++) {
|
||||||
LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %lu on card %d, chain %d\n",
|
LOG_I(PHY, "Mapping UE CC_id %d, tx_ant %d, freq %lu on card %d, chain %d\n",
|
||||||
CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
|
CC_id, i, downlink_frequency[CC_id][i], phy_vars_ue[CC_id]->rf_map.card, (phy_vars_ue[CC_id]->rf_map.chain)+i );
|
||||||
free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
|
free( phy_vars_ue[CC_id]->common_vars.txdata[i] );
|
||||||
txdata[i] = (int32_t *)malloc16_clear( 307200*sizeof(int32_t) );
|
phy_vars_ue[CC_id]->common_vars.txdata[i] = malloc16_clear( 307200*sizeof(int32_t) );
|
||||||
phy_vars_ue[CC_id]->common_vars.txdata[i] = txdata[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x]
|
// rxdata[x] points now to the same memory region as phy_vars_ue[CC_id]->common_vars.rxdata[x]
|
||||||
|
|||||||
Reference in New Issue
Block a user