Commit aff80ba1 authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge branch 'integration_develop-nr_2019w24' into 'develop-nr'

Integration develop nr 2019w24

See merge request oai/openairinterface5g!615
parents a404e190 99fa6a9f
......@@ -252,7 +252,7 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=11
NB_PATTERN_FILES=12
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
......@@ -331,7 +331,7 @@ case $key in
VM_NAME=ci-phy-sim
ARCHIVES_LOC=phy_sim
LOG_PATTERN=.Rel15.txt
NB_PATTERN_FILES=11
NB_PATTERN_FILES=12
BUILD_OPTIONS="--phy_simulators"
VM_MEMORY=8192
RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b"
......
......@@ -619,8 +619,6 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c)
##########################################################
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
......@@ -1218,6 +1216,7 @@ set(PHY_SRC_RU
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c
${OPENAIR1_DIR}/PHY/MODULATION/gen_75KHz.cpp
${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c
......@@ -1272,6 +1271,7 @@ set(PHY_SRC_UE
set(PHY_NR_SRC
${OPENAIR1_DIR}/PHY/INIT/nr_init.c
${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pss.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sss.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_pbch.c
......@@ -1281,8 +1281,11 @@ set(PHY_SRC_UE
${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_ulsch.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_tbs_tools.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_llr_computation.c
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
......@@ -1303,8 +1306,9 @@ set(PHY_SRC_UE
)
set(PHY_NR_UE_SRC
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/INIT/nr_parms.c
${OPENAIR1_DIR}/PHY/MODULATION/nr_modulation.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pss_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c
......@@ -1316,12 +1320,14 @@ set(PHY_SRC_UE
${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
${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_sch_dmrs.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_prach.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold_ue.c
......@@ -2127,6 +2133,12 @@ add_library(gnbScope MODULE
)
target_link_libraries(gnbScope forms)
add_library(rfsimulator MODULE
${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
)
target_link_libraries(rfsimulator SIMU ${ATLAS_LIBRARIES})
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
#include T directory even if the T is off because T macros are in the code
......@@ -2573,6 +2585,12 @@ add_executable(nr_ulschsim
${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)
add_executable(nr_ulsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
${OPENAIR_DIR}/common/utils/backtrace.c
${T_SOURCE})
target_link_libraries(nr_ulsim -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)
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
......
......@@ -684,7 +684,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="nr_pucchsim dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim"
simlist="nr_pucchsim dlsim ulsim polartest ldpctest smallblocktest nr_pbchsim nr_dlschsim nr_dlsim nr_ulschsim nr_ulsim"
for f in $simlist ; do
compilations \
phy_simulators $f \
......
......@@ -313,6 +313,7 @@ const char* eurecomFunctionsNames[] = {
"phy_enb_prach_rx",
"phy_ru_prach_rx",
"phy_enb_pdcch_tx",
"phy_enb_common_tx",
"phy_enb_rs_tx",
"phy_ue_generate_prach",
"phy_ue_ulsch_modulation",
......
......@@ -292,6 +292,7 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_MODULATION,
......
......@@ -41,7 +41,7 @@ typedef struct {
} T_cache_t;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_FUNCTIONS 192//190
#define VCD_NUM_FUNCTIONS 193//192//190
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES 136//128
......
......@@ -2249,6 +2249,11 @@ ID = VCD_FUNCTION_PHY_ENB_PDCCH_TX
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_enb_pdcch_tx
ID = VCD_FUNCTION_PHY_ENB_COMMON_TX
DESC = VCD function PHY_ENB_COMMON_TX
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = phy_enb_common_tx
ID = VCD_FUNCTION_PHY_ENB_RS_TX
DESC = VCD function PHY_ENB_RS_TX
GROUP = ALL:VCD:ENB:VCD_FUNCTION
......
**Table of Contents**
1. [OpenAirInterface eNB Feature Set](#openairinterface-enb-feature-set)
1. [eNB PHY Layer](#enb-phy-layer)
2. [eNB MAC Layer](#enb-mac-layer)
3. [eNB RLC Layer](#enb-rlc-layer)
4. [eNB PDCP Layer](#enb-pdcp-layer)
5. [eNB RRC Layer](#enb-rrc-layer)
6. [eNB X2AP](#enb-x2ap)
7. [eNB Advanced Features](#enb-advanced-features)
2. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set)
1. [LTE UE PHY Layer](#lte-ue-phy-layer)
2. [LTE UE MAC Layer](#lte-ue-mac-layer)
3. [LTE UE RLC Layer](#lte-ue-rlc-layer)
4. [LTE UE PDCP Layer](#lte-ue-pdcp-layer)
5. [LTE UE RRC Layer](#lte-ue-rrc-layer)
3. [OpenAirInterface Functional Split](#openairinterface-functional-split)
4. [OpenAirInterface 5G-NR Feature Set](#openairinterface-5g-nr-feature-set)
1. [General Parameters](#general-parameters)
2. [gNB Features](#gnb-features)
1. [gNB Physical Layer](#gnb-phy-layer)
2. [gNB Higher Layers](#gnb-higher-layers)
3. [NR UE Features](#nr-ue-features)
1. [NR UE Physical Layer](#nr-ue-phy-layer)
2. [NR UE Higher Layers](#nr-ue-higher-layers)
# OpenAirInterface Block diagram #
![Block Diagram](./oai_enb_block_diagram.png)
# OpenAirInterface eNB Feature Set #
## eNB PHY Layer ##
The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provides the following features:
- LTE release 8.6 compliant, and implements a subset of release 10
- FDD and TDD configurations: 1 (experimental) and 3
- Bandwidth: 5, 10, and 20 MHz
- Transmission modes: 1, 2 (stable), 3, 4, 5, 6, 7 (experimental)
- Max number of antennas: 2
- CQI/PMI reporting: aperiodic, feedback mode 3 - 0 and 3 - 1
- PRACH preamble format 0
- All downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH
- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS
- HARQ support (UL and DL)
- Highly optimized base band processing (including turbo decoder)
### Performances ###
**Transmission Mode, Bandwidth** | **Expected Throughput** | **Measured Throughput** | **Measurement Conditions**
-------------------------------- | ----------------------- | ------------------------| ----------------:
FDD DL: 5 MHz, 25 PRBS/ MCS 28 | 16 - 17 Mbit/s | TM1: 17.0 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | TM1: 32.8 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD DL: 20 MHz, 100 PRBS/ MCS 28 | 70 Mbit/s | TM1: 69.9 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
| | |
FDD UL: 5 MHz, 25 PRBS/ MCS 20 | 9 Mbit/s | TM1: 8.28 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | TM1: 15.2 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
FDD UL: 20 MHz, 100 PRBS/ MCS 20 | 35 Mbit/s | TM1: 18.6 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
| |
TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | 3.33 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | 8.90 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | N/A | COTS-UE Cat 4 (150/50 Mbps)
| | |
TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | 1.66 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | 1.89 Mbits/s | COTS-UE Cat 4 (150/50 Mbps)
TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | N/A | COTS-UE Cat 4 (150/50 Mbps)
- Number of supported UEs: **To Be Completed**
## eNB MAC Layer ##
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
- RRC interface for CCCH, DCCH, and DTCH
- Proportional fair scheduler (round robin scheduler soon)
- DCI generation
- HARQ Support
- RA procedures and RNTI management
- RLC interface (AM, UM)
- UL power control
- Link adaptation
## eNB RLC Layer ##
The RLC layer implements a full specification of the 3GPP 36.322 release v9.3.
- RLC TM (mainly used for BCCH and CCCH)
* Neither segment nor concatenate RLC SDUs
* Do not include a RLC header in the RLC PDU
* Delivery of received RLC PDUs to upper layers
- RLC UM (mainly used for DTCH)
* Segment or concatenate RLC SDUs according to the TB size selected by MAC
* Include a RLC header in the RLC PDU
* Duplication detection
* PDU reordering and reassembly
- RLC AM, compatible with 9.3
* Segmentation, re-segmentation, concatenation, and reassembly
* Padding
* Data transfer to the user
* RLC PDU retransmission in support of error control and correction
* Generation of data/control PDUs
## eNB PDCP Layer ##
The current PDCP layer is header compliant with **3GPP 36.323** Rel 10.1.0 and implements the following functions:
- User and control data transfer
- Sequence number management
- RB association with PDCP entity
- PDCP entity association with one or two RLC entities
- Integrity check and encryption using the AES and Snow3G algorithms
## eNB RRC Layer ##
The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following functions:
- System Information broadcast (SIB 1, 2, 3, and 13)
* SIB1: Up to 6 PLMN IDs broadcast
- RRC connection establishment
- RRC connection reconfiguration (addition and removal of radio bearers, connection release)
- RRC connection release
- RRC connection re-establishment
- Inter-frequency measurement collection and reporting (experimental)
- eMBMS for multicast and broadcast (experimental)
- Handover (experimental)
- Paging (soon)
## eNB X2AP ##
The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following functions:
- X2 Setup Request
- X2 Setup Response
## eNB Advanced Features ##
**To be completed**
# OpenAirInterface UE Feature Set #
## LTE UE PHY Layer ##
The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provides the following features:
- LTE release 8.6 compliant, and implements a subset of release 10
- FDD and TDD configurations: 1 (experimental) and 3
- Bandwidth: 5, 10, and 20 MHz
- Transmission modes: 1, 2 (stable)
- Max number of antennas: 2
- CQI/PMI reporting: aperiodic, feedback mode 3 - 0 and 3 - 1
- PRACH preamble format 0
- All downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH
- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS
## LTE UE MAC Layer ##
The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels.
- RRC interface for CCCH, DCCH, and DTCH
- HARQ Support
- RA procedures and RNTI management
- RLC interface (AM, UM)
- UL power control
- Link adaptation
## LTE UE RLC Layer ##
The RLC layer implements a full specification of the 3GPP 36.322 release v9.3.
## LTE UE PDCP Layer ##
The current PDCP layer is header compliant with **3GPP 36.323** Rel 10.1.0.
## LTE UE RRC Layer ##
The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following functions:
- System Information decoding
- RRC connection establishment
# OpenAirInterface Functional Split #
- RCC: Radio-Cloud Center
- RAU: Radio-Access Unit
- RRU: Remote Radio-Unit
![Functional Split Architecture](./oai_enb_func_split_arch.png)
- IF4.5 / IF5 : similar to IEEE P1914.1
- FAPI (IF2) : specified by Small Cell Forum (open-nFAPI implementation)
- IF1 : F1 in 3GPP Release 15
# OpenAirInterface 5G-NR Feature Set #
## General Parameters ##
The following features are valid for the gNB and the 5G-NR UE.
* Static TDD,
* Normal CP
* 30 kHz subcarrier spacing
* Bandwidths up to 80MHz (217 Physical Resource Blocks)
* Single antenna port (single beam)
* Slot format: 14 OFDM symbols in UL or DL
* Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported)
* Highly efficient 3GPP compliant polar encoder and decoder
* Encoder and decoder for short blocks
## gNB Features ##
### gNB PHY Layer ###
* Generation of PSS/SSS/PBCH for multiple beams and
* Generation of PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc)
- common search space configured by MIB
- user-specific search space configured by RRC
- DCI formats: 00, 10
* Generation of PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
- Single symbol DMRS, dmrs-TypeA-Position Pos2, DMRS configuration type 1
- PDSCH mapping type A
* NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc).
* NR-PUCCH
- Format 0 (ACK/NACK)
### gNB higher Layers ###
- NR RRC (38.331) Rel 15 messages using new asn1c
- LTE RRC (36.331) also updated to Rel 15
- Generation of MIB
- Application to read configuration file and program gNB RRC
- RRC -> MAC configuration
- MAC -> PHY configuration (using NR FAPI P5 interface)
- FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU
For more details see [this document](https://gitlab.eurecom.fr/oai/openairinterface5g/uploads/ba5368448d627743a28c770c29e8978e/OAI_Software_Architecture_for_Dual_Connectivity_in_E-UTRA_and_5G-NR_and_nFAPI_for_MAC-PHY_Interface.docx)
## NR UE Features ##
### NR UE PHY Layer ###
- initial synchronization
- Time tracking based on PDCCH DMRS
- Frequency offset estimation
- PBCH RX
- PDCCH RX
- PDSCH RX
- including first version of dual stream receiver for PDSCH
### NR UE higher Layers ###
For more details see [this document](https://gitlab.eurecom.fr/oai/openairinterface5g/uploads/f7386f3a64806fd6b2ac1fc3d0252fff/UE_FAPI-like_interface.docx)
......@@ -415,9 +415,6 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot
RU_proc_t *ru_proc;
int waitret,ret;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=10000000L;
......@@ -489,10 +486,6 @@ int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_t
int ret;
struct timespec wait;
wait.tv_sec=0;
wait.tv_nsec=5000000L;
AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
......@@ -529,7 +522,6 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
RU_proc_t *ru_proc=&ru->proc;
int ret;
int i;
struct timespec wait;
AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
for (i=0;i<gNB->num_RU;i++) {
......@@ -551,9 +543,6 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
}
wait.tv_sec=0;
wait.tv_nsec=5000000L;
// wake up TX for subframe n+sl_ahead
// lock the TX mutex and make sure the thread is ready
AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret);
......
......@@ -1208,6 +1208,12 @@ static void *ru_thread_tx( void *param ) {
int i = 0;
int ret;
if(ru->if_south == LOCAL_RF)
{
uhd_set_thread_prio();
LOG_I(PHY,"set ru_thread_tx uhd priority");
}
wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
printf( "ru_thread_tx ready\n");
......
#ifndef NR_SOFTMODEM_COMMON_H
#define NR_SOFTMODEM_COMMON_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <execinfo.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/sched.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include "targets/ARCH/COMMON/common_lib.h"
#undef MALLOC
#include "assertions.h"
#include "PHY/types.h"
#include <threadPool/thread-pool.h>
#if defined(ENABLE_USE_MME)
#include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
#endif
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM ""
#define CONFIG_HLP_CALUERB ""
#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n"
#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n"
#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n"
#define CONFIG_HLP_UERXG "set UE RX gain\n"
#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n"
#define CONFIG_HLP_UETXG "set UE TX gain\n"
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#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_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_TADV "Set timing_advance\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
#define CONFIG_HLP_TPORT "tracer port\n"
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n"
#define CONFIG_HLP_FLOG "Enable online log \n"
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_LOGPARAMS_DESC { \
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
#define CMDLINE_GLOGLEVEL_IDX 1
#define CMDLINE_GLOGVERBO_IDX 2
#define CMDLINE_STARTTELN_IDX 3
/***************************************************************************************************************************************/
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int rx_input_level_dBm;
extern uint8_t exit_missed_slots;
extern uint64_t num_missed_slots; // counter for the number of missed slots
extern int oaisim_flag;
extern volatile int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern int transmission_mode;
extern double cpuf;
#if defined(ENABLE_ITTI)
extern volatile int start_eNB;
extern volatile int start_UE;
#endif
#endif
......@@ -139,6 +139,7 @@ unsigned char NB_gNB_INST = 1;
int UE_scan = 1;
int UE_scan_carrier = 0;
runmode_t mode = normal_txrx;
double snr_dB=20;
FILE *input_fd=NULL;
......
This diff is collapsed.
......@@ -42,6 +42,7 @@
#include "SCHED/sched_common_vars.h"
#include "PHY/MODULATION/modulation_vars.h"
//#include "../../SIMU/USER/init_lte.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "LAYER2/MAC/mac_vars.h"
#include "LAYER2/MAC/mac_proto.h"
......@@ -113,6 +114,7 @@ volatile int oai_exit = 0;
static clock_source_t clock_source = internal;
int single_thread_flag=1;
double snr_dB=20;
int threequarter_fs=0;
......
#ifndef NR_UESOFTMODEM_H
#define NR_UESOFTMODEM_H
#define _GNU_SOURCE
#include <execinfo.h>
#include <fcntl.h>
#include <getopt.h>
#include <linux/sched.h>
#include <sched.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include "../../ARCH/COMMON/common_lib.h"
#undef MALLOC
#include "assertions.h"
#include "PHY/types.h"
#include <executables/nr-softmodem-common.h>
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#include <threadPool/thread-pool.h>
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
#if defined(ENABLE_ITTI)
#if defined(ENABLE_USE_MME)
#include "s1ap_eNB.h"
#ifdef PDCP_USE_NETLINK
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
#endif
#endif
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
#define CONFIG_HLP_CALUERM ""
#define CONFIG_HLP_CALUERB ""
#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n"
#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n"
#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n"
#define CONFIG_HLP_UERXG "set UE RX gain\n"
#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n"
#define CONFIG_HLP_UETXG "set UE TX gain\n"
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#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_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
#define CONFIG_HLP_TADV "Set timing_advance\n"
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
#define CONFIG_HLP_CHOFF "Channel id offset\n"
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
#define CONFIG_HLP_TPORT "tracer port\n"
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n"
/***************************************************************************************************************************************/
/* 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 */
......@@ -174,27 +84,10 @@
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
}
}
#define CONFIG_HLP_FLOG "Enable online log \n"
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters for LOG utility */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_LOGPARAMS_DESC { \
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
}
#define CMDLINE_ONLINELOG_IDX 0
#define CMDLINE_GLOGLEVEL_IDX 1
#define CMDLINE_GLOGVERBO_IDX 2
#define CMDLINE_STARTTELN_IDX 3
extern int T_port;
......@@ -203,35 +96,6 @@ extern int T_dont_fork;
/***************************************************************************************************************************************/
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
extern int rx_input_level_dBm;
extern uint8_t exit_missed_slots;
extern uint64_t num_missed_slots; // counter for the number of missed slots
extern int oaisim_flag;
extern volatile int oai_exit;
extern openair0_config_t openair0_cfg[MAX_CARDS];
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern int transmission_mode;
extern double cpuf;
#if defined(ENABLE_ITTI)
extern volatile int start_eNB;
extern volatile int start_UE;
#endif
// In nr-ue.c
extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
extern void fill_ue_band_info(void);
......
......@@ -689,12 +689,13 @@ typedef struct {
uint8_t frame_offset;
uint16_t number_symbols;
uint16_t start_symbol;
uint8_t nb_re_dmrs;
uint8_t length_dmrs;
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;
......
......@@ -80,8 +80,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *const fp = &gNB->frame_parms;
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;
NR_gNB_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;
......@@ -156,12 +156,14 @@ 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->rxdata = (int32_t **)malloc16(15*sizeof(int32_t*));
common_vars->txdataF = (int32_t **)malloc16(15*sizeof(int32_t*));
common_vars->rxdataF = (int32_t **)malloc16(64*sizeof(int32_t*));
common_vars->rxdataF = (int32_t **)malloc16(15*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
common_vars->txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP
common_vars->rxdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t));
common_vars->rxdata[i] = (int32_t*)malloc16_clear(fp->samples_per_frame*sizeof(int32_t));
LOG_D(PHY,"[INIT] common_vars->txdataF[%d] = %p (%lu bytes)\n",
i,common_vars->txdataF[i],
......@@ -198,39 +200,38 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
for (i=0; i<64; i++) prach_vars->prach_ifft[0][i] = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t));
prach_vars->rxsigF[0] = (int16_t **)malloc16_clear(64*sizeof(int16_t *));
*/
for (int ulsch_id=0; ulsch_id<NUMBER_OF_NR_ULSCH_MAX; ulsch_id++) {
for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME
pusch_vars[UE_id] = (LTE_eNB_PUSCH *)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(LTE_eNB_PUSCH) );
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id] = (NR_gNB_PUSCH *)malloc16_clear( sizeof(NR_gNB_PUSCH) );
pusch_vars[UE_id]->rxdataF_ext = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_ext2 = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->drs_ch_estimates_time = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->rxdataF_comp = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_mag = (int32_t **)malloc16( 2*sizeof(int32_t *) );
pusch_vars[UE_id]->ul_ch_magb = (int32_t **)malloc16( 2*sizeof(int32_t *) );
for (i=0; i<2; i++) {
// RK 2 times because of output format of FFT!
// FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12*fp->symbols_per_slot );
pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*cfg->rf_config.ul_carrier_bandwidth.value*12 );
}
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
pusch_vars[UE_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
} //UE_id
/*
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
gNB->UE_stats_ptr[UE_id] = &gNB->UE_stats[UE_id];
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
*/
gNB->pdsch_config_dedicated->p_a = dB0; //defaul value until overwritten by RRCConnectionReconfiguration
return (0);
}
/*
......@@ -281,8 +282,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) {
//NR_DL_FRAME_PARMS* const fp = &gNB->frame_parms;
//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;
NR_gNB_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;*/
uint32_t ***pdcch_dmrs = gNB->nr_gold_pdcch_dmrs;
......@@ -451,13 +452,17 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
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);
for (i=0; i<NUMBER_OF_NR_UE_MAX; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
for (j=0; j<2; j++) {
// ULSCH for RA
if(i==0) {
gNB->ulsch[i][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
gNB->ulsch[i][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
if (!gNB->ulsch[i][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
......@@ -466,7 +471,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
}
// ULSCH for data
gNB->ulsch[i+1][j] = new_gNB_ulsch(5, fp->N_RB_UL, 0);
gNB->ulsch[i+1][j] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL, 0);
if (!gNB->ulsch[i+1][j]) {
LOG_E(PHY,"Can't get gNB ulsch structures\n");
......@@ -486,7 +491,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
LOG_D(PHY,"gNB %d.%d : RA %p\n",gNB->Mod_id,gNB->CC_id,gNB->dlsch_ra);
gNB->rx_total_gain_dB=130;
for(i=0; i<NUMBER_OF_UE_MAX; i++)
for(i=0; i<NUMBER_OF_NR_UE_MAX; i++)
gNB->mu_mimo_mode[i].dl_pow_off = 2;
gNB->check_for_total_transmissions = 0;
......
......@@ -36,7 +36,8 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/NR_REFSIG/pss_nr.h"
#include "openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
//uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10};
......@@ -644,6 +645,19 @@ void phy_init_nr_ue__PDSCH( NR_UE_PDSCH* const pdsch, const NR_DL_FRAME_PARMS* c
}
}
void phy_init_nr_ue_PUSCH( NR_UE_PUSCH* const pusch, const NR_DL_FRAME_PARMS* const fp )
{
int i;
AssertFatal( pusch, "pusch==0" );
for (i=0; i<NR_MAX_NB_LAYERS; i++){
pusch->txdataF_layers[i] = (int32_t *)malloc16_clear((NR_MAX_PUSCH_ENCODED_LENGTH)*sizeof(int32_t*));
}
}
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
int nb_connected_eNB,
uint8_t abstraction_flag)
......@@ -655,18 +669,22 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
NR_UE_PDSCH** const pdsch_vars_ra = ue->pdsch_vars_ra;
NR_UE_PDSCH** const pdsch_vars_p = ue->pdsch_vars_p;
NR_UE_PDSCH** const pdsch_vars_mch = ue->pdsch_vars_MCH;
NR_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars;
NR_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdcch_vars;
NR_UE_PDSCH* (*const pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = ue->pdsch_vars;
NR_UE_PDCCH* (*const pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = ue->pdcch_vars;
NR_UE_PBCH** const pbch_vars = ue->pbch_vars;
NR_UE_PRACH** const prach_vars = ue->prach_vars;
NR_UE_PUSCH* (*const pusch_vars)[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX] = ue->pusch_vars;
int i,j,k,l;
int i,j,k,l,slot,symb,q,layer;
int eNB_id;
int th_id;
int n_ssb_crb=(fp->N_RB_DL-20);
int k_ssb=0;
uint32_t ****pusch_dmrs;
int N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig
int n_scid;
abstraction_flag = 0;
fp->nb_antennas_tx = 1;
fp->nb_antennas_rx=1;
......@@ -698,6 +716,59 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->total_received_bits[eNB_id] = 0;
}
/////////////////////////PUSCH init/////////////////////////
///////////
for (th_id = 0; th_id < RX_NB_TH_MAX; th_id++){
for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++){
(*pusch_vars)[th_id][eNB_id] = (NR_UE_PUSCH *)malloc16(sizeof(NR_UE_PUSCH));
phy_init_nr_ue_PUSCH( (*pusch_vars)[th_id][eNB_id], fp );
}
}
///////////
////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////PUSCH DMRS init/////////////////////////
///////////
// default values until overwritten by RRCConnectionReconfiguration
for (i=0;i<MAX_NR_OF_UL_ALLOCATIONS;i++){
ue->pusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t));
ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeA;
}
//------------- config DMRS parameters--------------//
ue->dmrs_UplinkConfig.pusch_dmrs_type = pusch_dmrs_type1;
ue->dmrs_UplinkConfig.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0;
ue->dmrs_UplinkConfig.pusch_maxLength = pusch_len1;
//-------------------------------------------------//
ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t***));
pusch_dmrs = ue->nr_gold_pusch_dmrs;
n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization
for (slot=0; slot<fp->slots_per_frame; slot++) {
pusch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t**));
AssertFatal(pusch_dmrs[slot]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d - malloc failed\n", slot);
for (symb=0; symb<fp->symbols_per_slot; symb++){
pusch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t*));
AssertFatal(pusch_dmrs[slot][symb]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb);
for (q=0; q<NR_MAX_NB_CODEWORDS; q++) {
pusch_dmrs[slot][symb][q] = (uint32_t*)malloc16(NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t));
AssertFatal(pusch_dmrs[slot][symb][q]!=NULL, "init_nr_ue_signal: pusch_dmrs for slot %d symbol %d codeword %d - malloc failed\n", slot, symb, q);
}
}
}
nr_init_pusch_dmrs(ue, N_n_scid, n_scid);
///////////
////////////////////////////////////////////////////////////////////////////////////////////
for (i=0;i<10;i++)
ue->tx_power_dBm[i]=-127;
......@@ -711,7 +782,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
for (i=0; i<fp->nb_antennas_tx; i++) {
common_vars->txdata[i] = (int32_t*)malloc16_clear( fp->samples_per_subframe*10*sizeof(int32_t) );
common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->ofdm_symbol_size*fp->symbols_per_slot*10*sizeof(int32_t) );
common_vars->txdataF[i] = (int32_t *)malloc16_clear( fp->samples_per_slot_wCP*sizeof(int32_t) );
}
// init RX buffers
......@@ -723,7 +794,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
for (i=0; i<fp->nb_antennas_rx; i++) {
common_vars->rxdata[i] = (int32_t*) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) );
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->ofdm_symbol_size*14) );
common_vars->common_vars_rx_data_per_thread[th_id].rxdataF[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->samples_per_slot_wCP) );
}
}
}
......@@ -895,6 +966,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->pdsch_config_dedicated->p_a = dBm3;
else
ue->pdsch_config_dedicated->p_a = dB0;
// set channel estimation to do linear interpolation in time
ue->high_speed_flag = 1;
......
......@@ -133,13 +133,13 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
case 106: //40 MHz
if (fp->threequarter_fs) {
fp->ofdm_symbol_size = 1536;
fp->first_carrier_offset = 900; //1536 - 636
fp->first_carrier_offset = 900; //1536 - ( (106*12) / 2 )
fp->nb_prefix_samples0 = 132;
fp->nb_prefix_samples = 108;
}
else {
fp->ofdm_symbol_size = 2048;
fp->first_carrier_offset = 1412; //2048 - 636
fp->first_carrier_offset = 1412; //2048 - ( (106*12) / 2 )
fp->nb_prefix_samples0 = 176;
fp->nb_prefix_samples = 144;
}
......@@ -152,13 +152,13 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
case 217: //80 MHz
if (fp->threequarter_fs) {
fp->ofdm_symbol_size = 3072;
fp->first_carrier_offset = 1770; //3072 - 1302
fp->first_carrier_offset = 1770; //3072 - ( (217*12) / 2 )
fp->nb_prefix_samples0 = 264;
fp->nb_prefix_samples = 216;
}
else {
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2794; //4096 - 1302
fp->first_carrier_offset = 2794; //4096 - ( (217*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
}
......@@ -167,14 +167,14 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp,
case 245:
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",N_RB_DL,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2626; //4096 - 1478
fp->first_carrier_offset = 2626; //4096 - ( (245*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
case 273:
AssertFatal(fp->threequarter_fs==0,"3/4 sampling impossible for N_RB %d and MU %d\n",N_RB_DL,mu);
fp->ofdm_symbol_size = 4096;
fp->first_carrier_offset = 2458; //4096 - 1638
fp->first_carrier_offset = 2458; //4096 - ( (273*12) / 2 )
fp->nb_prefix_samples0 = 352;
fp->nb_prefix_samples = 288;
break;
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nr_modulation.h"
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
void nr_modulation(uint32_t *in,
uint16_t length,
uint16_t mod_order,
int16_t *out) {
uint16_t offset;
uint16_t order;
int i,j;
uint8_t idx, b_idx;
offset = (mod_order==2)? NR_MOD_TABLE_QPSK_OFFSET : (mod_order==4)? NR_MOD_TABLE_QAM16_OFFSET : \
(mod_order==6)? NR_MOD_TABLE_QAM64_OFFSET: (mod_order==8)? NR_MOD_TABLE_QAM256_OFFSET : 0;
for (i=0; i<length/mod_order; i++) {
idx = 0;
for (j=0; j<mod_order; j++) {
b_idx = (i*mod_order+j)&0x1f;
if (i && (!b_idx))
in++;
idx ^= (((*in)>>b_idx)&1)<<(mod_order-j-1);
}
out[i<<1] = nr_mod_table[(offset+idx)<<1];
out[(i<<1)+1] = nr_mod_table[((offset+idx)<<1)+1];
}
}
void nr_layer_mapping(int16_t **mod_symbs,
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers) {
switch (n_layers) {
case 1:
memcpy((void*)tx_layers[0], (void*)mod_symbs[0], (n_symbs<<1)*sizeof(int16_t));
break;
case 2:
case 3:
case 4:
for (int i=0; i<n_symbs/n_layers; i++)
for (int l=0; l<n_layers; l++) {
tx_layers[l][i<<1] = mod_symbs[0][(n_layers*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[0][((n_layers*i+l)<<1)+1];
}
break;
case 5:
for (int i=0; i<n_symbs>>1; i++)
for (int l=0; l<2; l++) {
tx_layers[l][i<<1] = mod_symbs[0][((i<<1)+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<1)+l)<<1)+1];
}
for (int i=0; i<n_symbs/3; i++)
for (int l=2; l<5; l++) {
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
}
break;
case 6:
for (int q=0; q<2; q++)
for (int i=0; i<n_symbs/3; i++)
for (int l=0; l<3; l++) {
tx_layers[l][i<<1] = mod_symbs[q][(3*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[q][((3*i+l)<<1)+1];
}
break;
case 7:
for (int i=0; i<n_symbs/3; i++)
for (int l=0; l<3; l++) {
tx_layers[l][i<<1] = mod_symbs[1][(3*i+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[1][((3*i+l)<<1)+1];
}
for (int i=0; i<n_symbs/4; i++)
for (int l=3; l<7; l++) {
tx_layers[l][i<<1] = mod_symbs[0][((i<<2)+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[0][(((i<<2)+l)<<1)+1];
}
break;
case 8:
for (int q=0; q<2; q++)
for (int i=0; i<n_symbs>>2; i++)
for (int l=0; l<3; l++) {
tx_layers[l][i<<1] = mod_symbs[q][((i<<2)+l)<<1];
tx_layers[l][(i<<1)+1] = mod_symbs[q][(((i<<2)+l)<<1)+1];
}
break;
default:
AssertFatal(0, "Invalid number of layers %d\n", n_layers);
}
}
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i dft_in128[1][1200], dft_out128[1][1200];
#elif defined(__arm__)
int16x8_t dft_in128[1][1200], dft_out128[1][1200];
#endif
uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0];
uint32_t i, ip;
#if defined(__x86_64__) || defined(__i386__)
__m128i norm128;
#elif defined(__arm__)
int16x8_t norm128;
#endif
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
dft_in0[ip] = d[i];
}
switch (Msc_PUSCH) {
case 12:
dft12((int16_t *)dft_in0, (int16_t *)dft_out0);
#if defined(__x86_64__) || defined(__i386__)
norm128 = _mm_set1_epi16(9459);
#elif defined(__arm__)
norm128 = vdupq_n_s16(9459);
#endif
for (i=0; i<12; i++) {
#if defined(__x86_64__) || defined(__i386__)
((__m128i*)dft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)dft_out0)[i], norm128), 1);
#elif defined(__arm__)
((int16x8_t*)dft_out0)[i] = vqdmulhq_s16(((int16x8_t*)dft_out0)[i], norm128);
#endif
}
break;
case 24:
dft24((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 36:
dft36((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 48:
dft48((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 60:
dft60((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 72:
dft72((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 96:
dft96((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 108:
dft108((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 120:
dft120((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 144:
dft144((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 180:
dft180((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 192:
dft192((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 216:
dft216((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 240:
dft240((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 288:
dft288((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 300:
dft300((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 324:
dft324((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 360:
dft360((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 384:
dft384((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 432:
dft432((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 480:
dft480((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 540:
dft540((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 576:
dft576((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 600:
dft600((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 648:
dft648((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 720:
dft720((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 768:
dft768((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 864:
dft864((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 900:
dft900((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 960:
dft960((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 972:
dft972((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1080:
dft1080((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1152:
dft1152((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1200:
dft1200((int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
}
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
z[i] = dft_out0[ip];
}
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __NR_MODULATION_H__
#define __NR_MODULATION_H__
#include <stdint.h>
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#define DMRS_MOD_ORDER 2
/*! \brief Perform NR modulation. TS 38.211 V15.4.0 subclause 5.1
@param[in] in, Pointer to input bits
@param[in] length, size of input bits
@param[in] modulation_type, modulation order
@param[out] out, complex valued modulated symbols
*/
void nr_modulation(uint32_t *in,
uint16_t length,
uint16_t mod_order,
int16_t *out);
/*! \brief Perform NR layer mapping. TS 38.211 V15.4.0 subclause 7.3.1.3
@param[in] mod_symbs, double Pointer to modulated symbols for each codeword
@param[in] n_layers, number of layers
@param[in] n_symbs, number of modulated symbols
@param[out] tx_layers, modulated symbols for each layer
*/
void nr_layer_mapping(int16_t **mod_symbs,
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers);
/*!
\brief This function implements the OFDM front end processor on reception (FEP)
\param frame_parms Pointer to frame parameters
\param rxdata Pointer to input data in time domain
\param rxdataF Pointer to output data in frequency domain
\param symbol symbol within slot (0..12/14)
\param Ns Slot number (0..19)
\param sample_offset offset within rxdata (points to beginning of subframe)
\param no_prefix if 1 prefix is removed by HW
*/
int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdata,
int32_t *rxdataF,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix);
/*!
\brief This function implements the dft transform precoding in PUSCH
\param z Pointer to output in frequnecy domain
\param d Pointer to input in time domain
\param Msc_PUSCH number of allocated data subcarriers
*/
void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH);
#endif
\ No newline at end of file
......@@ -19,9 +19,10 @@
* contact@openairinterface.org
*/
#include "PHY/defs_UE.h"
#include "PHY/defs_nr_UE.h"
#include "PHY/defs_gNB.h"
#include "modulation_UE.h"
#include "nr_modulation.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
......@@ -198,3 +199,71 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
return(0);
}
int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdata,
int32_t *rxdataF,
unsigned char symbol,
unsigned char Ns,
int sample_offset,
int no_prefix)
{
uint32_t slot_offset;
uint32_t rxdata_offset;
unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
void (*dft)(int16_t *,int16_t *, int);
switch (frame_parms->ofdm_symbol_size) {
case 128:
dft = dft128;
break;
case 256:
dft = dft256;
break;
case 512:
dft = dft512;
break;
case 1024:
dft = dft1024;
break;
case 1536:
dft = dft1536;
break;
case 2048:
dft = dft2048;
break;
case 4096:
dft = dft4096;
break;
case 8192:
dft = dft8192;
break;
default:
dft = dft512;
break;
}
slot_offset = Ns * frame_parms->samples_per_slot;
if(symbol == 0)
rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET;
else
rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET;
dft((int16_t *)&rxdata[rxdata_offset],
(int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1);
return(0);
}
......@@ -54,6 +54,8 @@
int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit);
void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell);
void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell);
uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
#undef EXTERN
......
......@@ -81,7 +81,7 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
{
uint32_t x1, x2;
uint8_t reset;
uint8_t reset, q;
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs;
......@@ -89,16 +89,15 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid)
uint8_t n_scid=0; // again works only for 1_0
for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
for (uint8_t q=0; q<NR_MAX_NB_CODEWORDS; q++) {
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
for (uint32_t n=0; n<NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD; n++) {
pdsch_dmrs[slot][symb][q][n] = lte_gold_generic(&x1, &x2, reset);
pdsch_dmrs[slot][symb][0][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
}
}
}
}
for (q = 1; q < NR_MAX_NB_CODEWORDS; q++)
memcpy(pdsch_dmrs[slot][symb][q],pdsch_dmrs[slot][symb][0],sizeof(uint32_t)*NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD);
}
}
}
......@@ -160,3 +160,29 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,unsigned short lbar,unsigned short *n_idDM
}
}
}
void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t *N_n_scid, uint8_t n_scid)
{
uint32_t x1, x2, n;
uint8_t reset, slot, symb, q;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
uint32_t ****pusch_dmrs = ue->nr_gold_pusch_dmrs;
for (slot=0; slot<fp->slots_per_frame; slot++) {
for (symb=0; symb<fp->symbols_per_slot; symb++) {
reset = 1;
x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid));
for (n=0; n<NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD; n++) {
pusch_dmrs[slot][symb][0][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
for (q = 1; q < NR_MAX_NB_CODEWORDS; q++)
memcpy(pusch_dmrs[slot][symb][q],pusch_dmrs[slot][symb][0],sizeof(uint32_t)*NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD);
}
}
}
......@@ -23,7 +23,9 @@
/* Author R. Knopp / EURECOM / OpenAirInterface.org */
#ifndef __NR_REFSIG_DEFS__H__
#define __NR_REFSIG_DEFS__H__
#include "PHY/defs_nr_UE.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PBCH DMRS.
......@@ -61,5 +63,6 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue,
unsigned short *n_idDMRS,
unsigned short length_dmrs);
void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t *N_n_scid, uint8_t n_scid);
#endif
......@@ -32,14 +32,14 @@
#include "nr_dci.h"
#include "nr_dlsch.h"
#include "nr_sch_dmrs.h"
#include "PHY/MODULATION/nr_modulation.h"
//#define DEBUG_PDCCH_DMRS
//#define DEBUG_DCI
//#define DEBUG_CHANNEL_CODING
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format,
nfapi_nr_rnti_type_e rnti_type,
uint16_t N_RB,
......@@ -217,9 +217,9 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
#endif
}
nr_modulation(dmrs_seq, dmrs_length, MOD_QPSK, mod_dmrs[symb]);
nr_modulation(dmrs_seq, dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
} else
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, MOD_QPSK, mod_dmrs[symb]);
nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_PDCCH_DMRS
......@@ -264,7 +264,7 @@ uint8_t nr_generate_dci_top(NR_gNB_PDCCH pdcch_vars,
#endif
/// QPSK modulation
int16_t mod_dci[NR_MAX_DCI_SIZE>>1];
nr_modulation(scrambled_output, encoded_length, MOD_QPSK, mod_dci);
nr_modulation(scrambled_output, encoded_length, DMRS_MOD_ORDER, mod_dci); //Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DCI
for (int i=0; i<encoded_length>>1; i++)
......
This diff is collapsed.
......@@ -30,9 +30,10 @@
* \warning
*/
#include "PHY/defs_gNB.h"
#ifndef __NR_DLSCH__H
#define __NR_DLSCH__H
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
#include "PHY/defs_gNB.h"
void nr_get_time_domain_allocation_type(nfapi_nr_config_request_t config,
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
......@@ -52,14 +53,6 @@ void nr_get_rbg_list(uint32_t bitmap, uint8_t n_rbg, uint8_t* rbg_list);
void nr_get_PRG_parms(NR_BWP_PARMS* bwp, NR_gNB_DCI_ALLOC_t dci_alloc, uint8_t prb_bundling_type);
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
nfapi_nr_config_request_t config);
void nr_pdsch_codeword_scrambling(uint8_t *in,
uint16_t size,
uint8_t q,
......@@ -67,42 +60,21 @@ void nr_pdsch_codeword_scrambling(uint8_t *in,
uint32_t n_RNTI,
uint32_t* out);
void nr_modulation(uint32_t *in,
uint16_t length,
nr_mod_t modulation_type,
int16_t *out);
void nr_pdsch_codeword_modulation(uint32_t *in,
uint8_t Qm,
uint32_t length,
int16_t *out);
void nr_pdsch_layer_mapping(int16_t **mod_symbs,
uint8_t n_layers,
uint16_t n_symbs,
int16_t **tx_layers);
void nr_fill_dlsch(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
unsigned char *sdu);
uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t dlsch,
NR_gNB_DCI_ALLOC_t dci_alloc,
uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch,
NR_gNB_DCI_ALLOC_t *dci_alloc,
uint32_t ***pdsch_dmrs,
int32_t** txdataF,
int16_t amp,
int frame,
uint8_t slot,
NR_DL_FRAME_PARMS frame_parms,
nfapi_nr_config_request_t config);
/** \brief Computes available bits G.
@param nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs */
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs,uint8_t Qm, uint8_t Nl);
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_config_request_t *config);
void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch);
......@@ -120,3 +92,4 @@ int nr_dlsch_encoding(unsigned char *a,int frame,
void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size);
#endif
......@@ -151,11 +151,11 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
}
}
dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH>>1)*sizeof(int32_t*));
dlsch->txdataF[layer] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH/NR_MAX_NB_LAYERS)*sizeof(int32_t)); // NR_MAX_NB_LAYERS is already included in NR_MAX_PDSCH_ENCODED_LENGTH
}
for (int q=0; q<NR_MAX_NB_CODEWORDS; q++)
dlsch->mod_symbs[q] = (int32_t *)malloc16((NR_MAX_PDSCH_ENCODED_LENGTH>>1)*sizeof(int32_t*));
dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t));
dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*));
for (aa=0; aa<64; aa++) {
......
......@@ -34,6 +34,7 @@
/*Table 7.4.1.1.2-1 and 7.4.1.1.2-2 38211 Columns: ap - CDM group - Delta - Wf(0) - Wf(1) - Wt(0) - Wt(1)*/
/*Table 6.4.1.1.3-1 is identical to Table 7.4.1.1.2-1 and Table 6.4.1.1.3-2 is identical to Table 7.4.1.1.2-2. UL DMRS can reuse these tables*/
int8_t pdsch_dmrs_1[8][7] = {{0,0,0,1,1,1,1},
{1,0,0,1,-1,1,1},
{2,1,1,1,1,1,1},
......@@ -84,6 +85,13 @@ uint8_t get_delta(uint8_t ap, uint8_t config) {
return ((config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][2]):(pdsch_dmrs_2[ap][2]));
}
uint8_t get_l0(uint8_t config, uint8_t dmrs_typeA_position) {
return ((config==NFAPI_NR_DMRS_TYPE1)?dmrs_typeA_position:0);
uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) {
uint16_t dmrs_idx = (dmrs_type)? (6*n+k_prime+delta):((n<<2)+(k_prime<<1)+delta);
return dmrs_idx;
}
uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
return ((mapping_type==NFAPI_NR_PDSCH_MAPPING_TYPE_A)?dmrs_typeA_position:0);
}
......@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_sch_dmrs.c
/*! \file PHY/NR_TRANSPORT/nr_sch_dmrs.h
* \brief
* \author
* \date
......@@ -30,7 +30,7 @@
* \warning
*/
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#define NR_PDSCH_DMRS_ANTENNA_PORT0 1000
#define NR_PDSCH_DMRS_NB_ANTENNA_PORTS 12
......@@ -45,4 +45,6 @@ void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config);
uint8_t get_delta(uint8_t ap, uint8_t config);
uint8_t get_l0(uint8_t config, uint8_t dmrs_typeA_position);
uint16_t get_dmrs_freq_idx(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type);
uint8_t get_l0(uint8_t mapping_type, uint8_t dmrs_typeA_position);
......@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_coding.c
/*! \file PHY/NR_TRANSPORT/nr_tbs_tools.c
* \brief Top-level routines for implementing LDPC-coded (DLSCH) transport channels from 38-212, 15.2
* \author H.Wang
* \date 2018
......@@ -30,7 +30,7 @@
* \warning
*/
#include "nr_dlsch.h"
#include "nr_transport_common_proto.h"
/// Target code rate tables indexed by Imcs
uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \
......
......@@ -20,8 +20,8 @@
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_mcs.c
* \brief Some support routines for NR MCS computations
/*! \file PHY/NR_TRANSPORT/nr_transport_common_proto.h
* \brief Some support routines
* \author
* \date 2018
* \version 0.1
......@@ -34,6 +34,8 @@
#ifndef __NR_TRANSPORT_COMMON_PROTO__H__
#define __NR_TRANSPORT_COMMON_PROTO__H__
#include "PHY/defs_nr_common.h"
#define MAX_NUM_NR_DLSCH_SEGMENTS 16
#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS
......@@ -43,14 +45,21 @@
#define MAX_NUM_NR_CHANNEL_BITS (14*273*12*6) // 14 symbols, 273 RB
#define MAX_NUM_NR_RE (14*273*12)
// Functions below implement minor procedures from 38-214
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
#define NR_PUSCH_y 3 // UCI placeholder bit
/** \brief Computes Q based on I_MCS PDSCH and table_idx. Implements Table 5.1.3.1-2 from 38.214. */
uint8_t nr_get_Qm(uint8_t Imcs, uint8_t table_idx);
uint32_t nr_get_code_rate(uint8_t Imcs, uint8_t table_idx);
void nr_get_tbs(nfapi_nr_dl_config_dlsch_pdu *dlsch_pdu,
nfapi_nr_dl_config_dci_dl_pdu dci_pdu,
nfapi_nr_config_request_t config);
/** \brief Computes Q based on I_MCS PDSCH and when 'MCS-Table-PDSCH' is set to "256QAM". Implements Table 5.1.3.1-2 from 38.214.
@param I_MCS */
uint8_t get_nr_Qm(uint8_t I_MCS);
/** \brief Computes available bits G. */
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch, uint8_t nb_re_dmrs, uint16_t length_dmrs, uint8_t Qm, uint8_t Nl);
/** \brief Computes Q based on I_MCS PUSCH. Implements Table 6.1.4.1-1 from 38.214.
@param I_MCS */
uint8_t get_nr_Qm_ul(uint8_t I_MCS);
uint32_t nr_get_E(uint32_t G, uint8_t C, uint8_t Qm, uint8_t Nl, uint8_t r);
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_transport_proto.h.c
* \brief Function prototypes for PHY physical/transport channel processing and generation
* \author Ahmed Hussein
* \date 2019
* \version 0.1
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \note
* \warning
*/
#include "PHY/defs_nr_common.h"
/** \brief This function is the top-level entry point to PUSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- RB extraction (signal and channel estimates)
- channel compensation (matched filtering)
- RE extraction (dmrs)
- antenna combining (MRC, Alamouti, cycling)
- LLR computation
This function supports TM1, 2, 3, 5, and 6.
@param ue Pointer to PHY variables
@param UE_id id of current UE
@param frame Frame number
@param nr_tti_rx TTI number
@param symbol Symbol on which to act (within-in nr_TTI_rx)
@param harq_pid HARQ process ID
*/
void nr_rx_pusch(PHY_VARS_gNB *gNB,
uint8_t UE_id,
uint32_t frame,
uint8_t nr_tti_rx,
unsigned char symbol,
unsigned char harq_pid);
/** \brief This function performs RB extraction (signal and channel estimates) (currently signal only until channel estimation and compensation are implemented)
@param rxdataF pointer to the received frequency domain signal
@param rxdataF_ext pointer to the extracted frequency domain signal
@param rb_alloc RB allocation map (used for Resource Allocation Type 0 in NR)
@param symbol Symbol on which to act (within-in nr_TTI_rx)
@param start_rb The starting RB in the RB allocation (used for Resource Allocation Type 1 in NR)
@param nb_rb_pusch The number of RBs allocated (used for Resource Allocation Type 1 in NR)
@param frame_parms, Pointer to frame descriptor structure
*/
void nr_ulsch_extract_rbs_single(int **rxdataF,
int **rxdataF_ext,
uint32_t rxdataF_ext_offset,
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
unsigned char symbol,
unsigned short start_rb,
unsigned short nb_rb_pusch,
NR_DL_FRAME_PARMS *frame_parms);
/*!
\brief This function implements the idft transform precoding in PUSCH
\param z Pointer to input in frequnecy domain, and it is also the output in time domain
\param Msc_PUSCH number of allocated data subcarriers
*/
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH);
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@param rxdataF_comp Compensated channel output
@param ulsch_llr llr output
@param nb_re number of REs for this allocation
@param symbol OFDM symbol index in sub-frame
*/
void nr_ulsch_qpsk_llr(int32_t *rxdataF_comp,
int16_t *ulsch_llr,
uint32_t nb_re,
uint8_t symbol);
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream 16 QAM received waveforms.
@param rxdataF_comp Compensated channel output
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 16
@param ulsch_llr llr output
@param nb_re number of RBs for this allocation
@param symbol OFDM symbol index in sub-frame
*/
void nr_ulsch_16qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int16_t *ulsch_llr,
uint32_t nb_re,
uint8_t symbol);
/** \brief This function generates log-likelihood ratios (decoder input) for single-stream 64 QAM received waveforms.
@param rxdataF_comp Compensated channel output
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 64
@param ul_ch_magb uplink channel magnitude multiplied by the 2bd amplitude threshold in QAM 64
@param ulsch_llr llr output
@param nb_re number of REs for this allocation
@param symbol OFDM symbol index in sub-frame
*/
void nr_ulsch_64qam_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int16_t *ulsch_llr,
uint32_t nb_re,
uint8_t symbol);
/** \brief This function computes the log-likelihood ratios for 4, 16, and 64 QAM
@param rxdataF_comp Compensated channel output
@param ul_ch_mag uplink channel magnitude multiplied by the 1st amplitude threshold in QAM 64
@param ul_ch_magb uplink channel magnitude multiplied by the 2bd amplitude threshold in QAM 64
@param ulsch_llr llr output
@param nb_re number of REs for this allocation
@param symbol OFDM symbol index in sub-frame
@param mod_order modulation order
*/
void nr_ulsch_compute_llr(int32_t *rxdataF_comp,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int16_t *ulsch_llr,
uint32_t nb_re,
uint8_t symbol,
uint8_t mod_order);
\ No newline at end of file
......@@ -19,41 +19,40 @@
* contact@openairinterface.org
*/
/*! \file PHY/NR_TRANSPORT/nr_mcs.c
* \brief Some support routines for NR MCS computations
* \author
* \date 2018
/*! \file PHY/NR_TRANSPORT/nr_ulsch.c
* \brief Top-level routines for the reception of the PUSCH TS 38.211 v 15.4.0
* \author Ahmed Hussein
* \date 2019
* \version 0.1
* \company Eurecom
* \email:
* \company Fraunhofer IIS
* \email: ahmed.hussein@iis.fraunhofer.de
* \note
* \warning
*/
#include <stdint.h>
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
//get_Qm under PHY/LTE_TRANSPORT/lte_mcs.c is the same for NR.
uint8_t get_nr_Qm(uint8_t I_MCS)
void nr_ulsch_unscrambling(int16_t* llr,
uint32_t size,
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI)
{
if (I_MCS < 5)
return(2);
else if (I_MCS < 11)
return(4);
else if (I_MCS < 20)
return(6);
else
return(8);
}
uint8_t reset;
uint32_t x1, x2, s=0;
uint8_t get_nr_Qm_ul(uint8_t I_MCS) {
reset = 1;
x2 = (n_RNTI<<15) + Nid;
if (I_MCS < 2)
return(2); //This should be 1 if UE has reported to support pi/2 BPSK, and 2 otherwise.
else if (I_MCS < 10)
return(2);
else if (I_MCS < 17)
return(4);
else
return(6);
for (uint32_t i=0; i<size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic(&x1, &x2, reset);
reset = 0;
}
if (((s>>(i&0x1f))&1)==1)
llr[i] = -llr[i];
}
}
......@@ -36,6 +36,18 @@ 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);
/*! \brief Perform PUSCH decoding. TS 38.212 V15.4.0 subclause 6.2
@param phy_vars_gNB, Pointer to PHY data structure for gNB
@param UE_id, ID of UE transmitting this PUSCH
@param ulsch_llr, Pointer to received llr in ulsch
@param frame_parms, Pointer to frame descriptor structure
@param nb_symb_sch, number of symbols used in the uplink shared channel
@param nr_tti_rx, current received TTI
@param harq_pid, harq process id
@param is_crnti
*/
uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint8_t UE_id,
short *ulsch_llr,
......@@ -44,6 +56,26 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint16_t nb_symb_sch,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag);
uint8_t is_crnti);
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param llr, Pointer to llr bits
@param size, length of llr bits
@param q, codeword index (0,1)
@param Nid, cell id
@param n_RNTI, CRNTI
*/
void nr_ulsch_unscrambling(int16_t* llr,
uint32_t size,
uint8_t q,
uint32_t Nid,
uint32_t n_RNTI);
void nr_ulsch_procedures(PHY_VARS_gNB *gNB,
gNB_L1_rxtx_proc_t *proc,
int UE_id,
uint8_t harq_pid);
......@@ -233,7 +233,6 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch)
/// 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];
ulsch->harq_processes[i]->E=0;
ulsch->harq_processes[i]->G=0;
ulsch->harq_processes[i]->n_DMRS=0;
......@@ -278,8 +277,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
uint16_t nb_symb_sch,
uint8_t nr_tti_rx,
uint8_t harq_pid,
uint8_t is_crnti,
uint8_t llr8_flag)
uint8_t is_crnti)
{
uint32_t A,E;
......@@ -291,7 +289,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
int8_t llrProcBuf[OAI_UL_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32)));
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0];
NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id+1][0];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid];
nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &harq_process->ulsch_pdu.ulsch_pdu_rel15;
......@@ -301,16 +299,22 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
t_nrLDPC_time_stats* p_procTime = &procTime ;
t_nrLDPC_procBuf** p_nrLDPC_procBuf = harq_process->p_nrLDPC_procBuf;
int16_t z [68*384];
int8_t l [68*384];
//int16_t inv_d [68*384];
uint8_t kc;
uint8_t Ilbrm = 0;
int16_t z [68*384];
int8_t l [68*384];
uint8_t kc;
uint8_t Ilbrm = 0;
uint32_t Tbslbrm = 950984;
uint16_t nb_rb = 30; //to update
uint8_t nb_re_dmrs = 6;
uint16_t length_dmrs = 1;
double Coderate = 0.0;
double Coderate = 0.0;
// ------------------------------------------------------------------
uint16_t nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
uint16_t number_symbols = nfapi_ulsch_pdu_rel15->number_symbols;
uint8_t Qm = nfapi_ulsch_pdu_rel15->Qm;
uint8_t mcs = nfapi_ulsch_pdu_rel15->mcs;
uint8_t n_layers = nfapi_ulsch_pdu_rel15->n_layers;
uint8_t nb_re_dmrs = nfapi_ulsch_pdu_rel15->nb_re_dmrs;
uint8_t length_dmrs = nfapi_ulsch_pdu_rel15->length_dmrs;
// ------------------------------------------------------------------
uint32_t i,j;
......@@ -333,19 +337,18 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
return(ulsch->max_ldpc_iterations);
}
nb_rb = nfapi_ulsch_pdu_rel15->number_rbs;
// harq_process->trials[nfapi_ulsch_pdu_rel15->round]++;
harq_process->TBS = nr_compute_tbs(nfapi_ulsch_pdu_rel15->mcs, nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->n_layers);
harq_process->TBS = nr_compute_tbs(mcs, nb_rb, number_symbols, nb_re_dmrs, length_dmrs, n_layers);
A = harq_process->TBS;
ret = ulsch->max_ldpc_iterations;
G = nr_get_G(nb_rb, number_symbols, nb_re_dmrs, length_dmrs, Qm, n_layers);
// G = 0;
// G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers);
harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, nfapi_ulsch_pdu_rel15->Qm,nfapi_ulsch_pdu_rel15->n_layers);
G = harq_process->G;
LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nfapi_ulsch_pdu_rel15->mcs, nfapi_ulsch_pdu_rel15->n_layers, nb_symb_sch,nb_rb);
LOG_I(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, mcs, n_layers, nb_symb_sch,nb_rb);
if (harq_process->round == 0) {
......@@ -443,7 +446,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
Tbslbrm = nr_compute_tbs(28,nb_rb,frame_parms->symbols_per_slot,0,0, nfapi_ulsch_pdu_rel15->n_layers);
for (r=0; r<harq_process->C; r++) {
E = nr_get_E(G, harq_process->C, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers, r);
#if gNB_TIMING_TRACE
......@@ -582,10 +584,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
p_procTime);
if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) {
printf("Segment %d CRC OK\n",r);
LOG_I(PHY, "Segment %d CRC OK\n",r);
ret = 2;
} else {
printf("CRC NOK\n");
LOG_I(PHY, "CRC NOK\n");
ret = 1+ulsch->max_ldpc_iterations;
}
......@@ -595,7 +597,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
}
ret=no_iteration_ldpc;
for (int m=0; m < Kr>>3; m ++) {
harq_process->c[r][m]= (uint8_t) llrProcBuf[m];
}
......
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "nr_transport_proto.h"
#include "PHY/impl_defs_top.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
#include "PHY/defs_nr_common.h"
void nr_idft(uint32_t *z, uint32_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
__m128i idft_in128[1][1200], idft_out128[1][1200];
__m128i norm128;
#elif defined(__arm__)
int16x8_t idft_in128[1][1200], idft_out128[1][1200];
int16x8_t norm128;
#endif
int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0];
int i, ip;
LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
// conjugate input
for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__)||defined(__i386__)
*&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
#elif defined(__arm__)
*&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif
}
for (i=0,ip=0; i<Msc_PUSCH; i++, ip+=4) {
((uint32_t*)idft_in0)[ip+0] = z[i];
}
switch (Msc_PUSCH) {
case 12:
dft12((int16_t *)idft_in0, (int16_t *)idft_out0);
#if defined(__x86_64__)||defined(__i386__)
norm128 = _mm_set1_epi16(9459);
#elif defined(__arm__)
norm128 = vdupq_n_s16(9459);
#endif
for (i = 0; i < 12; i++) {
#if defined(__x86_64__)||defined(__i386__)
((__m128i*)idft_out0)[i] = _mm_slli_epi16(_mm_mulhi_epi16(((__m128i*)idft_out0)[i], norm128), 1);
#elif defined(__arm__)
((int16x8_t*)idft_out0)[i] = vqdmulhq_s16(((int16x8_t*)idft_out0)[i], norm128);
#endif
}
break;
case 24:
dft24(idft_in0, idft_out0, 1);
break;
case 36:
dft36(idft_in0, idft_out0, 1);
break;
case 48:
dft48(idft_in0, idft_out0, 1);
break;
case 60:
dft60(idft_in0, idft_out0, 1);
break;
case 72:
dft72(idft_in0, idft_out0, 1);
break;
case 96:
dft96(idft_in0, idft_out0, 1);
break;
case 108:
dft108(idft_in0, idft_out0, 1);
break;
case 120:
dft120(idft_in0, idft_out0, 1);
break;
case 144:
dft144(idft_in0, idft_out0, 1);
break;
case 180:
dft180(idft_in0, idft_out0, 1);
break;
case 192:
dft192(idft_in0, idft_out0, 1);
break;
case 216:
dft216(idft_in0, idft_out0, 1);
break;
case 240:
dft240(idft_in0, idft_out0, 1);
break;
case 288:
dft288(idft_in0, idft_out0, 1);
break;
case 300:
dft300(idft_in0, idft_out0, 1);
break;
case 324:
dft324((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 360:
dft360((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 384:
dft384((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 432:
dft432((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 480:
dft480((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 540:
dft540((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 576:
dft576((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 600:
dft600((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 648:
dft648((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 720:
dft720((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 768:
dft768((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 864:
dft864((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 900:
dft900((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 960:
dft960((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 972:
dft972((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1080:
dft1080((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1152:
dft1152((int16_t*)idft_in0, (int16_t*)idft_out0, 1);
break;
case 1200:
dft1200(idft_in0, idft_out0, 1);
break;
default:
// should not be reached
LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
return;
}
for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
z[i] = ((uint32_t*)idft_out0)[ip];
}
// conjugate output
for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
#elif defined(__arm__)
*&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void nr_ulsch_extract_rbs_single(int **rxdataF,
int **rxdataF_ext,
uint32_t rxdataF_ext_offset,
// unsigned int *rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
unsigned char symbol,
unsigned short start_rb,
unsigned short nb_rb_pusch,
NR_DL_FRAME_PARMS *frame_parms)
{
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx, is_dmrs_symbol = 0;
uint32_t rxF_ext_index = 0;
int16_t *rxF,*rxF_ext;
is_dmrs_symbol = (symbol == 2) ? 1 : 0; //to be updated from config
start_re = frame_parms->first_carrier_offset + (start_rb * NR_NB_SC_PER_RB);
nb_re_pusch = NR_NB_SC_PER_RB * nb_rb_pusch;
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
rxF_ext = (int16_t *)&rxdataF_ext[aarx][symbol * nb_re_pusch]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
for (re = 0; re < nb_re_pusch; re++) {
if ( (is_dmrs_symbol && ((re&1) != 0)) || (is_dmrs_symbol == 0) ) { // [hna] (re&1) != frame_parms->nushift) assuming only dmrs type 1 and mapping type A
// frame_parms->nushift should be initialized with 0
rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
rxF_ext_index = rxF_ext_index + 2;
}
}
}
}
void nr_rx_pusch(PHY_VARS_gNB *gNB,
uint8_t UE_id,
uint32_t frame,
uint8_t nr_tti_rx,
unsigned char symbol,
unsigned char harq_pid)
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_ul_config_ulsch_pdu_rel15_t *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu.ulsch_pdu_rel15;
uint32_t nb_re_pusch;
if(symbol == rel15_ul->start_symbol)
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = 0;
if (symbol == 2) // [hna] here it is assumed that symbol 2 carries 6 DMRS REs (dmrs-type 1)
nb_re_pusch = rel15_ul->number_rbs * 6;
else
nb_re_pusch = rel15_ul->number_rbs * NR_NB_SC_PER_RB;
//----------------------------------------------------------
//--------------------- RBs extraction ---------------------
//----------------------------------------------------------
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
gNB->pusch_vars[UE_id]->rxdataF_ext,
gNB->pusch_vars[UE_id]->rxdataF_ext_offset,
// rb_alloc, [hna] Resource Allocation Type 1 is assumed only for the moment
symbol,
rel15_ul->start_rb,
rel15_ul->number_rbs,
frame_parms);
#ifdef NR_SC_FDMA
nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
//----------------------------------------------------------
//-------------------- LLRs computation --------------------
//----------------------------------------------------------
nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_ext[0][symbol * rel15_ul->number_rbs * NR_NB_SC_PER_RB],
gNB->pusch_vars[UE_id]->ul_ch_mag,
gNB->pusch_vars[UE_id]->ul_ch_magb,
&gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->Qm],
nb_re_pusch,
symbol,
rel15_ul->Qm);
gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch;
}
This diff is collapsed.
......@@ -224,6 +224,52 @@ void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2
#endif
}
/*******************************************************************
*
* NAME : get_l0_ul
*
* PARAMETERS : mapping_type : PUSCH mapping type
* dmrs_typeA_position : higher layer parameter
*
* RETURN : demodulation reference signal for PUSCH
*
* DESCRIPTION : see TS 38.211 V15.4.0 Demodulation reference signals for PUSCH
*
*********************************************************************/
uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position) {
return ((mapping_type==typeA)?dmrs_typeA_position:0);
}
/*******************************************************************
*
* NAME : get_dmrs_freq_idx_ul
*
* PARAMETERS : n : index of DMRS symbol
* k_prime : k_prime = {0,1}
* delta : given by Tables 6.4.1.1.3-1 and 6.4.1.1.3-2
* dmrs_type : DMRS configuration type
*
* RETURN : demodulation reference signal for PUSCH
*
* DESCRIPTION : see TS 38.211 V15.4.0 Demodulation reference signals for PUSCH
*
*********************************************************************/
uint16_t get_dmrs_freq_idx_ul(uint8_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type) {
uint16_t dmrs_idx;
if (dmrs_type == pusch_dmrs_type1)
dmrs_idx = ((n<<2)+(k_prime<<1)+delta);
else
dmrs_idx = (6*n+k_prime+delta);
return dmrs_idx;
}
/*******************************************************************
*
* NAME : get_dmrs_pbch
......
......@@ -964,7 +964,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
break;
}
if (dlsch1_harq) {
switch (get_Qm(dlsch1_harq->mcs)) {
switch (nr_get_Qm(dlsch1_harq->mcs, 1)) {
case 2 :
if (rx_type==rx_standard) {
nr_dlsch_qpsk_llr(frame_parms,
......
......@@ -33,7 +33,7 @@
#define __NR_TRANSPORT_PROTO_UE__H__
#include "PHY/defs_nr_UE.h"
#include "SCHED_NR_UE/defs.h"
//#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include <math.h>
#include "nfapi_interface.h"
......@@ -1055,12 +1055,24 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS* frame_parms,
uint8_t harq_pid);
/*! \brief Fill up NR_UE_ULSCH_t and NR_UL_UE_HARQ_t structs
@param[in] UE, Pointer to PHY_VARS_NR_UE struct
@param[in] thread_id, thread id
@param[in] gNB_id, gNB id
@param[in] harq_pid, harq id
*/
int generate_ue_ulsch_params(PHY_VARS_NR_UE *UE,
uint8_t thread_id,
int gNB_id,
unsigned char 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
@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,
......@@ -1069,6 +1081,29 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
uint32_t n_RNTI,
uint32_t* out);
/** \brief Perform the following functionalities:
- encoding
- scrambling
- modulation
- transform precoding
*/
uint8_t nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
unsigned char harq_pid,
uint8_t slot,
uint8_t thread_id,
int eNB_id);
/** \brief This function does IFFT for PUSCH
*/
uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
uint8_t slot,
uint8_t Nl,
NR_DL_FRAME_PARMS *frame_parms);
uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
UE_nr_rxtx_proc_t *proc,
......@@ -1099,34 +1134,6 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue,
PDSCH_t dlsch_id,
uint8_t eNB_id);
/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- RB extraction (signal and channel estimates)
- channel compensation (matched filtering)
- RE extraction (pilot, PBCH, synch. signals)
- antenna combining (MRC, Alamouti, cycling)
- LLR computation
This function supports TM1, 2, 3, 5, and 6.
@param PHY_VARS_NR_UE Pointer to PHY variables
@param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH)
@param eNB_id eNb index (Nid1) 0,1,2
@param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver
@param subframe Subframe number
@param symbol Symbol on which to act (within sub-frame)
@param first_symbol_flag set to 1 on first DLSCH symbol
@param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
@param i_mod Modulation order of the interfering stream
*/
int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
PDSCH_t type,
uint8_t eNB_id,
uint8_t eNB_id_i,
uint32_t frame,
uint8_t subframe,
uint8_t symbol,
uint8_t first_symbol_flag,
RX_type_t rx_type,
uint8_t i_mod,
uint8_t harq_pid);
int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
uint32_t frame,
......@@ -1271,14 +1278,6 @@ uint16_t dci_decoding_procedure_emul(NR_UE_PDCCH **lte_ue_pdcch_vars,
DCI_ALLOC_t *dci_alloc_rx,
int16_t eNB_id);
/** \brief Compute Q (modulation order) based on I_MCS PDSCH. Implements table 7.1.7.1-1 from 36.213.
@param I_MCS */
uint8_t get_Qm(uint8_t I_MCS);
/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
@param I_MCS */
uint8_t get_Qm_ul(uint8_t I_MCS);
/** \brief Compute I_TBS (transport-block size) based on I_MCS for PDSCH. Implements table 7.1.7.1-1 from 36.213.
@param I_MCS */
uint8_t get_I_TBS(uint8_t I_MCS);
......@@ -1327,8 +1326,6 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
*/
uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL);
int get_G(NR_DL_FRAME_PARMS *frame_parms,uint16_t nb_rb,uint32_t *rb_alloc,uint8_t mod_order,uint8_t Nl,uint8_t num_pdcch_symbols,int frame,uint8_t subframe, uint8_t beamforming_mode);
int adjust_G(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe);
int adjust_G2(NR_DL_FRAME_PARMS *frame_parms,uint32_t *rb_alloc,uint8_t mod_order,uint8_t subframe,uint8_t symbol);
......@@ -1765,6 +1762,24 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES],
NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted);
/** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs
- RB extraction (signal and channel estimates)
- channel compensation (matched filtering)
- RE extraction (pilot, PBCH, synch. signals)
- antenna combining (MRC, Alamouti, cycling)
- LLR computation
This function supports TM1, 2, 3, 5, and 6.
@param ue Pointer to PHY variables
@param type Type of PDSCH (SI_PDSCH,RA_PDSCH,PDSCH,PMCH)
@param eNB_id eNb index (Nid1) 0,1,2
@param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver
@param frame Frame number
@param nr_tti_rx Subframe number
@param symbol Symbol on which to act (within sub-frame)
@param first_symbol_flag set to 1 on first DLSCH symbol
@param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice.
@param i_mod Modulation order of the interfering stream
*/
int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
PDSCH_t type,
unsigned char eNB_id,
......@@ -1777,8 +1792,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
unsigned char i_mod,
unsigned char harq_pid);
uint32_t nr_get_G(uint16_t nb_rb, uint16_t nb_symb_sch,uint8_t nb_re_dmrs,uint16_t length_dmrs, uint8_t Qm, uint8_t Nl) ;
uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
short *dlsch_llr,
NR_DL_FRAME_PARMS *frame_parms,
......
......@@ -138,10 +138,6 @@ typedef struct {
uint32_t sumKr;
/// Number of "Filler" bits
uint32_t F;
/// Msc_initial, Initial number of subcarriers for ULSCH
uint16_t Msc_initial;
/// Nsymb_initial, Initial number of symbols for ULSCH
uint8_t Nsymb_initial;
/// n_DMRS for cyclic shift of DMRS
uint8_t n_DMRS;
/// n_DMRS2 for cyclic shift of DMRS
......@@ -152,11 +148,12 @@ typedef struct {
// int calibration_flag;
/// Number of soft channel bits
uint32_t G;
// number of symbols
uint8_t nb_symbols;
// first symbol in the slot
// Number of modulated symbols carrying data
uint32_t num_of_mod_symbols;
// This is "L" in TS 38.214 V15.4.0 subclause 6.1.2.1
uint8_t number_of_symbols;
// This is "S" in TS 38.214 V15.4.0 subclause 6.1.2.1
uint8_t start_symbol;
// decode phich
uint8_t decode_phich;
} NR_UL_UE_HARQ_t;
......@@ -164,8 +161,12 @@ typedef struct {
typedef struct {
/// Current Number of Symbols
uint8_t Nsymb_pusch;
/// Nsc_pusch, number of allocated subcarriers for ULSCH
uint16_t Nsc_pusch;
/// number of DMRS resource elements
uint8_t nb_re_dmrs;
/// DMRS length
uint8_t length_dmrs;
/// SRS active flag
uint8_t srs_active;
//#if defined(UPGRADE_RAT_NR)
......@@ -201,9 +202,9 @@ typedef struct {
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
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_NR_RE];
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
int32_t z[MAX_NUM_NR_RE];
uint32_t d_mod[MAX_NUM_NR_RE];
/// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4)
uint32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16)));
/*
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
uint8_t q[MAX_CQI_PAYLOAD];
......@@ -231,6 +232,8 @@ typedef struct {
uint16_t rnti;
/// RNTI type
uint8_t rnti_type;
/// Cell ID
int Nid_cell;
/// f_PUSCH parameter for PUSCH power control
int16_t f_pusch;
/// Po_PUSCH - target output power for PUSCH
......
......@@ -39,7 +39,6 @@
#include "PHY/CODING/nrLDPC_encoder/defs.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
......@@ -205,7 +204,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
uint32_t *pz;
uint8_t mod_order;
uint16_t Kr,r,r_offset;
//uint8_t *d_tmp[MAX_NUM_DLSCH_SEGMENTS];
uint8_t BG;
uint32_t E;
uint8_t Ilbrm;
......@@ -224,7 +222,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
crc = 1;
harq_process = ulsch->harq_processes[harq_pid];
nb_rb = harq_process->nb_rb;
nb_symb_sch = harq_process->nb_symbols;
nb_symb_sch = harq_process->number_of_symbols;
A = harq_process->TBS;
pz = &Z;
mod_order = nr_get_Qm(harq_process->mcs,1);
......@@ -250,12 +248,12 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
printf("ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs);
LOG_D(PHY,"ulsch coding nb_rb %d nb_symb_sch %d nb_re_dmrs %d, length_dmrs %d\n", nb_rb,nb_symb_sch, nb_re_dmrs,length_dmrs);
G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,harq_process->Nl);
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
printf("ulsch 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, harq_process->Nl);
......@@ -327,7 +325,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
//start_meas(te_stats);
for (r=0; r<harq_process->C; r++) {
//d_tmp[r] = &harq_process->d[r][0];
//channel_input[r] = &harq_process->d[r][0];
#ifdef DEBUG_DLSCH_CODING
printf("Encoder: B %d F %d \n",harq_process->B, harq_process->F);
......@@ -354,7 +351,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
printf("\n");*/
//ldpc_encoder_optim_8seg(harq_process->c,d_tmp,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
ldpc_encoder_optim_8seg(harq_process->c,harq_process->d,Kr,BG,harq_process->C,NULL,NULL,NULL,NULL);
//stop_meas(te_stats);
......@@ -446,7 +442,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
}
memcpy(ulsch->g,harq_process->f,G>>3); // g is the concatenated code block
memcpy(ulsch->g,harq_process->f,G); // g is the concatenated code block
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_OUT);
......
This diff is collapsed.
......@@ -20,7 +20,7 @@
*/
#include "tools_defs.h"
#include "PHY/impl_defs_top.h"
#include "PHY/sse_intrin.h"
// Compute Energy of a complex signal vector, removing the DC component!
......@@ -97,6 +97,7 @@ int32_t signal_energy(int32_t *input,uint32_t length)
temp/=length;
temp<<=shift; // this is the average of x^2
// now remove the DC component
......@@ -114,6 +115,52 @@ int32_t signal_energy(int32_t *input,uint32_t length)
return((temp>0)?temp:1);
}
int32_t signal_energy_amp_shift(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();
mm3 = _mm_setzero_si64();
for (i=0; i<length>>1; i++) {
mm1 = in[i];
mm2 = mm1;
mm1 = _m_pmaddwd(mm1,mm1);
mm1 = _m_psradi(mm1,AMP_SHIFT);// shift any 32 bits blocs of the word by the value shift_p9
mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes
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; // 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);
mm2 = _m_psradi(mm2,AMP_SHIFT); // fixed point representation of elements
temp2 = _m_to_int(mm2);
temp2/=(length*length);
temp -= temp2;
_mm_empty();
_m_empty();
return((temp>0)?temp:1);
}
int32_t signal_energy_nodc(int32_t *input,uint32_t length)
{
......
......@@ -295,6 +295,13 @@ void mmxcopy(void *dest,void *src,int size);
*/
int32_t signal_energy(int32_t *,uint32_t);
/*!\fn int32_t signal_energy_fixed_p9(int *input, uint32_t length);
\brief Computes the signal energy per subcarrier
\ the input signal has a fixed point representation of AMP_SHIFT bits
\ the ouput energy has a fixed point representation of AMP_SHIFT bits
*/
int32_t signal_energy_amp_shift(int32_t *input, uint32_t length);
#ifdef LOCALIZATION
/*!\fn int32_t signal_energy(int *,uint32_t);
\brief Computes the signal energy per subcarrier
......
......@@ -234,8 +234,6 @@ typedef struct {
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;
//////////////////////////////////////////////////////////////
......@@ -354,6 +352,45 @@ typedef struct {
} NR_gNB_COMMON;
typedef struct {
/// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..2*ofdm_symbol_size[
int32_t **rxdataF_ext;
/// \brief Holds the received data in the frequency domain for the allocated RBs in normal format.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_ext2;
/// \brief Offset for calculating the index of rxdataF_ext for the current symbol
uint32_t rxdataF_ext_offset;
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..4*ofdm_symbol_size[
int32_t **drs_ch_estimates_time;
/// \brief Hold the channel estimates in frequency domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **drs_ch_estimates;
/// \brief Holds the compensated signal.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **rxdataF_comp;
/// \brief Magnitude of the UL channel estimates. Used for 2nd-bit level thresholds in LLR computation
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_mag;
/// \brief Magnitude of the UL channel estimates scaled for 3rd bit level thresholds in LLR computation
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[
int32_t **ul_ch_magb;
/// measured RX power based on DRS
int ulsch_power[2];
/// \brief llr values.
/// - first index: ? [0..1179743] (hard coded)
int16_t *llr;
} NR_gNB_PUSCH;
/// Context data structure for RX/TX portion of slot processing
typedef struct {
/// Component Carrier index
......@@ -569,13 +606,13 @@ typedef struct PHY_VARS_gNB_s {
Sched_Rsp_t Sched_INFO;
NR_gNB_PDCCH pdcch_vars;
NR_gNB_PBCH pbch;
LTE_eNB_PHICH phich_vars[2];
// 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_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
NR_gNB_DLSCH_t *dlsch[NUMBER_OF_NR_DLSCH_MAX][2]; // Nusers times two spatial streams
NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_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
......
......@@ -277,6 +277,11 @@ typedef struct {
} NR_UE_COMMON_PER_THREAD;
typedef struct {
/// TX buffers for multiple layers
int32_t *txdataF_layers[NR_MAX_NB_LAYERS];
} NR_UE_PUSCH;
typedef struct {
/// \brief Holds the transmit data in time domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER.
......@@ -943,6 +948,7 @@ 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_PUSCH *pusch_vars[RX_NB_TH_MAX][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];
......@@ -983,6 +989,9 @@ typedef struct {
/// PDCCH DMRS
uint32_t nr_gold_pdcch[7][20][3][52];
/// PUSCH DMRS sequence
uint32_t ****nr_gold_pusch_dmrs;
uint32_t X_u[64][839];
uint32_t high_speed_flag;
......
......@@ -42,6 +42,11 @@
#define nr_subframe_t lte_subframe_t
#define nr_slot_t lte_subframe_t
// [hna] This enables SC-FDMA transmission in Uplink. If disabled, then OFDMA is used in UPLINK.
#ifndef NR_SC_FDMA
// #define NR_SC_FDMA
#endif
#define MAX_NUM_SUBCARRIER_SPACING 5
#define NR_MAX_NB_RB 275
......@@ -74,9 +79,12 @@
/*used for the resource mapping*/
#define NR_MAX_PDCCH_DMRS_LENGTH 576 // 16(L)*2(QPSK)*3(3 DMRS symbs per REG)*6(REG per CCE)
#define NR_MAX_PDSCH_DMRS_LENGTH 3300 //275*6(k)*2(QPSK)
#define NR_MAX_PDSCH_DMRS_LENGTH 3300 //275*6(k)*2(QPSK real+imag)
#define NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD 104 // ceil(NR_MAX_PDSCH_DMRS_LENGTH/32)
#define NR_MAX_PUSCH_DMRS_LENGTH NR_MAX_PDSCH_DMRS_LENGTH
#define NR_MAX_PUSCH_DMRS_INIT_LENGTH_DWORD NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD
#define NR_MAX_DCI_PAYLOAD_SIZE 64
#define NR_MAX_DCI_SIZE 1728 //16(L)*2(QPSK)*9(12 RE per REG - 3(DMRS))*6(REG per CCE)
#define NR_MAX_DCI_SIZE_DWORD 54 // ceil(NR_MAX_DCI_SIZE/32)
......@@ -91,6 +99,7 @@
#define NR_MAX_NB_CODEWORDS 2
#define NR_MAX_NB_HARQ_PROCESSES 16
#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
typedef enum {
......
......@@ -243,11 +243,13 @@
//#define CHBCH_RSSI_MIN -75
#ifdef BIT8_TX
#define AMP 128
#define AMP_SHIFT 7
#else
#define AMP 512//1024 //4096
#define AMP_SHIFT 9
#endif
#define AMP ((1)<<AMP_SHIFT)
#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
......
......@@ -15,6 +15,10 @@ typedef struct {
int nr_tti_tx;
/// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception
int nr_tti_rx;
/// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission
int nr_slot_tx;
/// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission
int nr_slot_rx;
//#endif
/// subframe to act upon for transmission
int subframe_tx;
......
......@@ -23,7 +23,9 @@
#include "PHY/defs_gNB.h"
#include "sched_nr.h"
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "SCHED/sched_eNB.h"
#include "SCHED/sched_common_extern.h"
#include "nfapi_interface.h"
......@@ -31,7 +33,7 @@
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "T.h"
#include "assertions.h"
......@@ -166,10 +168,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t));
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,1);
if (nfapi_mode == 0 || nfapi_mode == 1) {
if (!(frame%ssb_frame_periodicity)) // generate SSB only for given frames according to SSB periodicity
nr_common_signal_procedures(gNB,frame, slot);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,0);
num_dci = gNB->pdcch_vars.num_dci;
num_pdsch_rnti = gNB->pdcch_vars.num_pdsch_rnti;
......@@ -188,11 +192,11 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
if (num_pdsch_rnti) {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1);
LOG_D(PHY, "PDSCH generation started (%d)\n", num_pdsch_rnti);
nr_generate_pdsch(*gNB->dlsch[0][0],
gNB->pdcch_vars.dci_alloc[0],
nr_generate_pdsch(gNB->dlsch[0][0],
&gNB->pdcch_vars.dci_alloc[0],
gNB->nr_gold_pdsch_dmrs[slot],
gNB->common_vars.txdataF,
AMP, frame,slot, *fp, *cfg);
AMP, frame, slot, fp, cfg);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
}
......@@ -200,3 +204,78 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,0);
}
void nr_ulsch_procedures(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int UE_id, uint8_t harq_pid) {
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[UE_id+1][0]->harq_processes[harq_pid]->ulsch_pdu;
nfapi_nr_ul_config_ulsch_pdu_rel15_t *nfapi_ulsch_pdu_rel15 = &rel15_ul->ulsch_pdu_rel15;
uint8_t ret;
uint32_t G;
int Nid_cell = 0; // [hna] shouldn't be a local variable (should be signaled)
G = nr_get_G(nfapi_ulsch_pdu_rel15->number_rbs, nfapi_ulsch_pdu_rel15->number_symbols, nfapi_ulsch_pdu_rel15->nb_re_dmrs, nfapi_ulsch_pdu_rel15->length_dmrs, nfapi_ulsch_pdu_rel15->Qm, nfapi_ulsch_pdu_rel15->n_layers);
//----------------------------------------------------------
//------------------- ULSCH unscrambling -------------------
//----------------------------------------------------------
nr_ulsch_unscrambling(gNB->pusch_vars[UE_id]->llr, G, 0, Nid_cell, rel15_ul->rnti);
//----------------------------------------------------------
//--------------------- ULSCH decoding ---------------------
//----------------------------------------------------------
ret = nr_ulsch_decoding(gNB, UE_id, gNB->pusch_vars[UE_id]->llr, frame_parms, proc->frame_rx,
nfapi_ulsch_pdu_rel15->number_symbols, proc->slot_rx, harq_pid, 0);
// if (ret > ulsch_gNB->max_ldpc_iterations)
// n_errors++;
}
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) {
uint8_t symbol;
unsigned char aa;
for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) {
// nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0);
for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) {
nr_slot_fep_ul(&gNB->frame_parms,
gNB->common_vars.rxdata[aa],
gNB->common_vars.rxdataF[aa],
symbol,
proc->slot_rx,
0,
0);
}
}
}
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end) {
uint8_t UE_id;
uint8_t symbol;
uint8_t harq_pid = 0; // [hna] Previously in LTE, the harq_pid was obtained from the subframe number (Synchronous HARQ)
// In NR, this should be signaled through uplink scheduling dci (i.e, DCI 0_0, 0_1) (Asynchronous HARQ)
for (UE_id = 0; UE_id < NUMBER_OF_NR_UE_MAX; UE_id++) {
for(symbol = symbol_start; symbol < symbol_end; symbol++) {
nr_rx_pusch(gNB, UE_id, proc->frame_rx, proc->slot_rx, symbol, harq_pid);
}
nr_ulsch_procedures(gNB, proc, UE_id, harq_pid);
}
}
......@@ -36,7 +36,9 @@
nr_slot_t nr_slot_select (nfapi_nr_config_request_t *cfg, unsigned char slot);
void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_t *cfg, NR_DL_FRAME_PARMS *fp);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx,int slot_tx, int do_meas);
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, uint8_t symbol_start, uint8_t symbol_end);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
......
......@@ -112,7 +112,7 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
@param mode calib/normal mode
@param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
*/
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t thread_id);
/*! \brief Scheduling for UE RX procedures in normal subframes.
@param last_slot Index of last slot (0-19)
@param phy_vars_ue Pointer to UE variables on which to act
......
......@@ -142,7 +142,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
uint8_t current_harq_pid = pusch_config_pdu->harq_process_nbr;
ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs;
ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb;
ulsch0->harq_processes[current_harq_pid]->nb_symbols = pusch_config_pdu->number_symbols;
ulsch0->harq_processes[current_harq_pid]->number_of_symbols = pusch_config_pdu->number_symbols;
ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol;
ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs;
ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi;
......
......@@ -2460,131 +2460,78 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
}
#endif
void phy_procedures_UE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) {
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id, uint8_t thread_id) {
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
fapi_nr_dci_pdu_rel15_t *ul_dci_pdu;
NR_UE_ULSCH_t *ulsch_ue;
NR_UL_UE_HARQ_t *harq_process_ul_ue;
//int32_t ulsch_start=0;
int nr_tti_tx = proc->nr_tti_tx;
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
unsigned int aa;
uint8_t isSubframeSRS;
/*
uint8_t next1_thread_id = ue->current_thread_id[proc->nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->nr_tti_rx]+1);
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
*/
int harq_pid, i, TBS;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, nr_tti_tx);
#if T_TRACER
T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(nr_tti_tx));
#endif
LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
ue->generate_ul_signal[eNB_id] = 0;
#if UE_TIMING_TRACE
start_meas(&ue->phy_proc_tx);
#endif
#ifdef EMOS
//phy_procedures_emos_UE_TX(next_slot);
#endif
ul_dci_pdu = &ue->dci_ind.dci_list[0].dci;
ue->tx_power_dBm[nr_tti_tx]=-127;
harq_pid = 0; //temporary implementation
if (abstraction_flag==0) {
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
memset(&ue->common_vars.txdataF[aa][nr_tti_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
0,
frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
}
}
if (ue->UE_mode[eNB_id] != PRACH) {
// check cell srs nr_tti_rx and ue srs nr_tti_rx. This has an impact on pusch encoding
isSubframeSRS = nr_is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->nr_tti_tx);
generate_ue_ulsch_params(ue,
0,
gNB_id,
harq_pid);
ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS);
ulsch_ue = ue->ulsch[thread_id][gNB_id][0]; // cwd_index = 0
harq_process_ul_ue = ulsch_ue->harq_processes[harq_pid];
ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
}
TBS = nr_compute_tbs(ul_dci_pdu->mcs, harq_process_ul_ue->nb_rb, ulsch_ue->Nsymb_pusch, ulsch_ue->nb_re_dmrs, ulsch_ue->length_dmrs, ul_dci_pdu->precod_nbr_layers);
//-----------------------------------------------------//
// to be removed later when MAC is ready
for (i = 0; i < TBS / 8; i++)
harq_process_ul_ue->a[i] = (unsigned char) rand();
//-----------------------------------------------------//
nr_ue_ulsch_procedures(ue,
harq_pid,
slot_tx,
0,
gNB_id);
/*
if (ue->UE_mode[eNB_id] == PUSCH) {
// check if we need to use PUCCH 1a/1b
ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
// check if we need to use SRS
ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
} // UE_mode==PUSCH
*/
#ifdef CBA
if ((ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag >= 1) &&
(ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == CBA_ACTIVE)) {
ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag=0; //-=1
// ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
//cba_mcs=ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs;
input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
access_mode=CBA_ACCESS;
LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: CBA num dci %d\n",
Mod_id,frame_tx,nr_tti_tx,
ue->ulsch[eNB_id]->num_cba_dci[nr_tti_tx]);
/*mac_xface->ue_get_sdu(Mod_id,
CC_id,
frame_tx,
proc->subframe_tx,
nr_tti_tx%(ue->frame_parms.ttis_per_subframe),
eNB_id,
ulsch_input_buffer,
input_buffer_length,
&access_mode);*/
ue->ulsch[eNB_id]->num_cba_dci[nr_tti_tx]=0;
if (access_mode > UNKNOWN_ACCESS) {
if (abstraction_flag==0) {
if (ulsch_encoding(ulsch_input_buffer,
ue,
harq_pid,
eNB_id,
proc->nr_tti_rx,
ue->transmission_mode[eNB_id],0,
0)!=0) { // Nbundled, to be updated!!!!
LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
return;
}
}
#ifdef PHY_ABSTRACTION
else {
ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,proc->nr_tti_rx,harq_pid,0);
}
#endif
} else {
ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
//reset_cba_uci(ue->ulsch[eNB_id]->o);
LOG_N(PHY,"[UE %d] Frame %d, nr_tti_rx %d: CBA transmission cancelled or postponed\n",
Mod_id, frame_tx,nr_tti_tx);
}
}
#endif // end CBA
if (abstraction_flag == 0) {
ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0));
} // mode != PRACH
nr_ue_pusch_common_procedures(ue,
slot_tx,
ul_dci_pdu->precod_nbr_layers,
&ue->frame_parms);
/*
if ((ue->UE_mode[eNB_id] == PRACH) &&
(ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
......@@ -2598,54 +2545,19 @@ void phy_procedures_UE_TX(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB
else {
ue->generate_prach=0;
}
*/
// reset DL ACK/NACK status
uint8_t N_bundled = 0;
if (ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0] != NULL)
{
nr_reset_ack(&ue->frame_parms,
ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][eNB_id][0]->harq_ack,
nr_tti_tx,
proc->nr_tti_rx,
ue->ulsch[eNB_id]->o_ACK,
&N_bundled,
0);
/*
nr_reset_ack(&ue->frame_parms,
ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack,
nr_tti_tx,
proc->nr_tti_rx,
ue->ulsch[eNB_id]->o_ACK,
&N_bundled,
0);
nr_reset_ack(&ue->frame_parms,
ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack,
nr_tti_tx,
proc->nr_tti_rx,
ue->ulsch[eNB_id]->o_ACK,
&N_bundled,
0);
*/
}
if (ue->dlsch_SI[eNB_id] != NULL)
nr_reset_ack(&ue->frame_parms,
ue->dlsch_SI[eNB_id]->harq_ack,
nr_tti_tx,
proc->nr_tti_rx,
ue->ulsch[eNB_id]->o_ACK,
&N_bundled,
0);
LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, nr_tti_tx);
LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
#if UE_TIMING_TRACE
stop_meas(&ue->phy_proc_tx);
#endif
}
/*
void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
{
int aa;//i,aa;
......@@ -2669,7 +2581,7 @@ void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstractio
}
}
#endif
*/
void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0..6]
PHY_VARS_NR_UE *ue,
......
......@@ -38,6 +38,7 @@
#include "PHY/defs_nr_UE.h"
#include <openair1/SCHED/sched_common.h>
#include <openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h>
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#ifndef NO_RAT_NR
......@@ -50,7 +51,8 @@
#endif
int8_t nr_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);
uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
/*
......@@ -111,7 +113,6 @@ void nr_generate_pucch3_4(int32_t **txdataF,
//extern uint8_t is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
//extern uint8_t is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id);
/*******************************************************************
*
* NAME : pucch_procedures_ue_nr
......
......@@ -43,6 +43,7 @@
#include "PHY/INIT/phy_init.h"
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/phy_vars.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
......@@ -104,7 +105,10 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
const int8_t channel,
const uint8_t* pduP,
const sdu_size_t pdu_len)
{return(0);}
{
return 0;
}
int rlc_module_init (void) {return(0);}
void pdcp_layer_init(void) {}
int rrc_init_nr_global_param(void){return(0);}
......@@ -121,8 +125,6 @@ void config_common(int Mod_idP,
// needed for some functions
PHY_VARS_NR_UE ***PHY_vars_UE_g;
short conjugate[8]__attribute__((aligned(32))) = {-1,1,-1,1,-1,1,-1,1};
openair0_config_t openair0_cfg[MAX_CARDS];
int main(int argc, char **argv)
......
......@@ -44,6 +44,7 @@
#include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
#include "PHY/phy_vars.h"
#include "SCHED_NR/sched_nr.h"
......@@ -79,7 +80,6 @@ void exit_function(const char* file, const char* function, const int line,const
}
// needed for some functions
PHY_VARS_NR_UE * PHY_vars_UE_g[1][1]={{NULL}};
openair0_config_t openair0_cfg[MAX_CARDS];
int main(int argc, char **argv)
......
This diff is collapsed.
This diff is collapsed.
......@@ -114,6 +114,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(
uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP,
uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe);
int8_t nr_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);
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format);
......@@ -123,6 +124,7 @@ 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);
void nr_ue_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
......
......@@ -2012,7 +2012,6 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e
}
void nr_ue_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
......
......@@ -43,7 +43,7 @@
int set_device(openair0_device *device) {
switch (device->type) {
case EXMIMO_DEV:
LOG_I(HW,"[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
......@@ -95,6 +95,8 @@ int set_transport(openair0_device *device) {
}
typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *);
//loader_shlibfunc_t shlib_fdesc[2];
/* look for the interface library and load it */
int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) {
......@@ -102,11 +104,12 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
int ret=0;
char *libname;
if (flag == RAU_LOCAL_RADIO_HEAD) {
if (getenv("RFSIMULATOR") != NULL)
libname="rfsimulator";
else
if (getenv("RFSIMULATOR") != NULL)
libname="rfsimulator";
else
libname=OAI_RF_LIBNAME;
shlib_fdesc[0].fname="device_init";
//shlib_fdesc[1].fname="uhd_set_thread_priority";
} else {
libname=OAI_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
......@@ -116,11 +119,32 @@ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_param
LOG_E(HW,"Library %s couldn't be loaded\n",libname);
} else {
ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
//uhd_set_thread_priority_fun = (set_prio_func_t)shlib_fdesc[1].fptr;
}
return ret;
}
void uhd_set_thread_prio(void) {
loader_shlibfunc_t shlib_fdesc[1];
int ret = 0;
char *libname;
if (getenv("RFSIMULATOR") != NULL)
libname="rfsimulator";
else
libname=OAI_RF_LIBNAME;
shlib_fdesc[0].fname="uhd_set_thread_priority";
ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
if (ret < 0) {
LOG_E(HW,"Library %s couldn't be loaded\n",libname);
} else {
(set_prio_func_t)shlib_fdesc[0].fptr();
}
return ret;
}
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {
......
......@@ -405,7 +405,7 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
#define sample_t uint32_t // 2*16 bits complex number
#define sample_t struct complex16 // 2*16 bits complex number
typedef struct {
uint64_t magic; // Magic value (see defines above)
......@@ -445,6 +445,10 @@ int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *open
#define gettid() syscall(__NR_gettid)
/*@}*/
void uhd_set_thread_prio(void);
typedef void(*set_prio_func_t)(void);
set_prio_func_t uhd_set_thread_priority_fun;
#ifdef __cplusplus
}
#endif
......
......@@ -1462,5 +1462,10 @@ extern "C" {
#endif
return 0;
}
void uhd_set_thread_priority(void) {
uhd::set_thread_priority_safe(1.0);
}
}
/*@}*/
......@@ -30,7 +30,7 @@ Then, you can use it freely
# Usage
Setting the env variable RFSIMULATOR enables the RF board simulator
It should the set to "enb" in the eNB
It should the set to "server" in the eNB or gNB
## 4G case
For the UE, it should be set to the IP address of the eNB
......@@ -62,6 +62,19 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
In UE, you can add "-d" to get the softscope
### Channel simulation
The RF channel simulator is called.
In current version all channel paramters are hard coded in the call to:
new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
AWGN,
bridge->sample_rate,
bridge->tx_bw,
0.0, // forgetting_factor
0, // maybe used for TA
0); // path_loss in dB
Only the input noise can be changed on command line with -s parameter.
With path loss = 0 set "-s 5" to see a little noise
#Caveacts
Still issues in power control: txgain, rxgain are not used
......
This diff is collapsed.
This diff is collapsed.
\documentclass[a4paper]{book}
\usepackage{a4wide}
\usepackage{makeidx}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{multicol}
\usepackage{float}
\usepackage{textcomp}
\usepackage{alltt}
\usepackage{amsmath}
\usepackage{amssymb}
\ifx\pdfoutput\undefined
\usepackage[ps2pdf,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\usepackage{pspicture}
\else
\usepackage[pdftex,
pagebackref=true,
colorlinks=true,
linkcolor=blue
]{hyperref}
\fi
\usepackage{doxygen}
\usepackage{times}
\makeindex
\setcounter{tocdepth}{1}
\renewcommand{\footrulewidth}{0.4pt}
\begin{document}
\begin{titlepage}
\vspace*{7cm}
\begin{center}
{\Large openair Specifications }\\
Phyiscal, Medium-Access, Radio-link Control, Packet Data Convergence Protocol and Radio Resource Control Layers\\
\vspace*{1cm}
{\large Generated by Doxygen 1.3.8}\\
\vspace*{0.5cm}
{\small Sun Oct 31 19:27:37 2004}\\
\end{center}
\end{titlepage}
\clearemptydoublepage
\pagenumbering{roman}
\tableofcontents
\clearemptydoublepage
\pagenumbering{arabic}
......@@ -254,7 +254,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.100.8,clock_source=external,time_source=external";
sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.10.2,clock_source=external,time_source=external";
}
);
......
......@@ -254,7 +254,7 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
sdr_addrs = "addr=192.168.30.2";
sdr_addrs = "type=x300";
}
);
......
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