Merge remote-tracking branch 'develop'

This commit is contained in:
Thomas Schlichter
2021-01-21 18:28:33 +01:00
103 changed files with 3355 additions and 1667 deletions
+2
View File
@@ -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
+1 -1
View File
@@ -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>
+5
View File
@@ -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})
+2
View File
@@ -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}\
}
+4 -3
View File
@@ -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++;
+3 -3
View File
@@ -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
+11 -7
View File
@@ -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
View File
@@ -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**
+34
View File
@@ -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.
+4 -85
View File
@@ -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
View File
@@ -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
View File
@@ -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
+61 -57
View File
@@ -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
+4
View File
@@ -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
+1
View File
@@ -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;
+34
View File
@@ -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++) {
+27 -67
View File
@@ -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;
}
}
}
+12 -14
View File
@@ -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++)
}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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);
+11 -8
View File
@@ -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]);
}
}
}
+154 -279
View File
@@ -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
+270 -96
View File
@@ -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
+3 -3
View File
@@ -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;
+1
View File
@@ -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)
+6 -4
View File
@@ -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);
+10
View File
@@ -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;
+105 -71
View File
@@ -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
+2 -2
View File
@@ -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;
+22 -13
View File
@@ -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
+4
View File
@@ -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;
+4
View File
@@ -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];
+2 -2
View File
@@ -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];
+16
View File
@@ -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 */
+12 -1
View File
@@ -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);
-1
View File
@@ -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"
+60 -2
View File
@@ -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__ */
+491 -13
View File
@@ -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
+59 -1
View File
@@ -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(
+9 -26
View File
@@ -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]
-54
View File
@@ -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];
+13 -2
View File
@@ -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);
-75
View File
@@ -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
-1
View File
@@ -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);
}
}
}
}
+97 -373
View File
@@ -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;
}
}
+2 -1
View File
@@ -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,
+2
View File
@@ -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);
+6 -1
View File
@@ -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
+296 -5
View File
@@ -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,
+9 -3
View File
@@ -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);
+7
View File
@@ -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__ */
-3
View File
@@ -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
+125 -31
View File
@@ -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;
+3 -2
View File
@@ -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 -1
View File
@@ -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.
+49
View File
@@ -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.
+27
View File
@@ -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.
+29
View File
@@ -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.
+27
View File
@@ -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.
-3
View File
@@ -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.
-3
View File
@@ -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.
-3
View File
@@ -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.
+2 -2
View File
@@ -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){
+142 -30
View File
@@ -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 */
+131 -33
View File
@@ -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);
+1
View File
@@ -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;
+6
View File
@@ -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,
+1 -1
View File
@@ -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");
+2 -2
View File
@@ -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++) {
+1 -1
View File
@@ -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);
}
+95 -1
View File
@@ -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));
+8 -7
View File
@@ -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,
+34 -1
View File
@@ -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(
+1
View File
@@ -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"
+7
View File
@@ -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
+1 -1
View File
@@ -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");
+48 -39
View File
@@ -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;
}
+83 -15
View File
@@ -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;
-2
View File
@@ -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);
-3
View File
@@ -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