Commit 9f5140ae authored by Francesco Mani's avatar Francesco Mani

Merge branch 'develop-nr' into nr_ssb_periodicity

parents 16fbe033 5db1b116
cmake_targets/log/
cmake_targets/ran_build/
cmake_targets/*/build/
targets/bin/
......@@ -131,10 +131,10 @@ pipeline {
}
}
stage ("Start VM -- nu-ue-usrp") {
stage ("Start VM -- nr-ue-usrp") {
steps {
timeout (time: 5, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nu-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
}
}
}
......@@ -239,7 +239,7 @@ pipeline {
steps {
gitlabCommitStatus(name: "Build nr-UE-usrp") {
timeout (time: 20, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nu-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
}
......
......@@ -39,7 +39,7 @@ function variant_usage {
echo " --variant phy-sim OR -v3"
echo " --variant cppcheck OR -v4"
echo " --variant gnb-usrp OR -v5"
echo " --variant nu-ue-usrp OR -v6"
echo " --variant nr-ue-usrp OR -v6"
echo " --variant enb-ethernet OR -v7"
echo " --variant ue-ethernet OR -v8"
}
......@@ -252,9 +252,9 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=8
NB_PATTERN_FILES=9
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=4096
VM_MEMORY=8192
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256]
shift
......@@ -331,9 +331,9 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=8
NB_PATTERN_FILES=9
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=4096
VM_MEMORY=8192
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
NBARGS=$[$NBARGS+256]
;;
......@@ -354,7 +354,7 @@ case $key in
BUILD_OPTIONS="--gNB -w USRP"
NBARGS=$[$NBARGS+256]
;;
nu-ue-usrp)
nr-ue-usrp)
VM_NAME=ci-ue-nr-usrp
ARCHIVES_LOC=nrue_usrp
LOG_PATTERN=.Rel15.txt
......
......@@ -671,7 +671,7 @@ add_boolean_option(EXMIMO_IOT True "????")
add_boolean_option(LOCALIZATION False "???")
add_integer_option(MAX_NUM_CCs 1 "????")
add_boolean_option(MU_RECEIVER False "????")
add_boolean_option(PHYSIM True "for L1 simulators (dlsim, ulsim, ...)")
add_boolean_option(PHYSIM False "for L1 simulators (dlsim, ulsim, ...)")
add_boolean_option(PHY_CONTEXT True "not clear: must remain False for dlsim")
add_boolean_option(PHY_EMUL False "not clear: must remain False for dlsim")
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator")
......@@ -1275,6 +1275,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_dlsch_coding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
......@@ -1304,6 +1305,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
......@@ -2394,11 +2396,10 @@ add_executable(nr-uesoftmodem
${rrc_h}
${s1ap_h}
# ${OPENAIR_BIN_DIR}/messages_xml.h
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/RT/USER/nr-ue.c
${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
${OPENAIR_DIR}/executables//nr-uesoftmodem.c
${OPENAIR_DIR}/executables/nr-ue.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
# ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
......@@ -2526,6 +2527,12 @@ add_executable(nr_dlsim
${T_SOURCE})
target_link_libraries(nr_dlsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
${OPENAIR_DIR}/common/utils/backtrace.c
${T_SOURCE})
target_link_libraries(nr_ulschsim -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} dl)
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
......
......@@ -691,7 +691,7 @@ function main() {
echo_info "Compiling unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim"
simlist="dlsim ulsim polartest ldpctest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim"
for f in $simlist ; do
compilations \
phy_simulators $f \
......
all: measurement_display thread-pool-test
measurement_display: measurement_display.c thread-pool.h
gcc measurement_display.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o measurement_display
thread-pool-test: thread-pool.c thread-pool.h
gcc -g thread-pool.c -I /data/openairinterface5g.nr/common/utils/ -I. /data/openairinterface5g.nr/common/utils/backtrace.c -lpthread -D TEST_THREAD_POOL -I../LOG -I../../utils/T -o thread-pool-test
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#define __USE_GNU
#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <stdint.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "thread-pool.h"
#define SEP "\t"
uint64_t cpuCyclesMicroSec;
int main(int argc, char *argv[]) {
if(argc != 2) {
printf("Need one paramter: the trace Linux pipe (fifo)");
exit(1);
}
mkfifo(argv[1],0666);
int fd=open(argv[1], O_RDONLY);
if ( fd == -1 ) {
perror("open read mode trace file:");
exit(1);
}
uint64_t deb=rdtsc();
usleep(100000);
cpuCyclesMicroSec=(rdtsc()-deb)/100000;
printf("Cycles per µs: %lu\n",cpuCyclesMicroSec);
printf("Key" SEP "delay to process" SEP "processing time" SEP "delay to be read answer\n");
notifiedFIFO_elt_t doneRequest;
while ( 1 ) {
if ( read(fd,&doneRequest, sizeof(doneRequest)) == sizeof(doneRequest)) {
printf("%lu" SEP "%lu" SEP "%lu" SEP "%lu" "\n",
doneRequest.key,
(doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec,
(doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec,
(doneRequest.returnTime-doneRequest.endProcessingTime)/cpuCyclesMicroSec
);
} else {
printf("no measurements\n");
sleep(1);
}
}
}
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#define _GNU_SOURCE
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/sysinfo.h>
#include <threadPool/thread-pool.h>
void displayList(notifiedFIFO_t *nf) {
int n=0;
notifiedFIFO_elt_t *ptr=nf->outF;
while(ptr) {
printf("element: %d, key: %lu\n",++n,ptr->key);
ptr=ptr->next;
}
printf("End of list: %d elements\n",n);
}
static inline notifiedFIFO_elt_t *pullNotifiedFifoRemember( notifiedFIFO_t *nf, struct one_thread *thr) {
mutexlock(nf->lockF);
while(!nf->outF)
condwait(nf->notifF, nf->lockF);
notifiedFIFO_elt_t *ret=nf->outF;
nf->outF=nf->outF->next;
if (nf->outF==NULL)
nf->inF=NULL;
// For abort feature
thr->runningOnKey=ret->key;
thr->abortFlag=false;
mutexunlock(nf->lockF);
return ret;
}
void *one_thread(void *arg) {
struct one_thread *myThread=(struct one_thread *) arg;
struct thread_pool *tp=myThread->pool;
// configure the thread core assignment
// TBD: reserve the core for us exclusively
if ( myThread->coreID >= 0 && myThread->coreID < get_nprocs_conf()) {
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(myThread->coreID, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
}
//Configure the thread scheduler policy for Linux
struct sched_param sparam= {0};
sparam.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
// set the thread name for debugging
sprintf(myThread->name,"Tpool_%d",myThread->coreID);
pthread_setname_np(pthread_self(), myThread->name );
// Infinite loop to process requests
do {
notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread);
if (tp->measurePerf) elt->startProcessingTime=rdtsc();
elt->processingFunc(NotifiedFifoData(elt));
if (tp->measurePerf) elt->endProcessingTime=rdtsc();
if (elt->reponseFifo) {
// Check if the job is still alive, else it has been aborted
mutexlock(tp->incomingFifo.lockF);
if (myThread->abortFlag)
delNotifiedFIFO_elt(elt);
else
pushNotifiedFIFO(elt->reponseFifo, elt);
mutexunlock(tp->incomingFifo.lockF);
}
} while (true);
}
void initTpool(char *params,tpool_t *pool, bool performanceMeas) {
memset(pool,0,sizeof(*pool));
char *measr=getenv("threadPoolMeasurements");
pool->measurePerf=performanceMeas;
// force measurement if the output is defined
pool->measurePerf=measr!=NULL;
if (measr) {
mkfifo(measr,0666);
AssertFatal(-1 != (pool->dummyTraceFd=
open(measr, O_RDONLY| O_NONBLOCK)),"");
AssertFatal(-1 != (pool->traceFd=
open(measr, O_WRONLY|O_APPEND|O_NOATIME|O_NONBLOCK)),"");
} else
pool->traceFd=-1;
//Configure the thread scheduler policy for Linux
struct sched_param sparam= {0};
sparam.sched_priority = sched_get_priority_max(SCHED_RR)-1;
pthread_setschedparam(pthread_self(), SCHED_RR, &sparam);
pool->activated=true;
initNotifiedFIFO(&pool->incomingFifo);
char *saveptr, * curptr;
pool->nbThreads=0;
pool->restrictRNTI=false;
curptr=strtok_r(params,",",&saveptr);
while ( curptr!=NULL ) {
int c=toupper(curptr[0]);
switch (c) {
case 'U':
pool->restrictRNTI=true;
break;
case 'N':
pool->activated=false;
break;
default:
pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread));
pool->allthreads->next=pool->allthreads;
printf("create a thread for core %d\n", atoi(curptr));
pool->allthreads->coreID=atoi(curptr);
pool->allthreads->id=pool->nbThreads;
pool->allthreads->pool=pool;
pthread_create(&pool->allthreads->threadID, NULL, one_thread, (void *)pool->allthreads);
pool->nbThreads++;
}
curptr=strtok_r(NULL,",",&saveptr);
}
if (pool->activated && pool->nbThreads==0) {
printf("No servers created in the thread pool, exit\n");
exit(1);
}
}
#ifdef TEST_THREAD_POOL
struct testData {
int id;
char txt[30];
};
void processing(void *arg) {
struct testData *in=(struct testData *)arg;
printf("doing: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() );
sprintf(in->txt,"Done by %ld, job %d", pthread_self(), in->id);
usleep(rand()%100);
printf("done: %d, %s, in thr %ld\n",in->id, in->txt,pthread_self() );
}
int main() {
notifiedFIFO_t myFifo;
initNotifiedFIFO(&myFifo);
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1234,NULL,NULL));
for(int i=10; i>1; i--) {
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 1000+i,NULL,NULL));
}
displayList(&myFifo);
notifiedFIFO_elt_t *tmp=pullNotifiedFIFO(&myFifo);
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
tmp=pullNotifiedFIFO(&myFifo);
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
abortNotifiedFIFO(&myFifo,1005);
printf("aborted 1005\n");
displayList(&myFifo);
pushNotifiedFIFO(&myFifo,newNotifiedFIFO_elt(sizeof(struct testData), 12345678, NULL, NULL));
displayList(&myFifo);
abortNotifiedFIFO(&myFifo,12345678);
printf("aborted 12345678\n");
displayList(&myFifo);
do {
tmp=pollNotifiedFIFO(&myFifo);
if (tmp) {
printf("pulled: %lu\n", tmp->key);
displayList(&myFifo);
} else
printf("Empty list \n");
} while(tmp);
tpool_t pool;
char params[]="1,2,3,u";
initTpool(params,&pool, true);
notifiedFIFO_t worker_back;
initNotifiedFIFO(&worker_back);
for (int i=0; i <1000 ; i++) {
notifiedFIFO_elt_t *work=newNotifiedFIFO_elt(sizeof(struct testData), i, &worker_back, processing);
struct testData *x=(struct testData *)NotifiedFifoData(work);
x->id=i;
pushTpool(&pool, work);
}
do {
tmp=pullTpool(&worker_back,&pool);
if (tmp) {
struct testData *dd=NotifiedFifoData(tmp);
printf("Result: %s\n",dd->txt);
delNotifiedFIFO_elt(tmp);
} else
printf("Empty list \n");
abortTpool(&pool,510);
} while(tmp);
return 0;
}
#endif
/*
Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <stdbool.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <assertions.h>
#include <LOG/log.h>
#ifdef DEBUG
#define THREADINIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
#else
#define THREADINIT PTHREAD_MUTEX_INITIALIZER
#endif
#define mutexinit(mutex) AssertFatal(pthread_mutex_init(&mutex,NULL)==0,"");
#define condinit(signal) AssertFatal(pthread_cond_init(&signal,NULL)==0,"");
#define mutexlock(mutex) AssertFatal(pthread_mutex_lock(&mutex)==0,"");
#define mutextrylock(mutex) pthread_mutex_trylock(&mutex)
#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,"");
#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,"");
typedef struct notifiedFIFO_elt_s {
struct notifiedFIFO_elt_s *next;
uint64_t key; //To filter out elements
struct notifiedFIFO_s *reponseFifo;
void (*processingFunc)(void *);
bool malloced;
uint64_t creationTime;
uint64_t startProcessingTime;
uint64_t endProcessingTime;
uint64_t returnTime;
void *msgData;
} notifiedFIFO_elt_t;
typedef struct notifiedFIFO_s {
notifiedFIFO_elt_t *outF;
notifiedFIFO_elt_t *inF;
pthread_mutex_t lockF;
pthread_cond_t notifF;
} notifiedFIFO_t;
// You can use this allocator or use any piece of memory
static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
uint64_t key,
notifiedFIFO_t *reponseFifo,
void (*processingFunc)(void *)) {
notifiedFIFO_elt_t *ret;
AssertFatal( NULL != (ret=(notifiedFIFO_elt_t *) malloc(sizeof(notifiedFIFO_elt_t)+size+32)), "");
ret->next=NULL;
ret->key=key;
ret->reponseFifo=reponseFifo;
ret->processingFunc=processingFunc;
// We set user data piece aligend 32 bytes to be able to process it with SIMD
ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32;
ret->malloced=true;
return ret;
}
static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt) {
return elt->msgData;
}
static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) {
if (elt->malloced) {
elt->malloced=false;
free(elt);
} else
printf("delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
//LOG_W(UTIL,"delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
}
static inline void initNotifiedFIFO(notifiedFIFO_t *nf) {
mutexinit(nf->lockF);
condinit (nf->notifF);
nf->inF=NULL;
nf->outF=NULL;
// No delete function: the creator has only to free the memory
}
static inline void pushNotifiedFIFO(notifiedFIFO_t *nf, notifiedFIFO_elt_t *msg) {
mutexlock(nf->lockF);
msg->next=NULL;
if (nf->outF == NULL)
nf->outF = msg;
if (nf->inF)
nf->inF->next = msg;
nf->inF = msg;
condbroadcast(nf->notifF);
mutexunlock(nf->lockF);
}
static inline notifiedFIFO_elt_t *pullNotifiedFIFO(notifiedFIFO_t *nf) {
mutexlock(nf->lockF);
while(!nf->outF)
condwait(nf->notifF, nf->lockF);
notifiedFIFO_elt_t *ret=nf->outF;
nf->outF=nf->outF->next;
if (nf->outF==NULL)
nf->inF=NULL;
mutexunlock(nf->lockF);
return ret;
}
static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) {
int tmp=mutextrylock(nf->lockF);
if (tmp != 0 )
return NULL;
notifiedFIFO_elt_t *ret=nf->outF;
if (ret!=NULL)
nf->outF=nf->outF->next;
if (nf->outF==NULL)
nf->inF=NULL;
mutexunlock(nf->lockF);
return ret;
}
// This function aborts all messages matching the key
// If the queue is used in thread pools, it doesn't cancels already running processing
// because the message has already been picked
static inline void abortNotifiedFIFO(notifiedFIFO_t *nf, uint64_t key) {
mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) {
if ( (*start)->key == key ) {
notifiedFIFO_elt_t *request=*start;
*start=(*start)->next;
delNotifiedFIFO_elt(request);
}
if (*start != NULL)
start=&(*start)->next;
}
mutexunlock(nf->lockF);
}
struct one_thread {
pthread_t threadID;
int id;
int coreID;
char name[256];
uint64_t runningOnKey;
bool abortFlag;
struct thread_pool *pool;
struct one_thread *next;
};
typedef struct thread_pool {
int activated;
bool measurePerf;
int traceFd;
int dummyTraceFd;
uint64_t cpuCyclesMicroSec;
uint64_t startProcessingUE;
int nbThreads;
bool restrictRNTI;
notifiedFIFO_t incomingFifo;
struct one_thread *allthreads;
} tpool_t;
static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
if (t->measurePerf) msg->creationTime=rdtsc();
pushNotifiedFIFO(&t->incomingFifo, msg);
}
static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
if (t->measurePerf)
msg->returnTime=rdtsc();
if (t->traceFd)
if(write(t->traceFd, msg, sizeof(*msg)));
return msg;
}
static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpool_t *t) {
notifiedFIFO_elt_t *msg= pollNotifiedFIFO(responseFifo);
if (msg == NULL)
return NULL;
if (t->measurePerf)
msg->returnTime=rdtsc();
if (t->traceFd)
if(write(t->traceFd, msg, sizeof(*msg)));
return msg;
}
static inline void abortTpool(tpool_t *t, uint64_t key) {
notifiedFIFO_t *nf=&t->incomingFifo;
mutexlock(nf->lockF);
notifiedFIFO_elt_t **start=&nf->outF;
while(*start!=NULL) {
if ( (*start)->key == key ) {
notifiedFIFO_elt_t *request=*start;
*start=(*start)->next;
delNotifiedFIFO_elt(request);
}
if (*start != NULL)
start=&(*start)->next;
}
struct one_thread *ptr=t->allthreads;
while(ptr!=NULL) {
if (ptr->runningOnKey==key)
ptr->abortFlag=true;
ptr=ptr->next;
}
mutexunlock(nf->lockF);
}
void initTpool(char *params,tpool_t *pool, bool performanceMeas);
#endif
# Thread pool
The thread pool is a working server, made of a set of worker threads that can be mapped on CPU cores.
Each worker loop on pick from the same input queue jobs to do.
When a job is done, the worker sends a return if a return is defined.
A selective abort allows to cancel parallel jobs (usage: a client pushed jobs, but from a response of one job, the other linked jobs becomes useless).
All the thread pool functions are thread safe, nevertheless the working functions are implemented by the thread pool client, so the client has to tackle the parallel execution of his functions called "processingFunc" hereafter.
## license
Author: Laurent Thomas, Open cells project
The owner share this piece code to Openairsoftware alliance as per OSA license terms
# jobs
A job is a message (notifiedFIFO_elt_t):
next: internal FIFO chain, do not set it
key: a long int that the client can use to identify a message or a group of messages
responseFifo: if the client defines a response FIFO, the message will be posted back after processing
processingFunc: any funtion (type void processingFunc(void *)) that the worker will launch
msgData: the data passed to processingFunc. It can be added automatically, or you can set it to a buffer you are managing
malloced: a boolean that enable internal free in these cases: no return Fifo or Abort feature
The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client.
# Queues of jobs
Queues are type of: notifiedFIFO_t that must be initialized by init_notifiedFIFO()
No delete function is required, the creator has only to free the data of type notifiedFIFO_t
push_notifiedFIFO() add a job in the queue
pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking
abort_notifiedFIFO() allows the customer to delete all waiting jobs that match with the key (see key in jobs definition)
# Thread pools
## initialization
The clients can create one or more thread pools with init_tpool()
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>"
## adding jobs
The client create their jobs messages as a notifiedFIFO_elt_t, then they push it with pushTpool() (that internally calls push_notifiedFIFO())
If they need a return, they have to create response queues with init_notifiedFIFO() and set this FIFO pointer in the notifiedFIFO_elt_t before pushing the job.
## abort
A abort service abortTpool() allows to abort all jobs that match a key (see jobs "key"). When the abort returns, it garanties no job (matching the key) response will be posted on response queues.
Nevertheless, jobs already performed before the return of abortTpool() are pushed in the response Fifo queue.
## Performance measurements
A performance measurement is integrated: the pool will automacillay fill timestamps:
* creationTime: time the request is push to the pool;
* startProcessingTime: time a worker start to run on the job
* endProcessingTime: time the worker finished the job
* returnTime: time the client reads the result
if you set the environement variable: thread-pool-measurements to a valid file name
These measurements will be wrote to this Linux pipe.
A tool to read the linux fifo and display it in ascii is provided: see the local directory Makefile for this tool and to compile the thread pool unitary tests.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -673,4 +673,45 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_dl_config_request_t;
typedef enum {nr_pusch_freq_hopping_disabled = 0 ,
nr_pusch_freq_hopping_enabled = 1
} nr_pusch_freq_hopping_t;
typedef struct{
uint8_t aperiodicSRS_ResourceTrigger;
} nfapi_nr_ul_srs_config_t;
typedef struct {
uint8_t bandwidth_part_ind;
uint16_t number_rbs;
uint16_t start_rb;
uint8_t frame_offset;
uint16_t number_symbols;
uint16_t start_symbol;
nr_pusch_freq_hopping_t pusch_freq_hopping;
uint8_t mcs;
uint8_t Qm;
uint8_t ndi;
uint8_t rv;
uint8_t harq_process_nbr;
int8_t accumulated_delta_PUSCH;
int8_t absolute_delta_PUSCH;
uint8_t n_layers;
uint8_t tpmi;
uint8_t n_dmrs_cdm_groups;
uint8_t dmrs_ports[4];
uint8_t n_front_load_symb;
nfapi_nr_ul_srs_config_t srs_config;
uint8_t csi_reportTriggerSize;
uint8_t maxCodeBlockGroupsPerTransportBlock;
uint8_t ptrs_dmrs_association_port;
uint8_t beta_offset_ind;
} nfapi_nr_ul_config_ulsch_pdu_rel15_t;
typedef struct {
uint16_t rnti;
nfapi_nr_ul_config_ulsch_pdu_rel15_t ulsch_pdu_rel15;
} nfapi_nr_ul_config_ulsch_pdu;
#endif
......@@ -453,7 +453,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int B,
unsigned int *C,
unsigned int *K,
unsigned int *Zout,
unsigned int *Zout,
unsigned int *F);
uint32_t nr_compute_tbs(uint8_t mcs,
......
......@@ -32,6 +32,7 @@
#include "coding_defs.h"
#include "assertions.h"
/*ref 36-212 v8.6.0 , pp 8-9 */
/* the highest degree is set by default */
......@@ -275,7 +276,7 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
break;
default:
crc_len=3;
AssertFatal(1,"Invalid crc_type \n");
}
for (int i=0; i<crc_len; i++)
......@@ -309,6 +310,9 @@ int check_crc(uint8_t* decoded_bytes, uint32_t n, uint32_t F, uint8_t crc_type)
crc = crc8(decoded_bytes,
n-8)>>24;
break;
default:
AssertFatal(1,"Invalid crc_type \n");
}
if (crc == oldcrc)
......
......@@ -34,7 +34,7 @@ int32_t nr_segmentation(unsigned char *input_buffer,
unsigned int B,
unsigned int *C,
unsigned int *K,
unsigned int *Zout,
unsigned int *Zout, // [hna] Zout is Zc
unsigned int *F)
{
......
......@@ -33,6 +33,7 @@
#include "assertions.h"
#include <math.h>
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
......@@ -77,12 +78,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
unsigned char abstraction_flag) {
// shortcuts
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
nfapi_nr_config_request_t *cfg = &gNB->gNB_config;
NR_gNB_COMMON *const common_vars = &gNB->common_vars;
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
LTE_eNB_PUSCH **const pusch_vars = gNB->pusch_vars;
LTE_eNB_SRS *const srs_vars = gNB->srs_vars;
LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;
int i, UE_id;
LOG_I(PHY,"[gNB %d] %s() About to wait for gNB to be configured\n", gNB->Mod_id, __FUNCTION__);
gNB->total_dlsch_bitrate = 0;
gNB->total_transmitted_bits = 0;
......@@ -110,7 +113,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
init_dfts();
// PBCH DMRS gold sequences generation
nr_init_pbch_dmrs(gNB);
// Polar encoder init for PBCH
//PDCCH DMRS init
gNB->nr_gold_pdcch_dmrs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
......@@ -148,6 +150,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
}
nr_init_pdsch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
/// Transport init necessary for NR synchro
init_nr_transport(gNB);
......@@ -167,14 +170,15 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
gNB->first_run_I0_measurements =
1; ///This flag used to be static. With multiple gNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
common_vars->rxdata = (int32_t **)NULL;
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t *));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t *));
for (i=0; i<15; i++) {
common_vars->txdataF[i] = (int32_t *)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) );
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
i,common_vars->txdataF[i],
fp->samples_per_frame_wCP*sizeof(int32_t));
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
for (i=0;i<15;i++){
common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t) ); // [hna] samples_per_frame without CP
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
i,common_vars->txdataF[i],
fp->samples_per_frame_wCP*sizeof(int32_t));
}
// Channel estimates for SRS
......@@ -423,6 +427,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
gNB_config->rf_config.ul_carrier_bandwidth.value,
gNB_config->sch_config.physical_cell_id.value,
fp->dl_CarrierFreq );
nr_init_frame_parms(gNB_config, fp);
if (RC.gNB[Mod_id][CC_id]->configured == 1) {
......@@ -442,6 +447,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_I(PHY, "Initialise nr transport\n");
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
......@@ -451,29 +457,38 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_E(PHY,"Can't get gNB dlsch structures for UE %d \n", i);
exit(-1);
}/* else {
gNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
gNB->dlsch[i][j]->rnti=0;
LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,gNB->dlsch[i][j], gNB->dlsch[i][j]->rnti);
}*/
///////////////////////// Initializing gNB ULSCH /////////////////////////
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
// ULSCH for RA
if(i==0) {
gNB->ulsch[i][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
if (!gNB->ulsch[i][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}
}
// ULSCH for data
gNB->ulsch[i+1][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
if (!gNB->ulsch[i+1][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}
//////////////////////////////////////////////////////////////////////////
}
//LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
//gNB->ulsch[1+i] = new_gNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
/*if (!gNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}*/
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
//gNB->transmission_mode[i] = fp->nb_antenna_ports_gNB==1 ? 1 : 2;
}
// ULSCH for RA
//gNB->ulsch[0] = new_gNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0);
/*if (!gNB->ulsch[0]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
exit(-1);
}*/
gNB->dlsch_SI = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
LOG_D(PHY,"gNB %d.%d : SI %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_SI);
gNB->dlsch_ra = new_gNB_dlsch(1,8,NSOFT, 0, fp, cfg);
......
......@@ -361,8 +361,13 @@ void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
uint16_t max_harq_tx )
{
int num_of_threads,num_of_code_words;
PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx;
for (num_of_threads=0;num_of_threads<RX_NB_TH_MAX;num_of_threads++)
for (num_of_code_words=0;num_of_code_words<NR_MAX_NB_CODEWORDS;num_of_code_words++)
phy_vars_ue->ulsch[eNB_id][num_of_threads][num_of_code_words]->Mlimit = max_harq_tx;
}
extern uint16_t beta_cqi[16];
......@@ -922,14 +927,14 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue,int abstraction_flag) {
for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
for (j=0; j<2; j++) {
for (k=0; k<RX_NB_TH_MAX; k++) {
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
AssertFatal((ue->dlsch[k][i][j] = new_nr_ue_dlsch(1,NUMBER_OF_HARQ_PID_MAX,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n");
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
LOG_D(PHY,"dlsch[%d][%d][%d] => %p\n",k,i,j,ue->dlsch[k][i][j]);
AssertFatal((ue->ulsch[k][i][j] = new_nr_ue_ulsch(ue->frame_parms.N_RB_UL, NUMBER_OF_HARQ_PID_MAX, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
LOG_D(PHY,"ulsch[%d][%d][%d] => %p\n",k,i,j,ue->ulsch[k][i][j]);
}
}
//AssertFatal((ue->ulsch[i] = new_ue_ulsch(ue->frame_parms.N_RB_UL, abstraction_flag))!=NULL,"Can't get ue ulsch structures\n");
ue->dlsch_SI[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
ue->dlsch_ra[i] = new_nr_ue_dlsch(1,1,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag);
......
......@@ -69,7 +69,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch)
#endif
if (dlsch->harq_processes[i]->b) {
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES);
free16(dlsch->harq_processes[i]->b,MAX_DLSCH_PAYLOAD_BYTES); //this should be MAX_NR_DLSCH_PAYLOAD_BYTES
dlsch->harq_processes[i]->b = NULL;
#ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch process %d b (%p)\n",i,dlsch->harq_processes[i]->b);
......@@ -195,8 +195,11 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
if (abstraction_flag==0) {
for (r=0; r<MAX_NUM_NR_DLSCH_SEGMENTS/bw_scaling; r++) {
// account for filler in first segment and CRCs for multiple segment case
// [hna] 8448 is the maximum CB size in NR
// 68*348 = 68*(maximum size of Zc)
// In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc)
dlsch->harq_processes[i]->c[r] = (uint8_t*)malloc16(8448);
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384);
dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output
if (dlsch->harq_processes[i]->c[r]) {
bzero(dlsch->harq_processes[i]->c[r],8448);
} else {
......@@ -272,7 +275,6 @@ int nr_dlsch_encoding(unsigned char *a,
unsigned int G;
unsigned int crc=1;
uint8_t harq_pid = dlsch->harq_ids[slot];
nfapi_nr_dl_config_dlsch_pdu_rel15_t rel15 = dlsch->harq_processes[harq_pid]->dlsch_pdu.dlsch_pdu_rel15;
uint16_t nb_rb = rel15.n_prb;
......@@ -302,7 +304,9 @@ int nr_dlsch_encoding(unsigned char *a,
A = rel15.transport_block_size;
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15.nb_layers);
LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order);
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, rel15.nb_layers);
......@@ -328,6 +332,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->B = A+24;
// dlsch->harq_processes[harq_pid]->b = a;
memcpy(dlsch->harq_processes[harq_pid]->b,a,(A/8)+4);
nr_segmentation(dlsch->harq_processes[harq_pid]->b,
......@@ -335,7 +340,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->B,
&dlsch->harq_processes[harq_pid]->C,
&dlsch->harq_processes[harq_pid]->K,
pz,
pz, // [hna] pz is Zc
&dlsch->harq_processes[harq_pid]->F);
F = dlsch->harq_processes[harq_pid]->F;
......@@ -388,6 +393,7 @@ int nr_dlsch_encoding(unsigned char *a,
//stop_meas(te_stats);
//printf("end ldpc encoder -- output\n");
//write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
#ifdef DEBUG_DLSCH_CODING
write_output("enc_input0.m","enc_in0",&dlsch->harq_processes[harq_pid]->c[0][0],Kr_bytes,1,4);
write_output("enc_output0.m","enc0",&dlsch->harq_processes[harq_pid]->d[0][0],(3*8*Kr_bytes)+12,1,4);
......@@ -429,6 +435,7 @@ int nr_dlsch_encoding(unsigned char *a,
rel15.redundancy_version,
E);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output ratematching e[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset);
......@@ -442,6 +449,7 @@ int nr_dlsch_encoding(unsigned char *a,
dlsch->harq_processes[harq_pid]->f+r_offset);
//stop_meas(i_stats);
#ifdef DEBUG_DLSCH_CODING
for (int i =0; i<16; i++)
printf("output interleaving f[%d]= %d r_offset %d\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset);
......@@ -455,5 +463,5 @@ int nr_dlsch_encoding(unsigned char *a,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
return(0);
return 0;
}
......@@ -38,7 +38,7 @@
#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
#define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056)
#define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056)
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
#define MAX_NUM_NR_RE (14*273*12)
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_ulsch.h
* \brief functions used for PUSCH/ULSCH physical and transport channels for gNB
* \author Ahmed Hussein
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \note
* \warning
*/
#include "PHY/defs_gNB.h"
void free_gNB_ulsch(NR_gNB_ULSCH_t *ulsch);
NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint16_t nb_symb_sch,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag);
This diff is collapsed.
......@@ -52,9 +52,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
ncoef = 32767 - coef;
//#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx%1024,subframe,ue->rx_offset);
//#endif //DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d: rx_offset (before) = %d\n",subframe,ue->rx_offset);
// we only use channel estimates from tx antenna 0 here
......@@ -122,8 +120,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
#ifdef DEBUG_PHY
LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx,
LOG_D(PHY,"AbsSubframe %d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
subframe,
ue->current_thread_id[subframe],
diff,
......
......@@ -203,14 +203,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
#endif
}
else {
LOG_E(PHY,"[UE][FATAL] Frame %d nr_tti_rx %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,nr_tti_rx);
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n",nr_tti_rx);
return(-1);
}
beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id];
break;
default:
LOG_E(PHY,"[UE][FATAL] Frame %d nr_tti_rx %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,nr_tti_rx,type);
LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type);
return(-1);
break;
}
......
......@@ -188,11 +188,6 @@ int nr_pbch_detection(PHY_VARS_NR_UE *ue, int pbch_initial_symbol, runmode_t mod
// ue->pbch_vars[0]->decoded_output[0] = ue->pbch_vars[0]->decoded_output[2];
// ue->pbch_vars[0]->decoded_output[2] = dummy;
for(int i=0; i<RX_NB_TH;i++)
{
ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
}
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully\n",ue->Mod_id);
#endif
......@@ -379,9 +374,8 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
if (ue->UE_scan_carrier == 0) {
#if UE_AUTOTEST_TRACE
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n",
LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : rx_offset %d, freq_offset %d \n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
ue->rx_offset,
ue->common_vars.freq_offset );
#endif
......@@ -392,30 +386,7 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
}
#if DISABLE_LOG_X
printf("[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
10*log10(ue->measurements.rssi),
ue->rx_total_gain_dB,
ue->measurements.n0_power_tot_dBm,
10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
(10*log10(ue->measurements.rsrq[0])));
printf("[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
duplex_string[fp->frame_type],
prefix_string[fp->Ncp],
fp->Nid_cell,
fp->N_RB_DL,
fp->phich_config_common.phich_duration,
phich_string[fp->phich_config_common.phich_resource],
fp->nb_antenna_ports_eNB);
#else
LOG_I(PHY, "[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
LOG_I(PHY, "[UE %d] RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm, rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
10*log10(ue->measurements.rssi),
ue->rx_total_gain_dB,
......@@ -433,22 +404,12 @@ int nr_initial_sync(PHY_VARS_NR_UE *ue, runmode_t mode)
fp->phich_config_common.phich_duration,
phich_string[fp->phich_config_common.phich_resource],
fp->nb_antenna_ports_eNB);*/
#endif
#if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
# if DISABLE_LOG_X
printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
LOG_I(PHY, "[UE %d] Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
# else
LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
ue->Mod_id,
ue->proc.proc_rxtx[0].frame_rx,
openair0_cfg[0].rx_freq[0]+ue->common_vars.freq_offset,
ue->common_vars.freq_offset);
# endif
#endif
} else {
#ifdef DEBUG_INITIAL_SYNC
......
......@@ -61,10 +61,10 @@ void free_nr_ue_dlsch(NR_UE_DLSCH_t *dlsch);
NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t max_turbo_iterations,uint8_t N_RB_DL, uint8_t abstraction_flag);
void free_ue_ulsch(NR_UE_ULSCH_t *ulsch);
void free_nr_ue_ulsch(NR_UE_ULSCH_t *ulsch);
NR_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
NR_UE_ULSCH_t *new_nr_ue_ulsch(unsigned char N_RB_UL, int number_of_harq_pids, uint8_t abstraction_flag);
void fill_UE_dlsch_MCH(PHY_VARS_NR_UE *ue,int mcs,int ndi,int rvidx,int eNB_id);
......@@ -1006,6 +1006,25 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t is_crnti,
uint8_t llr8_flag);
int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid);
/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param[in] in Pointer to input bits
@param[in] size of input bits
@param[in] Nid cell id
@param[in] n_RNTI CRNTI
@param[out] out the scrambled bits
*/
void nr_pusch_codeword_scrambling(uint8_t *in,
uint16_t size,
uint32_t Nid,
uint32_t n_RNTI,
uint32_t* out);
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
UE_nr_rxtx_proc_t *proc,
int eNB_id,
......
......@@ -102,6 +102,8 @@ typedef struct {
uint16_t first_rb;
/// Current Number of RBs
uint16_t nb_rb;
/// number of layers
uint8_t Nl;
/// Last TPC command
uint8_t TPC;
/// Transport block size
......@@ -110,20 +112,24 @@ typedef struct {
uint32_t B;
/// Length of ACK information (bits)
uint8_t O_ACK;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
/// Index of current HARQ round for this ULSCH
uint8_t round;
/// MCS format of this ULSCH
uint8_t mcs;
/// Redundancy-version of the current sub-frame
uint8_t rvidx;
/// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
unsigned char *a;
/// Pointer to the payload + CRC
uint8_t *b;
/// Pointers to transport block segments
uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
/// LDPC-code outputs
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][3*8448];
/// Interleaver outputs
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*8448];
uint8_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
/// LDPC-code outputs (TS 36.212 V15.4.0, Sec 5.3.2 p. 17)
uint8_t e[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
/// Rate matching (Interleaving) outputs (TS 36.212 V15.4.0, Sec 5.4.2.2 p. 30)
uint8_t f[MAX_NUM_NR_CHANNEL_BITS] __attribute__((aligned(32)));
/// Number of code segments
uint32_t C;
/// Number of bits in code segments
......@@ -158,6 +164,8 @@ typedef struct {
typedef struct {
/// Current Number of Symbols
uint8_t Nsymb_pusch;
/// number of DMRS resource elements
uint8_t nb_re_dmrs;
/// SRS active flag
uint8_t srs_active;
//#if defined(UPGRADE_RAT_NR)
......@@ -168,6 +176,7 @@ typedef struct {
// UL number of harq processes
uint8_t number_harq_processes_for_pusch;
#endif
/*
/// Pointer to CQI data (+1 for 8 bits crc)
uint8_t o[1+MAX_CQI_BYTES];
/// Length of CQI data (bits)
......@@ -180,22 +189,25 @@ typedef struct {
uint8_t O_RI;
/// Pointer to ACK
uint8_t o_ACK[4];
*/
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
uint8_t O_CQI_MIN;
/// ACK/NAK Bundling flag
uint8_t bundling;
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t e[MAX_NUM_CHANNEL_BITS];
/// Concatenated "g"-sequences (for definition see 36-212 V15.4.0 2018-12, p.31)
uint8_t g[MAX_NUM_NR_CHANNEL_BITS];
/// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t h[MAX_NUM_CHANNEL_BITS];
uint8_t h[MAX_NUM_NR_CHANNEL_BITS];
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
uint8_t b_tilde[MAX_NUM_CHANNEL_BITS];
uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS];
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
int32_t d[MAX_NUM_RE];
int32_t d[MAX_NUM_NR_RE];
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
int32_t z[MAX_NUM_RE];
int32_t z[MAX_NUM_NR_RE];
/*
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
uint8_t q[MAX_CQI_PAYLOAD];
/// coded and interleaved CQI bits
uint8_t o_w[(MAX_CQI_BITS+8)*3];
/// coded CQI bits
......@@ -204,6 +216,7 @@ typedef struct {
uint8_t q_ACK[MAX_ACK_PAYLOAD];
/// coded RI bits
uint8_t q_RI[MAX_RI_PAYLOAD];
*/
/// beta_offset_cqi times 8
uint16_t beta_offset_cqi_times8;
/// beta_offset_ri times 8
......@@ -229,9 +242,9 @@ typedef struct {
/// num active cba group
uint8_t num_active_cba_groups;
/// num dci found for cba
uint8_t num_cba_dci[10];
//uint8_t num_cba_dci[10];
/// allocated CBA RNTI
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
//uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
/// UL max-harq-retransmission
uint8_t Mlimit;
} NR_UE_ULSCH_t;
......
This diff is collapsed.
......@@ -38,6 +38,10 @@
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/impl_defs_top.h"
#include "PHY/defs_common.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h"
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
......@@ -72,6 +76,7 @@ typedef struct {
uint64_t dci_pdu[2];
} NR_gNB_DCI_ALLOC_t;
typedef struct {
uint8_t num_dci;
uint8_t num_pdsch_rnti;
......@@ -79,6 +84,14 @@ typedef struct {
} NR_gNB_PDCCH;
typedef enum {
NR_SCH_IDLE,
NR_ACTIVE,
NR_CBA_ACTIVE,
NR_DISABLED
} NR_SCH_status_t;
typedef struct {
/// Nfapi DLSCH PDU
nfapi_nr_dl_config_dlsch_pdu dlsch_pdu;
......@@ -114,7 +127,6 @@ typedef struct {
typedef struct {
/// Pointers to 16 HARQ processes for the DLSCH
NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES];
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
......@@ -160,6 +172,170 @@ typedef struct {
} NR_gNB_DLSCH_t;
typedef struct {
/// Nfapi ULSCH PDU
nfapi_nr_ul_config_ulsch_pdu ulsch_pdu;
/// Frame where current HARQ round was sent
uint32_t frame;
/// Subframe where current HARQ round was sent
uint32_t subframe;
/// Index of current HARQ round for this DLSCH
uint8_t round;
/// Last TPC command
uint8_t TPC;
/// MIMO mode for this DLSCH
MIMO_mode_t mimo_mode;
/// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK)
uint8_t dci_alloc;
/// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI)
uint8_t rar_alloc;
/// Status Flag indicating for this ULSCH (idle,active,disabled)
NR_SCH_status_t status;
/// Subframe scheduling indicator (i.e. Transmission opportunity indicator)
uint8_t subframe_scheduling_flag;
/// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator)
uint8_t subframe_cba_scheduling_flag;
/// PHICH active flag
uint8_t phich_active;
/// PHICH ACK
uint8_t phich_ACK;
/// First Allocated RB - previous scheduling. This is needed for PHICH generation which is done after a new scheduling
uint16_t previous_first_rb;
/// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around
uint8_t handled;
/// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up)
// int calibration_flag;
/// delta_TF for power control
int32_t delta_TF;
/////////////////////// ulsch decoding ///////////////////////
/// Transport block size (This is A from 38.212 V15.4.0 section 5.1)
uint32_t TBS;
/// Pointer to the payload (38.212 V15.4.0 section 5.1)
uint8_t *b;
/// The payload + CRC (24 bits) in bits (38.212 V15.4.0 section 5.1)
uint32_t B;
/// Pointers to code blocks after code block segmentation and CRC attachment (38.212 V15.4.0 section 5.2.2)
uint8_t *c[MAX_NUM_NR_ULSCH_SEGMENTS];
/// Number of bits in each code block (38.212 V15.4.0 section 5.2.2)
uint32_t K;
/// Number of "Filler" bits added in the code block segmentation (38.212 V15.4.0 section 5.2.2)
uint32_t F;
/// Number of code blocks after code block segmentation (38.212 V15.4.0 section 5.2.2)
uint32_t C;
/// Pointers to code blocks after LDPC coding (38.212 V15.4.0 section 5.3.2)
int16_t *d[MAX_NUM_NR_ULSCH_SEGMENTS];
/// LDPC processing buffer
t_nrLDPC_procBuf* p_nrLDPC_procBuf[MAX_NUM_NR_ULSCH_SEGMENTS];
/// LDPC lifting size (38.212 V15.4.0 table 5.3.2-1)
uint32_t Z;
/// code blocks after bit selection in rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
int16_t e[MAX_NUM_NR_DLSCH_SEGMENTS][3*8448];
/// Number of bits in each code block after rate matching for LDPC code (38.212 V15.4.0 section 5.4.2.1)
uint32_t E;
/// Number of soft channel bits after code block concatenation (38.212 V15.4.0 section 5.5)
uint32_t G;
//////////////////////////////////////////////////////////////
/////////////////////////// DMRS /////////////////////////////
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2)
uint8_t n_DMRS;
/// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
uint8_t n_DMRS2;
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling
/// This is needed for PHICH generation which
/// is done after a new scheduling
uint8_t previous_n_DMRS;
//////////////////////////////////////////////////////////////
///////////////////// UCI multiplexing ///////////////////////
/// CQI CRC status
uint8_t cqi_crc_status;
/// Pointer to CQI data
uint8_t o[MAX_CQI_BYTES];
/// Format of CQI data
UCI_format_t uci_format;
/// Length of CQI data under RI=1 assumption(bits)
uint8_t Or1;
/// Length of CQI data under RI=2 assumption(bits)
uint8_t Or2;
/// Rank information
uint8_t o_RI[2];
/// Length of rank information (bits)
uint8_t O_RI;
/// Pointer to ACK
uint8_t o_ACK[4];
/// Length of ACK information (bits)
uint8_t O_ACK;
/// The value of DAI in DCI format 0
uint8_t V_UL_DAI;
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
int8_t q[MAX_CQI_PAYLOAD];
/// number of coded CQI bits after interleaving
uint8_t o_RCC;
/// coded and interleaved CQI bits
int8_t o_w[(MAX_CQI_BITS+8)*3];
/// coded CQI bits
int8_t o_d[96+((MAX_CQI_BITS+8)*3)];
/// coded ACK bits
int16_t q_ACK[MAX_ACK_PAYLOAD];
/// coded RI bits
int16_t q_RI[MAX_RI_PAYLOAD];
/// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled
uint8_t h[MAX_NUM_CHANNEL_BITS];
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
int16_t w[MAX_NUM_ULSCH_SEGMENTS][3*(6144+64)];
//////////////////////////////////////////////////////////////
} NR_UL_gNB_HARQ_t;
typedef struct {
/// Pointers to 16 HARQ processes for the ULSCH
NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
/// Current HARQ process id
int harq_process_id[NR_MAX_SLOTS_PER_FRAME];
/// HARQ process mask, indicates which processes are currently active
uint16_t harq_mask;
/// ACK/NAK Bundling flag
uint8_t bundling;
/// beta_offset_cqi times 8
uint16_t beta_offset_cqi_times8;
/// beta_offset_ri times 8
uint16_t beta_offset_ri_times8;
/// beta_offset_harqack times 8
uint16_t beta_offset_harqack_times8;
/// Flag to indicate that gNB awaits UE Msg3
uint8_t Msg3_active;
/// Flag to indicate that gNB should decode UE Msg3
uint8_t Msg3_flag;
/// Subframe for Msg3
uint8_t Msg3_subframe;
/// Frame for Msg3
uint32_t Msg3_frame;
/// Allocated RNTI for this ULSCH
uint16_t rnti;
/// RNTI type
uint8_t rnti_type;
/// cyclic shift for DM RS
uint8_t cyclicShift;
/// for cooperative communication
uint8_t cooperation_flag;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
/// Maximum number of LDPC iterations
uint8_t max_ldpc_iterations;
/// number of iterations used in last LDPC decoding
uint8_t last_iteration_cnt;
/// num active cba group
uint8_t num_active_cba_groups;
/// num active cba group
uint16_t cba_rnti[NUM_MAX_CBA_GROUP];
} NR_gNB_ULSCH_t;
typedef struct {
/// \brief Pointers (dynamic) to the received data in the time domain.
/// - first index: rx antenna [0..nb_antennas_rx[
......@@ -394,17 +570,18 @@ typedef struct PHY_VARS_gNB_s {
LTE_eNB_PHICH phich_vars[2];
NR_gNB_COMMON common_vars;
LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PRACH prach_vars;
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
LTE_eNB_UCI uci_vars[NUMBER_OF_UE_MAX];
LTE_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
LTE_eNB_PRACH prach_vars;
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1][2]; // [Nusers times + number of RA][2 codewords], index 0 in [NUMBER_OF_UE_MAX+1] is for RA
// LTE_eNB_ULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA
NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p;
NR_gNB_DLSCH_t *dlsch_MCH;
NR_gNB_DLSCH_t *dlsch_PCH;
LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
LTE_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
uint8_t pbch_configured;
uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE
......
......@@ -267,27 +267,6 @@ typedef struct {
uint8_t CC_id;
/// Last RX timestamp
openair0_timestamp timestamp_rx;
/// pthread attributes for main UE thread
pthread_attr_t attr_ue;
/// scheduling parameters for main UE thread
struct sched_param sched_param_ue;
/// pthread descriptor main UE thread
pthread_t pthread_ue;
/// \brief Instance count for synch thread.
/// \internal This variable is protected by \ref mutex_synch.
int instance_cnt_synch;
/// pthread attributes for synch processing thread
pthread_attr_t attr_synch;
/// scheduling parameters for synch thread
struct sched_param sched_param_synch;
/// pthread descriptor synch thread
pthread_t pthread_synch;
/// condition variable for UE synch thread;
pthread_cond_t cond_synch;
/// mutex for UE synch thread
pthread_mutex_t mutex_synch;
/// set of scheduling variables RXn-TXnp4 threads
UE_nr_rxtx_proc_t proc_rxtx[RX_NB_TH];
} UE_nr_proc_t;
typedef enum {
......@@ -1056,8 +1035,8 @@ typedef struct {
NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
NR_UE_ULSCH_t *ulsch[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads
NR_UE_ULSCH_t *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words
NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX];
NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX];
......
......@@ -87,10 +87,10 @@
#define NR_MAX_CSET_DURATION 3
#define NR_MAX_NB_RBG 18
#define NR_MAX_NB_LAYERS 8
#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3)
#define NR_MAX_NB_CODEWORDS 2
#define NR_MAX_NB_HARQ_PROCESSES 16
#define NR_MAX_PDSCH_ENCODED_LENGTH 950984
#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_PDSCH_TBS 3824
typedef enum {
......
......@@ -232,7 +232,6 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
printf("half frame bit: %d\n", phy_config->config_req.pbch_config.half_frame_bit);
printf("-------------------------------\n");
PHY_vars_UE_g[0][0]->proc.proc_rxtx[0].frame_rx = phy_config->config_req.pbch_config.system_frame_number;
}
if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON){
......
......@@ -150,7 +150,7 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i
*
*********************************************************************/
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_harq_processes_pusch)
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx, uint8_t number_harq_processes_pusch)
{
NR_UE_ULSCH_t *ulsch;
......@@ -160,7 +160,7 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h
memset(ulsch,0,sizeof(NR_UE_ULSCH_t));
ue->ulsch[gNB_id] = ulsch;
ue->ulsch[thread_id][gNB_id][code_word_idx] = ulsch;
}
else {
LOG_E(PHY, "Fatal memory allocation problem at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
......@@ -185,7 +185,7 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h
}
for (int slot_tx = 0; slot_tx < NR_MAX_SLOTS_PER_FRAME; slot_tx++) {
ue->ulsch[gNB_id]->harq_process_id[slot_tx] = NR_MAX_HARQ_PROCESSES;
ue->ulsch[thread_id][gNB_id][code_word_idx]->harq_process_id[slot_tx] = NR_MAX_HARQ_PROCESSES;
}
}
......@@ -202,9 +202,9 @@ void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_h
*
*********************************************************************/
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id)
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx)
{
NR_UE_ULSCH_t *ulsch = ue->ulsch[gNB_id];
NR_UE_ULSCH_t *ulsch = ue->ulsch[thread_id][gNB_id][code_word_idx];
for (int process_id = 0; process_id < ulsch->number_harq_processes_for_pusch; process_id++) {
......@@ -215,7 +215,7 @@ void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id)
free16(ulsch, sizeof(NR_UE_ULSCH_t));
ue->ulsch[gNB_id] = NULL;
ue->ulsch[thread_id][gNB_id][code_word_idx] = NULL;
}
/*******************************************************************
......
......@@ -83,17 +83,21 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i
/** \brief This function configures uplink HARQ context
@param PHY_VARS_NR_UE ue context
@param gNB_id gNodeB identifier
@param thread_id RXTX thread index
@param code_word_idx code word index
@param number_harq_processes_pusch maximum number of uplink HARQ processes
@returns none */
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, uint8_t number_harq_processes_pusch);
void config_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx, uint8_t number_harq_processes_pusch);
/** \brief This function releases uplink HARQ context
@param PHY_VARS_NR_UE ue context
@param gNB_id gNodeB identifier
@param thread_id RXTX thread index
@param code_word_idx code word index
@returns none */
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id);
void release_uplink_harq_process(PHY_VARS_NR_UE *ue, int gNB_id, int thread_id, int code_word_idx);
/** \brief This function stores slot for transmission in HARQ context
@param ulsch uplink context
......
......@@ -36,7 +36,7 @@
#include "PHY/defs_UE.h"
#include "PHY/phy_extern_ue.h"
#include <sched.h>
#include "targets/RT/USER/lte-softmodem.h"
#include "executables/nr-uesoftmodem.h"
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#include "SCHED_UE/sched_UE.h"
......@@ -5116,13 +5116,13 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
if (msg_p != NULL) {
switch (ITTI_MSG_ID(msg_p)) {
case PHY_FIND_CELL_REQ:
LOG_I(PHY, "[UE %d] Received %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p));
LOG_I(PHY, "[UE ] Received %s\n", ITTI_MSG_NAME (msg_p));
/* TODO process the message */
break;
default:
LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p));
LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) , ITTI_MSG_NAME (msg_p));
break;
}
......
......@@ -409,7 +409,7 @@ int main(int argc, char **argv) {
r_im[i] = malloc(frame_length_complex_samples * sizeof(double));
bzero(r_im[i], frame_length_complex_samples * sizeof(double));
txdata[i] = malloc(frame_length_complex_samples * sizeof(int));
bzero(r_re[i], frame_length_complex_samples * sizeof(int));
bzero(r_re[i], frame_length_complex_samples * sizeof(int)); // [hna] r_re should be txdata
}
if (pbch_file_fd != NULL) {
......@@ -485,7 +485,7 @@ int main(int argc, char **argv) {
rel15->nb_layers = Nl;
rel15->nb_re_dmrs = nb_re_dmrs;
rel15->transport_block_size = TBS;
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384);
double *modulated_input = malloc16(sizeof(double) * 16 * 68 * 384); // [hna] 16 segments, 68*Zc
short *channel_output_fixed = malloc16(sizeof(short) * 16 * 68 * 384);
short *channel_output_uncoded = malloc16(sizeof(unsigned short) * 16 * 68 * 384);
double errors_bit_uncoded = 0;
......
This diff is collapsed.
......@@ -54,6 +54,8 @@
int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
{
int gNB_id = 0;
int thread_number = 0;
int code_word_idx = 0;
int harq_pid = 0;
int ndi = 1;
uint8_t rnti_type = _C_RNTI_;
......@@ -61,7 +63,7 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
printf("\nHARQ Uplink \n");
config_uplink_harq_process(phy_vars_ue , gNB_id, NR_DEFAULT_DLSCH_HARQ_PROCESSES);
config_uplink_harq_process(phy_vars_ue , gNB_id, thread_number, code_word_idx, NR_DEFAULT_DLSCH_HARQ_PROCESSES);
NR_UE_ULSCH_t *ulsch_harq = phy_vars_ue->ulsch[gNB_id];
......@@ -91,7 +93,7 @@ int test_harq_uplink(PHY_VARS_NR_UE *phy_vars_ue)
}
}
release_uplink_harq_process(phy_vars_ue , gNB_id);
release_uplink_harq_process(phy_vars_ue , gNB_id, thread_number, code_word_idx);
return 0;
}
......
......@@ -58,11 +58,7 @@ extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES
#ifndef PHYSIM
#define NB_INST 1
#else
extern unsigned char NB_INST;
#endif
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern unsigned char NB_RN_INST;
......
......@@ -43,10 +43,10 @@
/*!\brief UE layer 2 status */
typedef enum {
CONNECTION_OK = 0,
CONNECTION_LOST,
PHY_RESYNCH,
PHY_HO_PRACH
UE_CONNECTION_OK = 0,
UE_CONNECTION_LOST,
UE_PHY_RESYNCH,
UE_PHY_HO_PRACH
} NR_UE_L2_STATE_t;
typedef struct {
......
......@@ -30,8 +30,8 @@
* \warning
*/
#ifndef __LAYER2_MAC_PROTO_H__
#define __LAYER2_MAC_PROTO_H__
#ifndef __LAYER2_MAC_UE_PROTO_H__
#define __LAYER2_MAC_UE_PROTO_H__
#include "mac_defs.h"
#include "mac.h"
......
......@@ -686,7 +686,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(
mac->scheduled_response.dl_config = dl_config;
return CONNECTION_OK;
return UE_CONNECTION_OK;
}
//////////////
......
......@@ -102,13 +102,13 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
0, 0); // TODO check tx/rx frame/slot is need for NR version
switch(ret){
case CONNECTION_OK:
case UE_CONNECTION_OK:
break;
case CONNECTION_LOST:
case UE_CONNECTION_LOST:
break;
case PHY_RESYNCH:
case UE_PHY_RESYNCH:
break;
case PHY_HO_PRACH:
case UE_PHY_HO_PRACH:
break;
default:
break;
......
......@@ -44,17 +44,11 @@ extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue;
extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
#ifndef PHY_EMUL
#ifndef PHYSIM
//#define NB_INST 1
#else
extern unsigned char NB_INST;
#endif
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern unsigned short NODE_ID[1];
extern void* bigphys_malloc(int);
#endif
//CONSTANTS
......
......@@ -43,17 +43,11 @@ extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue;
extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue;
#ifndef PHY_EMUL
#ifndef PHYSIM
//#define NB_INST 1
#else
extern unsigned char NB_INST;
#endif
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern unsigned short NODE_ID[1];
extern void* bigphys_malloc(int);
#endif
//CONSTANTS
......
......@@ -424,7 +424,7 @@ extern "C"
* \returns 0 in success
*/
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
#define gettid() syscall(__NR_gettid)
/*@}*/
#ifdef __cplusplus
......
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
#define OPENAIRINTERFACE5G_LIMITS_H_
#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
#if 1 /*defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)*/
# define NUMBER_OF_eNB_MAX 1
# define NUMBER_OF_gNB_MAX 1
# define NUMBER_OF_RU_MAX 2
# define NUMBER_OF_NR_RU_MAX 2
# ifndef PHYSIM
# ifndef UE_EXPANSION
# define NUMBER_OF_UE_MAX 16
# define NUMBER_OF_NR_UE_MAX 16
......@@ -17,6 +18,12 @@
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# define NUMBER_OF_CONNECTED_gNB_MAX 1
# endif
# else
# define NUMBER_OF_UE_MAX 1
# define NUMBER_OF_NR_UE_MAX 1
# define NUMBER_OF_CONNECTED_eNB_MAX 1
# define NUMBER_OF_CONNECTED_gNB_MAX 1
# endif
#else
# define NUMBER_OF_eNB_MAX 7
# define NUMBER_OF_gNB_MAX 7
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment