Merge remote-tracking branch 'develop'
This commit is contained in:
@@ -178,6 +178,8 @@ function build_on_vm {
|
||||
echo "mkdir -p cmake_targets/log" >> $VM_CMDS
|
||||
echo "chmod 777 cmake_targets/log" >> $VM_CMDS
|
||||
echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS
|
||||
# Patching the pistache build for Xenial (cmake too old for new commits)
|
||||
echo "sed -i -e 's@cd pistache@cd pistache \&\& git checkout -f 9a65f40975fafca5bb5370ba6d0d00f42cbc4356@' ./tools/install_dependencies" >> $VM_CMDS
|
||||
echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS
|
||||
echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS
|
||||
echo "echo \"mkdir build\"" >> $VM_CMDS
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<testCase id="090102">
|
||||
<class>Initialize_OAI_UE</class>
|
||||
<desc>Initialize NR UE USRP</desc>
|
||||
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path .</Initialize_OAI_UE_args>
|
||||
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path .</Initialize_OAI_UE_args>
|
||||
<air_interface>NR</air_interface>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<testCase id="090104">
|
||||
<class>Initialize_OAI_UE</class>
|
||||
<desc>Initialize NR UE USRP</desc>
|
||||
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path .</Initialize_OAI_UE_args>
|
||||
<Initialize_OAI_UE_args>--phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path .</Initialize_OAI_UE_args>
|
||||
<air_interface>NR</air_interface>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -3232,6 +3232,7 @@ add_executable(nr_dlschsim
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
@@ -3246,6 +3247,7 @@ add_executable(nr_pbchsim
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
@@ -3262,6 +3264,7 @@ add_executable(nr_pucchsim
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
@@ -3280,6 +3283,7 @@ add_executable(nr_dlsim
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
@@ -3299,6 +3303,7 @@ add_executable(nr_prachsim
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES})
|
||||
|
||||
@@ -148,6 +148,7 @@ extern "C" {
|
||||
#define DEBUG_SECURITY (1<<11)
|
||||
#define DEBUG_NAS (1<<12)
|
||||
#define DEBUG_RLC (1<<13)
|
||||
#define DEBUG_DLSCH_DECOD (1<<14)
|
||||
#define UE_TIMING (1<<20)
|
||||
|
||||
|
||||
@@ -166,6 +167,7 @@ extern "C" {
|
||||
{"SECURITY", DEBUG_SECURITY},\
|
||||
{"NAS", DEBUG_NAS},\
|
||||
{"RLC", DEBUG_RLC},\
|
||||
{"DLSCH_DECOD", DEBUG_DLSCH_DECOD},\
|
||||
{"UE_TIMING", UE_TIMING},\
|
||||
{NULL,-1}\
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void *one_thread(void *arg) {
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
|
||||
void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name) {
|
||||
memset(pool,0,sizeof(*pool));
|
||||
char *measr=getenv("threadPoolMeasurements");
|
||||
pool->measurePerf=performanceMeas;
|
||||
@@ -116,6 +116,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
|
||||
pool->restrictRNTI=false;
|
||||
curptr=strtok_r(parms_cpy,",",&saveptr);
|
||||
struct one_thread * ptr;
|
||||
char *tname = (name == NULL ? "Tpool" : name);
|
||||
while ( curptr!=NULL ) {
|
||||
int c=toupper(curptr[0]);
|
||||
|
||||
@@ -129,7 +130,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
|
||||
break;
|
||||
|
||||
default:
|
||||
ptr=pool->allthreads;
|
||||
ptr=pool->allthreads;
|
||||
pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread));
|
||||
pool->allthreads->next=ptr;
|
||||
printf("create a thread for core %d\n", atoi(curptr));
|
||||
@@ -138,7 +139,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
|
||||
pool->allthreads->pool=pool;
|
||||
//Configure the thread scheduler policy for Linux
|
||||
// set the thread name for debugging
|
||||
sprintf(pool->allthreads->name,"Tpool_%d",pool->allthreads->coreID);
|
||||
sprintf(pool->allthreads->name,"%s%d_%d",tname,pool->nbThreads,pool->allthreads->coreID);
|
||||
threadCreate(&pool->allthreads->threadID, one_thread, (void *)pool->allthreads,
|
||||
pool->allthreads->name, pool->allthreads->coreID, OAI_PRIORITY_RT);
|
||||
pool->nbThreads++;
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,"");
|
||||
#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
|
||||
#define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
|
||||
|
||||
#define tpool_nbthreads(tpool) (tpool.nbThreads)
|
||||
typedef struct notifiedFIFO_elt_s {
|
||||
struct notifiedFIFO_elt_s *next;
|
||||
uint64_t key; //To filter out elements
|
||||
@@ -294,6 +294,6 @@ static inline int abortTpool(tpool_t *t, uint64_t key) {
|
||||
mutexunlock(nf->lockF);
|
||||
return nbRemoved;
|
||||
}
|
||||
void initTpool(char *params,tpool_t *pool, bool performanceMeas);
|
||||
|
||||
void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name);
|
||||
#define initTpool(PARAMPTR,TPOOLPTR, MEASURFLAG) initNamedTpool(PARAMPTR,TPOOLPTR, MEASURFLAG, NULL)
|
||||
#endif
|
||||
|
||||
@@ -112,13 +112,13 @@ No delete() call, same principle as not thread safe queues
|
||||
# Thread pools
|
||||
|
||||
## initialization
|
||||
The clients can create one or more thread pools with init_tpool()
|
||||
The clients can create one or more thread pools with `initTpool(char *params,tpool_t *pool, bool performanceMeas )` or `initNamedTpool(char *params,tpool_t *pool, bool performanceMeas , char *name)`
|
||||
|
||||
the params string structure: describes a list of cores, separated by "," that run a worker thread
|
||||
|
||||
If the core exists on the CPU, the thread pool initialization sets the affinity between this thread and the related code (use negative values is allowed, so the thread will never be mapped on a specific core).
|
||||
|
||||
The threads are all Linux real time scheduler, their name is set automatically is "Tpool_<core id>"
|
||||
The threads are all Linux real time scheduler, their name is set automatically to `Tpool<thread index>_<core id>` if initTpool is used or to `<name><thread index>_<core id>` when initNamedTpool is used.
|
||||
|
||||
## adding jobs
|
||||
The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
|
||||
@@ -132,11 +132,13 @@ A abort service abortTpool() allows to abort all jobs that match a key (see jobs
|
||||
Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
|
||||
|
||||
## API details
|
||||
Each thread pool (there can be several in the same process) should be initialized
|
||||
Each thread pool (there can be several in the same process) should be initialized once using one of the two API's:
|
||||
|
||||
### initTpool(char *params,tpool_t *pool, bool performanceMeas) is to be called oncepool
|
||||
### initNamedTpool(char *params,tpool_t *pool, bool performanceMeas,char *name)
|
||||
|
||||
the configuration parameter is a string, elements separated by ",":
|
||||
### initTpool(char *params,tpool_t *pool, bool performanceMeas)
|
||||
|
||||
`params`: the configuration parameter is a string, elements separator is a comma ",". An element can be:
|
||||
|
||||
* N: if a N is in the parameter list, no threads are created
|
||||
The purpose is to keep the same API in any case
|
||||
@@ -151,9 +153,11 @@ example: "-1,-1,-1"
|
||||
as there is no core number -1, the thread pool is made of 3 floating threads
|
||||
be careful with fix allocation: it is hard to be more clever than Linux kernel
|
||||
|
||||
pool is the memory you allocated before to store the thread pool internal state (same concept as above queues)
|
||||
`pool` is the memory you allocated before to store the thread pool internal state (same concept as above queues)
|
||||
|
||||
performanceMeas is a flag to enable measurements (well described in documentation)
|
||||
`performanceMeas` is a flag to enable measurements (well described in documentation)
|
||||
|
||||
`name` is used to build the thread names.
|
||||
|
||||
### pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg)
|
||||
|
||||
|
||||
+10
-6
@@ -295,6 +295,7 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
- NR RRC (38.331) Rel 15 messages using new asn1c
|
||||
- LTE RRC (36.331) also updated to Rel 15
|
||||
- Generation of CellGroupConfig (for eNB) and MIB
|
||||
- Generation of system information block 1 (SIB1)
|
||||
- Application to read configuration file and program gNB RRC
|
||||
- RRC can configure PDCP, RLC, MAC
|
||||
|
||||
@@ -305,7 +306,8 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
**gNB MAC**
|
||||
- MAC -> PHY configuration using NR FAPI P5 interface
|
||||
- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
|
||||
- Scheduler for RA procedreat gNB
|
||||
- Scheduler procedures for SIB1
|
||||
- Scheduler procedures for RA
|
||||
- MAC downlink scheduler (fixed allocations)
|
||||
- MAC header generation (including timing advance)
|
||||
- ACK / NACK handling and HARQ procedures for downlink
|
||||
@@ -350,11 +352,13 @@ The following features are valid for the gNB and the 5G-NR UE.
|
||||
|
||||
## UE Higher Layers ##
|
||||
|
||||
**gNB MAC**
|
||||
- Initial sync and MIB detection
|
||||
- MAC -> PHY configuration of PHY via UE FAPI P5 interface
|
||||
- Basic MAC to control PHY via UE FAPI P7 interface
|
||||
- Random access procedure
|
||||
**UE MAC**
|
||||
* Minimum system information (MSI)
|
||||
- Initial sync and MIB detection
|
||||
- System information block 1 (SIB1) reception
|
||||
* MAC -> PHY configuration of PHY via UE FAPI P5 interface
|
||||
* Basic MAC to control PHY via UE FAPI P7 interface
|
||||
* Random access procedure
|
||||
|
||||
|
||||
**RLC**
|
||||
|
||||
@@ -132,6 +132,40 @@ With the RF simulator (on the same machine):
|
||||
|
||||
`sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD`
|
||||
|
||||
## sa setup with OAI
|
||||
|
||||
The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1.
|
||||
|
||||
In order to run gNB in standalone mode, the following flag is needed at gNB:
|
||||
|
||||
`--sa`
|
||||
|
||||
### Run OAI in sa mode
|
||||
|
||||
At the gNB the --sa flag does the following
|
||||
- it reads the RRC configuration from the configuration file
|
||||
- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
|
||||
- the RRC encodes SIB1 according the configuration file and transmits it through PDSCH
|
||||
|
||||
At the UE the --sa flag will
|
||||
- read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them.
|
||||
|
||||
From the `cmake_targets/ran_build/build` folder:
|
||||
|
||||
gNB on machine 1:
|
||||
|
||||
`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --sa`
|
||||
|
||||
UE on machine 2:
|
||||
|
||||
`sudo ./nr-uesoftmodem --rrc_config_path . --sa`
|
||||
|
||||
With the RF simulator (on the same machine):
|
||||
|
||||
`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --rfsim --sa`
|
||||
|
||||
`sudo ./nr-uesoftmodem --rrc_config_path . --rfsim --sa`
|
||||
|
||||
## IF setup with OAI
|
||||
|
||||
The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment.
|
||||
|
||||
@@ -300,87 +300,11 @@ void exit_function(const char *file, const char *function, const int line, const
|
||||
}
|
||||
|
||||
|
||||
void *l2l1_task(void *arg) {
|
||||
MessageDef *message_p = NULL;
|
||||
int result;
|
||||
itti_set_task_real_time(TASK_L2L1);
|
||||
itti_mark_task_ready(TASK_L2L1);
|
||||
/* Wait for the initialize message */
|
||||
printf("Wait for the ITTI initialize message\n");
|
||||
|
||||
do {
|
||||
if (message_p != NULL) {
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
}
|
||||
|
||||
itti_receive_msg (TASK_L2L1, &message_p);
|
||||
|
||||
switch (ITTI_MSG_ID(message_p)) {
|
||||
case INITIALIZE_MESSAGE:
|
||||
/* Start gNB thread */
|
||||
LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
|
||||
start_gNB = 1;
|
||||
break;
|
||||
|
||||
case TERMINATE_MESSAGE:
|
||||
printf("received terminate message\n");
|
||||
oai_exit=1;
|
||||
start_gNB = 0;
|
||||
itti_exit_task ();
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
|
||||
break;
|
||||
}
|
||||
} while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
/* ???? no else but seems to be UE only ???
|
||||
do {
|
||||
// Wait for a message
|
||||
itti_receive_msg (TASK_L2L1, &message_p);
|
||||
|
||||
switch (ITTI_MSG_ID(message_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
oai_exit=1;
|
||||
itti_exit_task ();
|
||||
break;
|
||||
|
||||
case ACTIVATE_MESSAGE:
|
||||
start_UE = 1;
|
||||
break;
|
||||
|
||||
case DEACTIVATE_MESSAGE:
|
||||
start_UE = 0;
|
||||
break;
|
||||
|
||||
case MESSAGE_TEST:
|
||||
LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
} while(!oai_exit);
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb);
|
||||
itti_wait_ready(1);
|
||||
|
||||
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
|
||||
LOG_E(PDCP, "Create task for L2L1 failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gnb_nb > 0) {
|
||||
/* Last task to create, others task must be ready before its start */
|
||||
@@ -419,7 +343,7 @@ int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
}
|
||||
|
||||
|
||||
if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
|
||||
if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) {
|
||||
if (gnb_nb > 0) {
|
||||
/*
|
||||
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
|
||||
@@ -717,7 +641,6 @@ int stop_L1L2(module_id_t gnb_id) {
|
||||
|
||||
/* these tasks need to pick up new configuration */
|
||||
terminate_task(TASK_RRC_ENB, gnb_id);
|
||||
terminate_task(TASK_L2L1, gnb_id);
|
||||
LOG_I(GNB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id);
|
||||
kill_gNB_proc(gnb_id);
|
||||
LOG_I(GNB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id);
|
||||
@@ -753,13 +676,6 @@ int restart_L1L2(module_id_t gnb_id) {
|
||||
rrc_enb_init();
|
||||
itti_mark_task_ready(TASK_RRC_ENB);
|
||||
|
||||
if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
|
||||
LOG_E(PDCP, "Create task for L2L1 failed\n");
|
||||
return -1;
|
||||
} else {
|
||||
LOG_I(PDCP, "Re-created task for L2L1 successfully\n");
|
||||
}
|
||||
|
||||
/* pass a reconfiguration request which will configure everything down to
|
||||
* RC.eNB[i][j]->frame_parms, too */
|
||||
msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ);
|
||||
@@ -851,6 +767,9 @@ int main( int argc, char **argv )
|
||||
if (get_softmodem_params()->do_ra)
|
||||
AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
|
||||
|
||||
if (get_softmodem_params()->sa)
|
||||
AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n");
|
||||
|
||||
#if T_TRACER
|
||||
T_Config_Init();
|
||||
#endif
|
||||
|
||||
+17
-16
@@ -348,7 +348,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
|
||||
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
|
||||
#else
|
||||
uint64_t a=rdtsc();
|
||||
phy_procedures_nrUE_RX(UE, proc, gNB_id);
|
||||
phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel);
|
||||
LOG_D(PHY, "In %s: slot %d, time %lu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc()-a)/3500);
|
||||
#endif
|
||||
|
||||
@@ -522,7 +522,7 @@ void *UE_thread(void *arg) {
|
||||
|
||||
while (!oai_exit) {
|
||||
if (syncRunning) {
|
||||
notifiedFIFO_elt_t *res=tryPullTpool(&nf, Tpool);
|
||||
notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool));
|
||||
|
||||
if (res) {
|
||||
syncRunning=false;
|
||||
@@ -548,7 +548,7 @@ void *UE_thread(void *arg) {
|
||||
syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg);
|
||||
syncMsg->UE=UE;
|
||||
memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
|
||||
pushTpool(Tpool, Msg);
|
||||
pushTpool(&(get_nrUE_params()->Tpool), Msg);
|
||||
trashed_frames=0;
|
||||
syncRunning=true;
|
||||
continue;
|
||||
@@ -658,20 +658,19 @@ void *UE_thread(void *arg) {
|
||||
notifiedFIFO_elt_t *res;
|
||||
|
||||
while (nbSlotProcessing >= RX_NB_TH) {
|
||||
res=pullTpool(&nf, Tpool);
|
||||
res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
|
||||
nbSlotProcessing--;
|
||||
processingData_t *tmp=(processingData_t *)res->msgData;
|
||||
|
||||
if (tmp->proc.decoded_frame_rx != -1)
|
||||
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
|
||||
//decoded_frame_rx=tmp->proc.decoded_frame_rx;
|
||||
else
|
||||
decoded_frame_rx=-1;
|
||||
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
|
||||
}
|
||||
|
||||
if ( (decoded_frame_rx != curMsg->proc.frame_rx) &&
|
||||
(((decoded_frame_rx+1) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx) &&
|
||||
(((decoded_frame_rx+2) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx))
|
||||
if ( decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx)
|
||||
LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n",
|
||||
decoded_frame_rx, curMsg->proc.frame_rx );
|
||||
|
||||
@@ -698,18 +697,20 @@ void *UE_thread(void *arg) {
|
||||
|
||||
nbSlotProcessing++;
|
||||
msgToPush->key=slot_nr;
|
||||
pushTpool(Tpool, msgToPush);
|
||||
pushTpool(&(get_nrUE_params()->Tpool), msgToPush);
|
||||
|
||||
if (IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR")
|
||||
if ( IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR")
|
||||
// FixMe: Wait previous thread is done, because race conditions seems too bad
|
||||
// in case of actual RF board, the overlap between threads mitigate the issue
|
||||
// We must receive one message, that proves the slot processing is done
|
||||
res=pullTpool(&nf, Tpool);
|
||||
res=pullTpool(&nf, &(get_nrUE_params()->Tpool));
|
||||
nbSlotProcessing--;
|
||||
processingData_t *tmp=(processingData_t *)res->msgData;
|
||||
|
||||
if (tmp->proc.decoded_frame_rx != -1)
|
||||
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
|
||||
else
|
||||
decoded_frame_rx=-1;
|
||||
//decoded_frame_rx=tmp->proc.decoded_frame_rx;
|
||||
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks,res);
|
||||
@@ -760,11 +761,11 @@ void init_NR_UE_threads(int nb_inst) {
|
||||
LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]);
|
||||
threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX);
|
||||
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
pthread_t dlsch0_threads;
|
||||
threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1);
|
||||
#endif
|
||||
|
||||
if(get_nrUE_params()->nr_dlsch_parallel)
|
||||
{
|
||||
pthread_t dlsch0_threads;
|
||||
threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+82
-106
@@ -43,6 +43,7 @@
|
||||
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "PHY/MODULATION/modulation_vars.h"
|
||||
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
//#include "../../SIMU/USER/init_lte.h"
|
||||
|
||||
#include "LAYER2/MAC/mac_vars.h"
|
||||
@@ -81,6 +82,7 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
|
||||
#include "PHY/TOOLS/phy_scope_interface.h"
|
||||
#include "PHY/TOOLS/nr_phy_scope.h"
|
||||
#define NRUE_MAIN
|
||||
#include <executables/nr-uesoftmodem.h>
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/thread-common.h"
|
||||
@@ -96,34 +98,23 @@ pthread_cond_t sync_cond;
|
||||
pthread_mutex_t sync_mutex;
|
||||
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
|
||||
int config_sync_var=-1;
|
||||
tpool_t *Tpool;
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
tpool_t *Tpool_dl;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
RAN_CONTEXT_t RC;
|
||||
volatile int start_eNB = 0;
|
||||
volatile int start_UE = 0;
|
||||
volatile int oai_exit = 0;
|
||||
|
||||
// Command line options
|
||||
|
||||
extern int16_t nr_dlsch_demod_shift;
|
||||
static int tx_max_power[MAX_NUM_CCs] = {0};
|
||||
|
||||
int mac_enabled = 1;
|
||||
int single_thread_flag = 1;
|
||||
int threequarter_fs = 0;
|
||||
int UE_scan_carrier = 0;
|
||||
int UE_fo_compensation = 0;
|
||||
int UE_no_timing_correction = 0;
|
||||
int N_RB_DL = 0;
|
||||
int tddflag = 0;
|
||||
int vcdflag = 0;
|
||||
uint8_t nb_antenna_tx = 1;
|
||||
uint8_t nb_antenna_rx = 1;
|
||||
|
||||
double rx_gain_off = 0.0;
|
||||
uint32_t timing_advance = 0;
|
||||
char *usrp_args = NULL;
|
||||
char *rrc_config_path = NULL;
|
||||
int dumpframe = 0;
|
||||
@@ -149,8 +140,7 @@ int16_t node_synch_ref[MAX_NUM_CCs];
|
||||
int otg_enabled;
|
||||
double cpuf;
|
||||
|
||||
runmode_t mode = normal_txrx;
|
||||
int UE_scan = 0;
|
||||
|
||||
int chain_offset = 0;
|
||||
int card_offset = 0;
|
||||
uint64_t num_missed_slots = 0; // counter for the number of missed slots
|
||||
@@ -210,74 +200,35 @@ void exit_function(const char *file, const char *function, const int line, const
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void *l2l1_task(void *arg) {
|
||||
MessageDef *message_p = NULL;
|
||||
int result;
|
||||
itti_set_task_real_time(TASK_L2L1);
|
||||
itti_mark_task_ready(TASK_L2L1);
|
||||
|
||||
do {
|
||||
// Wait for a message
|
||||
itti_receive_msg (TASK_L2L1, &message_p);
|
||||
|
||||
switch (ITTI_MSG_ID(message_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
oai_exit=1;
|
||||
itti_exit_task ();
|
||||
break;
|
||||
|
||||
case ACTIVATE_MESSAGE:
|
||||
start_UE = 1;
|
||||
break;
|
||||
|
||||
case DEACTIVATE_MESSAGE:
|
||||
start_UE = 0;
|
||||
break;
|
||||
|
||||
case MESSAGE_TEST:
|
||||
LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
} while(!oai_exit);
|
||||
|
||||
return NULL;
|
||||
uint64_t get_nrUE_optmask(void) {
|
||||
return nrUE_params.optmask;
|
||||
}
|
||||
|
||||
uint64_t set_nrUE_optmask(uint64_t bitmask) {
|
||||
nrUE_params.optmask = nrUE_params.optmask | bitmask;
|
||||
return nrUE_params.optmask;
|
||||
}
|
||||
|
||||
nrUE_params_t *get_nrUE_params(void) {
|
||||
return &nrUE_params;
|
||||
}
|
||||
/* initialie thread pools used for NRUE processing paralleliation */
|
||||
void init_tpools(uint8_t nun_dlsch_threads) {
|
||||
char *params=calloc(1,(RX_NB_TH*3)+1);
|
||||
for (int i=0; i<RX_NB_TH; i++) {
|
||||
memcpy(params+(i*3),"-1,",3);
|
||||
}
|
||||
initTpool(params, &(nrUE_params.Tpool), false);
|
||||
free(params);
|
||||
init_dlsch_tpool( nun_dlsch_threads);
|
||||
}
|
||||
static void get_options(void) {
|
||||
|
||||
char *loopfile=NULL;
|
||||
paramdef_t cmdline_params[] =CMDLINE_NRUEPARAMS_DESC ;
|
||||
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
|
||||
config_process_cmdline( cmdline_params,numparams,NULL);
|
||||
|
||||
paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC_UE ;
|
||||
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
|
||||
paramdef_t cmdline_uemodeparams[] = CMDLINE_UEMODEPARAMS_DESC;
|
||||
paramdef_t cmdline_ueparams[] = CMDLINE_NRUEPARAMS_DESC;
|
||||
config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
|
||||
config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
|
||||
|
||||
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
|
||||
|
||||
if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
|
||||
|
||||
if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr)
|
||||
if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
|
||||
|
||||
if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr)
|
||||
if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect;
|
||||
|
||||
if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr)
|
||||
if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx;
|
||||
|
||||
if ((cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags & PARAMFLAG_PARAMSET) != 0)
|
||||
mode = rx_dump_frame;
|
||||
|
||||
if (vcdflag > 0)
|
||||
ouput_vcd = 1;
|
||||
@@ -289,10 +240,43 @@ static void get_options(void) {
|
||||
printf("%s\n",uecap_xer);
|
||||
uecap_xer_in=1;
|
||||
} /* UE with config file */
|
||||
init_tpools(nrUE_params.nr_dlsch_parallel);
|
||||
}
|
||||
|
||||
// set PHY vars from command line
|
||||
void set_options(int CC_id, PHY_VARS_NR_UE *UE){
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
paramdef_t cmdline_params[] = CMDLINE_NRUE_PHYPARAMS_DESC ;
|
||||
int numparams = sizeof(cmdline_params)/sizeof(paramdef_t);
|
||||
|
||||
UE->mode = normal_txrx;
|
||||
|
||||
config_process_cmdline( cmdline_params,numparams,NULL);
|
||||
|
||||
int pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRX_OPT);
|
||||
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue;
|
||||
|
||||
pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXMED_OPT);
|
||||
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_med;
|
||||
|
||||
pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXBYP_OPT);
|
||||
if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_byp;
|
||||
|
||||
pindex = config_paramidx_fromname(cmdline_params,numparams, DBGPRACH_OPT);
|
||||
if (cmdline_params[pindex].uptr)
|
||||
if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = debug_prach;
|
||||
|
||||
pindex = config_paramidx_fromname(cmdline_params,numparams,NOL2CONNECT_OPT );
|
||||
if (cmdline_params[pindex].uptr)
|
||||
if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = no_L2_connect;
|
||||
|
||||
pindex = config_paramidx_fromname(cmdline_params,numparams,CALIBPRACH_OPT );
|
||||
if (cmdline_params[pindex].uptr)
|
||||
if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = calib_prach_tx;
|
||||
|
||||
pindex = config_paramidx_fromname(cmdline_params,numparams,DUMPFRAME_OPT );
|
||||
if ((cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0)
|
||||
UE->mode = rx_dump_frame;
|
||||
|
||||
// Init power variables
|
||||
tx_max_power[CC_id] = tx_max_power[0];
|
||||
@@ -300,36 +284,28 @@ void set_options(int CC_id, PHY_VARS_NR_UE *UE){
|
||||
tx_gain[0][CC_id] = tx_gain[0][0];
|
||||
|
||||
// Set UE variables
|
||||
UE->mac_enabled = mac_enabled;
|
||||
UE->UE_scan = UE_scan;
|
||||
UE->UE_scan_carrier = UE_scan_carrier;
|
||||
UE->UE_fo_compensation = UE_fo_compensation;
|
||||
UE->no_timing_correction = UE_no_timing_correction;
|
||||
UE->mode = mode;
|
||||
UE->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
|
||||
UE->tx_total_gain_dB = (int)tx_gain[CC_id][0];
|
||||
UE->tx_power_max_dBm = tx_max_power[CC_id];
|
||||
UE->rf_map.card = card_offset;
|
||||
UE->rf_map.chain = CC_id + chain_offset;
|
||||
UE->timing_advance = timing_advance;
|
||||
|
||||
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", mode, UE_fo_compensation, UE_scan, UE_scan_carrier, UE_no_timing_correction);
|
||||
|
||||
LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n",
|
||||
UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction);
|
||||
|
||||
// Set FP variables
|
||||
NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
|
||||
fp->nb_antennas_tx = nb_antenna_tx;
|
||||
fp->nb_antennas_rx = nb_antenna_rx;
|
||||
fp->threequarter_fs = threequarter_fs;
|
||||
|
||||
|
||||
|
||||
if (tddflag){
|
||||
fp->frame_type = TDD;
|
||||
LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type);
|
||||
}
|
||||
if (N_RB_DL){
|
||||
fp->N_RB_DL = N_RB_DL;
|
||||
LOG_I(PHY, "Set UE N_RB_DL %d\n", N_RB_DL);
|
||||
}
|
||||
|
||||
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", nb_antenna_rx, nb_antenna_tx, threequarter_fs);
|
||||
LOG_I(PHY, "Set UE N_RB_DL %d\n", fp->N_RB_DL);
|
||||
|
||||
LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs);
|
||||
|
||||
}
|
||||
|
||||
@@ -498,23 +474,17 @@ int main( int argc, char **argv ) {
|
||||
// initialize logging
|
||||
logInit();
|
||||
// get options and fill parameters from configuration file
|
||||
get_options(); //Command-line options
|
||||
|
||||
get_options (); //Command-line options specific for NRUE
|
||||
|
||||
get_common_options(SOFTMODEM_5GUE_BIT );
|
||||
CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
|
||||
#if T_TRACER
|
||||
T_Config_Init();
|
||||
#endif
|
||||
//randominit (0);
|
||||
set_taus_seed (0);
|
||||
tpool_t pool;
|
||||
Tpool = &pool;
|
||||
char params[]="-1,-1";
|
||||
initTpool(params, Tpool, false);
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
tpool_t pool_dl;
|
||||
Tpool_dl = &pool_dl;
|
||||
char params_dl[]="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1";
|
||||
initTpool(params_dl, Tpool_dl, false);
|
||||
#endif
|
||||
|
||||
cpuf=get_cpu_freq_GHz();
|
||||
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
|
||||
|
||||
@@ -542,8 +512,12 @@ int main( int argc, char **argv ) {
|
||||
if (get_softmodem_params()->do_ra)
|
||||
AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
|
||||
|
||||
if (get_softmodem_params()->sa)
|
||||
AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n");
|
||||
|
||||
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
|
||||
|
||||
PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE));
|
||||
UE[CC_id] = PHY_vars_UE_g[0][CC_id];
|
||||
memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE));
|
||||
@@ -581,7 +555,9 @@ int main( int argc, char **argv ) {
|
||||
load_softscope("nr",PHY_vars_UE_g[0][0]);
|
||||
}
|
||||
|
||||
|
||||
init_NR_UE_threads(1);
|
||||
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
|
||||
printf("UE threads created by %ld\n", gettid());
|
||||
|
||||
// wait for end of program
|
||||
|
||||
@@ -5,72 +5,77 @@
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization"
|
||||
/***************************************************************************************************************************************/
|
||||
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
|
||||
when calling config_get or config_getlist functions */
|
||||
|
||||
#define CALIBRX_OPT "calib-ue-rx"
|
||||
#define CALIBRXMED_OPT "calib-ue-rx-med"
|
||||
#define CALIBRXBYP_OPT "calib-ue-rx-byp"
|
||||
#define DBGPRACH_OPT "debug-ue-prach"
|
||||
#define NOL2CONNECT_OPT "no-L2-connect"
|
||||
#define CALIBPRACH_OPT "calib-prach-tx"
|
||||
#define DUMPFRAME_OPT "ue-dump-frame"
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters defining UE running mode */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_NRUEPARAMS_DESC { \
|
||||
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \
|
||||
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
|
||||
{"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \
|
||||
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
|
||||
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters defining UE running mode */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_UEMODEPARAMS_DESC { \
|
||||
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
|
||||
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
#define CMDLINE_CALIBUERX_IDX 0
|
||||
#define CMDLINE_CALIBUERXMED_IDX 1
|
||||
#define CMDLINE_CALIBUERXBYP_IDX 2
|
||||
#define CMDLINE_DEBUGUEPRACH_IDX 3
|
||||
#define CMDLINE_NOL2CONNECT_IDX 4
|
||||
#define CMDLINE_CALIBPRACHTX_IDX 5
|
||||
#define CMDLINE_MEMLOOP_IDX 6
|
||||
#define CMDLINE_DUMPMEMORY_IDX 7
|
||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters specific to UE */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_NRUEPARAMS_DESC { \
|
||||
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \
|
||||
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \
|
||||
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \
|
||||
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \
|
||||
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
|
||||
{"r" , CONFIG_HLP_PRB, 0, iptr:&(N_RB_DL), defintval:25, TYPE_UINT, 0}, \
|
||||
{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0} \
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters common to gNB and UE */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CMDLINE_PARAMS_DESC_UE { \
|
||||
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
|
||||
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
|
||||
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
|
||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
|
||||
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
|
||||
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
|
||||
{"mac-enabled" , CONFIG_HLP_MAC, PARAMFLAG_BOOL, iptr:&mac_enabled, defintval:1, TYPE_INT, 0}, \
|
||||
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \
|
||||
{"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \
|
||||
#define CMDLINE_NRUE_PHYPARAMS_DESC { \
|
||||
{ CALIBRX_OPT, CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{ CALIBRXMED_OPT, CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{ CALIBRXBYP_OPT, CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
||||
{ DBGPRACH_OPT, CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{ NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
||||
{ DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
|
||||
{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \
|
||||
{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&(fp->nb_antennas_rx), defuintval:1, TYPE_UINT8, 0}, \
|
||||
{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&(fp->nb_antennas_tx), defuintval:1, TYPE_UINT8, 0}, \
|
||||
{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&(UE->UE_scan_carrier), defintval:0, TYPE_INT, 0}, \
|
||||
{"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&(UE->UE_fo_compensation), defintval:0, TYPE_INT, 0}, \
|
||||
{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \
|
||||
{"r" , CONFIG_HLP_PRB, 0, iptr:&(fp->N_RB_DL), defintval:25, TYPE_UINT, 0}, \
|
||||
{"A" , CONFIG_HLP_TADV, 0, iptr:&(UE->timing_advance), defintval:0, TYPE_INT, 0}, \
|
||||
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \
|
||||
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
|
||||
{"mac-enabled" , CONFIG_HLP_MAC, PARAMFLAG_BOOL, iptr:&(UE->mac_enabled), defintval:1, TYPE_INT, 0}, \
|
||||
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \
|
||||
}
|
||||
|
||||
extern int T_port;
|
||||
extern int T_nowait;
|
||||
extern int T_dont_fork;
|
||||
|
||||
typedef struct {
|
||||
uint64_t optmask; //mask to store boolean config options
|
||||
uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization
|
||||
tpool_t Tpool; // thread pool
|
||||
} nrUE_params_t;
|
||||
extern uint64_t get_nrUE_optmask(void);
|
||||
extern uint64_t set_nrUE_optmask(uint64_t bitmask);
|
||||
extern nrUE_params_t *get_nrUE_params(void);
|
||||
|
||||
#ifdef NRUE_MAIN
|
||||
nrUE_params_t nrUE_params;
|
||||
#endif
|
||||
|
||||
// In nr-ue.c
|
||||
extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
|
||||
@@ -81,6 +86,5 @@ extern void reset_opp_meas(void);
|
||||
extern void print_opp_meas(void);
|
||||
void *UE_thread(void *arg);
|
||||
void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag);
|
||||
extern tpool_t *Tpool;
|
||||
extern tpool_t *Tpool_dl;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,6 +56,7 @@ extern "C"
|
||||
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
|
||||
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
|
||||
#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
|
||||
#define CONFIG_HLP_SA "run gNB in standalone mode\n"
|
||||
#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n"
|
||||
#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0"
|
||||
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
|
||||
@@ -100,6 +101,7 @@ extern "C"
|
||||
#define TP_CONFIG softmodem_params.threadPoolConfig
|
||||
#define PHY_TEST softmodem_params.phy_test
|
||||
#define DO_RA softmodem_params.do_ra
|
||||
#define SA softmodem_params.sa
|
||||
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
|
||||
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
|
||||
#define CHAIN_OFFSET softmodem_params.chain_offset
|
||||
@@ -119,6 +121,7 @@ extern "C"
|
||||
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \
|
||||
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
|
||||
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \
|
||||
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, iptr:&SA, defintval:0, TYPE_INT, 0}, \
|
||||
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
|
||||
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
|
||||
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
|
||||
@@ -213,6 +216,7 @@ typedef struct {
|
||||
char threadPoolConfig[1024];
|
||||
int phy_test;
|
||||
int do_ra;
|
||||
int sa;
|
||||
uint8_t usim_test;
|
||||
int emulate_rf;
|
||||
int wait_for_sync; //eNodeB only
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
|
||||
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH 0x04
|
||||
|
||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
|
||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
|
||||
|
||||
@@ -120,6 +120,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
||||
nr_generate_modulation_table();
|
||||
nr_init_pdcch_dmrs(gNB, cfg->cell_config.phy_cell_id.value);
|
||||
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
|
||||
|
||||
//PDSCH DMRS init
|
||||
gNB->nr_gold_pdsch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
||||
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
|
||||
|
||||
@@ -276,6 +276,40 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
//PDCCH DMRS init (eNB offset = 0)
|
||||
ue->nr_gold_pdcch[0] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
|
||||
uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0];
|
||||
AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n");
|
||||
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
|
||||
AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot);
|
||||
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
|
||||
AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
}
|
||||
}
|
||||
|
||||
//PDSCH DMRS init (eNB offset = 0)
|
||||
ue->nr_gold_pdsch[0] = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***));
|
||||
uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0];
|
||||
|
||||
for (int slot=0; slot<fp->slots_per_frame; slot++) {
|
||||
pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **));
|
||||
AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot);
|
||||
|
||||
for (int symb=0; symb<fp->symbols_per_slot; symb++) {
|
||||
pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t *));
|
||||
AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
|
||||
|
||||
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++) {
|
||||
pdsch_dmrs[slot][symb][q] = (uint32_t *)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
|
||||
AssertFatal(pdsch_dmrs[slot][symb][q]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DLSCH
|
||||
for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
|
||||
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
|
||||
|
||||
@@ -26,6 +26,7 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
|
||||
unsigned int n, x1, x2;
|
||||
unsigned int Nid, i_ssb, i_ssb2;
|
||||
unsigned char Lmax, l, n_hf, N_hf;
|
||||
uint8_t reset;
|
||||
|
||||
Nid = ue->frame_parms.Nid_cell;
|
||||
Lmax = ue->frame_parms.Lmax;
|
||||
@@ -37,24 +38,12 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue)
|
||||
i_ssb = l & (Lmax-1);
|
||||
i_ssb2 = i_ssb + (n_hf<<2);
|
||||
|
||||
x1 = 1 + (1<<31);
|
||||
reset = 1;
|
||||
x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3);
|
||||
x2 = x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
|
||||
// skip first 50 double words (1600 bits)
|
||||
for (n = 1; n < 50; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
}
|
||||
|
||||
for (n=0; n<NR_PBCH_DMRS_LENGTH_DWORD; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
ue->nr_gold_pbch[n_hf][l][n] = x1 ^ x2;
|
||||
ue->nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -69,41 +58,27 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue,
|
||||
unsigned char ns,l;
|
||||
unsigned int n,x1,x2,x2tmp0;
|
||||
unsigned int nid;
|
||||
uint8_t reset;
|
||||
|
||||
if (n_idDMRS)
|
||||
nid = n_idDMRS;
|
||||
else
|
||||
nid = ue->frame_parms.Nid_cell;
|
||||
if (n_idDMRS)
|
||||
nid = n_idDMRS;
|
||||
else
|
||||
nid = ue->frame_parms.Nid_cell;
|
||||
|
||||
for (ns=0; ns<20; ns++) {
|
||||
for (ns=0; ns<ue->frame_parms.slots_per_frame; ns++) {
|
||||
|
||||
for (l=0; l<length_dmrs; l++) {
|
||||
for (l=0; l<length_dmrs; l++) {
|
||||
|
||||
x2tmp0 = ((14*ns+l+1)*((nid<<1)+1))<<17;
|
||||
x2 = (x2tmp0+(nid<<1))%(1<<31); //cinit
|
||||
|
||||
x1 = 1+ (1<<31);
|
||||
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
|
||||
// skip first 50 double words (1600 bits)
|
||||
for (n=1; n<50; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
//printf("x1 : %x, x2 : %x\n",x1,x2);
|
||||
}
|
||||
|
||||
for (n=0; n<52; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
ue->nr_gold_pdcch[0][ns][l][n] = x1^x2;
|
||||
// if (ns==1 && l==0) printf("n=%d : c %x\n",n,x1^x2);
|
||||
}
|
||||
}
|
||||
reset = 1;
|
||||
x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
|
||||
x2 = (x2tmp0+(nid<<1))%(1<<31); //cinit
|
||||
|
||||
for (n=0; n<NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD; n++) {
|
||||
ue->nr_gold_pdcch[0][ns][l][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
@@ -114,6 +89,7 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
unsigned int n,x1,x2,x2tmp0;
|
||||
int nscid;
|
||||
unsigned int nid;
|
||||
uint8_t reset;
|
||||
|
||||
/// to be updated from higher layer
|
||||
//unsigned short lbar = 0;
|
||||
@@ -126,32 +102,16 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
|
||||
|
||||
//printf("gold pdsch nid %d lbar %d\n",nid,lbar);
|
||||
|
||||
for (l=0; l<14; l++) {
|
||||
x2tmp0 = ((14*ns+l+1)*((nid<<1)+1))<<17;
|
||||
for (l=0; l<ue->frame_parms.symbols_per_slot; l++) {
|
||||
|
||||
reset = 1;
|
||||
x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17;
|
||||
x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit
|
||||
LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid);
|
||||
//printf("ns %d gold pdsch x2 %d\n",ns,x2);
|
||||
|
||||
x1 = 1+ (1<<31);
|
||||
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
|
||||
// skip first 50 double words (1600 bits)
|
||||
for (n=1; n<50; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
//printf("x1 : %x, x2 : %x\n",x1,x2);
|
||||
}
|
||||
|
||||
for (n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
ue->nr_gold_pdsch[nscid][ns][l][n] = x1^x2;
|
||||
// if ((ns==2)&&(l==0))
|
||||
//printf("n=%d : c %x\n",n,x1^x2);
|
||||
ue->nr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset);
|
||||
reset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include <LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
|
||||
#include "nr_dci.h"
|
||||
#include "nr_dlsch.h"
|
||||
#include "nr_sch_dmrs.h"
|
||||
@@ -81,17 +82,13 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
int rb_offset;
|
||||
int n_rb;
|
||||
|
||||
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
|
||||
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
|
||||
// compute rb_offset and n_prb based on frequency allocation
|
||||
|
||||
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
|
||||
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
|
||||
cset_start_sc = frame_parms.first_carrier_offset +
|
||||
(frame_parms.ssb_start_subcarrier/NR_NB_SC_PER_RB + rb_offset)*NR_NB_SC_PER_RB;
|
||||
} else
|
||||
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
|
||||
cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB;
|
||||
}
|
||||
|
||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||
/*The coreset is initialised
|
||||
@@ -105,8 +102,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
LOG_D(PHY, "Coreset rb_offset %d, nb_rb %d\n",rb_offset,n_rb);
|
||||
LOG_D(PHY, "Coreset starting subcarrier %d on symbol %d (%d symbols)\n", cset_start_sc, cset_start_symb, cset_nsymb);
|
||||
// DMRS length is per OFDM symbol
|
||||
AssertFatal(pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED,
|
||||
"Interleaved CCE REG MAPPING not supported\n");
|
||||
uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)?
|
||||
(n_rb*6) : (pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE)
|
||||
uint32_t encoded_length = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE)
|
||||
@@ -198,7 +193,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
|
||||
for (int m=0; m<NR_NB_SC_PER_RB; m++) {
|
||||
if ( m == (k_prime<<2)+1) { // DMRS if not already mapped
|
||||
if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) {
|
||||
//if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) {
|
||||
((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15;
|
||||
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15;
|
||||
#ifdef DEBUG_PDCCH_DMRS
|
||||
@@ -206,7 +201,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]);
|
||||
#endif
|
||||
dmrs_idx++;
|
||||
}
|
||||
//}
|
||||
|
||||
k_prime++;
|
||||
} else { // DCI payload
|
||||
@@ -225,7 +220,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
k -= frame_parms.ofdm_symbol_size;
|
||||
} // m
|
||||
} // reg_idx
|
||||
|
||||
|
||||
LOG_I(PHY, "DCI: payloadSize = %d | payload = %llx\n",
|
||||
*pdcch_pdu_rel15->dci_pdu.PayloadSizeBits,*(unsigned long long*)pdcch_pdu_rel15->dci_pdu.Payload);
|
||||
|
||||
} // for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
|
||||
/// Resource mapping
|
||||
|
||||
// Non interleaved VRB to PRB mapping
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart+rel15->BWPStart)*NR_NB_SC_PER_RB;
|
||||
if (start_sc >= frame_parms->ofdm_symbol_size)
|
||||
start_sc -= frame_parms->ofdm_symbol_size;
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
time_stats_t *dlsch_interleaving_stats,
|
||||
time_stats_t *dlsch_segmentation_stats);
|
||||
|
||||
|
||||
void init_dlsch_tpool(uint8_t nun_dlsch_threads);
|
||||
void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
|
||||
|
||||
void dump_pdsch_stats(PHY_VARS_gNB *gNB);
|
||||
|
||||
@@ -653,6 +653,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
unsigned short BWPStart,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch)
|
||||
{
|
||||
@@ -686,10 +687,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
#endif
|
||||
|
||||
// generate pilot for gNB port number 1000+p
|
||||
uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
|
||||
uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart;
|
||||
uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
|
||||
int8_t delta = get_delta(p, config_type);
|
||||
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
|
||||
nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset);
|
||||
|
||||
if (config_type == pdsch_dmrs_type1){
|
||||
nushift = (p>>1)&1;
|
||||
@@ -1321,7 +1322,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
|
||||
nr_slot_rx,
|
||||
symbol,frame_parms->ofdm_symbol_size,
|
||||
(int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
|
||||
ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol],
|
||||
ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol][0],
|
||||
&phase_per_symbol[2* symbol],
|
||||
&ptrs_re_symbol[symbol]);
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
|
||||
unsigned char Ns,
|
||||
unsigned short p,
|
||||
unsigned char symbol,
|
||||
unsigned short BWPStart,
|
||||
unsigned short bwp_start_subcarrier,
|
||||
unsigned short nb_rb_pdsch);
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <LAYER2/NR_MAC_UE/mac_defs.h>
|
||||
#include <LAYER2/NR_MAC_UE/mac_proto.h>
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
#include "nr_transport_proto_ue.h"
|
||||
@@ -371,7 +373,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
|
||||
LOG_DDD("n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb);
|
||||
int c_rb_by6;
|
||||
c_rb = n_BWP_start;
|
||||
c_rb = 0;
|
||||
for (int rb=0;rb<coreset_nbr_rb;rb++,c_rb++) {
|
||||
c_rb_by6 = c_rb/6;
|
||||
// skip zeros in frequency domain bitmap
|
||||
@@ -386,7 +388,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
// first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start)
|
||||
if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
|
||||
//if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
|
||||
LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
}
|
||||
@@ -394,7 +396,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
if ((c_rb >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
|
||||
// number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC)
|
||||
// if these conditions are true the pointer has to be situated at the 1st part of the rxdataF
|
||||
rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
|
||||
rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; // we point at the 1st part of the rxdataF in symbol
|
||||
LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
//rxF = &rxdataF[aarx][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
|
||||
@@ -406,7 +408,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
|
||||
if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) {
|
||||
//if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
LOG_D(PHY,"in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
@@ -416,7 +418,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
if ((c_rb > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) {
|
||||
// number of RBs is odd and c_rb is higher than half system bandwidth + 1
|
||||
// if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC
|
||||
rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol
|
||||
rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; // we point at the 1st part of the rxdataF in symbol
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
LOG_D(PHY,"in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
@@ -426,7 +428,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
|
||||
if ((c_rb == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC
|
||||
// if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC)
|
||||
// we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table)
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))];
|
||||
rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
|
||||
#ifdef NR_PDCCH_DCI_DEBUG
|
||||
LOG_D(PHY,"in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
|
||||
c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
|
||||
@@ -887,7 +889,8 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
n_rnti = rel15->rnti;
|
||||
|
||||
if (crc == n_rnti) {
|
||||
LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
|
||||
LOG_I(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
|
||||
proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation);
|
||||
dci_ind->SFN = proc->frame_rx;
|
||||
dci_ind->slot = proc->nr_slot_rx;
|
||||
dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti;
|
||||
@@ -898,7 +901,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
|
||||
dci_ind->number_of_dcis++;
|
||||
break; // If DCI is found, no need to check for remaining DCI lengths
|
||||
} else {
|
||||
LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]);
|
||||
LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "PHY/CODING/nrLDPC_extern.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
//#define DEBUG_DLSCH_DECODING
|
||||
|
||||
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
|
||||
|
||||
//#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX
|
||||
@@ -56,7 +56,23 @@ notifiedFIFO_t freeBlocks_dl;
|
||||
notifiedFIFO_elt_t *msgToPush_dl;
|
||||
int nbDlProcessing =0;
|
||||
|
||||
|
||||
static tpool_t pool_dl;
|
||||
|
||||
//extern double cpuf;
|
||||
void init_dlsch_tpool(uint8_t num_dlsch_threads)
|
||||
{
|
||||
if( num_dlsch_threads==0)
|
||||
return;
|
||||
|
||||
char *params=calloc(1,(num_dlsch_threads*3)+1);
|
||||
for (int i=0; i<num_dlsch_threads; i++) {
|
||||
memcpy(params+(i*3),"-1,",3);
|
||||
}
|
||||
initNamedTpool(params, &pool_dl, false,"dlsch");
|
||||
free(params);
|
||||
}
|
||||
|
||||
|
||||
void free_nr_ue_dlsch(NR_UE_DLSCH_t **dlschptr,uint8_t N_RB_DL)
|
||||
{
|
||||
@@ -140,7 +156,6 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
|
||||
dlsch->max_ldpc_iterations = max_ldpc_iterations;
|
||||
|
||||
for (i=0; i<Mdlharq; i++) {
|
||||
// printf("new_ue_dlsch: Harq process %d\n",i);
|
||||
dlsch->harq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t));
|
||||
|
||||
if (dlsch->harq_processes[i]) {
|
||||
@@ -188,7 +203,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
|
||||
return(dlsch);
|
||||
}
|
||||
|
||||
printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
|
||||
LOG_I(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag);
|
||||
free_nr_ue_dlsch(&dlsch,N_RB_DL);
|
||||
|
||||
return(NULL);
|
||||
@@ -250,7 +265,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
t_nrLDPC_time_stats* p_procTime =&procTime ;
|
||||
|
||||
if (!harq_process) {
|
||||
printf("dlsch_decoding.c: NULL harq_process pointer\n");
|
||||
LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
|
||||
return(dlsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
|
||||
@@ -290,12 +305,12 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
//NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0];
|
||||
|
||||
if (!dlsch_llr) {
|
||||
printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
|
||||
LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
|
||||
return(dlsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
|
||||
if (!frame_parms) {
|
||||
printf("dlsch_decoding.c: NULL frame_parms pointer\n");
|
||||
LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
|
||||
return(dlsch->max_ldpc_iterations + 1);
|
||||
}
|
||||
|
||||
@@ -391,12 +406,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
&harq_process->F,
|
||||
p_decParams->BG);
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
if (!frame%100)
|
||||
printf("K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
|
||||
#endif
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100))
|
||||
LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl);
|
||||
}
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
|
||||
|
||||
p_decParams->Z = harq_process->Z;
|
||||
@@ -422,9 +435,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
return((1+dlsch->max_ldpc_iterations));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
#endif
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
|
||||
|
||||
opp_enabled=1;
|
||||
|
||||
@@ -451,8 +464,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DEINTERLEAVING, VCD_FUNCTION_OUT);
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset);
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(dlsch_deinterleaving_stats);
|
||||
@@ -506,29 +517,19 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
|
||||
|
||||
r_offset += E;
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
if (r==0) {
|
||||
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
|
||||
write_output("decoder_in.m","dec",&harq_process->d[0][0],E,1,0);
|
||||
}
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
{
|
||||
LOG_I(PHY,"decoder input(segment %u) :",r);
|
||||
for (int i=0;i<E;i++)
|
||||
LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
|
||||
LOG_D(PHY,"\n");
|
||||
}
|
||||
|
||||
printf("decoder input(segment %u) :",r);
|
||||
int i;
|
||||
for (i=0;i<E;i++)
|
||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||
memset(harq_process->c[r],0,Kr_bytes);
|
||||
|
||||
// printf("done\n");
|
||||
|
||||
if (harq_process->C == 1){
|
||||
if (A > NR_MAX_PDSCH_TBS)
|
||||
crc_type = CRC24_A;
|
||||
@@ -549,9 +550,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
start_meas(dlsch_turbo_decoding_stats);
|
||||
#endif
|
||||
|
||||
//LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_slot_rx,r,harq_process->C-1, A);
|
||||
|
||||
//printf("harq process dr iteration %d\n", p_decParams->numMaxIter);
|
||||
|
||||
//set first 2*Z_c bits to zeros
|
||||
memset(&z[0],0,2*harq_process->Z*sizeof(int16_t));
|
||||
@@ -579,16 +577,17 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
// 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)) {
|
||||
LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r);
|
||||
if (r==0)
|
||||
for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);
|
||||
LOG_I(PHY,"Segment %u CRC OK\n\033[0m",r);
|
||||
if (r==0) {
|
||||
for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]);
|
||||
}
|
||||
|
||||
//Temporary hack
|
||||
no_iteration_ldpc = dlsch->max_ldpc_iterations;
|
||||
ret = no_iteration_ldpc;
|
||||
}
|
||||
else {
|
||||
LOG_D(PHY,"CRC NOK\n\033[0m");
|
||||
LOG_D(PHY,"CRC NOT OK\n\033[0m");
|
||||
ret = 1 + dlsch->max_ldpc_iterations;
|
||||
}
|
||||
|
||||
@@ -598,24 +597,17 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
nb_error_decod++;
|
||||
}
|
||||
|
||||
//if (!nb_total_decod%10000){
|
||||
//printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
|
||||
//}
|
||||
//else
|
||||
//printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++)
|
||||
{
|
||||
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
for (int k=0;k<A>>3;k++)
|
||||
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
|
||||
//write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4);
|
||||
#endif
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
{
|
||||
for (int k=0;k<A>>3;k++)
|
||||
LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret);
|
||||
}
|
||||
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
@@ -623,33 +615,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n",
|
||||
harq_process->C,
|
||||
r,
|
||||
dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
|
||||
dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
|
||||
dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
|
||||
|
||||
|
||||
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
|
||||
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
|
||||
LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
|
||||
err_flag = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (err_flag == 1) {
|
||||
//#if UE_DEBUG_TRACE
|
||||
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_I(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);
|
||||
//#endif
|
||||
|
||||
harq_process->harq_ack.ack = 0;
|
||||
harq_process->harq_ack.harq_id = harq_pid;
|
||||
harq_process->harq_ack.send_harq_status = 1;
|
||||
harq_process->errors[harq_process->round]++;
|
||||
|
||||
// printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round);
|
||||
if (harq_process->round >= dlsch->Mlimit) {
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
@@ -658,16 +639,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
if(is_crnti)
|
||||
{
|
||||
LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||
LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||
phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS);
|
||||
}
|
||||
|
||||
return((1 + dlsch->max_ldpc_iterations));
|
||||
} else {
|
||||
//#if UE_DEBUG_TRACE
|
||||
|
||||
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);
|
||||
//#endif
|
||||
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
@@ -691,11 +671,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
Kr = harq_process->K;
|
||||
Kr_bytes = Kr>>3;
|
||||
|
||||
/*
|
||||
printf("harq_pid %d\n",harq_pid);
|
||||
printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3);
|
||||
printf("C %d\n",harq_process->C);
|
||||
*/
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN);
|
||||
|
||||
@@ -706,30 +681,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
|
||||
printf("copied %d bytes to b sequence (harq_pid %d)\n",
|
||||
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
|
||||
printf("b[0] = %x,c[%d] = %x\n",
|
||||
harq_process->b[offset],
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
{
|
||||
LOG_D(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
|
||||
LOG_D(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
|
||||
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
|
||||
LOG_D(PHY,"b[0] = %p,c[%d] = %p\n",
|
||||
(void *)(uint64_t)(harq_process->b[offset]),
|
||||
harq_process->F>>3,
|
||||
harq_process->c[r]);
|
||||
|
||||
/*printf ("Printing payload bytes:");
|
||||
for (int i = 0; i < Kr_bytes; i++){
|
||||
printf("%d : %d \n", i, harq_process->b[i]);
|
||||
}*/
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_PHY_PAYLOAD_DEBUG)
|
||||
if (frame%100 == 0){
|
||||
LOG_I (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
|
||||
for (int i = 0; i <10 ; i++){ //Kr_bytes
|
||||
LOG_I(PHY, "[%d] : %x ", i, harq_process->b[i]);
|
||||
}
|
||||
(void *)(uint64_t)(harq_process->c[r]) );
|
||||
if (frame%100 == 0){
|
||||
LOG_D (PHY, "Printing 10 first payload bytes at frame: %d ", frame);
|
||||
for (int i = 0; i <10 ; i++){ //Kr_bytes
|
||||
LOG_D(PHY, "[%d] : %x ", i, harq_process->b[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT);
|
||||
@@ -739,7 +706,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
|
||||
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
int eNB_id,
|
||||
@@ -777,35 +744,29 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
t_nrLDPC_time_stats* p_procTime =&procTime ;
|
||||
int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
|
||||
if (!harq_process) {
|
||||
printf("dlsch_decoding.c: NULL harq_process pointer\n");
|
||||
LOG_E(PHY,"dlsch_decoding.c: NULL harq_process pointer\n");
|
||||
return(dlsch->max_ldpc_iterations);
|
||||
}
|
||||
t_nrLDPC_procBuf* p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[0];
|
||||
uint8_t Nl=4;
|
||||
int16_t z [68*384];
|
||||
int8_t l [68*384];
|
||||
//__m128i l;
|
||||
//int16_t inv_d [68*384];
|
||||
//int16_t *p_invd =&inv_d;
|
||||
uint8_t kb, kc;
|
||||
uint8_t kc;
|
||||
uint8_t Ilbrm = 1;
|
||||
uint32_t Tbslbrm = 950984;
|
||||
uint16_t nb_rb = 30;
|
||||
double Coderate = 0.0;
|
||||
uint8_t dmrs_type = harq_process->dmrsConfigType;
|
||||
//nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config;
|
||||
//uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value;
|
||||
|
||||
uint8_t nb_re_dmrs;
|
||||
if (dmrs_Type == NFAPI_NR_DMRS_TYPE1)
|
||||
if (dmrs_type == NFAPI_NR_DMRS_TYPE1)
|
||||
nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups;
|
||||
else
|
||||
nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups;
|
||||
|
||||
uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos);
|
||||
|
||||
uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos);
|
||||
|
||||
uint32_t i,j;
|
||||
// int nbDlProcessing =0;
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
@@ -815,14 +776,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN);
|
||||
|
||||
if (!dlsch_llr) {
|
||||
printf("dlsch_decoding.c: NULL dlsch_llr pointer\n");
|
||||
LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n");
|
||||
return(dlsch->max_ldpc_iterations);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!frame_parms) {
|
||||
printf("dlsch_decoding.c: NULL frame_parms pointer\n");
|
||||
LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n");
|
||||
return(dlsch->max_ldpc_iterations);
|
||||
}
|
||||
|
||||
@@ -865,14 +826,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
G = harq_process->G;
|
||||
|
||||
LOG_D(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
|
||||
LOG_I(PHY,"DLSCH Decoding main, harq_pid %d TBS %d G %d, nb_re_dmrs %d, length_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs, length_dmrs, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
|
||||
|
||||
proc->decoder_main_available = 1;
|
||||
proc->decoder_thread_available = 0;
|
||||
proc->decoder_thread_available1 = 0;
|
||||
//get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe);
|
||||
|
||||
// printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi);
|
||||
|
||||
if ((harq_process->R)<1024)
|
||||
Coderate = (float) (harq_process->R) /(float) 1024;
|
||||
@@ -928,7 +887,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
p_decParams->Z = harq_process->Z;
|
||||
|
||||
//printf("coderate %f kc %d \n", Coderate, kc);
|
||||
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
|
||||
p_decParams->outMode= 0;
|
||||
|
||||
@@ -946,15 +904,15 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||
return((1+dlsch->max_ldpc_iterations));
|
||||
}
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
#endif
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K);
|
||||
|
||||
|
||||
notifiedFIFO_elt_t *res_dl;
|
||||
opp_enabled=1;
|
||||
if (harq_process->C>1) {
|
||||
for (int nb_seg =1 ; nb_seg<harq_process->C; nb_seg++){
|
||||
if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
|
||||
if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) {
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
|
||||
}
|
||||
|
||||
@@ -976,7 +934,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
curMsg->proc.llr8_flag = llr8_flag;
|
||||
|
||||
msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg;
|
||||
pushTpool(Tpool_dl, msgToPush_dl);
|
||||
pushTpool(&pool_dl, msgToPush_dl);
|
||||
|
||||
/*Qm= harq_process->Qm;
|
||||
Nl=harq_process->Nl;
|
||||
@@ -1020,10 +978,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
harq_process->w[r],
|
||||
dlsch_llr+r_offset);
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
for (int i =0; i<16; i++)
|
||||
printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
|
||||
#endif
|
||||
LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(dlsch_deinterleaving_stats);
|
||||
@@ -1033,8 +990,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
start_meas(dlsch_rate_unmatching_stats);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
harq_process->TBS,
|
||||
@@ -1043,7 +1000,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
harq_process->Nl,
|
||||
harq_process->rvidx,
|
||||
harq_process->round);
|
||||
#endif
|
||||
|
||||
|
||||
// for tbslbrm calculation according to 5.4.2.1 of 38.212
|
||||
if (harq_process->Nl < Nl)
|
||||
@@ -1075,35 +1032,28 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
#endif
|
||||
}
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
|
||||
|
||||
//r_offset += E;
|
||||
//printf("main thread r_offset %d\n",r_offset);
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
for (int i =0; i<16; i++)
|
||||
printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
|
||||
#endif
|
||||
LOG_I(PHY,"rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset);
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
{
|
||||
|
||||
if (r==0) {
|
||||
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
|
||||
write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
|
||||
LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0);
|
||||
LOG_M("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0);
|
||||
}
|
||||
|
||||
printf("decoder input(segment %u) :",r);
|
||||
LOG_D(PHY,"decoder input(segment %u) :",r);
|
||||
for (int i=0;i<(3*8*Kr_bytes);i++)
|
||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
|
||||
LOG_D(PHY,"\n");
|
||||
}
|
||||
|
||||
|
||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||
memset(harq_process->c[r],0,Kr_bytes);
|
||||
|
||||
// printf("done\n");
|
||||
if (harq_process->C == 1){
|
||||
if (A > NR_MAX_PDSCH_TBS)
|
||||
crc_type = CRC24_A;
|
||||
@@ -1129,7 +1079,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(dlsch_turbo_decoding_stats);
|
||||
#endif
|
||||
LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
|
||||
LOG_I(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
|
||||
|
||||
/*for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
|
||||
inv_d[cnt] = (1)*harq_process->d[r][cnt];
|
||||
@@ -1165,11 +1115,11 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
}
|
||||
|
||||
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
|
||||
printf("Segment %u CRC OK\n",r);
|
||||
LOG_D(PHY,"Segment %u CRC OK\n",r);
|
||||
ret = 2;
|
||||
}
|
||||
else {
|
||||
printf("CRC NOK\n");
|
||||
LOG_I(PHY,"CRC NOK\n");
|
||||
ret = 1+dlsch->max_ldpc_iterations;
|
||||
}
|
||||
|
||||
@@ -1177,9 +1127,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout);
|
||||
}
|
||||
|
||||
//else
|
||||
//printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++)
|
||||
{
|
||||
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
@@ -1201,10 +1148,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
//printf("output channel decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
|
||||
//printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]);
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
for (int k=0;k<32;k++)
|
||||
printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
#endif
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
for (int k=0;k<32;k++)
|
||||
LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(dlsch_turbo_decoding_stats);
|
||||
@@ -1213,40 +1160,36 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
|
||||
if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// a Code segment is in error so break;
|
||||
LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
|
||||
LOG_I(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1);
|
||||
err_flag = 1;
|
||||
}
|
||||
//} //loop r
|
||||
|
||||
if (err_flag == 1) {
|
||||
#if UE_DEBUG_TRACE
|
||||
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",
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(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);
|
||||
#endif
|
||||
harq_process->harq_ack.ack = 0;
|
||||
harq_process->harq_ack.harq_id = harq_pid;
|
||||
harq_process->harq_ack.send_harq_status = 1;
|
||||
harq_process->errors[harq_process->round]++;
|
||||
harq_process->round++;
|
||||
|
||||
|
||||
// printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round);
|
||||
if (harq_process->round >= dlsch->Mlimit) {
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
}
|
||||
if(is_crnti)
|
||||
{
|
||||
LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||
LOG_I(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n",
|
||||
phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS);
|
||||
}
|
||||
|
||||
return((1+dlsch->max_ldpc_iterations));
|
||||
} else {
|
||||
#if UE_DEBUG_TRACE
|
||||
LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n",
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n",
|
||||
phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
|
||||
#endif
|
||||
|
||||
harq_process->status = SCH_IDLE;
|
||||
harq_process->round = 0;
|
||||
@@ -1300,15 +1243,16 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
Kr_bytes- - (harq_process->F>>3) -((harq_process->C>1)?3:0));
|
||||
offset += (Kr_bytes - (harq_process->F>>3) - ((harq_process->C>1)?3:0));
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
printf("Segment %u : Kr= %u bytes\n",r,Kr_bytes);
|
||||
printf("copied %d bytes to b sequence (harq_pid %d)\n",
|
||||
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
|
||||
printf("b[0] = %x,c[%d] = %x\n",
|
||||
harq_process->b[offset],
|
||||
harq_process->F>>3,
|
||||
harq_process->c[r]);
|
||||
#endif
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
{
|
||||
LOG_I(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes);
|
||||
LOG_I(PHY,"copied %d bytes to b sequence (harq_pid %d)\n",
|
||||
(Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid);
|
||||
LOG_I(PHY,"b[0] = %p,c[%d] = %p\n",
|
||||
(void *)(uint64_t)(harq_process->b[offset]),
|
||||
harq_process->F>>3,
|
||||
(void *)(uint64_t)(harq_process->c[r]));
|
||||
}
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT);
|
||||
@@ -1319,15 +1263,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
|
||||
|
||||
void nr_dlsch_decoding_process(void *arg)
|
||||
{
|
||||
nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg;
|
||||
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
|
||||
PHY_VARS_NR_UE *phy_vars_ue = rxtxD->UE;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
|
||||
int llr8_flag1;
|
||||
int32_t no_iteration_ldpc,length_dec;
|
||||
t_nrLDPC_dec_params decParams;
|
||||
@@ -1341,7 +1284,7 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
//__m128i l;
|
||||
//int16_t inv_d [68*384];
|
||||
//int16_t *p_invd =&inv_d;
|
||||
uint8_t kb, kc;
|
||||
uint8_t kc;
|
||||
uint8_t Ilbrm = 1;
|
||||
uint32_t Tbslbrm = 950984;
|
||||
uint16_t nb_rb = 30; //to update
|
||||
@@ -1351,8 +1294,6 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
uint16_t length_dmrs = 1;
|
||||
|
||||
uint32_t i,j;
|
||||
uint32_t k;
|
||||
|
||||
__m128i *pv = (__m128i*)&z;
|
||||
__m128i *pl = (__m128i*)&l;
|
||||
|
||||
@@ -1369,8 +1310,10 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
#endif
|
||||
uint32_t A,E;
|
||||
uint32_t G;
|
||||
uint32_t ret,offset;
|
||||
|
||||
uint32_t ret;
|
||||
uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bits_F;
|
||||
|
||||
uint8_t crc_type;
|
||||
uint8_t C,Cprime;
|
||||
uint8_t Qm;
|
||||
@@ -1381,31 +1324,17 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
int harq_pid = proc->harq_pid;
|
||||
llr8_flag1 = proc->llr8_flag;
|
||||
int frame = proc->frame_rx;
|
||||
int slot = proc->nr_slot_rx;
|
||||
r = proc->num_seg;
|
||||
|
||||
NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[proc->thread_id][eNB_id][0];
|
||||
NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid];
|
||||
short *dlsch_llr = phy_vars_ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0];
|
||||
//printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag);
|
||||
|
||||
p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf[r];
|
||||
nb_symb_sch = harq_process->nb_symbols;
|
||||
printf("dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
|
||||
LOG_I(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols);
|
||||
|
||||
|
||||
/*
|
||||
if (nb_rb > frame_parms->N_RB_DL) {
|
||||
printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb);
|
||||
return(max_ldpc_iterations);
|
||||
}*/
|
||||
|
||||
/*harq_pid = dlsch->current_harq_pid[proc->thread_id];
|
||||
if (harq_pid >= 8) {
|
||||
printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
|
||||
return(max_ldpc_iterations);
|
||||
}
|
||||
*/
|
||||
|
||||
nb_rb = harq_process->nb_rb;
|
||||
|
||||
harq_process->trials[harq_process->round]++;
|
||||
@@ -1422,7 +1351,7 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, harq_process->Qm,harq_process->Nl);
|
||||
G = harq_process->G;
|
||||
|
||||
LOG_D(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
|
||||
LOG_I(PHY,"DLSCH Decoding process, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb);
|
||||
|
||||
if ((harq_process->R)<1024)
|
||||
Coderate = (float) (harq_process->R) /(float) 1024;
|
||||
@@ -1478,36 +1407,13 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
|
||||
// }
|
||||
|
||||
//printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
|
||||
LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
|
||||
|
||||
|
||||
p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
|
||||
p_decParams->outMode= 0;
|
||||
|
||||
/*
|
||||
else {
|
||||
printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n");
|
||||
return(max_ldpc_iterations);
|
||||
}
|
||||
*/
|
||||
err_flag = 0;
|
||||
//r_offset = 0;
|
||||
|
||||
/*
|
||||
uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated
|
||||
|
||||
if (nb_rb != 273) {
|
||||
a_segments = a_segments*nb_rb;
|
||||
a_segments = a_segments/273 +1;
|
||||
}
|
||||
|
||||
if (harq_process->C > a_segments) {
|
||||
LOG_E(PHY,"Illegal harq_process->C %d > %d\n",harq_process->C,a_segments);
|
||||
return((1+dlsch->max_ldpc_iterations));
|
||||
}*/
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus);
|
||||
#endif
|
||||
|
||||
opp_enabled=1;
|
||||
|
||||
@@ -1522,9 +1428,7 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
r_offset = Nl*Qm*(G/(Nl*Qm*Cprime));
|
||||
else
|
||||
r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1);
|
||||
|
||||
// printf("thread0 r_offset %d\n",r_offset);
|
||||
|
||||
|
||||
//for (r=(harq_process->C/2); r<harq_process->C; r++) {
|
||||
// r=1; //(harq_process->C/2);
|
||||
|
||||
@@ -1544,10 +1448,10 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
harq_process->w[r],
|
||||
dlsch_llr+r_offset);
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
for (int i =0; i<16; i++)
|
||||
printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
|
||||
#endif
|
||||
LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset);
|
||||
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(dlsch_deinterleaving_stats);
|
||||
@@ -1557,8 +1461,8 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
start_meas(dlsch_rate_unmatching_stats);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n",
|
||||
harq_pid,r, G,
|
||||
Kr*3,
|
||||
harq_process->TBS,
|
||||
@@ -1567,7 +1471,7 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
harq_process->Nl,
|
||||
harq_process->rvidx,
|
||||
harq_process->round);
|
||||
#endif
|
||||
|
||||
|
||||
if (Nl<4)
|
||||
Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl);
|
||||
@@ -1598,25 +1502,14 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
//for (int i =0; i<16; i++)
|
||||
// printf("rx output ratematching d[%d]= %d r_offset %d\n", i,harq_process->d[r][i], r_offset);
|
||||
|
||||
//r_offset += E;
|
||||
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
if (r==0) {
|
||||
write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
|
||||
write_output("decoder_in.m","dec",&harq_process->d[0][0],(3*8*Kr_bytes)+12,1,0);
|
||||
if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) {
|
||||
LOG_D(PHY,"decoder input(segment %u) :",r);
|
||||
for (int i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||
LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]);
|
||||
LOG_D(PHY,"\n");
|
||||
}
|
||||
|
||||
printf("decoder input(segment %u) :",r);
|
||||
int i; for (i=0;i<(3*8*Kr_bytes)+12;i++)
|
||||
printf("%d : %d\n",i,harq_process->d[r][i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
|
||||
// printf("Clearing c, %p\n",harq_process->c[r]);
|
||||
memset(harq_process->c[r],0,Kr_bytes);
|
||||
|
||||
if (harq_process->C == 1){
|
||||
@@ -1634,18 +1527,18 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
|
||||
if (err_flag == 0) {
|
||||
/*
|
||||
LOG_D(PHY, "turbo algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
|
||||
LOG_D(PHY, "LDPC algo Kr=%d cb_cnt=%d C=%d nbRB=%d crc_type %d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d maxIter %d\n",
|
||||
Kr,r,harq_process->C,harq_process->nb_rb,crc_type,A,harq_process->TBS,
|
||||
harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round,dlsch->max_ldpc_iterations);
|
||||
*/
|
||||
if (llr8_flag1) {
|
||||
AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
|
||||
AssertFatal (Kr >= 256, "LDPC algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
|
||||
Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
|
||||
}
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(dlsch_turbo_decoding_stats);
|
||||
#endif
|
||||
// LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
|
||||
// LOG_D(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
|
||||
/*
|
||||
for (int cnt =0; cnt < (kc-2)*p_decParams->Z; cnt++){
|
||||
inv_d[cnt] = (1)*harq_process->d[r][cnt];
|
||||
@@ -1678,39 +1571,23 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
ret = 2;
|
||||
}
|
||||
else {
|
||||
LOG_D(PHY,"Segment %u CRC NOK\n",r);
|
||||
LOG_I(PHY,"Segment %u CRC NOK\n",r);
|
||||
ret = 1+dlsch->max_ldpc_iterations;
|
||||
}
|
||||
|
||||
if (no_iteration_ldpc > 10)
|
||||
LOG_D(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
|
||||
//else
|
||||
//printf("OK number of iteration LPDC %d\n", no_iteration_ldpc);
|
||||
LOG_I(PHY,"Error number of iteration LPDC %d\n", no_iteration_ldpc);
|
||||
|
||||
|
||||
for (int m=0; m < Kr>>3; m ++)
|
||||
{
|
||||
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
|
||||
}
|
||||
|
||||
/*for (int u=0; u < Kr>>3; u ++)
|
||||
{
|
||||
ullrProcBuf[u]= (uint8_t) llrProcBuf[u];
|
||||
}
|
||||
if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD))
|
||||
for (int k=0;k<2;k++)
|
||||
LOG_D(PHY,"segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
|
||||
|
||||
printf("output unsigned ullrProcBuf \n");
|
||||
|
||||
for (int j=0; j < Kr>>3; j ++)
|
||||
{
|
||||
|
||||
printf(" %d \n", ullrProcBuf[j]);
|
||||
|
||||
}
|
||||
printf(" \n");*/
|
||||
#ifdef DEBUG_DLSCH_DECODING
|
||||
for (int k=0;k<2;k++)
|
||||
printf("segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]);
|
||||
#endif
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(dlsch_turbo_decoding_stats);
|
||||
@@ -1729,13 +1606,12 @@ void nr_dlsch_decoding_process(void *arg)
|
||||
|
||||
void *dlsch_thread(void *arg) {
|
||||
//this thread should be over the processing thread to keep in real time
|
||||
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
|
||||
notifiedFIFO_t nf;
|
||||
initNotifiedFIFO(&nf);
|
||||
notifiedFIFO_elt_t *res_dl;
|
||||
initNotifiedFIFO_nothreadSafe(&freeBlocks_dl);
|
||||
|
||||
for (int i=0; i<RX_NB_TH_DL+1; i++){
|
||||
for (int i=0; i<tpool_nbthreads(pool_dl)+1; i++){
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,
|
||||
newNotifiedFIFO_elt(sizeof(nr_rxtx_thread_data_t), 0,&nf,nr_dlsch_decoding_process));}
|
||||
|
||||
@@ -1743,9 +1619,8 @@ void *dlsch_thread(void *arg) {
|
||||
|
||||
notifiedFIFO_elt_t *res;
|
||||
|
||||
while (nbDlProcessing >= RX_NB_TH_DL) {
|
||||
if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) {
|
||||
nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData;
|
||||
while (nbDlProcessing >= tpool_nbthreads(pool_dl)) {
|
||||
if ( (res=tryPullTpool(&nf, &pool_dl)) != NULL ) {
|
||||
//nbDlProcessing--;
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res);
|
||||
}
|
||||
@@ -1753,7 +1628,7 @@ void *dlsch_thread(void *arg) {
|
||||
usleep(200);
|
||||
}
|
||||
|
||||
res_dl=pullTpool(&nf, Tpool_dl);
|
||||
res_dl=pullTpool(&nf, &pool_dl);
|
||||
nbDlProcessing--;
|
||||
pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl);
|
||||
|
||||
@@ -1766,4 +1641,4 @@ void *dlsch_thread(void *arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -404,7 +404,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
symbol,
|
||||
pilots,
|
||||
config_type,
|
||||
start_rb,
|
||||
start_rb + dlsch0_harq->BWPStart,
|
||||
nb_rb_pdsch,
|
||||
nr_slot_rx,
|
||||
ue->high_speed_flag,
|
||||
@@ -422,7 +422,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
|
||||
len = (pilots==1)? ((config_type==pdsch_dmrs_type1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12);
|
||||
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||
#if DISABLE_LOG_X
|
||||
@@ -1626,6 +1626,8 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
|
||||
int16_t y = (len)>>x;
|
||||
//printf("len = %d = %d * 2^(%d)\n",len,y,x);
|
||||
|
||||
AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__);
|
||||
|
||||
for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++)
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
//clear average level
|
||||
|
||||
@@ -25,21 +25,18 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "nr_phy_scope.h"
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
#include <forms.h>
|
||||
|
||||
#define TPUT_WINDOW_LENGTH 100
|
||||
#define ScaleZone 4
|
||||
#define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe));
|
||||
|
||||
int otg_enabled;
|
||||
|
||||
FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
|
||||
|
||||
float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
|
||||
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};
|
||||
|
||||
typedef struct {
|
||||
int16_t r;
|
||||
@@ -49,10 +46,18 @@ typedef struct {
|
||||
|
||||
typedef struct OAIgraph {
|
||||
FL_OBJECT *graph;
|
||||
FL_OBJECT *text;
|
||||
float maxX;
|
||||
float maxY;
|
||||
float minX;
|
||||
float minY;
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
int waterFallh;
|
||||
double *waterFallAvg;
|
||||
boolean_t initDone;
|
||||
int iteration;
|
||||
void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
|
||||
void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
|
||||
@@ -94,57 +99,114 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static FL_OBJECT *commonGraph( int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
||||
FL_OBJECT *graph;
|
||||
graph=fl_add_xyplot(type, x, y, w, h, label);
|
||||
fl_set_object_lcolor(graph, FL_WHITE ); // Label color
|
||||
fl_set_object_color(graph, FL_BLACK, pointColor);
|
||||
fl_set_xyplot_symbol(graph, -1, drawsymbol);
|
||||
return graph;
|
||||
#define WATERFALL 10000
|
||||
|
||||
static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
||||
if (type==WATERFALL) {
|
||||
graph->waterFallh=h-15;
|
||||
graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh);
|
||||
|
||||
for (int i=0; i< graph->waterFallh; i++)
|
||||
graph->waterFallAvg[i]=0;
|
||||
|
||||
graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label);
|
||||
graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label);
|
||||
fl_set_object_lcolor(graph->text,FL_WHITE);
|
||||
fl_set_object_color(graph->text, FL_BLACK, FL_BLACK);
|
||||
fl_set_object_lalign(graph->text, FL_ALIGN_CENTER );
|
||||
} else {
|
||||
graph->graph=fl_add_xyplot(type, x, y, w, h, label);
|
||||
fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color
|
||||
fl_set_object_color(graph->graph, FL_BLACK, pointColor);
|
||||
|
||||
for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++)
|
||||
fl_set_xyplot_symbol(graph->graph, i, drawsymbol);
|
||||
}
|
||||
|
||||
graph->x=x;
|
||||
graph->y=y;
|
||||
graph->w=w;
|
||||
graph->h=h;
|
||||
graph->maxX=0;
|
||||
graph->maxY=0;
|
||||
graph->minX=0;
|
||||
graph->minY=0;
|
||||
graph->initDone=false;
|
||||
graph->iteration=0;
|
||||
}
|
||||
|
||||
static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
|
||||
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
||||
OAIgraph_t graph;
|
||||
graph.graph=commonGraph(type, x, y, w, h, label, pointColor);
|
||||
commonGraph(&graph, type, x, y, w, h, label, pointColor);
|
||||
graph.gNBfunct=funct;
|
||||
graph.nrUEfunct=NULL;
|
||||
graph.maxX=0;
|
||||
graph.maxY=0;
|
||||
graph.minX=0;
|
||||
graph.minY=0;
|
||||
return graph;
|
||||
}
|
||||
|
||||
static OAIgraph_t nrUEcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id),
|
||||
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
||||
OAIgraph_t graph;
|
||||
graph.graph=commonGraph(type, x, y, w, h, label, pointColor);
|
||||
commonGraph(&graph, type, x, y, w, h, label, pointColor);
|
||||
graph.gNBfunct=NULL;
|
||||
graph.nrUEfunct=funct;
|
||||
graph.maxX=0;
|
||||
graph.maxY=0;
|
||||
graph.minX=0;
|
||||
graph.minY=0;
|
||||
return graph;
|
||||
}
|
||||
|
||||
static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) {
|
||||
if ( maxX > graph->maxX || maxY > graph->maxY || minX < graph->minX || minY < graph->minY ) {
|
||||
if ( maxX > graph->maxX || minX < graph->minX ||
|
||||
abs(maxX-graph->maxX)>abs(graph->maxX)/2 ||
|
||||
abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) {
|
||||
graph->maxX/=2;
|
||||
graph->minX/=2;
|
||||
graph->maxX=max(graph->maxX,maxX);
|
||||
graph->minX=min(graph->minX,minX);
|
||||
fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2);
|
||||
}
|
||||
|
||||
if ( maxY > graph->maxY || minY < graph->minY ||
|
||||
abs(maxY-graph->maxY)>abs(graph->maxY)/2 ||
|
||||
abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) {
|
||||
graph->maxY/=2;
|
||||
graph->minY/=2;
|
||||
graph->maxY=max(graph->maxY,maxY);
|
||||
graph->minY=min(graph->minY,minY);
|
||||
fl_set_xyplot_ybounds(graph->graph, graph->minY, graph->maxY);
|
||||
fl_set_xyplot_xbounds(graph->graph, graph->minX, graph->maxX);
|
||||
fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2);
|
||||
}
|
||||
}
|
||||
|
||||
static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, int NoAutoScale) {
|
||||
if (layer==0)
|
||||
fl_set_xyplot_data(graph->graph,x,y,len,"","","");
|
||||
else
|
||||
fl_add_xyplot_overlay(graph->graph,layer,x,y,len,rx_antenna_colors[layer]);
|
||||
static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) {
|
||||
float *old_x;
|
||||
float *old_y;
|
||||
int old_len=-1;
|
||||
|
||||
if (graph->iteration >1)
|
||||
fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
|
||||
|
||||
if (old_len != len) {
|
||||
LOG_W(HW,"allocating graph of %d scope\n", len);
|
||||
float values[len];
|
||||
float time[len];
|
||||
|
||||
// make time in case we will use it
|
||||
for (int i=0; i<len; i++)
|
||||
time[i] = values[i] = i;
|
||||
|
||||
if (layer==0)
|
||||
fl_set_xyplot_data(graph->graph,time,values,len,"","","");
|
||||
else
|
||||
fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]);
|
||||
|
||||
fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
|
||||
AssertFatal(old_len==len,"");
|
||||
}
|
||||
|
||||
*x=old_x;
|
||||
*y=old_y;
|
||||
}
|
||||
|
||||
static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) {
|
||||
fl_redraw_object(graph->graph);
|
||||
|
||||
if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
|
||||
float maxX=0, maxY=0, minX=0, minY=0;
|
||||
@@ -156,46 +218,100 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye
|
||||
minY=min(minY,y[k]);
|
||||
}
|
||||
|
||||
setRange(graph,minX,maxX, minY, maxY);
|
||||
setRange(graph, minX-5, maxX+5, minY-5, maxY+5);
|
||||
}
|
||||
|
||||
graph->iteration++;
|
||||
}
|
||||
|
||||
static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
|
||||
fl_winset(FL_ObjWin(graph->graph));
|
||||
const int samplesPerPixel=datasize/graph->w;
|
||||
int displayPart=graph->waterFallh-ScaleZone;
|
||||
int row=graph->iteration%displayPart;
|
||||
double avg=0;
|
||||
|
||||
for (int i=0; i < displayPart; i++)
|
||||
avg+=graph->waterFallAvg[i];
|
||||
|
||||
avg/=displayPart;
|
||||
graph->waterFallAvg[row]=0;
|
||||
|
||||
for (int pix=0; pix<graph->w; pix++) {
|
||||
scopeSample_t *end=values+(pix+1)*samplesPerPixel;
|
||||
end-=2;
|
||||
AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize);
|
||||
double val=0;
|
||||
|
||||
for (scopeSample_t *s=values+(pix)*samplesPerPixel;
|
||||
s <end;
|
||||
s++)
|
||||
val += SquaredNorm(*s);
|
||||
|
||||
val/=samplesPerPixel;
|
||||
graph->waterFallAvg[row]+=val/graph->w;
|
||||
int col=0;
|
||||
|
||||
if (val > avg*2 )
|
||||
col=1;
|
||||
|
||||
if (val > avg*10 )
|
||||
col=2;
|
||||
|
||||
if (val > avg*100 )
|
||||
col=3;
|
||||
|
||||
fl_point(pix, graph->iteration%displayPart, water_colors[col]);
|
||||
}
|
||||
|
||||
if (graph->initDone==false) {
|
||||
for ( int i=0; i < graph->waterFallh; i++ )
|
||||
for ( int j = 0 ; j < graph->w ; j++ )
|
||||
fl_point(j, i, FL_BLACK);
|
||||
|
||||
for ( int i=1; i<divisions; i++)
|
||||
for (int j= displayPart; j<graph->waterFallh; j++)
|
||||
fl_point(i*(graph->w/divisions),j, FL_WHITE);
|
||||
|
||||
graph->initDone=true;
|
||||
}
|
||||
|
||||
fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg));
|
||||
graph->iteration++;
|
||||
}
|
||||
|
||||
static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
||||
float *values=malloc(len*sizeof(*values));
|
||||
float *time=malloc(len*sizeof(*time));
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
|
||||
for (int ant=0; ant<nb_ant; ant++) {
|
||||
if (data[ant] != NULL) {
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, ant);
|
||||
|
||||
for (int i=0; i<len; i+=8) {
|
||||
float *vals=values+i;
|
||||
float *tim=time+i;
|
||||
const scopeSample_t *in=&(data[ant][i]);
|
||||
|
||||
// TRY AUTOMATIC simd BY GCC
|
||||
for (int k=0; k<8; k++ ) {
|
||||
vals[k] = 10*log10(1.0+SquaredNorm(in[k]));
|
||||
tim[k] = i+k;
|
||||
}
|
||||
}
|
||||
|
||||
oai_xygraph(graph,time,values, len, ant, 10);
|
||||
}
|
||||
}
|
||||
|
||||
free(values);
|
||||
free(time);
|
||||
}
|
||||
|
||||
static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
||||
float values[len];
|
||||
float time[len];
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
|
||||
for (int ant=0; ant<nb_ant; ant++) {
|
||||
if (data[ant] != NULL) {
|
||||
for (int i=0; i<len; i++) {
|
||||
values[i] = SquaredNorm(data[ant][i]);
|
||||
time[i] = i;
|
||||
}
|
||||
|
||||
oai_xygraph(graph,time,values, len, ant, 10);
|
||||
@@ -203,6 +319,15 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc
|
||||
}
|
||||
}
|
||||
|
||||
static void gNBWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
//use 1st antenna
|
||||
genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0],
|
||||
frame_parms->samples_per_frame, frame_parms->slots_per_frame,
|
||||
"X axis:one frame in time");
|
||||
}
|
||||
|
||||
/* replaced by waterfall
|
||||
static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, const int nb_UEs) {
|
||||
// Received signal in time domain of receive antenna 0
|
||||
if (!phy_vars_ru->common.rxdata)
|
||||
@@ -213,11 +338,12 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy
|
||||
(const scopeSample_t **)phy_vars_ru->common.rxdata,
|
||||
frame_parms->samples_per_frame);
|
||||
}
|
||||
*/
|
||||
|
||||
static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
|
||||
float values[len];
|
||||
float time[len];
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
const int ant=0; // display antenna 0 for each UE
|
||||
|
||||
for (int ue=0; ue<nb_UEs; ue++) {
|
||||
@@ -226,7 +352,6 @@ static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *p
|
||||
if (data != NULL) {
|
||||
for (int i=0; i<len; i++) {
|
||||
values[i] = SquaredNorm(data[i]);
|
||||
time[i] = i;
|
||||
}
|
||||
|
||||
oai_xygraph(graph,time,values, len, ue, 10);
|
||||
@@ -234,26 +359,35 @@ static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *p
|
||||
}
|
||||
}
|
||||
|
||||
static void gNBfreqWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
//use 1st antenna
|
||||
genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP,
|
||||
frame_parms->slots_per_frame,
|
||||
"X axis: Frequency domain, one frame");
|
||||
}
|
||||
|
||||
/*
|
||||
static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx,
|
||||
(const scopeSample_t **)phy_vars_ru->common.rxdataF,
|
||||
frame_parms->samples_per_slot_wCP);
|
||||
}
|
||||
*/
|
||||
|
||||
static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
//int Qm = 2;
|
||||
int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
|
||||
float llr[coded_bits_per_codeword];
|
||||
float bit[coded_bits_per_codeword];
|
||||
|
||||
for (int ue=0; ue<nb_UEs; ue++) {
|
||||
int16_t *pusch_llr = (int16_t *)phy_vars_gnb->pusch_vars[ue]->llr;
|
||||
float *llr, *bit;
|
||||
oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
|
||||
|
||||
if (pusch_llr) {
|
||||
for (int i=0; i<coded_bits_per_codeword; i++) {
|
||||
llr[i] = (float) pusch_llr[i];
|
||||
bit[i] = (float) i;
|
||||
}
|
||||
|
||||
oai_xygraph(graph,bit,llr,coded_bits_per_codeword,ue,10);
|
||||
@@ -264,10 +398,11 @@ static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_v
|
||||
static void puschIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
|
||||
int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
|
||||
float I[sz], Q[sz];
|
||||
|
||||
for (int ue=0; ue<nb_UEs; ue++) {
|
||||
scopeSample_t *pusch_comp = (scopeSample_t *) phy_vars_gnb->pusch_vars[ue]->rxdataF_comp[0];
|
||||
float *I, *Q;
|
||||
oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
|
||||
|
||||
if (pusch_comp) {
|
||||
for (int k=0; k<sz; k++ ) {
|
||||
@@ -312,6 +447,9 @@ static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_va
|
||||
static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
|
||||
// PUSCH Throughput
|
||||
/*
|
||||
float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
|
||||
memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
||||
memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
||||
tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) 0;
|
||||
@@ -332,18 +470,18 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) {
|
||||
fl_set_object_color( obj, FL_BLACK, FL_WHITE );
|
||||
int curY=0,x,y,w,h;
|
||||
// Received signal
|
||||
fdui->graph[0] = gNBcommonGraph( timeSignal, FL_NORMAL_XYPLOT, 0, curY, 400, 100,
|
||||
"Received Signal (Time-Domain, dB)", FL_RED );
|
||||
fdui->graph[0] = gNBcommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100,
|
||||
"Received Signal (Time-Domain, one frame)", FL_RED );
|
||||
// Time-domain channel response
|
||||
fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100,
|
||||
"SRS Frequency Response (samples, abs)", FL_RED );
|
||||
fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
|
||||
fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
|
||||
curY+=h;
|
||||
// Frequency-domain channel response
|
||||
fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_NORMAL_XYPLOT, 0, curY, 800, 100,
|
||||
"Channel Frequency Response (RE, dB)", FL_RED );
|
||||
fdui->graph[2] = gNBcommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100,
|
||||
"Channel Frequency domain (RE, one frame)", FL_RED );
|
||||
fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
|
||||
curY+=h;
|
||||
curY+=h+20;
|
||||
// LLR of PUSCH
|
||||
fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200,
|
||||
"PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
|
||||
@@ -376,14 +514,15 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
|
||||
PHY_VARS_gNB *phy_vars_gnb,
|
||||
RU_t *phy_vars_ru,
|
||||
int UE_id) {
|
||||
static OAI_phy_scope_t *remeberForm=NULL;
|
||||
static OAI_phy_scope_t *rememberForm=NULL;
|
||||
|
||||
if (form==NULL)
|
||||
form=remeberForm;
|
||||
form=rememberForm;
|
||||
else
|
||||
remeberForm=form;
|
||||
rememberForm=form;
|
||||
|
||||
if (form==NULL) return;
|
||||
if (form==NULL)
|
||||
return;
|
||||
|
||||
int i=0;
|
||||
|
||||
@@ -392,7 +531,7 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
|
||||
i++;
|
||||
}
|
||||
|
||||
fl_check_forms();
|
||||
//fl_check_forms();
|
||||
}
|
||||
|
||||
static void *scope_thread_gNB(void *arg) {
|
||||
@@ -406,7 +545,9 @@ static void *scope_thread_gNB(void *arg) {
|
||||
pthread_attr_getstacksize(&atr, &stksize);
|
||||
pthread_attr_setstacksize(&atr,32*1024*1024 );
|
||||
sleep(3); // no clean interthread barriers
|
||||
fl_initialize (p->argc, p->argv, NULL, 0, 0);
|
||||
int fl_argc=1;
|
||||
char *name="5G-gNB-scope";
|
||||
fl_initialize (&fl_argc, &name, NULL, 0, 0);
|
||||
int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue);
|
||||
OAI_phy_scope_t *form_gnb = create_phy_scope_gnb();
|
||||
|
||||
@@ -425,12 +566,23 @@ void gNBinitScope(scopeParms_t *p) {
|
||||
threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
|
||||
}
|
||||
|
||||
static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
// Received signal in time domain of receive antenna 0
|
||||
genericWaterFall(graph,
|
||||
(scopeSample_t *) phy_vars_ue->common_vars.rxdata[0],
|
||||
phy_vars_ue->frame_parms.samples_per_frame,
|
||||
phy_vars_ue->frame_parms.slots_per_frame,
|
||||
"X axis: one frame time");
|
||||
}
|
||||
|
||||
/* replaced by waterfall
|
||||
static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
// Received signal in time domain of receive antenna 0
|
||||
genericLogPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
|
||||
(const scopeSample_t **) phy_vars_ue->common_vars.rxdata,
|
||||
phy_vars_ue->frame_parms.samples_per_frame);
|
||||
}
|
||||
*/
|
||||
|
||||
static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
// Channel Impulse Response
|
||||
@@ -439,6 +591,17 @@ static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue,
|
||||
phy_vars_ue->frame_parms.ofdm_symbol_size>>3);
|
||||
}
|
||||
|
||||
static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) {
|
||||
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms;
|
||||
//use 1st antenna
|
||||
genericWaterFall(graph,
|
||||
(scopeSample_t *)phy_vars_ue->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0],
|
||||
frame_parms->samples_per_slot_wCP,
|
||||
phy_vars_ue->frame_parms.slots_per_frame,
|
||||
"X axis: one frame frequency" );
|
||||
}
|
||||
|
||||
/*
|
||||
static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
// Channel Frequency Response (includes 5 complex sample for filter)
|
||||
if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates)
|
||||
@@ -449,12 +612,13 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
|
||||
uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB;
|
||||
scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates;
|
||||
int ind = 0;
|
||||
float chest_f_abs[frame_parms->ofdm_symbol_size];
|
||||
float freq[frame_parms->ofdm_symbol_size];
|
||||
float *freq, *chest_f_abs;
|
||||
oai_xygraph_getbuff(graph, &freq, &chest_f_abs, frame_parms->ofdm_symbol_size, 0);
|
||||
|
||||
for (int atx=0; atx<nb_antennas_tx; atx++) {
|
||||
for (int arx=0; arx<nb_antennas_rx; arx++) {
|
||||
if (chest_f[(atx<<1)+arx] != NULL) {
|
||||
|
||||
for (int k=0; k<frame_parms->ofdm_symbol_size; k++) {
|
||||
freq[ind] = (float)ind;
|
||||
chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k]));
|
||||
@@ -471,6 +635,7 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
|
||||
//fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
|
||||
oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
|
||||
}
|
||||
*/
|
||||
|
||||
static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
// PBCH LLRs
|
||||
@@ -478,11 +643,11 @@ static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
|
||||
return;
|
||||
|
||||
int16_t *pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
|
||||
float llr_pbch[864], bit_pbch[864];
|
||||
float *llr_pbch, *bit_pbch;
|
||||
oai_xygraph_getbuff(graph, &bit_pbch, &llr_pbch, 864, 0);
|
||||
|
||||
for (int i=0; i<864; i++) {
|
||||
llr_pbch[i] = (float) pbch_llr[i];
|
||||
bit_pbch[i] = (float) i;
|
||||
}
|
||||
|
||||
oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10);
|
||||
@@ -494,8 +659,10 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
||||
return;
|
||||
|
||||
scopeSample_t *pbch_comp = (scopeSample_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
|
||||
localBuff(I,180*3);
|
||||
localBuff(Q,180*3);
|
||||
float *I, *Q;
|
||||
oai_xygraph_getbuff(graph, &I, &Q, 180*3, 0);
|
||||
memset(I,0,180*3*sizeof(*I));
|
||||
memset(Q,0,180*3*sizeof(*Q));
|
||||
int first_symbol=1;
|
||||
int base=0;
|
||||
|
||||
@@ -517,7 +684,8 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
||||
base+=nb_re;
|
||||
}
|
||||
|
||||
oai_xygraph(graph,I,Q,base,0,10);
|
||||
AssertFatal(base <= 180*3,"");
|
||||
oai_xygraph(graph,I,Q,base,0, 10);
|
||||
}
|
||||
|
||||
static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
@@ -528,8 +696,8 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
|
||||
int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
|
||||
int Qm = 2;
|
||||
int coded_bits_per_codeword = num_re*Qm;
|
||||
localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX);
|
||||
localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX);
|
||||
float *llr, *bit;
|
||||
oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
|
||||
int base=0;
|
||||
|
||||
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
|
||||
@@ -537,12 +705,12 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
|
||||
|
||||
for (int i=0; i<coded_bits_per_codeword; i++) {
|
||||
llr[base+i] = (float) pdcch_llr[i];
|
||||
bit[base+i] = (float) base+i;
|
||||
}
|
||||
|
||||
base+=coded_bits_per_codeword;
|
||||
}
|
||||
|
||||
AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
|
||||
oai_xygraph(graph,bit,llr,base,0,10);
|
||||
}
|
||||
|
||||
@@ -552,8 +720,8 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
||||
return;
|
||||
|
||||
int nb=4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
|
||||
localBuff(I,nb*RX_NB_TH_MAX);
|
||||
localBuff(Q,nb*RX_NB_TH_MAX);
|
||||
float *I, *Q;
|
||||
oai_xygraph_getbuff(graph, &I, &Q, nb*RX_NB_TH_MAX, 0);
|
||||
int base=0;
|
||||
|
||||
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
|
||||
@@ -567,6 +735,7 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
|
||||
base+=nb;
|
||||
}
|
||||
|
||||
AssertFatal(base <= nb*RX_NB_TH_MAX, "");
|
||||
oai_xygraph(graph,I,Q,base,0,10);
|
||||
}
|
||||
|
||||
@@ -578,8 +747,8 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB
|
||||
int num_re = 4500;
|
||||
int Qm = 2;
|
||||
int coded_bits_per_codeword = num_re*Qm;
|
||||
localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX);
|
||||
localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX);
|
||||
float *llr, *bit;
|
||||
oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
|
||||
int base=0;
|
||||
|
||||
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
|
||||
@@ -593,6 +762,7 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB
|
||||
base+=coded_bits_per_codeword;
|
||||
}
|
||||
|
||||
AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
|
||||
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
|
||||
oai_xygraph(graph,bit,llr,base,0,10);
|
||||
}
|
||||
@@ -604,9 +774,11 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
|
||||
|
||||
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
|
||||
int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer
|
||||
localBuff(I,sz*RX_NB_TH_MAX);
|
||||
localBuff(Q,sz*RX_NB_TH_MAX);
|
||||
float *I, *Q;
|
||||
oai_xygraph_getbuff(graph, &I, &Q, sz*RX_NB_TH_MAX, 0);
|
||||
int base=0;
|
||||
memset(I+base, 0, sz*RX_NB_TH_MAX * sizeof(*I));
|
||||
memset(Q+base, 0, sz*RX_NB_TH_MAX * sizeof(*Q));
|
||||
|
||||
for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
|
||||
scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0];
|
||||
@@ -619,11 +791,16 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
|
||||
base+=sz;
|
||||
}
|
||||
|
||||
oai_xygraph(graph,I,Q,base,0,10);
|
||||
AssertFatal(base <= sz*RX_NB_TH_MAX, "");
|
||||
oai_xygraph(graph,I,Q,sz*RX_NB_TH_MAX,0,10);
|
||||
}
|
||||
|
||||
static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
|
||||
/*
|
||||
float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
|
||||
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
|
||||
|
||||
|
||||
// PDSCH Throughput
|
||||
memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
|
||||
@@ -652,18 +829,18 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
|
||||
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
|
||||
int curY=0,x,y,w,h;
|
||||
// Received signal
|
||||
fdui->graph[0] = nrUEcommonGraph(ueTimeResponse,
|
||||
FL_NORMAL_XYPLOT, 0, curY, 400, 100, "Received Signal (Time-Domain, dB)", FL_RED );
|
||||
fdui->graph[0] = nrUEcommonGraph(ueWaterFall,
|
||||
WATERFALL, 0, curY, 400, 100, "Received Signal (Time-Domain, one frame)", FL_RED );
|
||||
// Time-domain channel response
|
||||
fdui->graph[1] = nrUEcommonGraph(ueChannelResponse,
|
||||
FL_NORMAL_XYPLOT, 400, curY, 400, 100, "Channel Impulse Response (samples, abs)", FL_RED );
|
||||
fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
|
||||
fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
|
||||
curY+=h;
|
||||
// Frequency-domain channel response
|
||||
fdui->graph[2] = nrUEcommonGraph(uePbchFrequencyResp,
|
||||
FL_IMPULSE_XYPLOT, 0, curY, 800, 100, "Channel Frequency data (RE, dB)", FL_RED );
|
||||
fdui->graph[2] = nrUEcommonGraph(ueFreqWaterFall,
|
||||
WATERFALL, 0, curY, 800, 100, "Channel Frequency (RE, one slot)", FL_RED );
|
||||
fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
|
||||
curY+=h;
|
||||
curY+=h+20;
|
||||
// LLR of PBCH
|
||||
fdui->graph[3] = nrUEcommonGraph(uePbchLLR,
|
||||
FL_POINTS_XYPLOT, 0, curY, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN );
|
||||
@@ -733,7 +910,7 @@ void phy_scope_nrUE(OAI_phy_scope_t *form,
|
||||
i++;
|
||||
}
|
||||
|
||||
fl_check_forms();
|
||||
//fl_check_forms();
|
||||
}
|
||||
|
||||
|
||||
@@ -749,9 +926,12 @@ static void *nrUEscopeThread(void *arg) {
|
||||
OAI_phy_scope_t *form_nrue=create_phy_scope_nrue(0);
|
||||
|
||||
while (!oai_exit) {
|
||||
fl_freeze_form(form_nrue->phy_scope);
|
||||
phy_scope_nrUE(form_nrue,
|
||||
ue,
|
||||
0,0);
|
||||
fl_unfreeze_form(form_nrue->phy_scope);
|
||||
fl_redraw_form(form_nrue->phy_scope);
|
||||
usleep(99*1000);
|
||||
}
|
||||
|
||||
@@ -766,11 +946,11 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
|
||||
|
||||
void nrscope_autoinit(void *dataptr) {
|
||||
AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context");
|
||||
|
||||
|
||||
if (IS_SOFTMODEM_GNB_BIT)
|
||||
gNBinitScope(dataptr);
|
||||
gNBinitScope(dataptr);
|
||||
else
|
||||
nrUEinitScope(dataptr);
|
||||
nrUEinitScope(dataptr);
|
||||
}
|
||||
// Kept to put back the functionality soon
|
||||
#if 0
|
||||
@@ -799,8 +979,6 @@ static void reset_stats_gNB(FL_OBJECT *button,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FD_stats_form *create_form_stats_form(int ID) {
|
||||
FL_OBJECT *obj;
|
||||
FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
|
||||
@@ -820,7 +998,3 @@ static FD_stats_form *create_form_stats_form(int ID) {
|
||||
return fdui;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -834,7 +834,7 @@ typedef struct {
|
||||
|
||||
UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
|
||||
/// cell-specific reference symbols
|
||||
uint32_t lte_gold_table[7][20][2][14];
|
||||
//uint32_t lte_gold_table[7][20][2][14];
|
||||
|
||||
#if defined(UPGRADE_RAT_NR)
|
||||
|
||||
@@ -848,10 +848,10 @@ typedef struct {
|
||||
uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
||||
|
||||
/// PDSCH DMRS
|
||||
uint32_t nr_gold_pdsch[2][20][14][NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD];
|
||||
uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||
|
||||
/// PDCCH DMRS
|
||||
uint32_t nr_gold_pdcch[7][20][3][52];
|
||||
uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX];
|
||||
|
||||
/// PUSCH DMRS sequence
|
||||
uint32_t ****nr_gold_pusch_dmrs;
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!)
|
||||
#define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH
|
||||
#define NR_MAX_PDSCH_TBS 3824
|
||||
#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.
|
||||
|
||||
#define MAX_NUM_NR_DLSCH_SEGMENTS 34
|
||||
#define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
|
||||
|
||||
@@ -111,13 +111,15 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
|
||||
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id);
|
||||
|
||||
/*! \brief Scheduling for UE RX procedures in normal subframes.
|
||||
@param ue Pointer to UE variables on which to act
|
||||
@param proc Pointer to proc information
|
||||
@param gNB_id Local id of eNB on which to act
|
||||
@param ue Pointer to UE variables on which to act
|
||||
@param proc Pointer to proc information
|
||||
@param gNB_id Local id of eNB on which to act
|
||||
@param dlsch_parallel use multithreaded dlsch processing
|
||||
*/
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t gNB_id);
|
||||
uint8_t gNB_id,
|
||||
uint8_t dlsch_parallel);
|
||||
|
||||
int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
|
||||
|
||||
|
||||
@@ -85,6 +85,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
|
||||
dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
|
||||
}
|
||||
else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
|
||||
dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
|
||||
dlsch0->rnti_type = _SI_RNTI_;
|
||||
dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
|
||||
}
|
||||
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
|
||||
uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr;
|
||||
@@ -116,6 +121,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
|
||||
dlsch0_harq->Nl=1;
|
||||
dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
|
||||
dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
|
||||
if (dlsch0_harq->status != ACTIVE) {
|
||||
// dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the
|
||||
// following flag to skip PDSCH procedures in that case.
|
||||
dlsch0->active = 0;
|
||||
}
|
||||
dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai;
|
||||
/* PTRS */
|
||||
dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "nr/nr_common.h"
|
||||
#include "assertions.h"
|
||||
#include "defs.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
#include "SCHED/phy_procedures_emos.h"
|
||||
#endif
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/nr-uesoftmodem.h"
|
||||
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
|
||||
|
||||
//#define DEBUG_PHY_PROC
|
||||
@@ -785,12 +787,12 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
|
||||
if (!dlsch1) {
|
||||
int harq_pid = dlsch0->current_harq_pid;
|
||||
uint16_t BWPStart = dlsch0->harq_processes[harq_pid]->BWPStart;
|
||||
// uint16_t BWPSize = dlsch0->harq_processes[harq_pid]->BWPSize;
|
||||
uint16_t pdsch_start_rb = dlsch0->harq_processes[harq_pid]->start_rb;
|
||||
uint16_t pdsch_nb_rb = dlsch0->harq_processes[harq_pid]->nb_rb;
|
||||
uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol;
|
||||
uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols;
|
||||
NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
|
||||
uint16_t BWPStart = dlsch0_harq->BWPStart;
|
||||
uint16_t pdsch_start_rb = dlsch0_harq->start_rb;
|
||||
uint16_t pdsch_nb_rb = dlsch0_harq->nb_rb;
|
||||
uint16_t s0 = dlsch0_harq->start_symbol;
|
||||
uint16_t s1 = dlsch0_harq->nb_symbols;
|
||||
|
||||
LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
|
||||
|
||||
@@ -803,6 +805,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
nr_slot_rx,
|
||||
aatx /*p*/,
|
||||
m,
|
||||
BWPStart,
|
||||
ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
|
||||
pdsch_nb_rb);
|
||||
LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m);
|
||||
@@ -821,16 +824,29 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t first_symbol_with_data = s0;
|
||||
uint32_t dmrs_data_re;
|
||||
|
||||
if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1)
|
||||
dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups;
|
||||
else
|
||||
dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups;
|
||||
|
||||
while ((dmrs_data_re == 0) && (dlsch0_harq->dlDmrsSymbPos & (1 << first_symbol_with_data))) {
|
||||
first_symbol_with_data++;
|
||||
}
|
||||
|
||||
for (m = s0; m < (s1 + s0); m++) {
|
||||
|
||||
dual_stream_UE = 0;
|
||||
eNB_id_i = eNB_id+1;
|
||||
i_mod = 0;
|
||||
|
||||
if ((m==s0) && (m<3))
|
||||
first_symbol_flag = 1;
|
||||
if (( m==first_symbol_with_data ) && (m<4))
|
||||
first_symbol_flag = 1;
|
||||
else
|
||||
first_symbol_flag = 0;
|
||||
first_symbol_flag = 0;
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
uint8_t slot = 0;
|
||||
if(m >= ue->frame_parms.symbols_per_slot>>1)
|
||||
@@ -840,7 +856,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
// process DLSCH received in first slot
|
||||
// skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed
|
||||
if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) == 0) {
|
||||
if (nr_rx_pdsch(ue,
|
||||
if (nr_rx_pdsch(ue,
|
||||
proc,
|
||||
pdsch,
|
||||
eNB_id,
|
||||
@@ -853,10 +869,10 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
i_mod,
|
||||
dlsch0->current_harq_pid) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS)
|
||||
if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1];
|
||||
else if (pdsch == PDSCH) {
|
||||
if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1];
|
||||
else if (pdsch == PDSCH || pdsch == SI_PDSCH) {
|
||||
if (nr_rx_pdsch(ue,
|
||||
proc,
|
||||
pdsch,
|
||||
@@ -871,7 +887,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
|
||||
dlsch0->current_harq_pid) < 0)
|
||||
return -1;
|
||||
}
|
||||
else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n");
|
||||
else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n");
|
||||
}
|
||||
if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]);
|
||||
#if UE_TIMING_TRACE
|
||||
@@ -898,7 +914,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
PDSCH_t pdsch,
|
||||
NR_UE_DLSCH_t *dlsch0,
|
||||
NR_UE_DLSCH_t *dlsch1,
|
||||
int *dlsch_errors) {
|
||||
int *dlsch_errors,
|
||||
uint8_t dlsch_parallel) {
|
||||
|
||||
if (dlsch0==NULL)
|
||||
AssertFatal(0,"dlsch0 should be defined at this level \n");
|
||||
@@ -1030,8 +1047,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
|
||||
#endif
|
||||
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
ret = nr_dlsch_decoding_mthread(ue,
|
||||
if( dlsch_parallel)
|
||||
{
|
||||
ret = nr_dlsch_decoding_mthread(ue,
|
||||
proc,
|
||||
eNB_id,
|
||||
pdsch_vars->llr[0],
|
||||
@@ -1044,9 +1062,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
harq_pid,
|
||||
pdsch==PDSCH?1:0,
|
||||
dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
|
||||
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret = %d\n", ret);
|
||||
#else
|
||||
ret = nr_dlsch_decoding(ue,
|
||||
LOG_T(PHY,"dlsch decoding is parallelized, ret = %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = nr_dlsch_decoding(ue,
|
||||
proc,
|
||||
eNB_id,
|
||||
pdsch_vars->llr[0],
|
||||
@@ -1059,9 +1079,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
harq_pid,
|
||||
pdsch==PDSCH?1:0,
|
||||
dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
|
||||
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret = %d\n", ret);
|
||||
//printf("start cW0 dlsch decoding\n");
|
||||
#endif
|
||||
LOG_T(PHY,"Sequential dlsch decoding , ret = %d\n", ret);
|
||||
}
|
||||
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
|
||||
@@ -1113,38 +1133,40 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
start_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
|
||||
#endif
|
||||
|
||||
#ifdef UE_DLSCH_PARALLELISATION
|
||||
ret1 = nr_dlsch_decoding_mthread(ue,
|
||||
proc,
|
||||
eNB_id,
|
||||
pdsch_vars->llr[1],
|
||||
&ue->frame_parms,
|
||||
dlsch1,
|
||||
dlsch1->harq_processes[harq_pid],
|
||||
frame_rx,
|
||||
nb_symb_sch,
|
||||
nr_slot_rx,
|
||||
harq_pid,
|
||||
pdsch==PDSCH?1:0,
|
||||
dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
|
||||
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1);
|
||||
#else
|
||||
ret1 = nr_dlsch_decoding(ue,
|
||||
proc,
|
||||
eNB_id,
|
||||
pdsch_vars->llr[1],
|
||||
&ue->frame_parms,
|
||||
dlsch1,
|
||||
dlsch1->harq_processes[harq_pid],
|
||||
frame_rx,
|
||||
nb_symb_sch,
|
||||
nr_slot_rx,
|
||||
harq_pid,
|
||||
pdsch==PDSCH?1:0,//proc->decoder_switch,
|
||||
dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
|
||||
LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret1 = %d\n", ret1);
|
||||
printf("start cw1 dlsch decoding\n");
|
||||
#endif
|
||||
if(dlsch_parallel)
|
||||
{
|
||||
ret1 = nr_dlsch_decoding_mthread(ue,
|
||||
proc,
|
||||
eNB_id,
|
||||
pdsch_vars->llr[1],
|
||||
&ue->frame_parms,
|
||||
dlsch1,
|
||||
dlsch1->harq_processes[harq_pid],
|
||||
frame_rx,
|
||||
nb_symb_sch,
|
||||
nr_slot_rx,
|
||||
harq_pid,
|
||||
pdsch==PDSCH?1:0,
|
||||
dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
|
||||
LOG_T(PHY,"CW dlsch decoding is parallelized, ret1 = %d\n", ret1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret1 = nr_dlsch_decoding(ue,
|
||||
proc,
|
||||
eNB_id,
|
||||
pdsch_vars->llr[1],
|
||||
&ue->frame_parms,
|
||||
dlsch1,
|
||||
dlsch1->harq_processes[harq_pid],
|
||||
frame_rx,
|
||||
nb_symb_sch,
|
||||
nr_slot_rx,
|
||||
harq_pid,
|
||||
pdsch==PDSCH?1:0,//proc->decoder_switch,
|
||||
dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
|
||||
LOG_T(PHY,"CWW sequential dlsch decoding, ret1 = %d\n", ret1);
|
||||
}
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]);
|
||||
@@ -1189,6 +1211,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
|
||||
nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
|
||||
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus);
|
||||
break;
|
||||
case SI_PDSCH:
|
||||
rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1674,8 +1699,10 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL
|
||||
|
||||
int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t gNB_id)
|
||||
{
|
||||
uint8_t gNB_id,
|
||||
uint8_t dlsch_parallel
|
||||
)
|
||||
{
|
||||
int frame_rx = proc->frame_rx;
|
||||
int nr_slot_rx = proc->nr_slot_rx;
|
||||
int slot_pbch;
|
||||
@@ -1772,29 +1799,30 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
0,
|
||||
0);
|
||||
|
||||
dci_cnt = 0;
|
||||
for(int n_ss = 0; n_ss<pdcch_vars->nb_search_space; n_ss++) {
|
||||
|
||||
// note: this only works if RBs for PDCCH are contigous!
|
||||
LOG_D(PHY,"pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n",
|
||||
fp->first_carrier_offset,pdcch_vars->pdcch_config[0].BWPStart,coreset_start_rb);
|
||||
LOG_D(PHY, "pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n",
|
||||
fp->first_carrier_offset, pdcch_vars->pdcch_config[n_ss].BWPStart, coreset_start_rb);
|
||||
|
||||
if (coreset_nb_rb > 0)
|
||||
nr_pdcch_channel_estimation(ue,
|
||||
proc,
|
||||
0,
|
||||
nr_slot_rx,
|
||||
l,
|
||||
fp->first_carrier_offset+(pdcch_vars->pdcch_config[0].BWPStart + coreset_start_rb)*12,
|
||||
fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12,
|
||||
coreset_nb_rb);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->ofdm_demod_stats);
|
||||
#endif
|
||||
|
||||
//printf("phy procedure pdcch start measurement l =%d\n",l);
|
||||
//nr_ue_measurement_procedures(l,ue,proc,gNB_id,(nr_slot_rx),mode);
|
||||
|
||||
}
|
||||
|
||||
dci_cnt = nr_ue_pdcch_procedures(gNB_id, ue, proc);
|
||||
dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc);
|
||||
}
|
||||
}
|
||||
|
||||
if (dci_cnt > 0) {
|
||||
|
||||
@@ -1803,6 +1831,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
NR_UE_DLSCH_t *dlsch = NULL;
|
||||
if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1){
|
||||
dlsch = ue->dlsch[proc->thread_id][gNB_id][0];
|
||||
} else if (ue->dlsch_SI[0]->active == 1){
|
||||
dlsch = ue->dlsch_SI[0];
|
||||
} else if (ue->dlsch_ra[0]->active == 1){
|
||||
dlsch = ue->dlsch_ra[0];
|
||||
}
|
||||
@@ -1870,7 +1900,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
SI_PDSCH,
|
||||
ue->dlsch_SI[gNB_id],
|
||||
NULL,
|
||||
&ue->dlsch_SI_errors[gNB_id]);
|
||||
&ue->dlsch_SI_errors[gNB_id],
|
||||
dlsch_parallel);
|
||||
|
||||
// deactivate dlsch once dlsch proc is done
|
||||
ue->dlsch_SI[gNB_id]->active = 0;
|
||||
@@ -1894,7 +1925,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
P_PDSCH,
|
||||
ue->dlsch_p[gNB_id],
|
||||
NULL,
|
||||
&ue->dlsch_p_errors[gNB_id]);
|
||||
&ue->dlsch_p_errors[gNB_id],
|
||||
dlsch_parallel);
|
||||
|
||||
// deactivate dlsch once dlsch proc is done
|
||||
ue->dlsch_p[gNB_id]->active = 0;
|
||||
@@ -1918,7 +1950,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
RA_PDSCH,
|
||||
ue->dlsch_ra[gNB_id],
|
||||
NULL,
|
||||
&ue->dlsch_ra_errors[gNB_id]);
|
||||
&ue->dlsch_ra_errors[gNB_id],
|
||||
dlsch_parallel);
|
||||
|
||||
// deactivate dlsch once dlsch proc is done
|
||||
ue->dlsch_ra[gNB_id]->active = 0;
|
||||
@@ -1943,7 +1976,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
|
||||
PDSCH,
|
||||
ue->dlsch[proc->thread_id][gNB_id][0],
|
||||
ue->dlsch[proc->thread_id][gNB_id][1],
|
||||
&ue->dlsch_errors[gNB_id]);
|
||||
&ue->dlsch_errors[gNB_id],
|
||||
dlsch_parallel);
|
||||
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
|
||||
@@ -446,7 +446,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
int max_code_rate = 0;
|
||||
//int max_code_rate = 0;
|
||||
//int Q_m = BITS_PER_SYMBOL_QPSK; /* default pucch modulation type is QPSK with 2 bits per symbol */
|
||||
int N_sc_ctrl_RB = 0;
|
||||
int O_CRC = 0;
|
||||
@@ -503,7 +503,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_
|
||||
if (format != pucch_format0_nr) {
|
||||
|
||||
if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1 != NULL) {
|
||||
max_code_rate = code_rate_r_time_100[mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->maxCodeRate[0]]; /* it is code rate * 10 */
|
||||
//max_code_rate = code_rate_r_time_100[mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->maxCodeRate[0]]; /* it is code rate * 10 */
|
||||
|
||||
if ((O_ACK != 0) && (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->simultaneousHARQ_ACK_CSI[0] == 0)) {
|
||||
N_UCI = N_UCI - O_CSI;
|
||||
|
||||
@@ -146,6 +146,10 @@ int is_x2ap_enabled(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// needed for some functions
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg);
|
||||
@@ -270,7 +274,7 @@ int main(int argc, char **argv)
|
||||
uint16_t ptrsSymbPerSlot = 0;
|
||||
uint16_t rbSize = 106;
|
||||
uint8_t mcsIndex = 9;
|
||||
|
||||
uint8_t dlsch_threads = 0;
|
||||
if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) {
|
||||
exit_fun("[NR_DLSIM] Error, configuration module init failed\n");
|
||||
}
|
||||
@@ -281,7 +285,7 @@ int main(int argc, char **argv)
|
||||
|
||||
FILE *scg_fd=NULL;
|
||||
|
||||
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:e:m:w:T:U:q")) != -1) {
|
||||
while ((c = getopt (argc, argv, "f:hA:pf:g:i:j:n:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:q")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
scg_fd = fopen(optarg,"r");
|
||||
@@ -448,7 +452,9 @@ int main(int argc, char **argv)
|
||||
case 'b':
|
||||
g_rbSize = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
dlsch_threads = atoi(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
g_mcsIndex = atoi(optarg);
|
||||
break;
|
||||
@@ -519,11 +525,12 @@ int main(int argc, char **argv)
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n");
|
||||
printf("-P Print DLSCH performances\n");
|
||||
printf("-w Write txdata to binary file (one frame)\n");
|
||||
printf("-d number of dlsch threads, 0: no dlsch parallelization\n");
|
||||
exit (-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logInit();
|
||||
set_glog(loglvl);
|
||||
T_stdout = 1;
|
||||
@@ -534,6 +541,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (snr1set==0)
|
||||
snr1 = snr0+10;
|
||||
init_dlsch_tpool(dlsch_threads);
|
||||
|
||||
|
||||
RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *));
|
||||
@@ -752,16 +760,16 @@ int main(int argc, char **argv)
|
||||
|
||||
nr_l2_init_ue(NULL);
|
||||
UE_mac = get_mac_inst(0);
|
||||
|
||||
|
||||
UE->if_inst = nr_ue_if_module_init(0);
|
||||
UE->if_inst->scheduled_response = nr_ue_scheduled_response;
|
||||
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
|
||||
UE->if_inst->dl_indication = nr_ue_dl_indication;
|
||||
UE->if_inst->ul_indication = dummy_nr_ue_ul_indication;
|
||||
|
||||
|
||||
|
||||
UE_mac->if_module = nr_ue_if_module_init(0);
|
||||
|
||||
|
||||
unsigned int available_bits=0;
|
||||
unsigned char *estimated_output_bit;
|
||||
unsigned char *test_input_bit;
|
||||
@@ -819,7 +827,7 @@ int main(int argc, char **argv)
|
||||
reset_meas(&gNB->tinput);
|
||||
reset_meas(&gNB->tprep);
|
||||
reset_meas(&gNB->tparity);
|
||||
reset_meas(&gNB->toutput);
|
||||
reset_meas(&gNB->toutput);
|
||||
|
||||
clear_pdsch_stats(gNB);
|
||||
|
||||
@@ -918,7 +926,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);
|
||||
if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset);
|
||||
|
||||
|
||||
//TODO: loop over slots
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
|
||||
@@ -980,18 +988,19 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
|
||||
nr_ue_scheduled_response(&scheduled_response);
|
||||
|
||||
phy_procedures_nrUE_RX(UE,
|
||||
&UE_proc,
|
||||
0);
|
||||
0,
|
||||
dlsch_threads);
|
||||
|
||||
//printf("dlsim round %d ends\n",round);
|
||||
round++;
|
||||
} // round
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
//---------------------- count errors ----------------------
|
||||
//----------------------------------------------------------
|
||||
@@ -1030,7 +1039,7 @@ int main(int argc, char **argv)
|
||||
|
||||
}
|
||||
for (i = 0; i < TBS; i++) {
|
||||
|
||||
|
||||
estimated_output_bit[i] = (UE_harq_process->b[i/8] & (1 << (i & 7))) >> (i & 7);
|
||||
test_input_bit[i] = (gNB_dlsch->harq_processes[harq_pid]->b[i / 8] & (1 << (i & 7))) >> (i & 7); // Further correct for multiple segments
|
||||
|
||||
|
||||
@@ -107,6 +107,10 @@ int is_x2ap_enabled(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
|
||||
char c;
|
||||
|
||||
@@ -126,6 +126,10 @@ int is_x2ap_enabled(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// needed for some functions
|
||||
uint16_t n_rnti = 0x1234;
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
@@ -399,8 +399,8 @@ typedef struct NbIoTRrcConfigurationReq_s {
|
||||
|
||||
// gNB: GNB_APP -> RRC messages
|
||||
typedef struct NRRrcConfigurationReq_s {
|
||||
uint32_t cell_identity;
|
||||
uint16_t tac;
|
||||
uint64_t cell_identity;
|
||||
uint32_t tac;
|
||||
uint16_t mcc[PLMN_LIST_MAX_SIZE];
|
||||
uint16_t mnc[PLMN_LIST_MAX_SIZE];
|
||||
uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
/* cell configuration section name */
|
||||
#define GNB_CONFIG_STRING_GNB_LIST "gNBs"
|
||||
|
||||
#define GNB_CONFIG_STRING_PDCCH_CONFIGSIB1 "pdcch_ConfigSIB1"
|
||||
#define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon"
|
||||
#define GNB_CONFIG_STRING_PHYSCELLID "physCellId"
|
||||
#define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset"
|
||||
@@ -210,6 +211,21 @@
|
||||
|
||||
#define CARRIERBANDWIDTH_OKVALUES {11,18,24,25,31,32,38,51,52,65,66,78,79,93,106,107,121,132,133,135,160,162,189,216,217,245,264,270,273}
|
||||
|
||||
/*--------------------------------------------------------------------------------------------------------------------*/
|
||||
/* pdcch_ConfigSIB1 parameters */
|
||||
/*--------------------------------------------------------------------------------------------------------------------*/
|
||||
#define CONTROL_RESOURCE_SET_ZERO "controlResourceSetZero"
|
||||
#define SEARCH_SPACE_ZERO "searchSpaceZero"
|
||||
|
||||
#define PDCCH_CONFIGSIB1PARAMS_DESC(pdcch_ConfigSIB1) { \
|
||||
{CONTROL_RESOURCE_SET_ZERO, NULL, 0, i64ptr:&pdcch_ConfigSIB1->controlResourceSetZero, defintval:0, TYPE_INT64, 0}, \
|
||||
{SEARCH_SPACE_ZERO, NULL, 0, i64ptr:&pdcch_ConfigSIB1->searchSpaceZero, defintval:0, TYPE_INT64, 0} \
|
||||
}
|
||||
|
||||
#define CONTROL_RESOURCE_SET_ZERO_IDX 0
|
||||
#define SEARCH_SPACE_ZERO_IDX 1
|
||||
/*--------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* Serving Cell Config Common configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
|
||||
@@ -574,6 +574,17 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
|
||||
gnb_id = *(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr);
|
||||
}
|
||||
|
||||
// pdcch_ConfigSIB1
|
||||
rrc->carrier.pdcch_ConfigSIB1 = calloc(1,sizeof(NR_PDCCH_ConfigSIB1_t));
|
||||
paramdef_t pdcch_ConfigSIB1[] = PDCCH_CONFIGSIB1PARAMS_DESC(rrc->carrier.pdcch_ConfigSIB1);
|
||||
paramlist_def_t pdcch_ConfigSIB1ParamList = {GNB_CONFIG_STRING_PDCCH_CONFIGSIB1, NULL, 0};
|
||||
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
|
||||
config_getlist(&pdcch_ConfigSIB1ParamList, NULL, 0, aprefix);
|
||||
if (pdcch_ConfigSIB1ParamList.numelt > 0) {
|
||||
sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_PDCCH_CONFIGSIB1, 0);
|
||||
config_get(pdcch_ConfigSIB1,sizeof(pdcch_ConfigSIB1)/sizeof(paramdef_t),aprefix);
|
||||
}
|
||||
|
||||
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
|
||||
|
||||
config_getlist(&SCCsParamList, NULL, 0, aprefix);
|
||||
@@ -1009,7 +1020,7 @@ void NRRCConfig(void) {
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
|
||||
/* get global parameters, defined outside any section in the config file */
|
||||
|
||||
|
||||
LOG_I(GNB_APP, "Getting GNBSParams\n");
|
||||
|
||||
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
@@ -78,7 +78,6 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none"
|
||||
#define GNB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING "annoying"
|
||||
#define GNB_CONFIG_STRING_ASN1_VERBOSITY_INFO "info"
|
||||
|
||||
|
||||
/* global parameters, not under a specific section */
|
||||
#define GNB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
|
||||
|
||||
@@ -37,6 +37,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TABLE_38213_13_1_NUM_INDEXES 15
|
||||
#define TABLE_38213_13_2_NUM_INDEXES 14
|
||||
#define TABLE_38213_13_3_NUM_INDEXES 9
|
||||
#define TABLE_38213_13_4_NUM_INDEXES 16
|
||||
#define TABLE_38213_13_5_NUM_INDEXES 9
|
||||
#define TABLE_38213_13_6_NUM_INDEXES 10
|
||||
#define TABLE_38213_13_7_NUM_INDEXES 12
|
||||
#define TABLE_38213_13_8_NUM_INDEXES 8
|
||||
#define TABLE_38213_13_9_NUM_INDEXES 4
|
||||
#define TABLE_38213_13_10_NUM_INDEXES 8
|
||||
#define TABLE_38213_13_11_NUM_INDEXES 16
|
||||
#define TABLE_38213_13_12_NUM_INDEXES 14
|
||||
|
||||
// Definitions for MAC control and data
|
||||
#define NR_BCCH_DL_SCH 3 // SI
|
||||
#define NR_BCCH_BCH 5 // MIB
|
||||
@@ -45,8 +58,8 @@
|
||||
#define MAX_BWP_SIZE 275
|
||||
|
||||
typedef enum frequency_range_e {
|
||||
FR1 = 0,
|
||||
FR2
|
||||
FR1 = 0,
|
||||
FR2
|
||||
} frequency_range_t;
|
||||
|
||||
// For both DL/UL-SCH
|
||||
@@ -405,6 +418,51 @@ typedef enum {
|
||||
NR_RNTI_MCS_C,
|
||||
} nr_rnti_type_t;
|
||||
|
||||
typedef enum subcarrier_spacing_e {
|
||||
scs_15kHz = 0x1,
|
||||
scs_30kHz = 0x2,
|
||||
scs_60kHz = 0x4,
|
||||
scs_120kHz = 0x8,
|
||||
scs_240kHz = 0x16
|
||||
} subcarrier_spacing_t;
|
||||
|
||||
typedef enum channel_bandwidth_e {
|
||||
bw_5MHz = 0x1,
|
||||
bw_10MHz = 0x2,
|
||||
bw_20MHz = 0x4,
|
||||
bw_40MHz = 0x8,
|
||||
bw_80MHz = 0x16,
|
||||
bw_100MHz = 0x32
|
||||
} channel_bandwidth_t;
|
||||
|
||||
typedef enum nr_ssb_and_cset_mux_pattern_type_e {
|
||||
NR_SSB_AND_CSET_MUX_PATTERN_TYPE1=1,
|
||||
NR_SSB_AND_CSET_MUX_PATTERN_TYPE2,
|
||||
NR_SSB_AND_CSET_MUX_PATTERN_TYPE3
|
||||
} nr_ssb_and_cset_mux_pattern_type_t;
|
||||
|
||||
typedef enum {
|
||||
SFN_C_MOD_2_EQ_0,
|
||||
SFN_C_MOD_2_EQ_1,
|
||||
SFN_C_IMPOSSIBLE
|
||||
} SFN_C_TYPE;
|
||||
|
||||
typedef struct Type0_PDCCH_CSS_config_s {
|
||||
int32_t num_rbs;
|
||||
int32_t num_symbols;
|
||||
int32_t rb_offset; // Offset from SSB RB0
|
||||
uint32_t type0_pdcch_ss_mux_pattern;
|
||||
uint16_t frame;
|
||||
SFN_C_TYPE sfn_c;
|
||||
uint32_t n_c;
|
||||
uint32_t n_0;
|
||||
uint32_t number_of_search_space_per_slot;
|
||||
uint32_t first_symbol_index;
|
||||
uint32_t search_space_duration;
|
||||
uint32_t ssb_length;
|
||||
uint32_t ssb_index;
|
||||
uint32_t cset_start_rb;
|
||||
} NR_Type0_PDCCH_CSS_config_t;
|
||||
|
||||
#endif /*__LAYER2_MAC_H__ */
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include <limits.h>
|
||||
|
||||
#define reserved 0xffff
|
||||
|
||||
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
|
||||
|
||||
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
|
||||
@@ -48,6 +50,73 @@ uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,8
|
||||
// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3}
|
||||
uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69};
|
||||
|
||||
|
||||
// specification mapping talbe, table_38$x_$y_$z_c$a
|
||||
// - $x: specification
|
||||
// - $y: subclause-major
|
||||
// - $z: subclause-minor
|
||||
// - $a: ($a)th of column in table, start from zero
|
||||
const int32_t table_38213_13_1_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_1_c2[16] = {24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 96, 96, 96, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_1_c3[16] = { 2, 2, 2, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_1_c4[16] = { 0, 2, 4, 0, 2, 4, 12, 16, 12, 16, 12, 16, 38, 38, 38, reserved}; // index 15 reserved
|
||||
|
||||
const int32_t table_38213_13_2_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved}; // index 14-15 reserved
|
||||
const int32_t table_38213_13_2_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved}; // index 14-15 reserved
|
||||
const int32_t table_38213_13_2_c3[16] = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved}; // index 14-15 reserved
|
||||
const int32_t table_38213_13_2_c4[16] = { 5, 6, 7, 8, 5, 6, 7, 8, 18, 20, 18, 20, 18, 20, reserved, reserved}; // index 14-15 reserved
|
||||
|
||||
const int32_t table_38213_13_3_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_3_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_3_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_3_c4[16] = { 2, 6, 2, 6, 2, 6, 28, 28, 28, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
|
||||
const int32_t table_38213_13_4_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
const int32_t table_38213_13_4_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48};
|
||||
const int32_t table_38213_13_4_c3[16] = { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2};
|
||||
const int32_t table_38213_13_4_c4[16] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 12, 14, 16, 12, 14, 16};
|
||||
|
||||
const int32_t table_38213_13_5_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_5_c2[16] = {48, 48, 48, 96, 96, 96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_5_c3[16] = { 1, 2, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_5_c4[16] = { 4, 4, 4, 0, 56, 0, 56, 0, 56, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
|
||||
const int32_t table_38213_13_6_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
const int32_t table_38213_13_6_c2[16] = {24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
const int32_t table_38213_13_6_c3[16] = { 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
const int32_t table_38213_13_6_c4[16] = { 0, 4, 0, 4, 0, 28, 0, 28, 0, 28, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
|
||||
const int32_t table_38213_13_7_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, reserved, reserved, reserved, reserved}; // index 12-15 reserved
|
||||
const int32_t table_38213_13_7_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 48, 48, 96, 96, reserved, reserved, reserved, reserved}; // index 12-15 reserved
|
||||
const int32_t table_38213_13_7_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved}; // index 12-15 reserved
|
||||
const int32_t table_38213_13_7_c4[16] = { 0, 8, 0, 8, 0, 8, 28, 28,-41, 49,-41, 97, reserved, reserved, reserved, reserved}; // index 12-15 reserved, condition A as default
|
||||
|
||||
const int32_t table_38213_13_8_c1[16] = { 1, 1, 1, 1, 3, 3, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_8_c2[16] = {24, 24, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_8_c3[16] = { 2, 2, 1, 2, 2, 2, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_8_c4[16] = { 0, 4, 14, 14,-20, 24,-20, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved, condition A as default
|
||||
|
||||
const int32_t table_38213_13_9_c1[16] = {1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
const int32_t table_38213_13_9_c2[16] = {96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
const int32_t table_38213_13_9_c3[16] = { 1, 1, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
const int32_t table_38213_13_9_c4[16] = { 0, 16, 0, 16, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
|
||||
const int32_t table_38213_13_10_c1[16] = {1, 1, 1, 1, 2, 2, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved
|
||||
const int32_t table_38213_13_10_c2[16] = {48, 48, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved
|
||||
const int32_t table_38213_13_10_c3[16] = { 1, 1, 2, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved
|
||||
const int32_t table_38213_13_10_c4[16] = { 0, 8, 0, 8,-41, 25,-41, 49, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved, condition A as default
|
||||
|
||||
const float table_38213_13_11_c1[16] = { 0, 0, 2, 2, 5, 5, 7, 7, 0, 5, 0, 0, 2, 2, 5, 5}; // O
|
||||
const int32_t table_38213_13_11_c2[16] = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 1, 1, 1, 1, 1, 1, 1}; // M
|
||||
const int32_t table_38213_13_11_c4[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2}; // i is even as default
|
||||
|
||||
const float table_38213_13_12_c1[16] = { 0, 0, 2.5f, 2.5f, 5, 5, 0, 2.5f, 5, 7.5f, 7.5f, 7.5f, 0, 5, reserved, reserved}; // O, index 14-15 reserved
|
||||
const int32_t table_38213_13_12_c2[16] = { 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, reserved, reserved}; // index 14-15 reserved
|
||||
const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 1, reserved, reserved}; // M, index 14-15 reserved
|
||||
|
||||
const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 };
|
||||
|
||||
const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"};
|
||||
const char *duplex_mode[]={"FDD","TDD"};
|
||||
|
||||
@@ -974,6 +1043,33 @@ int64_t *get_prach_config_info(uint32_t pointa,
|
||||
return prach_config_info_p;
|
||||
}
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss) {
|
||||
|
||||
if (ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0) {
|
||||
*aggregation_level = 1;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel1;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel2 != NR_SearchSpace__nrofCandidates__aggregationLevel2_n0) {
|
||||
*aggregation_level = 2;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel2;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel4 != NR_SearchSpace__nrofCandidates__aggregationLevel4_n0) {
|
||||
*aggregation_level = 4;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel4;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel8 != NR_SearchSpace__nrofCandidates__aggregationLevel8_n0) {
|
||||
*aggregation_level = 8;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel8;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel16 != NR_SearchSpace__nrofCandidates__aggregationLevel16_n0) {
|
||||
*aggregation_level = 16;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
|
||||
uint16_t *slot_period,
|
||||
uint16_t *offset) {
|
||||
@@ -2337,11 +2433,19 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
|
||||
long rbg_size_config;
|
||||
int num_entries = 0;
|
||||
int pusch_antenna_ports = 1; // TODO hardcoded number of antenna ports for pusch
|
||||
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
NR_PDSCH_Config_t *pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup;
|
||||
NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
NR_SRS_Config_t *srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup;
|
||||
|
||||
NR_BWP_Downlink_t *bwp = NULL;
|
||||
NR_BWP_Uplink_t *ubwp = NULL;
|
||||
NR_PDSCH_Config_t *pdsch_config = NULL;
|
||||
NR_PUSCH_Config_t *pusch_Config = NULL;
|
||||
NR_SRS_Config_t *srs_config = NULL;
|
||||
if(bwp_id > 0) {
|
||||
bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup;
|
||||
pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup;
|
||||
}
|
||||
|
||||
switch(format) {
|
||||
/*Only sizes for 0_0 and 1_0 are correct at the moment*/
|
||||
@@ -2538,8 +2642,13 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
|
||||
|
||||
case NR_DL_DCI_FORMAT_1_0:
|
||||
/// fixed: Format identifier 1, VRB2PRB 1, MCS 5, NDI 1, RV 2, HARQ PID 4, DAI 2, PUCCH TPC 2, PUCCH RInd 3, PDSCH to HARQ TInd 3 Time Domain assgnmt 4 -- 28
|
||||
size += 28;
|
||||
size = 28;
|
||||
size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment
|
||||
|
||||
dci_pdu->frequency_domain_assignment.nbits = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
dci_pdu->time_domain_assignment.nbits = 4;
|
||||
dci_pdu->vrb_to_prb_mapping.nbits = 1;
|
||||
|
||||
break;
|
||||
|
||||
case NR_DL_DCI_FORMAT_1_1:
|
||||
@@ -2789,8 +2898,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
|
||||
case 5 :
|
||||
case 6 :
|
||||
case 7 :
|
||||
AssertFatal(1==0,"Incoompatible NrOfSymbols %d and dmrs_Additional_Position %d\n",
|
||||
NrOfSymbols,(int)*dmrs_config->dmrs_AdditionalPosition);
|
||||
return(1<<l0);
|
||||
break;
|
||||
case 8 :
|
||||
case 9:
|
||||
@@ -2798,26 +2906,26 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
|
||||
if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
|
||||
return(1<<l0 | 1<<9);
|
||||
else
|
||||
return(1<<l0 | 1<<6 | 1<<9);
|
||||
break;
|
||||
case 12:
|
||||
if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
|
||||
if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
|
||||
return(1<<l0 | 1<<9);
|
||||
else if (pos2==1)
|
||||
return(1<<l0 | 1<<6 | 1<<9);
|
||||
else if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3)
|
||||
else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3)
|
||||
return(1<<l0 | 1<<5 | 1<<8 | 1<<11);
|
||||
break;
|
||||
case 13:
|
||||
case 14:
|
||||
if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
|
||||
if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1)
|
||||
return(1<<l0 | 1<<11);
|
||||
else if (pos2==1)
|
||||
return(1<<l0 | 1<<7 | 1<<11);
|
||||
else if (*dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3)
|
||||
else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3)
|
||||
return(1<<l0 | 1<<5 | 1<<8 | 1<<11);
|
||||
break;
|
||||
}
|
||||
@@ -2963,3 +3071,373 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
||||
//printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs);
|
||||
return valid;
|
||||
}
|
||||
uint32_t get_ssb_slot(uint32_t ssb_index){
|
||||
// this function now only support f <= 3GHz
|
||||
return ssb_index & 0x3 ;
|
||||
|
||||
// return first_symbol(case, freq, ssb_index) / 14
|
||||
}
|
||||
|
||||
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
NR_MIB_t *mib,
|
||||
uint8_t extra_bits,
|
||||
uint32_t ssb_length,
|
||||
uint32_t ssb_index,
|
||||
uint32_t ssb_offset_point_a) {
|
||||
|
||||
// deafult for testing
|
||||
subcarrier_spacing_t scs_ssb = scs_30kHz;
|
||||
channel_bandwidth_t min_channel_bw = bw_10MHz;
|
||||
frequency_range_t frequency_range = FR1;
|
||||
const uint32_t num_slot_per_frame = 20;
|
||||
|
||||
type0_PDCCH_CSS_config->ssb_length = ssb_length;
|
||||
type0_PDCCH_CSS_config->ssb_index = ssb_index;
|
||||
type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused);
|
||||
|
||||
uint16_t frame_number_4lsb = 0;
|
||||
for (int i=0; i<4; i++) {
|
||||
frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
|
||||
}
|
||||
|
||||
uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
|
||||
uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset;
|
||||
|
||||
type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4;
|
||||
type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb;
|
||||
|
||||
if(type0_PDCCH_CSS_config->ssb_length == 64){
|
||||
type0_PDCCH_CSS_config->ssb_index = type0_PDCCH_CSS_config->ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] }
|
||||
}else{
|
||||
if(ssb_subcarrier_offset_msb){
|
||||
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
// assume carrier frequency < 6GHz
|
||||
subcarrier_spacing_t scs_pdcch;
|
||||
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
|
||||
scs_pdcch = scs_15kHz;
|
||||
}else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
|
||||
scs_pdcch = scs_30kHz;
|
||||
}
|
||||
|
||||
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
|
||||
uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero);
|
||||
uint32_t index_4lsb = (mib->pdcch_ConfigSIB1.searchSpaceZero);
|
||||
|
||||
type0_PDCCH_CSS_config->num_rbs = -1;
|
||||
type0_PDCCH_CSS_config->num_symbols = -1;
|
||||
type0_PDCCH_CSS_config->rb_offset = -1;
|
||||
|
||||
// type0-pdcch coreset
|
||||
switch( (scs_ssb << 5) | scs_pdcch ){
|
||||
case (scs_15kHz << 5) | scs_15kHz :
|
||||
AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_1_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_15kHz << 5) | scs_30kHz:
|
||||
AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_2_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_30kHz << 5) | scs_15kHz:
|
||||
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
|
||||
AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_3_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_3_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_3_c4[index_4msb];
|
||||
}else if(min_channel_bw & bw_40MHz){
|
||||
AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_5_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_5_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_5_c4[index_4msb];
|
||||
}else{ ; }
|
||||
|
||||
break;
|
||||
|
||||
case (scs_30kHz << 5) | scs_30kHz:
|
||||
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_4_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_4_c4[index_4msb];
|
||||
|
||||
}else if(min_channel_bw & bw_40MHz){
|
||||
AssertFatal(index_4msb < 10, "38.213 Table 13-6 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_6_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_6_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_6_c4[index_4msb];
|
||||
}else{ ; }
|
||||
break;
|
||||
|
||||
case (scs_120kHz << 5) | scs_60kHz:
|
||||
AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
|
||||
if(index_4msb & 0x7){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
}else if(index_4msb & 0x18){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 2;
|
||||
}else{ ; }
|
||||
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_7_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_7_c3[index_4msb];
|
||||
if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb] - 1;
|
||||
}else{
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb];
|
||||
}
|
||||
break;
|
||||
|
||||
case (scs_120kHz << 5) | scs_120kHz:
|
||||
AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
|
||||
if(index_4msb & 0x3){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
}else if(index_4msb & 0x0c){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 3;
|
||||
}
|
||||
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_8_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_8_c3[index_4msb];
|
||||
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb] - 1;
|
||||
}else{
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb];
|
||||
}
|
||||
break;
|
||||
|
||||
case (scs_240kHz << 5) | scs_60kHz:
|
||||
AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_9_c3[index_4msb];
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_240kHz << 5) | scs_120kHz:
|
||||
AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
|
||||
if(index_4msb & 0x3){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
}else if(index_4msb & 0x0c){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 2;
|
||||
}
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_10_c2[index_4msb];
|
||||
type0_PDCCH_CSS_config->num_symbols = table_38213_13_10_c3[index_4msb];
|
||||
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb]-1;
|
||||
}else{
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_D(MAC,"Coreset0: index_4msb=%d, num_rbs=%d, num_symb=%d, rb_offset=%d\n",
|
||||
index_4msb,type0_PDCCH_CSS_config->num_rbs,type0_PDCCH_CSS_config->num_symbols,type0_PDCCH_CSS_config->rb_offset );
|
||||
|
||||
AssertFatal(type0_PDCCH_CSS_config->num_rbs != -1, "Type0 PDCCH coreset num_rbs undefined");
|
||||
AssertFatal(type0_PDCCH_CSS_config->num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined");
|
||||
AssertFatal(type0_PDCCH_CSS_config->rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined");
|
||||
|
||||
|
||||
//uint32_t cell_id = 0; // obtain from L1 later
|
||||
|
||||
//mac->type0_pdcch_dci_config.coreset.rb_start = rb_offset;
|
||||
//mac->type0_pdcch_dci_config.coreset.rb_end = rb_offset + num_rbs - 1;
|
||||
|
||||
// uint64_t mask = 0x0;
|
||||
// uint8_t i;
|
||||
// for(i=0; i<(type0_PDCCH_CSS_config->num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs
|
||||
// mask = mask >> 1;
|
||||
// mask = mask | 0x100000000000;
|
||||
// }
|
||||
|
||||
//LOG_I(MAC,">>>>>>>>mask %x num_rbs %d rb_offset %d\n", mask, num_rbs, rb_offset);
|
||||
|
||||
// mac->type0_pdcch_dci_config.coreset.frequency_domain_resource = mask;
|
||||
// mac->type0_pdcch_dci_config.coreset.rb_offset = rb_offset; // additional parameter other than coreset
|
||||
//
|
||||
// //mac->type0_pdcch_dci_config.type0_pdcch_coreset.duration = num_symbols;
|
||||
// mac->type0_pdcch_dci_config.coreset.cce_reg_mapping_type = CCE_REG_MAPPING_TYPE_INTERLEAVED;
|
||||
// mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2
|
||||
// mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2
|
||||
// mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_shift_index = cell_id;
|
||||
// mac->type0_pdcch_dci_config.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE;
|
||||
// mac->type0_pdcch_dci_config.coreset.pdcch_dmrs_scrambling_id = cell_id;
|
||||
|
||||
|
||||
// type0-pdcch search space
|
||||
float big_o = 0.0f;
|
||||
float big_m = 0.0f;
|
||||
type0_PDCCH_CSS_config->sfn_c = SFN_C_IMPOSSIBLE; // only valid for mux=1
|
||||
type0_PDCCH_CSS_config->n_c = UINT_MAX;
|
||||
type0_PDCCH_CSS_config->number_of_search_space_per_slot = UINT_MAX;
|
||||
type0_PDCCH_CSS_config->first_symbol_index = UINT_MAX;
|
||||
type0_PDCCH_CSS_config->search_space_duration = 0; // element of search space
|
||||
// 38.213 table 10.1-1
|
||||
|
||||
/// MUX PATTERN 1
|
||||
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){
|
||||
big_o = table_38213_13_11_c1[index_4lsb];
|
||||
type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
|
||||
big_m = table_38213_13_11_c3[index_4lsb];
|
||||
|
||||
uint32_t temp = (uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
|
||||
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
|
||||
if((temp/num_slot_per_frame) & 0x1){
|
||||
type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1;
|
||||
}else{
|
||||
type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_0;
|
||||
}
|
||||
|
||||
if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (type0_PDCCH_CSS_config->ssb_index&1)){
|
||||
type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols;
|
||||
}else{
|
||||
type0_PDCCH_CSS_config->first_symbol_index = table_38213_13_11_c4[index_4lsb];
|
||||
}
|
||||
// 38.213 chapter 13: over two consecutive slots
|
||||
type0_PDCCH_CSS_config->search_space_duration = 2;
|
||||
}
|
||||
|
||||
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){
|
||||
big_o = table_38213_13_12_c1[index_4lsb];
|
||||
type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
|
||||
big_m = table_38213_13_12_c3[index_4lsb];
|
||||
|
||||
if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (type0_PDCCH_CSS_config->ssb_index&1)){
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 7;
|
||||
}else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (type0_PDCCH_CSS_config->ssb_index&1)){
|
||||
type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols;
|
||||
}else{
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
}
|
||||
// 38.213 chapter 13: over two consecutive slots
|
||||
type0_PDCCH_CSS_config->search_space_duration = 2;
|
||||
}
|
||||
|
||||
/// MUX PATTERN 2
|
||||
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){
|
||||
|
||||
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){
|
||||
// 38.213 Table 13-13
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
|
||||
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
|
||||
case 0:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
break;
|
||||
case 1:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 1;
|
||||
break;
|
||||
case 2:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 6;
|
||||
break;
|
||||
case 3:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 7;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
}else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){
|
||||
// 38.213 Table 13-14
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
|
||||
switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8
|
||||
case 0:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
break;
|
||||
case 1:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 1;
|
||||
break;
|
||||
case 2:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 2;
|
||||
break;
|
||||
case 3:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 3;
|
||||
break;
|
||||
case 4:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 12;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
|
||||
break;
|
||||
case 5:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 13;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
|
||||
break;
|
||||
case 6:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
break;
|
||||
case 7:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}else{ ; }
|
||||
// 38.213 chapter 13: over one slot
|
||||
type0_PDCCH_CSS_config->search_space_duration = 1;
|
||||
}
|
||||
|
||||
/// MUX PATTERN 3
|
||||
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){
|
||||
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){
|
||||
// 38.213 Table 13-15
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
|
||||
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
|
||||
case 0:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 4;
|
||||
break;
|
||||
case 1:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 8;
|
||||
break;
|
||||
case 2:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 2;
|
||||
break;
|
||||
case 3:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 6;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}else{ ; }
|
||||
// 38.213 chapter 13: over one slot
|
||||
type0_PDCCH_CSS_config->search_space_duration = 1;
|
||||
}
|
||||
|
||||
AssertFatal(type0_PDCCH_CSS_config->number_of_search_space_per_slot!=UINT_MAX,"");
|
||||
|
||||
// uint32_t coreset_duration = num_symbols * number_of_search_space_per_slot;
|
||||
// mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0];
|
||||
// mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1];
|
||||
// mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4
|
||||
// mac->type0_pdcch_dci_config.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8
|
||||
// mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16
|
||||
// mac->type0_pdcch_dci_config.duration = search_space_duration;
|
||||
// mac->type0_pdcch_dci_config.coreset.duration = coreset_duration; // coreset
|
||||
// AssertFatal(first_symbol_index!=UINT_MAX,"");
|
||||
// mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff;
|
||||
|
||||
AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,"");
|
||||
AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,"");
|
||||
|
||||
type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
|
||||
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
#ifndef __LAYER2_NR_MAC_COMMON_H__
|
||||
#define __LAYER2_NR_MAC_COMMON_H__
|
||||
|
||||
#include "NR_MIB.h"
|
||||
#include "NR_PDSCH-Config.h"
|
||||
#include "NR_CellGroupConfig.h"
|
||||
#include "nr_mac.h"
|
||||
#include "openair1/PHY/impl_defs_nr.h"
|
||||
|
||||
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
|
||||
|
||||
@@ -59,6 +61,10 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,
|
||||
uint16_t N_RB,
|
||||
int bwp_id);
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss,
|
||||
uint16_t *slot_period,
|
||||
uint16_t *offset);
|
||||
@@ -120,6 +126,13 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
|
||||
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
|
||||
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
|
||||
|
||||
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
NR_MIB_t *mib,
|
||||
uint8_t extra_bits,
|
||||
uint32_t ssb_length,
|
||||
uint32_t ssb_index,
|
||||
uint32_t ssb_offset_point_a);
|
||||
|
||||
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
|
||||
|
||||
bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
||||
|
||||
@@ -77,5 +77,66 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
|
||||
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||
#endif*/
|
||||
|
||||
// Type0-PDCCH search space
|
||||
extern const int32_t table_38213_13_1_c1[16];
|
||||
extern const int32_t table_38213_13_1_c2[16];
|
||||
extern const int32_t table_38213_13_1_c3[16];
|
||||
extern const int32_t table_38213_13_1_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_2_c1[16];
|
||||
extern const int32_t table_38213_13_2_c2[16];
|
||||
extern const int32_t table_38213_13_2_c3[16];
|
||||
extern const int32_t table_38213_13_2_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_3_c1[16];
|
||||
extern const int32_t table_38213_13_3_c2[16];
|
||||
extern const int32_t table_38213_13_3_c3[16];
|
||||
extern const int32_t table_38213_13_3_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_4_c1[16];
|
||||
extern const int32_t table_38213_13_4_c2[16];
|
||||
extern const int32_t table_38213_13_4_c3[16];
|
||||
extern const int32_t table_38213_13_4_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_5_c1[16];
|
||||
extern const int32_t table_38213_13_5_c2[16];
|
||||
extern const int32_t table_38213_13_5_c3[16];
|
||||
extern const int32_t table_38213_13_5_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_6_c1[16];
|
||||
extern const int32_t table_38213_13_6_c2[16];
|
||||
extern const int32_t table_38213_13_6_c3[16];
|
||||
extern const int32_t table_38213_13_6_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_7_c1[16];
|
||||
extern const int32_t table_38213_13_7_c2[16];
|
||||
extern const int32_t table_38213_13_7_c3[16];
|
||||
extern const int32_t table_38213_13_7_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_8_c1[16];
|
||||
extern const int32_t table_38213_13_8_c2[16];
|
||||
extern const int32_t table_38213_13_8_c3[16];
|
||||
extern const int32_t table_38213_13_8_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_9_c1[16];
|
||||
extern const int32_t table_38213_13_9_c2[16];
|
||||
extern const int32_t table_38213_13_9_c3[16];
|
||||
extern const int32_t table_38213_13_9_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_10_c1[16];
|
||||
extern const int32_t table_38213_13_10_c2[16];
|
||||
extern const int32_t table_38213_13_10_c3[16];
|
||||
extern const int32_t table_38213_13_10_c4[16];
|
||||
|
||||
extern const float table_38213_13_11_c1[16];
|
||||
extern const int32_t table_38213_13_11_c2[16];
|
||||
extern const float table_38213_13_11_c3[16];
|
||||
extern const int32_t table_38213_13_11_c4[16];
|
||||
|
||||
extern const float table_38213_13_12_c1[16];
|
||||
extern const int32_t table_38213_13_12_c2[16];
|
||||
extern const float table_38213_13_12_c3[16];
|
||||
|
||||
extern const int32_t table_38213_10_1_1_c2[5];
|
||||
|
||||
#endif //DEF_H
|
||||
|
||||
@@ -437,13 +437,71 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){
|
||||
NR_SearchSpace_t *css = commonSearchSpaceList->list.array[css_id];
|
||||
AssertFatal(css->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n");
|
||||
AssertFatal(*css->controlResourceSetId == mac->coreset[dl_bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n");
|
||||
AssertFatal(css->searchSpaceId != 0, "css->searchSpaceId is 0\n");
|
||||
AssertFatal(css->searchSpaceType != NULL, "css->searchSpaceType is null\n");
|
||||
AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n");
|
||||
AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n");
|
||||
mac->SSpace[0][0][ss_id] = css;
|
||||
ss_id++;
|
||||
}
|
||||
|
||||
// TODO: Merge this code in a single function as fill_default_searchSpaceZero() in rrc_gNB_reconfig.c
|
||||
// Search space zero
|
||||
if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero));
|
||||
if(mac->search_space_zero->controlResourceSetId == NULL) mac->search_space_zero->controlResourceSetId=calloc(1,sizeof(*mac->search_space_zero->controlResourceSetId));
|
||||
if(mac->search_space_zero->monitoringSymbolsWithinSlot == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot = calloc(1,sizeof(*mac->search_space_zero->monitoringSymbolsWithinSlot));
|
||||
if(mac->search_space_zero->monitoringSymbolsWithinSlot->buf == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot->buf = calloc(1,2);
|
||||
if(mac->search_space_zero->nrofCandidates == NULL) mac->search_space_zero->nrofCandidates = calloc(1,sizeof(*mac->search_space_zero->nrofCandidates));
|
||||
if(mac->search_space_zero->searchSpaceType == NULL) mac->search_space_zero->searchSpaceType = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType));
|
||||
if(mac->search_space_zero->searchSpaceType->choice.common == NULL) mac->search_space_zero->searchSpaceType->choice.common=calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common));
|
||||
if(mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
|
||||
mac->search_space_zero->searchSpaceId = 0;
|
||||
*mac->search_space_zero->controlResourceSetId = 0;
|
||||
mac->search_space_zero->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*mac->search_space_zero->monitoringSlotPeriodicityAndOffset));
|
||||
mac->search_space_zero->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
|
||||
mac->search_space_zero->duration=NULL;
|
||||
// should be '1100 0000 0000 00'B (LSB first!), first two symbols in slot, adjust if needed
|
||||
mac->search_space_zero->monitoringSymbolsWithinSlot->buf[1] = 0;
|
||||
mac->search_space_zero->monitoringSymbolsWithinSlot->buf[0] = (1<<7) | (1<<6);
|
||||
mac->search_space_zero->monitoringSymbolsWithinSlot->size = 2;
|
||||
mac->search_space_zero->monitoringSymbolsWithinSlot->bits_unused = 2;
|
||||
|
||||
// FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
|
||||
mac->search_space_zero->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
|
||||
mac->search_space_zero->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
|
||||
mac->search_space_zero->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0;
|
||||
mac->search_space_zero->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1;
|
||||
mac->search_space_zero->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
|
||||
mac->search_space_zero->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
|
||||
|
||||
// Coreset0
|
||||
if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0));
|
||||
mac->coreset0->controlResourceSetId = 0;
|
||||
// frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
|
||||
if(mac->coreset0->frequencyDomainResources.buf == NULL) mac->coreset0->frequencyDomainResources.buf = calloc(1,6);
|
||||
mac->coreset0->frequencyDomainResources.buf[0] = 0xff;
|
||||
mac->coreset0->frequencyDomainResources.buf[1] = 0;
|
||||
mac->coreset0->frequencyDomainResources.buf[2] = 0;
|
||||
mac->coreset0->frequencyDomainResources.buf[3] = 0;
|
||||
mac->coreset0->frequencyDomainResources.buf[4] = 0;
|
||||
mac->coreset0->frequencyDomainResources.buf[5] = 0;
|
||||
mac->coreset0->frequencyDomainResources.size = 6;
|
||||
mac->coreset0->frequencyDomainResources.bits_unused = 3;
|
||||
mac->coreset0->duration = 1;
|
||||
mac->coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*mac->coreset0->cce_REG_MappingType.choice.interleaved));
|
||||
mac->coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
|
||||
mac->coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL;
|
||||
mac->coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
|
||||
if(mac->coreset0->tci_StatesPDCCH_ToAddList == NULL) mac->coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*mac->coreset0->tci_StatesPDCCH_ToAddList));
|
||||
NR_TCI_StateId_t *tci[8];
|
||||
for (int i=0;i<8;i++) {
|
||||
tci[i]=calloc(1,sizeof(*tci[i]));
|
||||
*tci[i] = i;
|
||||
ASN_SEQUENCE_ADD(&mac->coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
|
||||
}
|
||||
mac->coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
|
||||
mac->coreset0->tci_PresentInDCI = NULL;
|
||||
mac->coreset0->pdcch_DMRS_ScramblingID = NULL;
|
||||
|
||||
}
|
||||
|
||||
int nr_rrc_mac_config_req_ue(
|
||||
|
||||
@@ -170,12 +170,6 @@ typedef enum {
|
||||
UE_PHY_HO_PRACH
|
||||
} NR_UE_L2_STATE_t;
|
||||
|
||||
typedef enum {
|
||||
SFN_C_MOD_2_EQ_0,
|
||||
SFN_C_MOD_2_EQ_1,
|
||||
SFN_C_IMPOSSIBLE
|
||||
} SFN_C_TYPE;
|
||||
|
||||
// LTE structure, might need to be adapted for NR
|
||||
typedef struct {
|
||||
/// buffer status for each lcgid
|
||||
@@ -304,9 +298,9 @@ typedef struct {
|
||||
typedef struct {
|
||||
|
||||
uint8_t freq_hopping;
|
||||
uint8_t Msg3_t_alloc;
|
||||
uint8_t Msg3_f_alloc;
|
||||
uint8_t mcs;
|
||||
uint8_t Msg3_t_alloc;
|
||||
uint16_t Msg3_f_alloc;
|
||||
|
||||
} RAR_grant_t;
|
||||
|
||||
@@ -354,6 +348,8 @@ typedef struct {
|
||||
uint16_t crnti;
|
||||
/// RA configuration
|
||||
RA_config_t ra;
|
||||
/// SSB index from MIB decoding
|
||||
uint8_t mib_ssb;
|
||||
|
||||
//// FAPI-like interface message
|
||||
fapi_nr_ul_config_request_t *ul_config_request;
|
||||
@@ -369,6 +365,11 @@ typedef struct {
|
||||
|
||||
/// PHR
|
||||
uint8_t PHR_reporting_active;
|
||||
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
||||
NR_SearchSpace_t *search_space_zero;
|
||||
NR_ControlResourceSet_t *coreset0;
|
||||
|
||||
} NR_UE_MAC_INST_t;
|
||||
|
||||
typedef enum seach_space_mask_e {
|
||||
@@ -379,24 +380,6 @@ typedef enum seach_space_mask_e {
|
||||
type3_pdcch = 0x10
|
||||
} search_space_mask_t;
|
||||
|
||||
typedef enum subcarrier_spacing_e {
|
||||
scs_15kHz = 0x1,
|
||||
scs_30kHz = 0x2,
|
||||
scs_60kHz = 0x4,
|
||||
scs_120kHz = 0x8,
|
||||
scs_240kHz = 0x16
|
||||
} subcarrier_spacing_t;
|
||||
|
||||
typedef enum channel_bandwidth_e {
|
||||
bw_5MHz = 0x1,
|
||||
bw_10MHz = 0x2,
|
||||
bw_20MHz = 0x4,
|
||||
bw_40MHz = 0x8,
|
||||
bw_80MHz = 0x16,
|
||||
bw_100MHz = 0x32
|
||||
} channel_bandwidth_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS:
|
||||
uint8_t carrier_ind ; // 1 CARRIER_IND: 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213]
|
||||
|
||||
@@ -34,58 +34,6 @@
|
||||
|
||||
//extern NR_UE_MAC_INST_t *UE_mac_inst;
|
||||
|
||||
// Type0-PDCCH search space
|
||||
extern const int32_t table_38213_13_1_c2[16];
|
||||
extern const int32_t table_38213_13_1_c3[16];
|
||||
extern const int32_t table_38213_13_1_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_2_c2[16];
|
||||
extern const int32_t table_38213_13_2_c3[16];
|
||||
extern const int32_t table_38213_13_2_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_3_c2[16];
|
||||
extern const int32_t table_38213_13_3_c3[16];
|
||||
extern const int32_t table_38213_13_3_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_4_c2[16];
|
||||
extern const int32_t table_38213_13_4_c3[16];
|
||||
extern const int32_t table_38213_13_4_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_5_c2[16];
|
||||
extern const int32_t table_38213_13_5_c3[16];
|
||||
extern const int32_t table_38213_13_5_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_6_c2[16];
|
||||
extern const int32_t table_38213_13_6_c3[16];
|
||||
extern const int32_t table_38213_13_6_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_7_c2[16];
|
||||
extern const int32_t table_38213_13_7_c3[16];
|
||||
extern const int32_t table_38213_13_7_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_8_c2[16];
|
||||
extern const int32_t table_38213_13_8_c3[16];
|
||||
extern const int32_t table_38213_13_8_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_9_c2[16];
|
||||
extern const int32_t table_38213_13_9_c3[16];
|
||||
extern const int32_t table_38213_13_9_c4[16];
|
||||
|
||||
extern const int32_t table_38213_13_10_c2[16];
|
||||
extern const int32_t table_38213_13_10_c3[16];
|
||||
extern const int32_t table_38213_13_10_c4[16];
|
||||
|
||||
extern const float table_38213_13_11_c1[16];
|
||||
extern const int32_t table_38213_13_11_c2[16];
|
||||
extern const float table_38213_13_11_c3[16];
|
||||
extern const int32_t table_38213_13_11_c4[16];
|
||||
|
||||
extern const float table_38213_13_12_c1[16];
|
||||
extern const int32_t table_38213_13_12_c2[16];
|
||||
extern const float table_38213_13_12_c3[16];
|
||||
|
||||
extern const int32_t table_38213_10_1_1_c2[5];
|
||||
|
||||
// DCI extraction
|
||||
// for PUSCH from TS 38.214 subclause 6.1.2.1.1
|
||||
extern uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3];
|
||||
@@ -94,8 +42,6 @@ extern uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3];
|
||||
|
||||
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
|
||||
|
||||
extern const uint8_t table_9_2_2_1[16][8];
|
||||
|
||||
// DCI
|
||||
extern const uint8_t table_7_3_1_1_2_2_3_4_5[64][20];
|
||||
extern const uint8_t table_7_3_1_1_2_12[14][3];
|
||||
|
||||
@@ -56,6 +56,19 @@ int8_t nr_ue_decode_mib(
|
||||
void *pduP,
|
||||
uint16_t cell_id );
|
||||
|
||||
/**\brief decode sib1 pdu in NR_UE, from if_module dl_ind
|
||||
\param module_id module id
|
||||
\param cc_id component carrier id
|
||||
\param gNB_index gNB index
|
||||
\param sibs_mask sibs mask
|
||||
\param pduP pointer to pdu
|
||||
\param pdu_length length of pdu */
|
||||
int8_t nr_ue_decode_sib1(module_id_t module_id,
|
||||
int cc_id,
|
||||
unsigned int gNB_index,
|
||||
uint32_t sibs_mask,
|
||||
uint8_t *pduP,
|
||||
uint32_t pdu_len);
|
||||
|
||||
/**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config)
|
||||
\param module_id module id
|
||||
@@ -123,8 +136,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci);
|
||||
|
||||
uint32_t get_ssb_frame(uint32_t test);
|
||||
uint32_t get_ssb_slot(uint32_t ssb_index);
|
||||
|
||||
|
||||
uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
|
||||
|
||||
|
||||
@@ -32,84 +32,9 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define reserved 0xffff
|
||||
|
||||
const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"};
|
||||
const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"};
|
||||
|
||||
// specification mapping talbe, table_38$x_$y_$z_c$a
|
||||
// - $x: specification
|
||||
// - $y: subclause-major
|
||||
// - $z: subclause-minor
|
||||
// - $a: ($a)th of column in table, start from zero
|
||||
const int32_t table_38213_13_1_c2[16] = {24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 96, 96, 96, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_1_c3[16] = { 2, 2, 2, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_1_c4[16] = { 0, 2, 4, 0, 2, 4, 12, 16, 12, 16, 12, 16, 38, 38, 38, reserved}; // index 15 reserved
|
||||
|
||||
const int32_t table_38213_13_2_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved}; // index 14-15 reserved
|
||||
const int32_t table_38213_13_2_c3[16] = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved}; // index 14-15 reserved
|
||||
const int32_t table_38213_13_2_c4[16] = { 5, 6, 7, 8, 5, 6, 7, 8, 18, 20, 18, 20, 18, 20, reserved, reserved}; // index 14-15 reserved
|
||||
|
||||
const int32_t table_38213_13_3_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_3_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_3_c4[16] = { 2, 6, 2, 6, 2, 6, 28, 28, 28, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
|
||||
const int32_t table_38213_13_4_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48};
|
||||
const int32_t table_38213_13_4_c3[16] = { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2};
|
||||
const int32_t table_38213_13_4_c4[16] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 12, 14, 16, 12, 14, 16};
|
||||
|
||||
const int32_t table_38213_13_5_c2[16] = {48, 48, 48, 96, 96, 96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_5_c3[16] = { 1, 2, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
const int32_t table_38213_13_5_c4[16] = { 4, 4, 4, 0, 56, 0, 56, 0, 56, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved
|
||||
|
||||
const int32_t table_38213_13_6_c2[16] = {24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
const int32_t table_38213_13_6_c3[16] = { 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
const int32_t table_38213_13_6_c4[16] = { 0, 4, 0, 4, 0, 28, 0, 28, 0, 28, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved
|
||||
|
||||
const int32_t table_38213_13_7_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 48, 48, 96, 96, reserved, reserved, reserved, reserved}; // index 12-15 reserved
|
||||
const int32_t table_38213_13_7_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved}; // index 12-15 reserved
|
||||
const int32_t table_38213_13_7_c4[16] = { 0, 8, 0, 8, 0, 8, 28, 28,-41, 49,-41, 97, reserved, reserved, reserved, reserved}; // index 12-15 reserved, condition A as default
|
||||
|
||||
const int32_t table_38213_13_8_c2[16] = { 1, 1, 1, 1, 3, 3, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_8_c3[16] = {24, 24, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved
|
||||
const int32_t table_38213_13_8_c4[16] = { 0, 4, 14, 14,-20, 24,-20, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved, condition A as default
|
||||
|
||||
const int32_t table_38213_13_9_c2[16] = {96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
const int32_t table_38213_13_9_c3[16] = { 1, 1, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
const int32_t table_38213_13_9_c4[16] = { 0, 16, 0, 16, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved
|
||||
|
||||
const int32_t table_38213_13_10_c2[16] = {48, 48, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved
|
||||
const int32_t table_38213_13_10_c3[16] = { 1, 1, 2, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved
|
||||
const int32_t table_38213_13_10_c4[16] = { 0, 8, 0, 8,-41, 25,-41, 49, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved, condition A as default
|
||||
|
||||
const float table_38213_13_11_c1[16] = { 0, 0, 2, 2, 5, 5, 7, 7, 0, 5, 0, 0, 2, 2, 5, 5}; // O
|
||||
const int32_t table_38213_13_11_c2[16] = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 1, 1, 1, 1, 1, 1, 1}; // M
|
||||
const int32_t table_38213_13_11_c4[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2}; // i is even as default
|
||||
|
||||
const float table_38213_13_12_c1[16] = { 0, 0, 2.5f, 2.5f, 5, 5, 0, 2.5f, 5, 7.5f, 7.5f, 7.5f, 0, 5, reserved, reserved}; // O, index 14-15 reserved
|
||||
const int32_t table_38213_13_12_c2[16] = { 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, reserved, reserved}; // index 14-15 reserved
|
||||
const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 1, reserved, reserved}; // M, index 14-15 reserved
|
||||
|
||||
const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 };
|
||||
|
||||
const uint8_t table_9_2_2_1[16][8]={{0,12,2, 0, 0,3,0,0},
|
||||
{0,12,2, 0, 0,4,8,0},
|
||||
{0,12,2, 3, 0,4,8,0},
|
||||
{1,10,4, 0, 0,6,0,0},
|
||||
{1,10,4, 0, 0,3,6,9},
|
||||
{1,10,4, 2, 0,3,6,9},
|
||||
{1,10,4, 4, 0,3,6,9},
|
||||
{1,4, 10,0, 0,6,0,0},
|
||||
{1,4, 10,0, 0,3,6,9},
|
||||
{1,4, 10,2, 0,3,6,9},
|
||||
{1,4, 10,4, 0,3,6,9},
|
||||
{1,0, 14,0, 0,6,0,0},
|
||||
{1,0, 14,0, 0,3,6,9},
|
||||
{1,0, 14,2, 0,3,6,9},
|
||||
{1,0, 14,4, 0,3,6,9},
|
||||
{1,0, 14,26,0,3,0,0}};
|
||||
|
||||
// table_7_3_1_1_2_2_3_4_5 contains values for number of layers and precoding information for tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2
|
||||
// the first 6 columns contain table 7.3.1.1.2-2: Precoding information and number of layers, for 4 antenna ports, if transformPrecoder=disabled and maxRank = 2 or 3 or 4
|
||||
// next six columns contain table 7.3.1.1.2-3: Precoding information and number of layers for 4 antenna ports, if transformPrecoder= enabled, or if transformPrecoder=disabled and maxRank = 1
|
||||
|
||||
@@ -52,7 +52,6 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst)
|
||||
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
|
||||
if (rrc_inst) {
|
||||
nr_rrc_mac_config_req_ue(0,0,0,NULL,rrc_inst->cell_group_config);
|
||||
|
||||
if (IS_SOFTMODEM_NOS1){
|
||||
AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__);
|
||||
pdcp_layer_init();
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include <stdio.h>
|
||||
#include "nfapi_nr_interface.h"
|
||||
|
||||
#ifdef NR_PDCCH_DCI_TOOLS_DEBUG
|
||||
#define LOG_DCI_D(a...) printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) ->" a)
|
||||
@@ -53,17 +54,33 @@ dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
|
||||
|
||||
LOG_D(MAC,"Filling search candidates for DCI\n");
|
||||
|
||||
rel15->number_of_candidates=4;
|
||||
rel15->CCE[0]=0;
|
||||
rel15->L[0]=4;
|
||||
rel15->CCE[1]=4;
|
||||
rel15->L[1]=4;
|
||||
rel15->CCE[2]=8;
|
||||
rel15->L[2]=4;
|
||||
rel15->CCE[3]=12;
|
||||
rel15->L[3]=4;
|
||||
|
||||
if(ss->searchSpaceId == 0) {
|
||||
// TODO: Update the maximum number of PDCCH candidates accordingly with Aggregation Level
|
||||
rel15->number_of_candidates=1;
|
||||
rel15->CCE[0]=0;
|
||||
rel15->L[0]=6;
|
||||
} else {
|
||||
rel15->number_of_candidates=4;
|
||||
rel15->CCE[0]=0;
|
||||
rel15->L[0]=4;
|
||||
rel15->CCE[1]=4;
|
||||
rel15->L[1]=4;
|
||||
rel15->CCE[2]=8;
|
||||
rel15->L[2]=4;
|
||||
rel15->CCE[3]=12;
|
||||
rel15->L[3]=4;
|
||||
}
|
||||
|
||||
uint8_t aggregation;
|
||||
find_aggregation_candidates(&aggregation,
|
||||
&rel15->number_of_candidates,
|
||||
ss);
|
||||
|
||||
for (int i=0; i<rel15->number_of_candidates; i++) {
|
||||
rel15->CCE[i] = i*aggregation;
|
||||
rel15->L[i] = aggregation;
|
||||
}
|
||||
}
|
||||
|
||||
void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id){
|
||||
@@ -78,11 +95,21 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
NR_BWP_DownlinkCommon_t *bwp_Common = mac->DLbwp[bwp_id - 1]->bwp_Common;
|
||||
NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP;
|
||||
NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
|
||||
|
||||
// CORESET configuration
|
||||
NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id - 1];
|
||||
NR_SearchSpace_t *ss;
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
if(ss_id>=0) {
|
||||
ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id];
|
||||
coreset = mac->coreset[bwp_id - 1][coreset_id - 1];
|
||||
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
|
||||
} else {
|
||||
ss = mac->search_space_zero;
|
||||
coreset = mac->coreset0;
|
||||
rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
|
||||
}
|
||||
|
||||
rel15->coreset.duration = coreset->duration;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i];
|
||||
rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED;
|
||||
@@ -97,7 +124,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
rel15->coreset.InterleaverSize = 0;
|
||||
rel15->coreset.ShiftIndex = 0;
|
||||
}
|
||||
rel15->coreset.CoreSetType = 1;
|
||||
|
||||
rel15->coreset.precoder_granularity = coreset->precoderGranularity;
|
||||
|
||||
// Scrambling RNTI
|
||||
@@ -147,6 +174,20 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
|
||||
case NR_RNTI_SP_CSI:
|
||||
break;
|
||||
case NR_RNTI_SI:
|
||||
// we use DL BWP dedicated
|
||||
sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
|
||||
|
||||
// for SPS=14 8 MSBs in positions 13 down to 6
|
||||
monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
|
||||
|
||||
rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values
|
||||
rel15->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
rel15->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon;
|
||||
|
||||
for (int i = 0; i < rel15->num_dci_options; i++) {
|
||||
rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_SFI:
|
||||
break;
|
||||
@@ -209,8 +250,11 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
// Fetch configuration for searchSpaceZero
|
||||
// note: The search space with the SearchSpaceId = 0 identifies the search space configured via PBCH (MIB) and in ServingCellConfigCommon (searchSpaceZero).
|
||||
if (pdcch_ConfigCommon->choice.setup->searchSpaceZero){
|
||||
if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 == NULL){
|
||||
pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*pdcch_ConfigCommon->choice.setup->searchSpaceSIB1));
|
||||
}
|
||||
*pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = 0;
|
||||
LOG_D(MAC, "[DCI_CONFIG] Configure SearchSpace#0 of the initial BWP\n");
|
||||
LOG_W(MAC, "[DCI_CONFIG] This should not be available yet...");
|
||||
}
|
||||
if (ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0){
|
||||
// check available SS IDs
|
||||
@@ -330,4 +374,25 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Search space 0, CORESET ID 0
|
||||
|
||||
NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common;
|
||||
NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon;
|
||||
|
||||
if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
|
||||
|
||||
NR_SearchSpace_t *ss0 = mac->search_space_zero;
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15;
|
||||
|
||||
if (ss0->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){
|
||||
if( (frame%2 == mac->type0_PDCCH_CSS_config.sfn_c) && (slot == mac->type0_PDCCH_CSS_config.n_0) ){
|
||||
rel15->num_dci_options = 1;
|
||||
rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1);
|
||||
fill_dci_search_candidates(ss0, rel15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "NR_MAC_COMMON/nr_mac.h"
|
||||
#include "NR_MAC_UE/mac_proto.h"
|
||||
#include "NR_MAC_UE/mac_extern.h"
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
/* PHY */
|
||||
@@ -90,12 +91,6 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
|
||||
|
||||
}
|
||||
|
||||
uint32_t get_ssb_slot(uint32_t ssb_index){
|
||||
// this function now only support f <= 3GHz
|
||||
return ssb_index & 0x3 ;
|
||||
|
||||
// return first_symbol(case, freq, ssb_index) / 14
|
||||
}
|
||||
|
||||
int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
int cc_id,
|
||||
@@ -141,346 +136,33 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
LOG_D(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
|
||||
LOG_D(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
|
||||
LOG_D(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit);
|
||||
LOG_D(MAC,"ssb index(extra bits): %d\n", (int)ssb_index);
|
||||
LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index);
|
||||
|
||||
subcarrier_spacing_t scs_ssb = scs_30kHz; // default for
|
||||
//const uint32_t scs_index = 0;
|
||||
const uint32_t num_slot_per_frame = 20;
|
||||
subcarrier_spacing_t scs_pdcch;
|
||||
//storing ssb index in the mac structure
|
||||
mac->mib_ssb = ssb_index;
|
||||
|
||||
// assume carrier frequency < 6GHz
|
||||
if(mac->mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
|
||||
scs_pdcch = scs_15kHz;
|
||||
}else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
|
||||
scs_pdcch = scs_30kHz;
|
||||
}
|
||||
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index,
|
||||
mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
|
||||
|
||||
channel_bandwidth_t min_channel_bw = bw_10MHz; // deafult for testing
|
||||
|
||||
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
|
||||
frequency_range_t frequency_range = FR1;
|
||||
uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero);
|
||||
uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1.searchSpaceZero);
|
||||
int32_t num_rbs = -1;
|
||||
int32_t num_symbols = -1;
|
||||
int32_t rb_offset = -1;
|
||||
LOG_D(MAC,"<<<<<<<<<configSIB1: controlResourceSetZero %d searchSpaceZero %d scs_ssb %d scs_pdcch %d switch %d ",
|
||||
index_4msb,index_4lsb,scs_ssb,scs_pdcch, (scs_ssb << 5)|scs_pdcch);
|
||||
ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; // TODO: ssb_index should obtain from L1 in case Lssb != 64
|
||||
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
|
||||
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
|
||||
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
|
||||
mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame;
|
||||
mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
|
||||
|
||||
// type0-pdcch coreset
|
||||
switch( (scs_ssb << 5)|scs_pdcch ){
|
||||
case (scs_15kHz << 5) | scs_15kHz :
|
||||
AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_1_c2[index_4msb];
|
||||
num_symbols = table_38213_13_1_c3[index_4msb];
|
||||
rb_offset = table_38213_13_1_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_15kHz << 5) | scs_30kHz:
|
||||
AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_2_c2[index_4msb];
|
||||
num_symbols = table_38213_13_2_c3[index_4msb];
|
||||
rb_offset = table_38213_13_2_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_30kHz << 5) | scs_15kHz:
|
||||
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
|
||||
AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_3_c2[index_4msb];
|
||||
num_symbols = table_38213_13_3_c3[index_4msb];
|
||||
rb_offset = table_38213_13_3_c4[index_4msb];
|
||||
}else if(min_channel_bw & bw_40MHz){
|
||||
AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n");
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_5_c2[index_4msb];
|
||||
num_symbols = table_38213_13_5_c3[index_4msb];
|
||||
rb_offset = table_38213_13_5_c4[index_4msb];
|
||||
}else{ ; }
|
||||
|
||||
break;
|
||||
|
||||
case (scs_30kHz << 5) | scs_30kHz:
|
||||
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_4_c2[index_4msb];
|
||||
num_symbols = table_38213_13_4_c3[index_4msb];
|
||||
rb_offset = table_38213_13_4_c4[index_4msb];
|
||||
LOG_D(MAC,"<<<<<<<<<index_4msb %d num_rbs %d num_symb %d rb_offset %d\n",index_4msb,num_rbs,num_symbols,rb_offset );
|
||||
}else if(min_channel_bw & bw_40MHz){
|
||||
AssertFatal(index_4msb < 10, "38.213 Table 13-6 4 MSB out of range\n");
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_6_c2[index_4msb];
|
||||
num_symbols = table_38213_13_6_c3[index_4msb];
|
||||
rb_offset = table_38213_13_6_c4[index_4msb];
|
||||
}else{ ; }
|
||||
break;
|
||||
|
||||
case (scs_120kHz << 5) | scs_60kHz:
|
||||
AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
|
||||
if(index_4msb & 0x7){
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
}else if(index_4msb & 0x18){
|
||||
mac->type0_pdcch_ss_mux_pattern = 2;
|
||||
}else{ ; }
|
||||
|
||||
num_rbs = table_38213_13_7_c2[index_4msb];
|
||||
num_symbols = table_38213_13_7_c3[index_4msb];
|
||||
if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){
|
||||
rb_offset = table_38213_13_7_c4[index_4msb] - 1;
|
||||
}else{
|
||||
rb_offset = table_38213_13_7_c4[index_4msb];
|
||||
}
|
||||
break;
|
||||
|
||||
case (scs_120kHz << 5) | scs_120kHz:
|
||||
AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
|
||||
if(index_4msb & 0x3){
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
}else if(index_4msb & 0x0c){
|
||||
mac->type0_pdcch_ss_mux_pattern = 3;
|
||||
}
|
||||
|
||||
num_rbs = table_38213_13_8_c2[index_4msb];
|
||||
num_symbols = table_38213_13_8_c3[index_4msb];
|
||||
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
|
||||
rb_offset = table_38213_13_8_c4[index_4msb] - 1;
|
||||
}else{
|
||||
rb_offset = table_38213_13_8_c4[index_4msb];
|
||||
}
|
||||
break;
|
||||
|
||||
case (scs_240kHz << 5) | scs_60kHz:
|
||||
AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
num_rbs = table_38213_13_9_c2[index_4msb];
|
||||
num_symbols = table_38213_13_9_c3[index_4msb];
|
||||
rb_offset = table_38213_13_9_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_240kHz << 5) | scs_120kHz:
|
||||
AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
|
||||
if(index_4msb & 0x3){
|
||||
mac->type0_pdcch_ss_mux_pattern = 1;
|
||||
}else if(index_4msb & 0x0c){
|
||||
mac->type0_pdcch_ss_mux_pattern = 2;
|
||||
}
|
||||
num_rbs = table_38213_13_10_c2[index_4msb];
|
||||
num_symbols = table_38213_13_10_c3[index_4msb];
|
||||
if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){
|
||||
rb_offset = table_38213_13_10_c4[index_4msb]-1;
|
||||
}else{
|
||||
rb_offset = table_38213_13_10_c4[index_4msb];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
AssertFatal(num_rbs != -1, "Type0 PDCCH coreset num_rbs undefined");
|
||||
AssertFatal(num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined");
|
||||
AssertFatal(rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined");
|
||||
|
||||
//uint32_t cell_id = 0; // obtain from L1 later
|
||||
|
||||
//mac->type0_pdcch_dci_config.coreset.rb_start = rb_offset;
|
||||
//mac->type0_pdcch_dci_config.coreset.rb_end = rb_offset + num_rbs - 1;
|
||||
uint64_t mask = 0x0;
|
||||
uint8_t i;
|
||||
for(i=0; i<(num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs
|
||||
mask = mask >> 1;
|
||||
mask = mask | 0x100000000000;
|
||||
}
|
||||
//LOG_I(MAC,">>>>>>>>mask %x num_rbs %d rb_offset %d\n", mask, num_rbs, rb_offset);
|
||||
/*
|
||||
mac->type0_pdcch_dci_config.coreset.frequency_domain_resource = mask;
|
||||
mac->type0_pdcch_dci_config.coreset.rb_offset = rb_offset; // additional parameter other than coreset
|
||||
|
||||
//mac->type0_pdcch_dci_config.type0_pdcch_coreset.duration = num_symbols;
|
||||
mac->type0_pdcch_dci_config.coreset.cce_reg_mapping_type = CCE_REG_MAPPING_TYPE_INTERLEAVED;
|
||||
mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_reg_bundle_size = 6; // L 38.211 7.3.2.2
|
||||
mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_interleaver_size = 2; // R 38.211 7.3.2.2
|
||||
mac->type0_pdcch_dci_config.coreset.cce_reg_interleaved_shift_index = cell_id;
|
||||
mac->type0_pdcch_dci_config.coreset.precoder_granularity = PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE;
|
||||
mac->type0_pdcch_dci_config.coreset.pdcch_dmrs_scrambling_id = cell_id;
|
||||
*/
|
||||
|
||||
|
||||
// type0-pdcch search space
|
||||
float big_o;
|
||||
float big_m;
|
||||
uint32_t temp;
|
||||
SFN_C_TYPE sfn_c=SFN_C_IMPOSSIBLE; // only valid for mux=1
|
||||
uint32_t n_c=UINT_MAX;
|
||||
uint32_t number_of_search_space_per_slot=UINT_MAX;
|
||||
// uint32_t first_symbol_index=UINT_MAX;
|
||||
// uint32_t search_space_duration; // element of search space
|
||||
// 38.213 table 10.1-1
|
||||
|
||||
/// MUX PATTERN 1
|
||||
if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){
|
||||
big_o = table_38213_13_11_c1[index_4lsb];
|
||||
number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
|
||||
big_m = table_38213_13_11_c3[index_4lsb];
|
||||
|
||||
temp = (uint32_t)(big_o*pow(2, scs_pdcch)) + (uint32_t)(ssb_index*big_m);
|
||||
n_c = temp / num_slot_per_frame;
|
||||
if((temp/num_slot_per_frame) & 0x1){
|
||||
sfn_c = SFN_C_MOD_2_EQ_1;
|
||||
}else{
|
||||
sfn_c = SFN_C_MOD_2_EQ_0;
|
||||
}
|
||||
|
||||
// if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (ssb_index&1)){
|
||||
// first_symbol_index = num_symbols;
|
||||
// }else{
|
||||
// first_symbol_index = table_38213_13_11_c4[index_4lsb];
|
||||
// }
|
||||
// 38.213 chapter 13: over two consecutive slots
|
||||
// search_space_duration = 2;
|
||||
}
|
||||
|
||||
if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){
|
||||
big_o = table_38213_13_12_c1[index_4lsb];
|
||||
number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
|
||||
big_m = table_38213_13_12_c3[index_4lsb];
|
||||
|
||||
// if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (ssb_index&1)){
|
||||
// first_symbol_index = 7;
|
||||
// }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (ssb_index&1)){
|
||||
// first_symbol_index = num_symbols;
|
||||
// }else{
|
||||
// first_symbol_index = 0;
|
||||
// }
|
||||
// 38.213 chapter 13: over two consecutive slots
|
||||
//search_space_duration = 2;
|
||||
}
|
||||
|
||||
/// MUX PATTERN 2
|
||||
if(mac->type0_pdcch_ss_mux_pattern == 2){
|
||||
|
||||
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){
|
||||
// 38.213 Table 13-13
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
n_c = get_ssb_slot(ssb_index);
|
||||
// switch(ssb_index & 0x3){ // ssb_index(i) mod 4
|
||||
// case 0:
|
||||
// first_symbol_index = 0;
|
||||
// break;
|
||||
// case 1:
|
||||
// first_symbol_index = 1;
|
||||
// break;
|
||||
// case 2:
|
||||
// first_symbol_index = 6;
|
||||
// break;
|
||||
// case 3:
|
||||
// first_symbol_index = 7;
|
||||
// break;
|
||||
// default: break;
|
||||
// }
|
||||
|
||||
}else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){
|
||||
// 38.213 Table 13-14
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
n_c = get_ssb_slot(ssb_index);
|
||||
switch(ssb_index & 0x7){ // ssb_index(i) mod 8
|
||||
case 0:
|
||||
// first_symbol_index = 0;
|
||||
break;
|
||||
case 1:
|
||||
// first_symbol_index = 1;
|
||||
break;
|
||||
case 2:
|
||||
// first_symbol_index = 2;
|
||||
break;
|
||||
case 3:
|
||||
// first_symbol_index = 3;
|
||||
break;
|
||||
case 4:
|
||||
// first_symbol_index = 12;
|
||||
n_c = get_ssb_slot(ssb_index) - 1;
|
||||
break;
|
||||
case 5:
|
||||
// first_symbol_index = 13;
|
||||
n_c = get_ssb_slot(ssb_index) - 1;
|
||||
break;
|
||||
case 6:
|
||||
// first_symbol_index = 0;
|
||||
break;
|
||||
case 7:
|
||||
// first_symbol_index = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}else{ ; }
|
||||
// 38.213 chapter 13: over one slot
|
||||
// search_space_duration = 1;
|
||||
}
|
||||
|
||||
/// MUX PATTERN 3
|
||||
if(mac->type0_pdcch_ss_mux_pattern == 3){
|
||||
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){
|
||||
// 38.213 Table 13-15
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
n_c = get_ssb_slot(ssb_index);
|
||||
// switch(ssb_index & 0x3){ // ssb_index(i) mod 4
|
||||
// case 0:
|
||||
// first_symbol_index = 4;
|
||||
// break;
|
||||
// case 1:
|
||||
// first_symbol_index = 8;
|
||||
// break;
|
||||
// case 2:
|
||||
// first_symbol_index = 2;
|
||||
// break;
|
||||
// case 3:
|
||||
// first_symbol_index = 6;
|
||||
// break;
|
||||
// default: break;
|
||||
// }
|
||||
}else{ ; }
|
||||
// 38.213 chapter 13: over one slot
|
||||
// search_space_duration = 1;
|
||||
}
|
||||
|
||||
AssertFatal(number_of_search_space_per_slot!=UINT_MAX,"");
|
||||
/*
|
||||
uint32_t coreset_duration = num_symbols * number_of_search_space_per_slot;
|
||||
mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0];
|
||||
mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1];
|
||||
mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4
|
||||
mac->type0_pdcch_dci_config.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8
|
||||
mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16
|
||||
mac->type0_pdcch_dci_config.duration = search_space_duration;
|
||||
mac->type0_pdcch_dci_config.coreset.duration = coreset_duration; // coreset
|
||||
AssertFatal(first_symbol_index!=UINT_MAX,"");
|
||||
mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff;
|
||||
*/
|
||||
AssertFatal(sfn_c!=SFN_C_IMPOSSIBLE,"");
|
||||
AssertFatal(n_c!=UINT_MAX,"");
|
||||
mac->type0_pdcch_ss_sfn_c = sfn_c;
|
||||
mac->type0_pdcch_ss_n_c = n_c;
|
||||
|
||||
// fill in the elements in config request inside P5 message
|
||||
mac->phy_config.Mod_id = module_id;
|
||||
mac->phy_config.CC_id = cc_id;
|
||||
|
||||
mac->dl_config_request.sfn = frame;
|
||||
mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
|
||||
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t nr_ue_decode_sib1(module_id_t module_id,
|
||||
int cc_id,
|
||||
unsigned int gNB_index,
|
||||
uint32_t sibs_mask,
|
||||
uint8_t *pduP,
|
||||
uint32_t pdu_len) {
|
||||
LOG_D(MAC, "Decode sib1\n");
|
||||
nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: change to UE parameter, scs: 15KHz, slot duration: 1ms
|
||||
@@ -521,6 +203,11 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG_D(MAC,"riv = %i\n", riv);
|
||||
LOG_D(MAC,"n_RB_DLBWP = %i\n", n_RB_DLBWP);
|
||||
LOG_D(MAC,"number_rbs = %i\n", dlsch_config_pdu->number_rbs);
|
||||
LOG_D(MAC,"start_rb = %i\n", dlsch_config_pdu->start_rb);
|
||||
|
||||
}
|
||||
if(pusch_config_pdu != NULL){
|
||||
/*
|
||||
@@ -692,6 +379,11 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
|
||||
SLIV2SL(startSymbolAndLength,&S,&L);
|
||||
dlsch_config_pdu->start_symbol=S;
|
||||
dlsch_config_pdu->number_symbols=L;
|
||||
|
||||
LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength);
|
||||
LOG_D(MAC,"start_symbol = %i\n", dlsch_config_pdu->start_symbol);
|
||||
LOG_D(MAC,"number_symbols = %i\n", dlsch_config_pdu->number_symbols);
|
||||
|
||||
}
|
||||
else {// Default configuration from tables
|
||||
// k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
|
||||
@@ -949,14 +641,31 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
*/
|
||||
|
||||
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti;
|
||||
//fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_pdu_1_0 = dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
|
||||
dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
uint16_t BWPSize = 0;
|
||||
|
||||
if(rnti == SI_RNTI) {
|
||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH;
|
||||
dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon;
|
||||
pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2'
|
||||
BWPSize = dlsch_config_pdu_1_0->BWPSize;
|
||||
} else {
|
||||
if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){
|
||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
|
||||
} else {
|
||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
|
||||
}
|
||||
dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
BWPSize = n_RB_DLBWP;
|
||||
}
|
||||
|
||||
/* IDENTIFIER_DCI_FORMATS */
|
||||
/* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */
|
||||
if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,n_RB_DLBWP,dci->frequency_domain_assignment.val) < 0)
|
||||
if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,BWPSize,dci->frequency_domain_assignment.val) < 0)
|
||||
return -1;
|
||||
/* TIME_DOM_RESOURCE_ASSIGNMENT */
|
||||
if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0)
|
||||
@@ -964,7 +673,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
/* dmrs symbol positions*/
|
||||
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
|
||||
mac->scc->dmrs_TypeA_Position,
|
||||
dlsch_config_pdu_1_0->number_symbols);
|
||||
dlsch_config_pdu_1_0->start_symbol+dlsch_config_pdu_1_0->number_symbols);
|
||||
dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
|
||||
/* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
|
||||
if (dlsch_config_pdu_1_0->number_symbols == 2)
|
||||
@@ -1052,12 +761,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
|
||||
dlsch_config_pdu_1_0->pucch_resource_id,
|
||||
dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind);
|
||||
|
||||
if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){
|
||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH;
|
||||
} else {
|
||||
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
|
||||
}
|
||||
|
||||
// dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP;
|
||||
|
||||
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
|
||||
@@ -1374,7 +1077,6 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
|
||||
case NR_RNTI_RA:
|
||||
case NR_RNTI_TC:
|
||||
case NR_RNTI_P:
|
||||
case NR_RNTI_SI:
|
||||
if (mac->DLbwp[0]->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero) {
|
||||
NR_BWP_Id_t bwp_id = mac->DL_BWP_Id;
|
||||
uint8_t coreset_id = 0; // assuming controlResourceSetId is 0 for controlResourceSetZero
|
||||
@@ -1384,9 +1086,12 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){
|
||||
N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
}
|
||||
break;
|
||||
case NR_RNTI_SI:
|
||||
N_RB = mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
break;
|
||||
case NR_RNTI_C:
|
||||
N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
break;
|
||||
N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
break;
|
||||
}
|
||||
return N_RB;
|
||||
|
||||
@@ -1617,23 +1322,42 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
|
||||
break;
|
||||
|
||||
case NR_RNTI_SI:
|
||||
/*
|
||||
// Freq domain assignment 0-16 bit
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
for (int i=0; i<fsize; i++)
|
||||
*dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment>>(fsize-i-1))&1)<<(dci_size-pos++);
|
||||
// Time domain assignment 4 bit
|
||||
for (int i=0; i<4; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment>>(3-i))&1)<<(dci_size-pos++);
|
||||
// VRB to PRB mapping 1 bit
|
||||
*dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&1)<<(dci_size-pos++);
|
||||
// MCS 5bit //bit over 32, so dci_pdu ++
|
||||
for (int i=0; i<5; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++);
|
||||
// Redundancy version 2bit
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++);
|
||||
*/
|
||||
|
||||
// Freq domain assignment 0-16 bit
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
pos+=fsize;
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
|
||||
|
||||
// Time domain assignment 4 bit
|
||||
pos+=4;
|
||||
dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
|
||||
|
||||
// VRB to PRB mapping 1 bit
|
||||
pos++;
|
||||
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
|
||||
// MCS 5bit //bit over 32, so dci_pdu ++
|
||||
pos+=5;
|
||||
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
|
||||
|
||||
// Redundancy version 2 bit
|
||||
pos+=2;
|
||||
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3;
|
||||
|
||||
// System information indicator 1 bit
|
||||
pos++;
|
||||
dci_pdu_rel15->system_info_indicator = (*dci_pdu>>(dci_size-pos))&0x1;
|
||||
|
||||
LOG_D(MAC,"N_RB = %i\n", N_RB);
|
||||
LOG_D(MAC,"dci_size = %i\n", dci_size);
|
||||
LOG_D(MAC,"fsize = %i\n", fsize);
|
||||
LOG_D(MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
|
||||
LOG_D(MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
|
||||
LOG_D(MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
|
||||
LOG_D(MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
|
||||
LOG_D(MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
|
||||
LOG_D(MAC,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator);
|
||||
|
||||
break;
|
||||
|
||||
case NR_RNTI_TC:
|
||||
@@ -2583,4 +2307,4 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,6 +470,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
|
||||
mask = (1 << ((int) ceil(log2((ibwp_size*(ibwp_size+1))>>1)))) - 1;
|
||||
else
|
||||
mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1;
|
||||
|
||||
f_alloc = rar_grant->Msg3_f_alloc & mask;
|
||||
nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc);
|
||||
|
||||
@@ -1580,7 +1581,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
|
||||
|
||||
// WIP Need to get the proper selected ssb_idx
|
||||
// Initial beam selection functionality is not available yet
|
||||
uint8_t selected_gnb_ssb_idx = 0;
|
||||
uint8_t selected_gnb_ssb_idx = mac->mib_ssb;
|
||||
|
||||
// Get any valid PRACH occasion in the current slot for the selected SSB index
|
||||
is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx,
|
||||
|
||||
@@ -385,6 +385,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
|
||||
if (secondaryCellGroup) {
|
||||
|
||||
RC.nrmac[Mod_idP]->secondaryCellGroupCommon = secondaryCellGroup;
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
if (add_ue == 1 && get_softmodem_params()->phy_test) {
|
||||
const int UE_id = add_new_nr_ue(Mod_idP,rnti);
|
||||
|
||||
@@ -360,7 +360,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
|
||||
}
|
||||
|
||||
const uint64_t dlsch_in_slot_bitmap = (1 << 1) | (1 << 2);
|
||||
const uint64_t dlsch_in_slot_bitmap = (1 << 1) | (1 << 3);
|
||||
const uint64_t ulsch_in_slot_bitmap = (1 << 8);
|
||||
|
||||
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
|
||||
@@ -388,6 +388,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
// This schedules MIB
|
||||
schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
|
||||
// This schedules SIB1
|
||||
if ( get_softmodem_params()->sa == 1 )
|
||||
schedule_nr_sib1(module_idP, frame, slot);
|
||||
|
||||
|
||||
// This schedule PRACH if we are not in phy_test mode
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
/* we need to make sure that resources for PRACH are free. To avoid that
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "GNB_APP/RRC_nr_paramsvalues.h"
|
||||
#include "assertions.h"
|
||||
#include "NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_MAC_gNB/mac_proto.h"
|
||||
@@ -38,21 +39,19 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "UTIL/OPT/opt.h"
|
||||
#include "OCG.h"
|
||||
#include "OCG_extern.h"
|
||||
|
||||
#include "RRC/NR/nr_rrc_extern.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
|
||||
//#include "LAYER2/MAC/pre_processor.c"
|
||||
#include "pdcp.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#define ENABLE_MAC_PAYLOAD_DEBUG
|
||||
#define DEBUG_eNB_SCHEDULER 1
|
||||
|
||||
#include "common/ran_context.h"
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern uint8_t SSB_Table[38];
|
||||
|
||||
@@ -153,6 +152,17 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
|
||||
dl_req->nPDUs++;
|
||||
}
|
||||
|
||||
// Get type0_PDCCH_CSS_config parameters
|
||||
NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms;
|
||||
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
|
||||
uint8_t gNB_xtra_byte = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
gNB_xtra_byte |= ((RC.gNB[module_idP]->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
|
||||
}
|
||||
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config, mib, gNB_xtra_byte, frame_parms->Lmax,
|
||||
frame_parms->ssb_index, frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);
|
||||
|
||||
}
|
||||
|
||||
// checking if there is any SSB in slot
|
||||
@@ -214,3 +224,284 @@ void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) {
|
||||
for (int rb = 0; rb < 20; rb++)
|
||||
vrb_map[rbStart + rb] = 1;
|
||||
}
|
||||
|
||||
void schedule_control_sib1(module_id_t module_id,
|
||||
int CC_id,
|
||||
int time_domain_allocation,
|
||||
uint8_t mcsTableIdx,
|
||||
uint8_t mcs,
|
||||
int num_total_bytes) {
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *servingcellconfigcommon = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
|
||||
if (gNB_mac->sched_ctrlCommon == NULL){
|
||||
gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon));
|
||||
gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
|
||||
gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
|
||||
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
|
||||
gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
|
||||
fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space);
|
||||
fill_default_coresetZero(gNB_mac->sched_ctrlCommon->coreset,servingcellconfigcommon);
|
||||
fill_default_initialDownlinkBWP(gNB_mac->sched_ctrlCommon->active_bwp,servingcellconfigcommon);
|
||||
}
|
||||
gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
|
||||
|
||||
gNB_mac->sched_ctrlCommon->time_domain_allocation = time_domain_allocation;
|
||||
gNB_mac->sched_ctrlCommon->mcsTableIdx = mcsTableIdx;
|
||||
gNB_mac->sched_ctrlCommon->mcs = mcs;
|
||||
gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes;
|
||||
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&gNB_mac->sched_ctrlCommon->aggregation_level, &nr_of_candidates, gNB_mac->sched_ctrlCommon->search_space);
|
||||
|
||||
gNB_mac->sched_ctrlCommon->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
gNB_mac->sched_ctrlCommon->active_bwp,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
0,
|
||||
0,
|
||||
nr_of_candidates);
|
||||
|
||||
if (gNB_mac->sched_ctrlCommon->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
|
||||
// Calculate number of symbols
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
if (nrOfSymbols == 2) {
|
||||
gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 1;
|
||||
} else {
|
||||
gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 2;
|
||||
}
|
||||
|
||||
// Calculate number of PRB_DMRS
|
||||
uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
|
||||
uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
|
||||
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
|
||||
|
||||
int rbSize = 0;
|
||||
uint32_t TBS = 0;
|
||||
do {
|
||||
rbSize++;
|
||||
TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3;
|
||||
|
||||
// FIXME: Something is not working in nr_modulation() for TBS = 84, so we need to skip it
|
||||
} while ( (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes) || (TBS==84) );
|
||||
|
||||
gNB_mac->sched_ctrlCommon->rbSize = rbSize;
|
||||
gNB_mac->sched_ctrlCommon->rbStart = 0;
|
||||
|
||||
LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength);
|
||||
LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex);
|
||||
LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols);
|
||||
LOG_D(MAC,"rbSize = %i\n", gNB_mac->sched_ctrlCommon->rbSize);
|
||||
LOG_D(MAC,"TBS = %i\n", TBS);
|
||||
|
||||
// Mark the corresponding RBs as used
|
||||
for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->rbSize; rb++) {
|
||||
vrb_map[rb + rbStart] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
uint32_t TBS,
|
||||
int StartSymbolIndex,
|
||||
int NrOfSymbols) {
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
|
||||
NR_COMMON_channels_t *cc = gNB_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = gNB_mac->secondaryCellGroupCommon;
|
||||
NR_BWP_Downlink_t *bwp = gNB_mac->sched_ctrlCommon->active_bwp;
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
|
||||
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
|
||||
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
|
||||
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
|
||||
|
||||
pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
|
||||
|
||||
pdsch_pdu_rel15->pduBitmap = 0;
|
||||
pdsch_pdu_rel15->rnti = SI_RNTI;
|
||||
pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
|
||||
|
||||
pdsch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
|
||||
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
if (bwp->bwp_Common->genericParameters.cyclicPrefix) {
|
||||
pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix;
|
||||
} else {
|
||||
pdsch_pdu_rel15->CyclicPrefix = 0;
|
||||
}
|
||||
|
||||
pdsch_pdu_rel15->NrOfCodewords = 1;
|
||||
pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs,0);
|
||||
pdsch_pdu_rel15->qamModOrder[0] = 2;
|
||||
pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->mcs;
|
||||
pdsch_pdu_rel15->mcsTable[0] = 0;
|
||||
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0];
|
||||
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->nrOfLayers = 1;
|
||||
pdsch_pdu_rel15->transmissionScheme = 0;
|
||||
pdsch_pdu_rel15->refPoint = 1;
|
||||
pdsch_pdu_rel15->dmrsConfigType = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
|
||||
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
|
||||
pdsch_pdu_rel15->SCID = 0;
|
||||
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData;
|
||||
pdsch_pdu_rel15->dmrsPorts = 1;
|
||||
pdsch_pdu_rel15->resourceAlloc = 1;
|
||||
pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->rbStart;
|
||||
pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->rbSize;
|
||||
pdsch_pdu_rel15->VRBtoPRBMapping = 0;
|
||||
pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx);
|
||||
pdsch_pdu_rel15->TBSize[0] = TBS;
|
||||
pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->mcsTableIdx;
|
||||
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
|
||||
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
|
||||
|
||||
pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->StartSymbolIndex+pdsch_pdu_rel15->NrOfSymbols);
|
||||
|
||||
LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos);
|
||||
|
||||
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
|
||||
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET);
|
||||
|
||||
dci_pdu_rel15[0].bwp_indicator.val = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id;
|
||||
|
||||
// frequency domain assignment
|
||||
dci_pdu_rel15[0].frequency_domain_assignment.val =
|
||||
PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
gNB_mac->type0_PDCCH_CSS_config.num_rbs);
|
||||
|
||||
dci_pdu_rel15[0].time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
|
||||
dci_pdu_rel15[0].mcs = gNB_mac->sched_ctrlCommon->mcs;
|
||||
dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0];
|
||||
dci_pdu_rel15[0].harq_pid = 0;
|
||||
dci_pdu_rel15[0].ndi = 0;
|
||||
dci_pdu_rel15[0].dai[0].val = 0;
|
||||
dci_pdu_rel15[0].tpc = 0; // table 7.2.1-1 in 38.213
|
||||
dci_pdu_rel15[0].pucch_resource_indicator = 0;
|
||||
dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = 0;
|
||||
dci_pdu_rel15[0].antenna_ports.val = 0;
|
||||
dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID;
|
||||
|
||||
nr_configure_pdcch(gNB_mac,
|
||||
pdcch_pdu_rel15,
|
||||
SI_RNTI,
|
||||
gNB_mac->sched_ctrlCommon->search_space,
|
||||
gNB_mac->sched_ctrlCommon->coreset,
|
||||
scc,
|
||||
bwp,
|
||||
gNB_mac->sched_ctrlCommon->aggregation_level,
|
||||
gNB_mac->sched_ctrlCommon->cce_index);
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
dci_formats[0] = NR_DL_DCI_FORMAT_1_0;
|
||||
rnti_types[0] = NR_RNTI_SI;
|
||||
|
||||
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id);
|
||||
|
||||
dl_req->nPDUs += 2;
|
||||
|
||||
LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
|
||||
LOG_D(MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
|
||||
LOG_D(MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing);
|
||||
LOG_D(MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix);
|
||||
LOG_D(MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex);
|
||||
LOG_D(MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols);
|
||||
for(int n=0;n<6;n++) LOG_D(MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]);
|
||||
LOG_D(MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType);
|
||||
LOG_D(MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize);
|
||||
LOG_D(MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize);
|
||||
LOG_D(MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType);
|
||||
LOG_D(MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex);
|
||||
LOG_D(MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity);
|
||||
LOG_D(MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
|
||||
|
||||
}
|
||||
|
||||
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
|
||||
LOG_D(MAC,"Schedule_nr_sib1: frameP = %i, slotP = %i\n", frameP, slotP);
|
||||
|
||||
// TODO: Get these values from RRC
|
||||
const int CC_id = 0;
|
||||
int time_domain_allocation = 0;
|
||||
uint8_t mcsTableIdx = 0;
|
||||
uint8_t mcs = 6;
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
|
||||
|
||||
if( (frameP%2 == gNB_mac->type0_PDCCH_CSS_config.sfn_c) && (slotP == gNB_mac->type0_PDCCH_CSS_config.n_0) && (gNB_mac->type0_PDCCH_CSS_config.num_rbs > 0) ) {
|
||||
|
||||
LOG_D(MAC,"> SIB1 transmission\n");
|
||||
|
||||
// Get SIB1
|
||||
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
|
||||
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
|
||||
LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
|
||||
LOG_D(MAC,"SIB1: \n");
|
||||
for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
|
||||
|
||||
// Configure sched_ctrlCommon for SIB1
|
||||
schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, sib1_sdu_length);
|
||||
|
||||
// Calculate number of symbols
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
// Calculate number of PRB_DMRS
|
||||
uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
|
||||
uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
|
||||
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
|
||||
|
||||
const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols);
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
|
||||
// Data to be transmitted
|
||||
bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
|
||||
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
|
||||
|
||||
tx_req->PDU_length = TBS;
|
||||
tx_req->PDU_index = gNB_mac->pdu_index[0]++;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frameP;
|
||||
gNB_mac->TX_req[CC_id].Slot = slotP;
|
||||
}
|
||||
}
|
||||
@@ -424,8 +424,7 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /*dedicated*/);
|
||||
int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
|
||||
@@ -395,8 +395,12 @@ void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
|
||||
return;
|
||||
|
||||
const uint16_t rbStart = 0;
|
||||
const uint16_t rbSize = 50; /* due to OAI UE limitations */
|
||||
const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
uint16_t rbStart = 0;
|
||||
uint16_t rbSize = 50; /* due to OAI UE limitations */
|
||||
if (rbSize>bw)
|
||||
rbSize = bw;
|
||||
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
|
||||
for (int i = rbStart; i < rbStart + rbSize; ++i) {
|
||||
|
||||
@@ -176,7 +176,13 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
// NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
|
||||
int coreset_id = coreset->controlResourceSetId;
|
||||
int *cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
|
||||
|
||||
int *cce_list;
|
||||
if(bwp->bwp_Id == 0) {
|
||||
cce_list = nr_mac->cce_list[1][0];
|
||||
} else {
|
||||
cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
|
||||
}
|
||||
|
||||
int n_rb=0;
|
||||
for (int i=0;i<6;i++)
|
||||
@@ -191,12 +197,9 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
const uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE;
|
||||
const uint16_t M_s_max = nr_of_candidates;
|
||||
|
||||
AssertFatal(m < nr_of_candidates,
|
||||
"PDCCH candidate index %d in CORESET %d exceeds the maximum "
|
||||
"number of PDCCH candidates (%d)\n",
|
||||
m,
|
||||
coreset_id,
|
||||
nr_of_candidates);
|
||||
//PDCCH candidate index m in CORESET exceeds the maximum number of PDCCH candidates
|
||||
if(m >= nr_of_candidates)
|
||||
return -1;
|
||||
|
||||
int first_cce = aggregation * (( Y + CEILIDIV((m*N_cce),(aggregation*M_s_max)) + n_CI ) % CEILIDIV(N_cce,aggregation));
|
||||
|
||||
@@ -833,8 +836,12 @@ void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
pdcch_pdu->ShiftIndex = 0;
|
||||
}
|
||||
|
||||
pdcch_pdu->CoreSetType = 1;
|
||||
|
||||
if(coreset->controlResourceSetId == 0) {
|
||||
pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
|
||||
} else{
|
||||
pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG;
|
||||
}
|
||||
|
||||
//precoderGranularity
|
||||
pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
|
||||
|
||||
@@ -1329,22 +1336,42 @@ void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc,
|
||||
break;
|
||||
|
||||
case NR_RNTI_SI:
|
||||
// Freq domain assignment 0-16 bit
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
for (int i=0; i<fsize; i++)
|
||||
*dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val>>(fsize-i-1))&1)<<(dci_size-pos++);
|
||||
// Time domain assignment 4 bit
|
||||
for (int i=0; i<4; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val>>(3-i))&1)<<(dci_size-pos++);
|
||||
// VRB to PRB mapping 1 bit
|
||||
*dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&1)<<(dci_size-pos++);
|
||||
// MCS 5bit //bit over 32, so dci_pdu ++
|
||||
for (int i=0; i<5; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++);
|
||||
// Redundancy version 2bit
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++);
|
||||
|
||||
pos=1;
|
||||
|
||||
// Freq domain assignment 0-16 bit
|
||||
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
|
||||
for (int i=0; i<fsize; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val>>(fsize-1-i))&1)<<(dci_size-pos++);
|
||||
|
||||
// Time domain assignment 4 bit
|
||||
for (int i=0; i<4; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val>>(3-i))&1)<<(dci_size-pos++);
|
||||
|
||||
// VRB to PRB mapping 1 bit
|
||||
*dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&1)<<(dci_size-pos++);
|
||||
|
||||
// MCS 5bit //bit over 32, so dci_pdu ++
|
||||
for (int i=0; i<5; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->mcs>>(4-i))&1)<<(dci_size-pos++);
|
||||
|
||||
// Redundancy version 2 bit
|
||||
for (int i=0; i<2; i++)
|
||||
*dci_pdu |= (((uint64_t)dci_pdu_rel15->rv>>(1-i))&1)<<(dci_size-pos++);
|
||||
|
||||
// System information indicator 1bit
|
||||
*dci_pdu |= ((uint64_t)dci_pdu_rel15->system_info_indicator&1)<<(dci_size-pos++);
|
||||
|
||||
// reserved 15 bits
|
||||
|
||||
LOG_D(PHY,"dci_size = %i\n", dci_size);
|
||||
LOG_D(PHY,"fsize = %i\n", fsize);
|
||||
LOG_D(PHY,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
|
||||
LOG_D(PHY,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
|
||||
LOG_D(PHY,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
|
||||
LOG_D(PHY,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
|
||||
LOG_D(PHY,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
|
||||
LOG_D(PHY,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator);
|
||||
|
||||
break;
|
||||
|
||||
case NR_RNTI_TC:
|
||||
@@ -1994,32 +2021,6 @@ void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
}
|
||||
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss) {
|
||||
|
||||
if (ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0) {
|
||||
*aggregation_level = 1;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel1;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel2 != NR_SearchSpace__nrofCandidates__aggregationLevel2_n0) {
|
||||
*aggregation_level = 2;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel2;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel4 != NR_SearchSpace__nrofCandidates__aggregationLevel4_n0) {
|
||||
*aggregation_level = 4;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel4;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel8 != NR_SearchSpace__nrofCandidates__aggregationLevel8_n0) {
|
||||
*aggregation_level = 8;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel8;
|
||||
}
|
||||
if (ss->nrofCandidates->aggregationLevel16 != NR_SearchSpace__nrofCandidates__aggregationLevel16_n0) {
|
||||
*aggregation_level = 16;
|
||||
*nr_of_candidates = ss->nrofCandidates->aggregationLevel16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*void fill_nfapi_coresets_and_searchspaces(NR_CellGroupConfig_t *cg,
|
||||
nfapi_nr_coreset_t *coreset,
|
||||
|
||||
@@ -80,6 +80,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
|
||||
void schedule_control_sib1(module_id_t module_id,
|
||||
int CC_id,
|
||||
int time_domain_allocation,
|
||||
uint8_t mcsTableIdx,
|
||||
uint8_t mcs,
|
||||
int num_total_bytes);
|
||||
|
||||
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
|
||||
|
||||
/* \brief default preprocessor */
|
||||
void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
@@ -296,9 +305,6 @@ NR_SearchSpace_t *get_searchspace(
|
||||
NR_BWP_Downlink_t *bwp,
|
||||
NR_SearchSpace__searchSpaceType_PR target_ss);
|
||||
|
||||
void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
|
||||
/* MAC */
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "NR_TAG.h"
|
||||
@@ -552,6 +554,11 @@ typedef struct gNB_MAC_INST_s {
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
/// UL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_ul pre_processor_ul;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrlCommon;
|
||||
NR_CellGroupConfig_t *secondaryCellGroupCommon;
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
||||
|
||||
} gNB_MAC_INST;
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_GNB_H__ */
|
||||
|
||||
@@ -13,6 +13,3 @@ RLC AM
|
||||
- 36.322 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception
|
||||
buffer
|
||||
[...] and in-sequence byte segments of the AMD PDU with SN = VR(R) [...]
|
||||
|
||||
- use SOstart/SOend in NACK reporting, do not NACK full PDU if
|
||||
parts of it have been received
|
||||
|
||||
@@ -898,6 +898,64 @@ static tx_pdu_size_t compute_new_pdu_size(rlc_entity_am_t *entity, int maxsize)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return number of missing parts of a sn
|
||||
* if everything is missing (nothing received), return 0
|
||||
*/
|
||||
static int count_nack_missing_parts(rlc_entity_am_t *entity, int sn)
|
||||
{
|
||||
rlc_rx_pdu_segment_t *l = entity->rx_list;
|
||||
int last_byte;
|
||||
int new_last_byte;
|
||||
int count;
|
||||
|
||||
while (l != NULL) {
|
||||
if (l->sn == sn)
|
||||
break;
|
||||
l = l->next;
|
||||
}
|
||||
/* nothing received, everything is missing, return 0 */
|
||||
if (l == NULL)
|
||||
return 0;
|
||||
|
||||
last_byte = -1;
|
||||
count = 0;
|
||||
while (l != NULL && l->sn == sn) {
|
||||
if (l->so > last_byte + 1)
|
||||
/* missing part detected */
|
||||
count++;
|
||||
if (l->is_last)
|
||||
/* end of PDU reached - no more missing part to add */
|
||||
return count;
|
||||
new_last_byte = l->so + l->size - l->data_offset - 1;
|
||||
if (new_last_byte > last_byte)
|
||||
last_byte = new_last_byte;
|
||||
l = l->next;
|
||||
}
|
||||
/* at this point: end of PDU not received, one more missing part */
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* return size of nack reporting for sn, in bits */
|
||||
static int segment_nack_size(rlc_entity_am_t *entity, int sn)
|
||||
{
|
||||
/* nack + e1 + e2 = 12 bits
|
||||
* SOstart + SOend = 30 bits
|
||||
*/
|
||||
int count;
|
||||
|
||||
count = count_nack_missing_parts(entity, sn);
|
||||
|
||||
/* count_nack_missing_parts returns 0 when everything is missing
|
||||
* in which case we don't have SOstart/SOend, so only 12 bits
|
||||
*/
|
||||
if (count == 0)
|
||||
return 12;
|
||||
|
||||
return count * (12 + 30);
|
||||
}
|
||||
|
||||
static int status_size(rlc_entity_am_t *entity, int maxsize)
|
||||
{
|
||||
/* let's count bits */
|
||||
@@ -912,11 +970,16 @@ static int status_size(rlc_entity_am_t *entity, int maxsize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* each NACK adds 12 bits */
|
||||
/* add size of NACKs */
|
||||
sn = entity->vr_r;
|
||||
while (bits + 12 <= maxsize && sn_compare_rx(entity, sn, entity->vr_ms) < 0) {
|
||||
if (!(rlc_am_segment_full(entity, sn)))
|
||||
bits += 12;
|
||||
while (sn_compare_rx(entity, sn, entity->vr_ms) < 0) {
|
||||
if (!(rlc_am_segment_full(entity, sn))) {
|
||||
int nack_size = segment_nack_size(entity, sn);
|
||||
/* stop there if not enough room */
|
||||
if (bits + nack_size > maxsize)
|
||||
break;
|
||||
bits += nack_size;
|
||||
}
|
||||
sn = (sn + 1) % 1024;
|
||||
}
|
||||
|
||||
@@ -929,7 +992,8 @@ static int generate_status(rlc_entity_am_t *entity, char *buffer, int size)
|
||||
int bits = 15; /* minimum size is 15 (header+ack_sn+e1) */
|
||||
int sn;
|
||||
rlc_pdu_encoder_t encoder;
|
||||
int has_nack = 0;
|
||||
rlc_pdu_encoder_t encoder_ack;
|
||||
rlc_pdu_encoder_t previous_e1;
|
||||
int ack;
|
||||
|
||||
rlc_pdu_encoder_init(&encoder, buffer, size);
|
||||
@@ -947,24 +1011,68 @@ static int generate_status(rlc_entity_am_t *entity, char *buffer, int size)
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 3); /* CPT */
|
||||
|
||||
/* reserve room for ACK (it will be set after putting the NACKs) */
|
||||
encoder_ack = encoder;
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 10);
|
||||
/* put 0 for e1, will be set to 1 later in the code if needed */
|
||||
previous_e1 = encoder;
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 1);
|
||||
|
||||
/* at this point, ACK is VR(R) */
|
||||
ack = entity->vr_r;
|
||||
|
||||
/* each NACK adds 12 bits */
|
||||
sn = entity->vr_r;
|
||||
while (bits + 12 <= size && sn_compare_rx(entity, sn, entity->vr_ms) < 0) {
|
||||
while (sn_compare_rx(entity, sn, entity->vr_ms) < 0) {
|
||||
if (!(rlc_am_segment_full(entity, sn))) {
|
||||
/* put previous e1 (is 1) */
|
||||
rlc_pdu_encoder_put_bits(&encoder, 1, 1);
|
||||
/* if previous was NACK, put previous e2 (0, we don't do 'so' thing) */
|
||||
if (has_nack)
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 1);
|
||||
/* put NACKed sn */
|
||||
rlc_pdu_encoder_put_bits(&encoder, sn, 10);
|
||||
has_nack = 1;
|
||||
bits += 12;
|
||||
rlc_rx_pdu_segment_t *l;
|
||||
int i;
|
||||
int count = count_nack_missing_parts(entity, sn);
|
||||
int nack_bits = count == 0 ? 12 : count * (12 + 30);
|
||||
int last_byte;
|
||||
int new_last_byte;
|
||||
int so_start;
|
||||
int so_end;
|
||||
/* if not enough room, stop putting NACKs */
|
||||
if (bits + nack_bits > size)
|
||||
break;
|
||||
/* set previous e1 to 1 */
|
||||
rlc_pdu_encoder_put_bits(&previous_e1, 1, 1);
|
||||
|
||||
if (count == 0) {
|
||||
/* simply NACK, no SOstart/SOend */
|
||||
rlc_pdu_encoder_put_bits(&encoder, sn, 10); /* nack */
|
||||
previous_e1 = encoder;
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 2); /* e1, e2 */
|
||||
} else {
|
||||
/* count is not 0, so we have 'count' NACK+e1+e2+SOstart+SOend */
|
||||
l = entity->rx_list;
|
||||
last_byte = -1;
|
||||
while (l->sn != sn) l = l->next;
|
||||
for (i = 0; i < count; i++) {
|
||||
rlc_pdu_encoder_put_bits(&encoder, sn, 10); /* nack */
|
||||
previous_e1 = encoder;
|
||||
/* all NACKs but the last have a following NACK, set e1 for them */
|
||||
rlc_pdu_encoder_put_bits(&encoder, i != count - 1, 1); /* e1 */
|
||||
rlc_pdu_encoder_put_bits(&encoder, 1, 1); /* e2 */
|
||||
/* look for the next segment with missing data before it */
|
||||
while (l != NULL && l->sn == sn && !(l->so > last_byte + 1)) {
|
||||
new_last_byte = l->so + l->size - l->data_offset - 1;
|
||||
if (new_last_byte > last_byte)
|
||||
last_byte = new_last_byte;
|
||||
l = l->next;
|
||||
}
|
||||
so_start = last_byte + 1;
|
||||
if (l == NULL)
|
||||
so_end = 0x7fff;
|
||||
else
|
||||
so_end = l->so - 1;
|
||||
rlc_pdu_encoder_put_bits(&encoder, so_start, 15);
|
||||
rlc_pdu_encoder_put_bits(&encoder, so_end, 15);
|
||||
if (l != NULL)
|
||||
last_byte = l->so + l->size - l->data_offset - 1;
|
||||
}
|
||||
}
|
||||
|
||||
bits += nack_bits;
|
||||
} else {
|
||||
/* this sn is full and we put all NACKs before it, use it for ACK */
|
||||
ack = (sn + 1) % 1024;
|
||||
@@ -972,24 +1080,10 @@ static int generate_status(rlc_entity_am_t *entity, char *buffer, int size)
|
||||
sn = (sn + 1) % 1024;
|
||||
}
|
||||
|
||||
/* go to highest full sn+1 for ACK, VR(MS) is the limit */
|
||||
while (sn_compare_rx(entity, sn, entity->vr_ms) < 0 &&
|
||||
rlc_am_segment_full(entity, sn)) {
|
||||
ack = (sn + 1) % 1024;
|
||||
sn = (sn + 1) % 1024;
|
||||
}
|
||||
|
||||
/* at this point, if last put was NACK then put 2 bits else put 1 bit */
|
||||
if (has_nack)
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 2);
|
||||
else
|
||||
rlc_pdu_encoder_put_bits(&encoder, 0, 1);
|
||||
|
||||
rlc_pdu_encoder_align(&encoder);
|
||||
|
||||
/* let's put the ACK */
|
||||
buffer[0] |= ack >> 6;
|
||||
buffer[1] |= (ack & 0x3f) << 2;
|
||||
rlc_pdu_encoder_put_bits(&encoder_ack, ack, 10);
|
||||
|
||||
/* reset the trigger */
|
||||
entity->status_triggered = 0;
|
||||
|
||||
@@ -233,9 +233,10 @@ static void put_bit(rlc_pdu_encoder_t *encoder, int bit)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
encoder->buffer[encoder->byte] <<= 1;
|
||||
if (bit)
|
||||
encoder->buffer[encoder->byte] |= 1;
|
||||
encoder->buffer[encoder->byte] |= 1 << (7 - encoder->bit);
|
||||
else
|
||||
encoder->buffer[encoder->byte] &= ~(1 << (7 - encoder->bit));
|
||||
|
||||
encoder->bit++;
|
||||
if (encoder->bit == 8) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_count=45
|
||||
test_count=49
|
||||
|
||||
for i in `seq $test_count`
|
||||
do
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* rlc am test ack/nack reporting with segmented SDUs
|
||||
* eNB sends SDU in big PDU, not received
|
||||
* eNB retx with smaller PDUs, not received except a few
|
||||
* after some time, RX works again, UE should NACK with SOstart/SOend
|
||||
*
|
||||
* this test was written because in the past we didn't generate NACKs with
|
||||
* SOstart/SOend, potentially leading to infinite retransmissions, even with
|
||||
* good radio conditions (well, there will be max ReTX reached at some point).
|
||||
* The scenario is as follows:
|
||||
* the eNB transmits many many PDUs segments and asks for status
|
||||
* report at some point (but before sending all the segments). The UE then
|
||||
* generates a (wrong) NACK without SOstart/SOend, and then the eNB has to
|
||||
* resend everything from start (all bytes of the PDU have been NACKed because
|
||||
* there is no SOstart/SOend). Then the eNB will again ask for status report
|
||||
* before sending everything and the process repeats all over again.
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
UE_RECV_FAILS, 1,
|
||||
ENB_RECV_FAILS, 1,
|
||||
ENB_SDU, 0, 300,
|
||||
ENB_PDU_SIZE, 500,
|
||||
UE_PDU_SIZE, 1000,
|
||||
TIME, 2,
|
||||
ENB_PDU_SIZE, 7,
|
||||
TIME, 50,
|
||||
UE_RECV_FAILS, 0,
|
||||
TIME, 51,
|
||||
UE_RECV_FAILS, 1,
|
||||
TIME, 60,
|
||||
UE_RECV_FAILS, 0,
|
||||
TIME, 61,
|
||||
UE_RECV_FAILS, 1,
|
||||
TIME, 70,
|
||||
UE_RECV_FAILS, 0,
|
||||
TIME, 71,
|
||||
UE_RECV_FAILS, 1,
|
||||
TIME, 80,
|
||||
UE_RECV_FAILS, 0,
|
||||
TIME, 81,
|
||||
UE_RECV_FAILS, 1,
|
||||
TIME, 140,
|
||||
UE_RECV_FAILS, 0,
|
||||
ENB_RECV_FAILS, 0,
|
||||
TIME, 150,
|
||||
ENB_PDU_SIZE, 200,
|
||||
TIME, -1
|
||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* am: test function segment_nack_size, case "if (count == 0) return 12;"
|
||||
* The eNB sends 5 PDUs, only first and last received by the UE. Then we
|
||||
* ask for the UE's buffer status to trigger the case.
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
ENB_RECV_FAILS, 1,
|
||||
ENB_PDU_SIZE, 100,
|
||||
UE_PDU_SIZE, 100,
|
||||
TIME, 2,
|
||||
ENB_SDU, 0, 10,
|
||||
TIME, 3,
|
||||
UE_RECV_FAILS, 1,
|
||||
ENB_SDU, 1, 10,
|
||||
TIME, 4,
|
||||
ENB_SDU, 2, 10,
|
||||
TIME, 5,
|
||||
ENB_SDU, 3, 10,
|
||||
TIME, 6,
|
||||
UE_RECV_FAILS, 0,
|
||||
ENB_RECV_FAILS, 0,
|
||||
ENB_SDU, 4, 10,
|
||||
TIME, 42,
|
||||
UE_BUFFER_STATUS,
|
||||
TIME, -1
|
||||
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* am: test case "if (bits + nack_size > maxsize)" in functions status_size
|
||||
* and generate_status.
|
||||
* The eNB sends 5 PDUs, only first and last received by the UE. Then we
|
||||
* ask for the UE's buffer status to trigger the case. UE PDU size is
|
||||
* limited to 6 to trigger the case.
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
ENB_RECV_FAILS, 1,
|
||||
ENB_PDU_SIZE, 100,
|
||||
UE_PDU_SIZE, 6,
|
||||
TIME, 2,
|
||||
ENB_SDU, 0, 10,
|
||||
TIME, 3,
|
||||
UE_RECV_FAILS, 1,
|
||||
ENB_SDU, 1, 10,
|
||||
TIME, 4,
|
||||
ENB_SDU, 2, 10,
|
||||
TIME, 5,
|
||||
ENB_SDU, 3, 10,
|
||||
TIME, 6,
|
||||
UE_RECV_FAILS, 0,
|
||||
ENB_RECV_FAILS, 0,
|
||||
ENB_SDU, 4, 10,
|
||||
TIME, 42,
|
||||
UE_BUFFER_STATUS,
|
||||
TIME, -1
|
||||
Binary file not shown.
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* rlc am test ack/nack reporting with segmented SDUs
|
||||
*
|
||||
* 5 SDUs put into 6 PDUs, all PDUs received expect the 3rd. Then
|
||||
* retransmission happens with smaller PDU size.
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
ENB_SDU, 0, 60,
|
||||
ENB_SDU, 1, 160,
|
||||
ENB_SDU, 2, 130,
|
||||
ENB_SDU, 3, 120,
|
||||
ENB_SDU, 4, 100,
|
||||
ENB_PDU_SIZE, 100,
|
||||
UE_PDU_SIZE, 1000,
|
||||
TIME, 3,
|
||||
UE_RECV_FAILS, 1,
|
||||
TIME, 4,
|
||||
UE_RECV_FAILS, 0,
|
||||
TIME, 7,
|
||||
ENB_PDU_SIZE, 40,
|
||||
TIME, 42,
|
||||
UE_RECV_FAILS, 1,
|
||||
TIME, 80,
|
||||
UE_RECV_FAILS, 0,
|
||||
TIME, -1
|
||||
Binary file not shown.
@@ -5,9 +5,6 @@
|
||||
* [1..600] is received but ACK/NACK not
|
||||
* eNB retx with still smaller PDUs [1..400] [401..600] [601..900]
|
||||
* all is received, ACKs/NACKs go through
|
||||
*
|
||||
* this test will fail if NACK mechanism uses SOstart/SOend
|
||||
* (not implemented for the moment)
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
|
||||
Binary file not shown.
@@ -6,9 +6,6 @@
|
||||
* eNB retx with still smaller PDUs [1..400] [401..600] [601..900]
|
||||
* [401..600] received, ACK goes through
|
||||
* link clean, all goes through
|
||||
*
|
||||
* this test will fail if NACK mechanism uses SOstart/SOend
|
||||
* (not implemented for the moment)
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
|
||||
Binary file not shown.
@@ -11,9 +11,6 @@
|
||||
* In the current RLC implementation, this is impossible. If we send [12..21]
|
||||
* it means [1..21] has been split and so we won't sent it later on.
|
||||
* Maybe with HARQ retransmissions in PHY/MAC in bad radio conditions?
|
||||
*
|
||||
* this test will fail if NACK mechanism uses SOstart/SOend
|
||||
* (not implemented for the moment)
|
||||
*/
|
||||
TIME, 1,
|
||||
ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4,
|
||||
|
||||
Binary file not shown.
@@ -62,9 +62,9 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui
|
||||
|
||||
// L2 Abstraction Layer
|
||||
int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len){
|
||||
|
||||
return 0;
|
||||
return nr_ue_decode_sib1(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len);
|
||||
}
|
||||
|
||||
// L2 Abstraction Layer
|
||||
int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci){
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "pdcp.h"
|
||||
#include "msc.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
@@ -43,6 +45,103 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
int generate_pdcch_ConfigSIB1(NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1,
|
||||
long ssbSubcarrierSpacing,
|
||||
long subCarrierSpacingCommon,
|
||||
channel_bandwidth_t min_channel_bw) {
|
||||
|
||||
nr_ssb_and_cset_mux_pattern_type_t mux_pattern = 0;
|
||||
|
||||
switch (ssbSubcarrierSpacing) {
|
||||
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_1_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_1_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_2_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_2_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_SubcarrierSpacing_kHz30:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) {
|
||||
|
||||
if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_3_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_3_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (min_channel_bw == bw_40MHz) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_5_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_5_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid min_bandwidth\n");
|
||||
}
|
||||
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) {
|
||||
|
||||
if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_4_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_4_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (min_channel_bw == bw_40MHz) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_6_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_6_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid min_bandwidth\n");
|
||||
}
|
||||
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_SubcarrierSpacing_kHz120:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_7_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_7_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_8_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_8_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_SubcarrierSpacing_kHz240:
|
||||
if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_9_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_9_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) {
|
||||
pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_10_NUM_INDEXES;
|
||||
mux_pattern = table_38213_13_10_c1[pdcch_ConfigSIB1->controlResourceSetZero];
|
||||
} else {
|
||||
AssertFatal(true,"Invalid subCarrierSpacingCommon\n");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(true,"Invalid ssbSubcarrierSpacing\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
frequency_range_t frequency_range = FR1;
|
||||
if(ssbSubcarrierSpacing>=60) {
|
||||
frequency_range = FR2;
|
||||
}
|
||||
|
||||
pdcch_ConfigSIB1->searchSpaceZero = 0;
|
||||
if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR1){
|
||||
pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_11_NUM_INDEXES;
|
||||
}
|
||||
if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR2){
|
||||
pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_12_NUM_INDEXES;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nr_rrc_mac_remove_ue(module_id_t mod_idP,
|
||||
rnti_t rntiP){
|
||||
@@ -129,41 +228,54 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
|
||||
LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
|
||||
#endif
|
||||
|
||||
gNB_RRC_INST *rrc;
|
||||
rrc_gNB_carrier_data_t *carrier;
|
||||
NR_BCCH_BCH_Message_t *mib;
|
||||
NR_SRB_INFO * srb_info;
|
||||
char payload_size, *payload_pP;
|
||||
|
||||
rrc = RC.nrrrc[Mod_idP];
|
||||
carrier = &rrc->carrier;
|
||||
mib = &carrier->mib;
|
||||
srb_info = &carrier->Srb0;
|
||||
rrc_gNB_carrier_data_t *carrier;
|
||||
NR_BCCH_BCH_Message_t *mib;
|
||||
NR_SRB_INFO *srb_info;
|
||||
char payload_size, *payload_pP;
|
||||
|
||||
/* MIBCH */
|
||||
if( (Srb_id & RAB_OFFSET ) == MIBCH) {
|
||||
mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2;
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message,
|
||||
NULL,
|
||||
(void *)mib,
|
||||
carrier->MIB,
|
||||
24);
|
||||
LOG_D(NR_RRC,"Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n",frameP,sfn_msb,carrier->MIB,enc_rval.encoded);
|
||||
buffer_pP[0]=carrier->MIB[0];
|
||||
buffer_pP[1]=carrier->MIB[1];
|
||||
buffer_pP[2]=carrier->MIB[2];
|
||||
LOG_D(NR_RRC,"MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n",buffer_pP[0],buffer_pP[1],buffer_pP[2]);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return(3);
|
||||
}
|
||||
carrier = &RC.nrrrc[Mod_idP]->carrier;
|
||||
mib = &carrier->mib;
|
||||
srb_info = &carrier->Srb0;
|
||||
|
||||
/* MIBCH */
|
||||
if ((Srb_id & RAB_OFFSET) == MIBCH) {
|
||||
|
||||
// Currently we are getting the pdcch_ConfigSIB1 from the configuration file.
|
||||
// Uncomment this function for a dynamic pdcch_ConfigSIB1.
|
||||
//channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1
|
||||
//generate_pdcch_ConfigSIB1(carrier->pdcch_ConfigSIB1,
|
||||
// *carrier->servingcellconfigcommon->ssbSubcarrierSpacing,
|
||||
// carrier->mib.message.choice.mib->subCarrierSpacingCommon,
|
||||
// min_channel_bw);
|
||||
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = carrier->pdcch_ConfigSIB1->controlResourceSetZero;
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = carrier->pdcch_ConfigSIB1->searchSpaceZero;
|
||||
|
||||
mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2;
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message,
|
||||
NULL,
|
||||
(void *) mib,
|
||||
carrier->MIB,
|
||||
24);
|
||||
LOG_D(NR_RRC, "Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n", frameP, sfn_msb, carrier->MIB,
|
||||
enc_rval.encoded);
|
||||
buffer_pP[0] = carrier->MIB[0];
|
||||
buffer_pP[1] = carrier->MIB[1];
|
||||
buffer_pP[2] = carrier->MIB[2];
|
||||
LOG_D(NR_RRC, "MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n", buffer_pP[0], buffer_pP[1],
|
||||
buffer_pP[2]);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
return (3);
|
||||
}
|
||||
|
||||
/* TODO BCCH SIB1 SIBs */
|
||||
if ((Srb_id & RAB_OFFSET ) == BCCH) {
|
||||
memcpy(&buffer_pP[0],
|
||||
RC.rrc[Mod_idP]->carrier[CC_id].SIB1_MBMS,
|
||||
RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_MBMS);
|
||||
memcpy(&buffer_pP[0],
|
||||
RC.nrrrc[Mod_idP]->carrier.SIB1,
|
||||
RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1);
|
||||
|
||||
return RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1;
|
||||
}
|
||||
|
||||
/* CCCH */
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include "NR_SDAP-Config.h"
|
||||
#include "NR_RRCReconfigurationComplete.h"
|
||||
#include "NR_RRCReconfigurationComplete-IEs.h"
|
||||
#include "PHY/defs_nr_common.h"
|
||||
#if defined(NR_Rel16)
|
||||
#include "NR_SCS-SpecificCarrier.h"
|
||||
#include "NR_TDD-UL-DL-ConfigCommon.h"
|
||||
@@ -226,12 +227,19 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
|
||||
mib->message.choice.mib->spare.bits_unused = 7; // This makes a spare of 1 bits
|
||||
|
||||
mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15;
|
||||
|
||||
/*
|
||||
* The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables
|
||||
* the reverse allocation is in nr_ue_decode_mib()
|
||||
*/
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero;
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero;
|
||||
* The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables
|
||||
* the reverse allocation is in nr_ue_decode_mib()
|
||||
*/
|
||||
if(rrc->carrier.pdcch_ConfigSIB1) {
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = rrc->carrier.pdcch_ConfigSIB1->controlResourceSetZero;
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = rrc->carrier.pdcch_ConfigSIB1->searchSpaceZero;
|
||||
} else {
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero;
|
||||
mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero;
|
||||
}
|
||||
|
||||
AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n");
|
||||
switch (*scc->ssbSubcarrierSpacing) {
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
@@ -297,27 +305,28 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
asn_enc_rval_t enc_rval;
|
||||
|
||||
// TODO : Add support for more than one PLMN
|
||||
//int num_plmn = configuration->num_plmn;
|
||||
int num_plmn = 1;
|
||||
int num_plmn = 1; // int num_plmn = configuration->num_plmn;
|
||||
struct NR_PLMN_Identity nr_plmn[num_plmn];
|
||||
NR_MCC_MNC_Digit_t nr_mcc_digit[num_plmn][3];
|
||||
NR_MCC_MNC_Digit_t nr_mnc_digit[num_plmn][3];
|
||||
memset(nr_plmn,0,sizeof(nr_plmn));
|
||||
memset(nr_mcc_digit,0,sizeof(nr_mcc_digit));
|
||||
memset(nr_mnc_digit,0,sizeof(nr_mnc_digit));
|
||||
|
||||
// struct NR_UAC_BarringInfoSet nr_uac_BarringInfoSet;
|
||||
|
||||
NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t));
|
||||
carrier->siblock1 = sib1_message;
|
||||
sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1;
|
||||
sib1_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1));
|
||||
sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1;
|
||||
sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1));
|
||||
|
||||
|
||||
struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1;
|
||||
|
||||
// cellSelectionInfo
|
||||
sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo));
|
||||
sib1->cellSelectionInfo->q_RxLevMin = -50;
|
||||
|
||||
// cellAccessRelatedInfo
|
||||
struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo));
|
||||
asn_set_empty(&nr_plmn_info->plmn_IdentityList.list);
|
||||
for (int i = 0; i < num_plmn; ++i) {
|
||||
@@ -329,44 +338,133 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][0]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][1]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][2]);
|
||||
nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10;
|
||||
if(configuration->mnc_digit_length[i] == 3) nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10;
|
||||
nr_mnc_digit[i][1] = (configuration->mnc[i]/10)%10;
|
||||
nr_mnc_digit[i][2] = (configuration->mnc[i])%10;
|
||||
nr_plmn[i].mnc.list.size=0;
|
||||
nr_plmn[i].mnc.list.count=0;
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][0]);
|
||||
if(configuration->mnc_digit_length[i] == 3) ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][0]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][1]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][2]);
|
||||
ASN_SEQUENCE_ADD(&nr_plmn_info->plmn_IdentityList.list, &nr_plmn[i]);
|
||||
}//end plmn loop
|
||||
|
||||
nr_plmn_info->cellIdentity.buf = CALLOC(1,8);
|
||||
nr_plmn_info->cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff;
|
||||
nr_plmn_info->cellIdentity.size= 4;
|
||||
nr_plmn_info->cellIdentity.buf = CALLOC(1,5);
|
||||
nr_plmn_info->cellIdentity.buf[0]= (configuration->cell_identity >> 28) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[1]= (configuration->cell_identity >> 20) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[2]= (configuration->cell_identity >> 12) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[3]= (configuration->cell_identity >> 4) & 0xff;
|
||||
nr_plmn_info->cellIdentity.buf[4]= (configuration->cell_identity << 4) & 0xff;
|
||||
nr_plmn_info->cellIdentity.size= 5;
|
||||
nr_plmn_info->cellIdentity.bits_unused= 4;
|
||||
nr_plmn_info->cellReservedForOperatorUse = 0;
|
||||
nr_plmn_info->cellReservedForOperatorUse = NR_PLMN_IdentityInfo__cellReservedForOperatorUse_reserved;
|
||||
|
||||
nr_plmn_info->trackingAreaCode = CALLOC(1,sizeof(NR_TrackingAreaCode_t));
|
||||
nr_plmn_info->trackingAreaCode->buf = CALLOC(1,3);
|
||||
nr_plmn_info->trackingAreaCode->buf[0] = ( ((uint32_t)configuration->tac) >> 16) & 0xff;
|
||||
nr_plmn_info->trackingAreaCode->buf[1] = ( ((uint32_t)configuration->tac) >> 8) & 0xff;
|
||||
nr_plmn_info->trackingAreaCode->buf[2] = ( ((uint32_t)configuration->tac) >> 0) & 0xff;
|
||||
nr_plmn_info->trackingAreaCode->size = 3;
|
||||
nr_plmn_info->trackingAreaCode->bits_unused = 0;
|
||||
|
||||
ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, nr_plmn_info);
|
||||
#if 0
|
||||
sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo));
|
||||
memset(sib1->uac_BarringInfo, 0, sizeof(struct NR_SIB1__uac_BarringInfo));
|
||||
nr_uac_BarringInfoSet.uac_BarringFactor = NR_UAC_BarringInfoSet__uac_BarringFactor_p95;
|
||||
nr_uac_BarringInfoSet.uac_BarringTime = NR_UAC_BarringInfoSet__uac_BarringTime_s4;
|
||||
nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.buf = MALLOC(1);
|
||||
memset(nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.buf,0,1);
|
||||
nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.size = 1;
|
||||
nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.bits_unused = 1;
|
||||
ASN_SEQUENCE_ADD(&sib1->uac_BarringInfo->uac_BarringInfoSetList, &nr_uac_BarringInfoSet);
|
||||
#endif
|
||||
//encode SIB1 to data
|
||||
carrier->SIB1=(uint8_t *) malloc16(128);
|
||||
|
||||
// connEstFailureControl
|
||||
// TODO: add connEstFailureControl
|
||||
|
||||
//si-SchedulingInfo
|
||||
/*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo));
|
||||
asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list);
|
||||
sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s20;
|
||||
struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo));
|
||||
schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting;
|
||||
schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf8;
|
||||
asn_set_empty(&schedulingInfo->sib_MappingInfo.list);
|
||||
e_NR_SIB_TypeInfo__type *sib_type = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type));
|
||||
*sib_type = NR_SIB_TypeInfo__type_sibType3;
|
||||
ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type);
|
||||
ASN_SEQUENCE_ADD(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/
|
||||
|
||||
// servingCellConfigCommon
|
||||
sib1->servingCellConfigCommon = CALLOC(1,sizeof(struct NR_ServingCellConfigCommonSIB));
|
||||
|
||||
asn_set_empty(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list);
|
||||
asn_set_empty(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list);
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.cyclicPrefix = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix;
|
||||
for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count; i++) {
|
||||
struct NR_NR_MultiBandInfo *nrMultiBandInfo = CALLOC(1,sizeof(struct NR_NR_MultiBandInfo));
|
||||
nrMultiBandInfo->freqBandIndicatorNR = configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[i];
|
||||
ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list,nrMultiBandInfo);
|
||||
}
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
|
||||
for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) {
|
||||
ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list,configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[i]);
|
||||
}
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.bcch_Config.modificationPeriodCoeff = NR_BCCH_Config__modificationPeriodCoeff_n2;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle = 0;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present = NR_PCCH_Config__nAndPagingFrameOffset_PR_oneT;
|
||||
sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns = NR_PCCH_Config__ns_four;
|
||||
|
||||
sib1->servingCellConfigCommon->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommonSIB));
|
||||
asn_set_empty(&sib1->servingCellConfigCommon->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list);
|
||||
for(int i = 0; i< configuration->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.count; i++) {
|
||||
ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list,configuration->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[i]);
|
||||
}
|
||||
sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.genericParameters = configuration->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon;
|
||||
sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon;
|
||||
sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon;
|
||||
|
||||
sib1->servingCellConfigCommon->n_TimingAdvanceOffset = configuration->scc->n_TimingAdvanceOffset;
|
||||
sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.shortBitmap;
|
||||
sib1->servingCellConfigCommon->ssb_PeriodicityServingCell = *configuration->scc->ssb_periodicityServingCell;
|
||||
sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon));
|
||||
sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = configuration->scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing;
|
||||
sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->pattern1 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->pattern2 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern2;
|
||||
sib1->servingCellConfigCommon->ss_PBCH_BlockPower = configuration->scc->ss_PBCH_BlockPower;
|
||||
|
||||
// ims-EmergencySupport
|
||||
// TODO: add ims-EmergencySupport
|
||||
|
||||
// eCallOverIMS-Support
|
||||
// TODO: add eCallOverIMS-Support
|
||||
|
||||
// ue-TimersAndConstants
|
||||
// TODO: add ue-TimersAndConstants
|
||||
|
||||
// uac-BarringInfo
|
||||
/*sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo));
|
||||
NR_UAC_BarringInfoSet_t *nr_uac_BarringInfoSet = CALLOC(1, sizeof(NR_UAC_BarringInfoSet_t));
|
||||
asn_set_empty(&sib1->uac_BarringInfo->uac_BarringInfoSetList);
|
||||
nr_uac_BarringInfoSet->uac_BarringFactor = NR_UAC_BarringInfoSet__uac_BarringFactor_p95;
|
||||
nr_uac_BarringInfoSet->uac_BarringTime = NR_UAC_BarringInfoSet__uac_BarringTime_s4;
|
||||
nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.buf = CALLOC(1, 1);
|
||||
nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.size = 1;
|
||||
nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.bits_unused = 1;
|
||||
ASN_SEQUENCE_ADD(&sib1->uac_BarringInfo->uac_BarringInfoSetList, nr_uac_BarringInfoSet);*/
|
||||
|
||||
// useFullResumeID
|
||||
// TODO: add useFullResumeID
|
||||
|
||||
// lateNonCriticalExtension
|
||||
// TODO: add lateNonCriticalExtension
|
||||
|
||||
// nonCriticalExtension
|
||||
// TODO: add nonCriticalExtension
|
||||
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1_message->message.choice.c1->choice.systemInformationBlockType1);
|
||||
|
||||
if(carrier->SIB1 == NULL) carrier->SIB1=(uint8_t *) malloc16(NR_MAX_SIB_LENGTH/8);
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||
NULL,
|
||||
(void *)sib1_message,
|
||||
carrier->SIB1,
|
||||
128);
|
||||
NR_MAX_SIB_LENGTH/8);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
|
||||
|
||||
@@ -403,6 +403,7 @@ typedef struct {
|
||||
int pucch_TargetSNRx10;
|
||||
NR_BCCH_DL_SCH_Message_t *siblock1;
|
||||
NR_ServingCellConfigCommon_t *servingcellconfigcommon;
|
||||
NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup[MAX_NR_RRC_UE_CONTEXTS];
|
||||
NR_SRB_INFO SI;
|
||||
NR_SRB_INFO Srb0;
|
||||
|
||||
@@ -71,6 +71,12 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
|
||||
void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti);
|
||||
|
||||
void fill_default_initialDownlinkBWP(NR_BWP_Downlink_t *bwp, NR_ServingCellConfigCommon_t *servingcellconfigcommon);
|
||||
|
||||
void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellConfigCommon_t *servingcellconfigcommon);
|
||||
|
||||
void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0);
|
||||
|
||||
void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
int scg_id,
|
||||
|
||||
@@ -225,7 +225,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
|
||||
(NR_CellGroupConfig_t *)NULL
|
||||
);
|
||||
|
||||
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
|
||||
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa > 0) {
|
||||
// This is for phytest only, emulate first X2 message if uecap.raw file is present
|
||||
FILE *fd;
|
||||
fd = fopen("uecap.raw","r");
|
||||
|
||||
@@ -98,7 +98,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
total_size = (enc_rval.encoded+7)>>3;
|
||||
|
||||
FILE *fd; // file to be generated for nr-ue
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0) {
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa == 1) {
|
||||
// This is for phytest only, emulate first X2 message if uecap.raw file is present
|
||||
LOG_I(RRC,"Dumping NR_RRCReconfiguration message (%jd bytes)\n",(enc_rval.encoded+7)>>3);
|
||||
for (int i=0; i<(enc_rval.encoded+7)>>3; i++) {
|
||||
@@ -123,7 +123,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
|
||||
|
||||
|
||||
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0) {
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa == 1) {
|
||||
|
||||
LOG_I(RRC,"Dumping scg_RB_Config message (%jd bytes)\n",(enc_rval.encoded+7)>>3);
|
||||
for (int i=0; i<(enc_rval.encoded+7)>>3; i++) {
|
||||
|
||||
@@ -162,7 +162,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
|
||||
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
|
||||
carrier->initial_csi_index[rrc->Nb_ue] = 0;
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1){
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
|
||||
ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
fill_default_rbconfig(ue_context_p->ue_context.rb_config);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,99 @@
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
void fill_default_initialDownlinkBWP(NR_BWP_Downlink_t *bwp, NR_ServingCellConfigCommon_t *servingcellconfigcommon) {
|
||||
|
||||
bwp->bwp_Id = 0;
|
||||
|
||||
bwp->bwp_Common=calloc(1,sizeof(*bwp->bwp_Common));
|
||||
memcpy((void*)&bwp->bwp_Common,
|
||||
&servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP,
|
||||
sizeof(bwp->bwp_Common));
|
||||
|
||||
bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated));
|
||||
bwp->bwp_Dedicated->pdsch_Config = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config));
|
||||
bwp->bwp_Dedicated->pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0;
|
||||
}
|
||||
|
||||
void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellConfigCommon_t *servingcellconfigcommon) {
|
||||
|
||||
coreset0->controlResourceSetId = 0;
|
||||
|
||||
// frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
|
||||
if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6);
|
||||
coreset0->frequencyDomainResources.buf[0] = 0xff;
|
||||
coreset0->frequencyDomainResources.buf[1] = 0;
|
||||
coreset0->frequencyDomainResources.buf[2] = 0;
|
||||
coreset0->frequencyDomainResources.buf[3] = 0;
|
||||
coreset0->frequencyDomainResources.buf[4] = 0;
|
||||
coreset0->frequencyDomainResources.buf[5] = 0;
|
||||
coreset0->frequencyDomainResources.size = 6;
|
||||
coreset0->frequencyDomainResources.bits_unused = 3;
|
||||
coreset0->duration = 1;
|
||||
coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
|
||||
coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved));
|
||||
coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6;
|
||||
coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
|
||||
coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = servingcellconfigcommon->physCellId;
|
||||
coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
|
||||
|
||||
if(coreset0->tci_StatesPDCCH_ToAddList == NULL) coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList));
|
||||
|
||||
NR_TCI_StateId_t *tci[8];
|
||||
for (int i=0;i<8;i++) {
|
||||
tci[i]=calloc(1,sizeof(*tci[i]));
|
||||
*tci[i] = i;
|
||||
ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
|
||||
}
|
||||
coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
|
||||
coreset0->tci_PresentInDCI = NULL;
|
||||
coreset0->pdcch_DMRS_ScramblingID = NULL;
|
||||
|
||||
}
|
||||
|
||||
void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) {
|
||||
|
||||
if(ss0->controlResourceSetId == NULL) ss0->controlResourceSetId=calloc(1,sizeof(*ss0->controlResourceSetId));
|
||||
if(ss0->monitoringSymbolsWithinSlot == NULL) ss0->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss0->monitoringSymbolsWithinSlot));
|
||||
if(ss0->monitoringSymbolsWithinSlot->buf == NULL) ss0->monitoringSymbolsWithinSlot->buf = calloc(1,2);
|
||||
if(ss0->nrofCandidates == NULL) ss0->nrofCandidates = calloc(1,sizeof(*ss0->nrofCandidates));
|
||||
if(ss0->searchSpaceType == NULL) ss0->searchSpaceType = calloc(1,sizeof(*ss0->searchSpaceType));
|
||||
if(ss0->searchSpaceType->choice.common == NULL) ss0->searchSpaceType->choice.common=calloc(1,sizeof(*ss0->searchSpaceType->choice.common));
|
||||
if(ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
|
||||
|
||||
ss0->searchSpaceId = 0;
|
||||
*ss0->controlResourceSetId = 0;
|
||||
ss0->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss0->monitoringSlotPeriodicityAndOffset));
|
||||
ss0->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1;
|
||||
ss0->duration=NULL;
|
||||
|
||||
// should be '1100 0000 0000 00'B (LSB first!), first two symols in slot, adjust if needed
|
||||
ss0->monitoringSymbolsWithinSlot->buf[1] = 0;
|
||||
ss0->monitoringSymbolsWithinSlot->buf[0] = (1<<7) | (1<<6);
|
||||
ss0->monitoringSymbolsWithinSlot->size = 2;
|
||||
ss0->monitoringSymbolsWithinSlot->bits_unused = 2;
|
||||
|
||||
// FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
|
||||
ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
|
||||
ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
|
||||
ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n0;
|
||||
ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n1;
|
||||
ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
|
||||
|
||||
ss0->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common;
|
||||
}
|
||||
|
||||
void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
NR_CellGroupConfig_t *secondaryCellGroup,
|
||||
@@ -457,7 +550,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss);
|
||||
|
||||
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=NULL;
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1));
|
||||
*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=0;
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation=NULL;
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->pagingSearchSpace=NULL;
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace));
|
||||
|
||||
@@ -46,16 +46,17 @@ nr_mac_rrc_data_ind_ue(
|
||||
const sdu_size_t pdu_len){
|
||||
|
||||
switch(channel){
|
||||
case NR_BCCH_BCH:
|
||||
AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message( module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case NR_BCCH_BCH:
|
||||
AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
|
||||
break;
|
||||
case NR_BCCH_DL_SCH:
|
||||
AssertFatal( nr_rrc_ue_decode_NR_SIB1_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-DLSCH error!\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
|
||||
|
||||
@@ -458,7 +458,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
|
||||
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
|
||||
}
|
||||
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1 || get_softmodem_params()->sa == 1) {
|
||||
// read in files for RRCReconfiguration and RBconfig
|
||||
FILE *fd;
|
||||
char filename[1024];
|
||||
@@ -1477,6 +1477,39 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*brief decode SIB1 message*/
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
|
||||
|
||||
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
|
||||
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
|
||||
&asn_DEF_NR_BCCH_DL_SCH_Message,
|
||||
(void **)&bcch_message,
|
||||
(const void *)bufferP,
|
||||
buffer_len);
|
||||
|
||||
if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
|
||||
LOG_D(RRC,"NR_BCCH_DL_SCH decode error\n");
|
||||
SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
|
||||
if(sib1 != NULL){
|
||||
SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 );
|
||||
}
|
||||
sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
|
||||
if (*(int64_t*)sib1 != 1) {
|
||||
LOG_D(RRC, "SIB1 address: %lx\n", *(int64_t*)sib1);
|
||||
xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1);
|
||||
}
|
||||
else
|
||||
LOG_E(PHY, "sib1 is starting by 8 times 0\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// from NR SRB3
|
||||
int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "NR_asn_constant.h"
|
||||
#include "NR_SchedulingRequestToAddMod.h"
|
||||
#include "NR_MIB.h"
|
||||
#include "NR_SIB1.h"
|
||||
#include "NR_BCCH-BCH-Message.h"
|
||||
#include "NR_DL-DCCH-Message.h"
|
||||
#include "../NR/nr_rrc_defs.h"
|
||||
|
||||
@@ -86,6 +86,13 @@ int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_beare
|
||||
\param sdu_len length of buffer*/
|
||||
int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
|
||||
|
||||
/**\brief decode NR SIB1 message
|
||||
\param module_idP module id
|
||||
\param gNB_index gNB index
|
||||
\param sduP pointer to buffer of ASN message
|
||||
\param sdu_len length of buffer*/
|
||||
int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
|
||||
|
||||
/**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3
|
||||
\param module_id module id
|
||||
\param gNB_index gNB index
|
||||
|
||||
@@ -284,7 +284,7 @@ int create_gNB_tasks(uint32_t gnb_nb) {
|
||||
}
|
||||
}
|
||||
|
||||
if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
|
||||
if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) {
|
||||
if (gnb_nb > 0) {
|
||||
if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) {
|
||||
LOG_E(S1AP, "Create task for NGAP failed\n");
|
||||
|
||||
@@ -91,13 +91,13 @@ extern RAN_CONTEXT_t RC;
|
||||
|
||||
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||
static telnetshell_cmddef_t rfsimu_cmdarray[] = {
|
||||
{"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||
{"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||
{"","",NULL},
|
||||
};
|
||||
|
||||
static telnetshell_vardef_t rfsimu_vardef[] = {
|
||||
{"",0,NULL}
|
||||
};
|
||||
};
|
||||
pthread_mutex_t Sockmutex;
|
||||
|
||||
typedef struct complex16 sample_t; // 2*16 bits complex number
|
||||
@@ -170,11 +170,13 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
static bool init_done=false;
|
||||
|
||||
if (!init_done) {
|
||||
uint64_t rand;
|
||||
FILE *h=fopen("/dev/random","r");
|
||||
uint64_t rand;
|
||||
FILE *h=fopen("/dev/random","r");
|
||||
|
||||
if ( 1 != fread(&rand,sizeof(rand),1,h) )
|
||||
LOG_W(HW, "Simulator can't read /dev/random\n");
|
||||
fclose(h);
|
||||
|
||||
fclose(h);
|
||||
randominit(rand);
|
||||
tableNor(rand);
|
||||
init_done=true;
|
||||
@@ -189,7 +191,6 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
bridge->chan_offset, // maybe used for TA
|
||||
bridge->chan_pathloss); // path_loss in dB
|
||||
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
|
||||
|
||||
random_channel(ptr->channel_model,false);
|
||||
}
|
||||
}
|
||||
@@ -317,25 +318,29 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
||||
}
|
||||
|
||||
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
|
||||
char *modelname=NULL;
|
||||
char *modelname=NULL;
|
||||
int s = sscanf(buff,"%ms\n",&modelname);
|
||||
|
||||
if (s == 1) {
|
||||
int channelmod=modelid_fromname(modelname);
|
||||
|
||||
if (channelmod<0)
|
||||
prnt("ERROR: model %s unknown\n",modelname);
|
||||
else {
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
buffer_t *b=&t->buf[i];
|
||||
|
||||
if (b->conn_sock >= 0 ) {
|
||||
channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels,
|
||||
channelmod,
|
||||
t->sample_rate,
|
||||
t->tx_bw,
|
||||
30e-9, // TDL delay-spread parameter
|
||||
t->chan_forgetfact, // forgetting_factor
|
||||
t->chan_offset, // maybe used for TA
|
||||
t->chan_pathloss); // path_loss in dB
|
||||
channelmod,
|
||||
t->sample_rate,
|
||||
t->tx_bw,
|
||||
30e-9, // TDL delay-spread parameter
|
||||
t->chan_forgetfact, // forgetting_factor
|
||||
t->chan_offset, // maybe used for TA
|
||||
t->chan_pathloss); // path_loss in dB
|
||||
set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
|
||||
random_channel(newmodel,false);
|
||||
channel_desc_t *oldmodel=b->channel_model;
|
||||
@@ -346,8 +351,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prnt("ERROR: no model specified\n");
|
||||
prnt("ERROR: no model specified\n");
|
||||
}
|
||||
|
||||
free(modelname);
|
||||
return CMDSTATUS_FOUND;
|
||||
}
|
||||
@@ -368,7 +374,7 @@ sin_addr:
|
||||
};
|
||||
bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr));
|
||||
AssertFatal(listen(t->listen_sock, 5) == 0, "");
|
||||
struct epoll_event ev={0};
|
||||
struct epoll_event ev= {0};
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = t->listen_sock;
|
||||
AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, "");
|
||||
@@ -440,7 +446,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
|
||||
|
||||
if (t->lastWroteTS > timestamp+nsamps)
|
||||
LOG_E(HW,"Not supported to send Tx out of order (same in USRP) %lu, %lu\n",
|
||||
t->lastWroteTS, timestamp);
|
||||
t->lastWroteTS, timestamp);
|
||||
|
||||
t->lastWroteTS=timestamp+nsamps;
|
||||
|
||||
@@ -505,9 +511,9 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
||||
if ( b->headerMode)
|
||||
blockSz=b->remainToTransfer;
|
||||
else
|
||||
blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ?
|
||||
blockSz= b->transferPtr + b->remainToTransfer <= b->circularBufEnd ?
|
||||
b->remainToTransfer :
|
||||
b->circularBufEnd - 1 - b->transferPtr ;
|
||||
b->circularBufEnd - b->transferPtr ;
|
||||
|
||||
ssize_t sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
|
||||
|
||||
@@ -523,7 +529,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
||||
AssertFatal((b->remainToTransfer-=sz) >= 0, "");
|
||||
b->transferPtr+=sz;
|
||||
|
||||
if (b->transferPtr==b->circularBufEnd - 1)
|
||||
if (b->transferPtr==b->circularBufEnd )
|
||||
b->transferPtr=(char *)b->circularBuf;
|
||||
|
||||
// check the header and start block transfer
|
||||
@@ -552,14 +558,13 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memset(b->circularBuf, 0, sampleToByte(CirSize,1));
|
||||
}
|
||||
memset(b->circularBuf, 0, sampleToByte(CirSize,1));
|
||||
}
|
||||
|
||||
if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS < 1000)
|
||||
LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS );
|
||||
|
||||
b->lastReceivedTS=b->th.timestamp;
|
||||
|
||||
} else if ( b->lastReceivedTS > b->th.timestamp && b->th.size == 1 ) {
|
||||
LOG_W(HW,"Received Rx/Tx synchro out of order\n");
|
||||
b->trashingPacket=true;
|
||||
@@ -650,15 +655,15 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
// assuming this should have been done earlier if a Tx would exist
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
struct complex16 v= {0};
|
||||
void *samplesVoid[t->tx_num_channels];
|
||||
void *dummyS[t->tx_num_channels];
|
||||
|
||||
for ( int i=0; i < t->tx_num_channels; i++)
|
||||
samplesVoid[i]=(void *)&v;
|
||||
dummyS[i]=(void *)&v;
|
||||
|
||||
LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n",
|
||||
t->lastWroteTS, t->nextTimestamp);
|
||||
rfsimulator_write_internal(t, t->nextTimestamp,
|
||||
samplesVoid, 1,
|
||||
dummyS, 1,
|
||||
t->tx_num_channels, 1, true);
|
||||
} else {
|
||||
pthread_mutex_unlock(&Sockmutex);
|
||||
@@ -706,8 +711,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
// it seems legacy behavior is: never in UL, each frame in DL
|
||||
if (reGenerateChannel)
|
||||
random_channel(ptr->channel_model,0);
|
||||
|
||||
if (t->poll_telnetcmdq)
|
||||
t->poll_telnetcmdq(t->telnetcmd_qid,t);
|
||||
t->poll_telnetcmdq(t->telnetcmd_qid,t);
|
||||
|
||||
for (int a=0; a<nbAnt; a++) {//loop over number of Rx antennas
|
||||
if ( ptr->channel_model != NULL ) // apply a channel model
|
||||
@@ -721,12 +727,13 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
||||
else { // no channel modeling
|
||||
sample_t *out=(sample_t *)samplesVoid[a];
|
||||
int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas
|
||||
|
||||
//LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx);
|
||||
for (int i=0; i < nsamps; i++) {//loop over nsamps
|
||||
for (int a_tx=0; a_tx<nbAnt_tx; a_tx++){//sum up signals from nbAnt_tx antennas
|
||||
out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
|
||||
out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
|
||||
} // end for a_tx
|
||||
for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas
|
||||
out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r;
|
||||
out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i;
|
||||
} // end for a_tx
|
||||
} // end for i (number of samps)
|
||||
} // end of no channel modeling
|
||||
} // end for a (number of rx antennas)
|
||||
@@ -804,18 +811,20 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
||||
//randominit(0);
|
||||
set_taus_seed(0);
|
||||
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
|
||||
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
|
||||
add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
|
||||
|
||||
|
||||
if (addcmd != NULL) {
|
||||
rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME);
|
||||
rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME);
|
||||
addcmd("rfsimu",rfsimu_vardef,rfsimu_cmdarray);
|
||||
|
||||
for(int i=0; rfsimu_cmdarray[i].cmdfunc != NULL; i++) {
|
||||
if ( rfsimu_cmdarray[i].qptr != NULL) {
|
||||
if ( rfsimu_cmdarray[i].qptr != NULL) {
|
||||
rfsimulator->telnetcmd_qid = rfsimu_cmdarray[i].qptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ int fullread(int fd, void *_buf, int count) {
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
|
||||
if (l <= 0) return -1;
|
||||
if (l <= 0)
|
||||
return -1;
|
||||
|
||||
count -= l;
|
||||
buf += l;
|
||||
@@ -43,6 +44,44 @@ int fullread(int fd, void *_buf, int count) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
#define shift 4
|
||||
int32_t signal_energy(int32_t *input,uint32_t length) {
|
||||
int32_t i;
|
||||
int32_t temp,temp2;
|
||||
register __m64 mm0,mm1,mm2,mm3;
|
||||
__m64 *in = (__m64 *)input;
|
||||
mm0 = _mm_setzero_si64();//pxor(mm0,mm0);
|
||||
mm3 = _mm_setzero_si64();//pxor(mm3,mm3);
|
||||
|
||||
for (i=0; i<length>>1; i++) {
|
||||
mm1 = in[i];
|
||||
mm2 = mm1;
|
||||
mm1 = _m_pmaddwd(mm1,mm1);
|
||||
mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift
|
||||
mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes
|
||||
// mm2 = _m_psrawi(mm2,shift_DC);
|
||||
mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes
|
||||
}
|
||||
|
||||
mm1 = mm0;
|
||||
mm0 = _m_psrlqi(mm0,32);
|
||||
mm0 = _m_paddd(mm0,mm1);
|
||||
temp = _m_to_int(mm0);
|
||||
temp/=length;
|
||||
temp<<=shift; // this is the average of x^2
|
||||
// now remove the DC component
|
||||
mm2 = _m_psrlqi(mm3,32);
|
||||
mm2 = _m_paddw(mm2,mm3);
|
||||
mm2 = _m_pmaddwd(mm2,mm2);
|
||||
temp2 = _m_to_int(mm2);
|
||||
temp2/=(length*length);
|
||||
// temp2<<=(2*shift_DC);
|
||||
temp -= temp2;
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
return((temp>0)?temp:1);
|
||||
}
|
||||
|
||||
|
||||
void fullwrite(int fd, void *_buf, int count) {
|
||||
char *buf = _buf;
|
||||
@@ -131,8 +170,8 @@ void setblocking(int sock, enum blocking_t active) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if(argc != 4) {
|
||||
printf("Need parameters: source file, server or destination IP, TCP port\n");
|
||||
if(argc < 4) {
|
||||
printf("Need parameters: source file, server or destination IP, TCP port (4043), 'UL|DL' if raw 2*16bits format: UL for UL IQ, DL for DL IQs \n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -147,10 +186,21 @@ int main(int argc, char *argv[]) {
|
||||
serviceSock=client_start(argv[2],atoi(argv[3]));
|
||||
}
|
||||
|
||||
uint64_t typeStamp=ENB_MAGICDL_FDD;
|
||||
boolean_t raw=false;
|
||||
|
||||
if ( argc == 5 ) {
|
||||
raw=true;
|
||||
|
||||
if (strcmp(argv[4],"UL") == 0 )
|
||||
typeStamp=UE_MAGICDL_FDD;
|
||||
}
|
||||
|
||||
samplesBlockHeader_t header;
|
||||
int bufSize=100000;
|
||||
void *buff=malloc(bufSize);
|
||||
uint64_t readTS=0;
|
||||
uint64_t timestamp=0;
|
||||
const int blockSize=1000;
|
||||
|
||||
while (1) {
|
||||
//Rewind the file to loop on the samples
|
||||
@@ -159,10 +209,21 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Read one block and send it
|
||||
setblocking(serviceSock, blocking);
|
||||
AssertFatal(read(fd,&header,sizeof(header)), "");
|
||||
|
||||
if ( raw ) {
|
||||
header.magic=typeStamp;
|
||||
header.size=blockSize;
|
||||
header.nbAnt=1;
|
||||
header.timestamp=timestamp;
|
||||
timestamp+=blockSize;
|
||||
header.option_value=0;
|
||||
header.option_flag=0;
|
||||
} else {
|
||||
AssertFatal(read(fd,&header,sizeof(header)), "");
|
||||
}
|
||||
|
||||
fullwrite(serviceSock, &header, sizeof(header));
|
||||
int dataSize=sizeof(int32_t)*header.size*header.nbAnt;
|
||||
uint64_t wroteTS=header.timestamp;
|
||||
|
||||
if (dataSize>bufSize) {
|
||||
void *new_buff = realloc(buff, dataSize);
|
||||
@@ -176,21 +237,28 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
AssertFatal(read(fd,buff,dataSize) == dataSize, "");
|
||||
|
||||
if (raw) // UHD shifts the 12 ADC values in MSB
|
||||
for (int i=0; i<header.size*header.nbAnt*2; i++)
|
||||
((int16_t *)buff)[i]/=16;
|
||||
|
||||
usleep(1000);
|
||||
printf("sending at ts: %lu, number of samples: %d, energy: %d\n",
|
||||
header.timestamp, header.size, signal_energy(buff, header.size));
|
||||
fullwrite(serviceSock, buff, dataSize);
|
||||
// Purge incoming samples
|
||||
setblocking(serviceSock, blocking);
|
||||
setblocking(serviceSock, notBlocking);
|
||||
int ret;
|
||||
|
||||
while(readTS < wroteTS) {
|
||||
if ( fullread(serviceSock, &header,sizeof(header)) != sizeof(header) ||
|
||||
fullread(serviceSock, buff, sizeof(int32_t)*header.size*header.nbAnt) !=
|
||||
sizeof(int32_t)*header.size*header.nbAnt
|
||||
) {
|
||||
do {
|
||||
char buff[64000];
|
||||
ret=read(serviceSock, buff, 64000);
|
||||
|
||||
if ( ret<0 && !( errno == EAGAIN || errno == EWOULDBLOCK ) ) {
|
||||
printf("error: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
readTS=header.timestamp;
|
||||
}
|
||||
} while ( ret > 0 ) ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#ifndef CREATE_NR_TASKS_H_
|
||||
#define CREATE_NR_TASKS_H_
|
||||
|
||||
/* External declaration of L2L1 task that depend on the target */
|
||||
extern void *l2l1_task(void *arg);
|
||||
|
||||
int create_gNB_tasks(uint32_t gnb_nb);
|
||||
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
#ifndef CREATE_TASKS_H_
|
||||
#define CREATE_TASKS_H_
|
||||
|
||||
/* External declaration of L2L1 task that depend on the target */
|
||||
extern void *l2l1_task(void *arg);
|
||||
|
||||
int create_tasks(uint32_t enb_nb);
|
||||
int create_tasks_ue(uint32_t ue_nb);
|
||||
int create_tasks_mbms(uint32_t enb_nb);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user