Merge branch 'nr_initialsync' of https://gitlab.eurecom.fr/oai/openairinterface5g into nr_initialsync
This commit is contained in:
@@ -1267,6 +1267,12 @@ set(PHY_SRC_UE
|
||||
# actual source
|
||||
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
|
||||
${OPENAIR1_DIR}/PHY/INIT/nr_parms.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
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dmrs_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
|
||||
${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/file_output.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
|
||||
@@ -2153,6 +2159,76 @@ target_link_libraries (nr-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRY
|
||||
target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-softmodem ${T_LIB})
|
||||
|
||||
# nr-uesoftmodem is UE implementation
|
||||
#######################################
|
||||
|
||||
add_executable(nr-uesoftmodem
|
||||
${rrc_h}
|
||||
${s1ap_h}
|
||||
${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-ue.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${XFORMS_SOURCE}
|
||||
${XFORMS_SOURCE_SOFTMODEM}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries (nr-uesoftmodem
|
||||
-Wl,--start-group
|
||||
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_NR_UE PHY_COMMON PHY_UE PHY_RU LFDS L2_UE
|
||||
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem ${T_LIB})
|
||||
|
||||
# nr-uesoftmodem is UE implementation
|
||||
#######################################
|
||||
|
||||
add_executable(nr-uesoftmodem-nos1
|
||||
${rrc_h}
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-ue.c
|
||||
${OPENAIR_TARGETS}/RT/USER/nr-uesoftmodem.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${XFORMS_SOURCE}
|
||||
${XFORMS_SOURCE_SOFTMODEM}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries (nr-uesoftmodem-nos1
|
||||
-Wl,--start-group
|
||||
RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_NR_UE PHY_COMMON PHY_UE PHY_RU LFDS L2_UE
|
||||
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (nr-uesoftmodem-nos1 ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem-nos1 ${T_LIB})
|
||||
|
||||
# USIM process
|
||||
#################
|
||||
#add_executable(usim
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#define __MODULATION_DEFS__H__
|
||||
#include "PHY/defs_common.h"
|
||||
#include "modulation_common.h"
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
/** @addtogroup _PHY_MODULATION_
|
||||
* @{
|
||||
*/
|
||||
@@ -46,6 +48,13 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
|
||||
int no_prefix,
|
||||
int reset_freq_est);
|
||||
|
||||
int slot_fep_pbch(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
unsigned char l,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix,
|
||||
int reset_freq_est);
|
||||
|
||||
int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
|
||||
unsigned char l,
|
||||
int subframe,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "modulation_UE.h"
|
||||
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
|
||||
|
||||
@@ -27,6 +28,207 @@
|
||||
|
||||
#define SOFFSET 0
|
||||
|
||||
int slot_fep_pbch(PHY_VARS_NR_UE *ue,
|
||||
unsigned char l,
|
||||
unsigned char Ns,
|
||||
int sample_offset,
|
||||
int no_prefix,
|
||||
int reset_freq_est)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
NR_UE_COMMON *common_vars = &ue->common_vars;
|
||||
uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
|
||||
unsigned char aa;
|
||||
unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
|
||||
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);
|
||||
unsigned int subframe_offset;//,subframe_offset_F;
|
||||
unsigned int slot_offset;
|
||||
int i;
|
||||
unsigned int frame_length_samples = frame_parms->samples_per_subframe * 10;
|
||||
unsigned int rx_offset;
|
||||
|
||||
/*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
|
||||
unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
|
||||
LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
|
||||
int uespec_pilot[9][1200];*/
|
||||
|
||||
void (*dft)(int16_t *,int16_t *, int);
|
||||
int tmp_dft_in[2048] __attribute__ ((aligned (32))); // This is for misalignment issues for 6 and 15 PRBs
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
dft = dft512;
|
||||
break;
|
||||
}
|
||||
|
||||
if (no_prefix) {
|
||||
subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
|
||||
slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2);
|
||||
} else {
|
||||
subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
|
||||
slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
|
||||
}
|
||||
|
||||
if (l<0 || l>=7-frame_parms->Ncp) {
|
||||
printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (Ns<0 || Ns>=20) {
|
||||
printf("slot_fep: Ns must be between 0 and 19\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
|
||||
// Align with 256 bit
|
||||
// rx_offset = rx_offset&0xfffffff8;
|
||||
|
||||
if (l==0) {
|
||||
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
|
||||
(short *)&common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft((int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
}
|
||||
} else {
|
||||
rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
|
||||
// (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
LOG_I(PHY,"slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
|
||||
nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
|
||||
#endif
|
||||
|
||||
if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
|
||||
memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
|
||||
(void *)&common_vars->rxdata[aa][0],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
if ((rx_offset&7)!=0) { // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
|
||||
memcpy((void *)tmp_dft_in,
|
||||
(void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
|
||||
frame_parms->ofdm_symbol_size*sizeof(int));
|
||||
dft((int16_t *)tmp_dft_in,
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
} else { // use dft input from RX buffer directly
|
||||
|
||||
dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
|
||||
(int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
|
||||
}
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->rx_dft_stats);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
// if (ue->frame <100)
|
||||
printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx, symbol,rx_offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ue->perfect_ce == 0) {
|
||||
if ((l==0) || (l==(4-frame_parms->Ncp))) {
|
||||
for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
|
||||
#endif
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_channel_estimation_stats);
|
||||
#endif
|
||||
/* nr_pbch_channel_estimation(ue,eNB_id,0,
|
||||
Ns,
|
||||
aa,
|
||||
l,
|
||||
symbol);*/
|
||||
}
|
||||
|
||||
|
||||
// do frequency offset estimation here!
|
||||
// use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
|
||||
#ifdef DEBUG_FEP
|
||||
printf("Frequency offset estimation\n");
|
||||
#endif
|
||||
|
||||
if (l==(4-frame_parms->Ncp)) {
|
||||
|
||||
#if UE_TIMING_TRACE
|
||||
start_meas(&ue->dlsch_freq_offset_estimation_stats);
|
||||
#endif
|
||||
|
||||
/*lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[0],
|
||||
frame_parms,
|
||||
l,
|
||||
&common_vars->freq_offset,
|
||||
reset_freq_est);*/
|
||||
#if UE_TIMING_TRACE
|
||||
stop_meas(&ue->dlsch_freq_offset_estimation_stats);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FEP
|
||||
printf("slot_fep: done\n");
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
int slot_fep(PHY_VARS_UE *ue,
|
||||
unsigned char l,
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : ul_ref_seq_nr.c
|
||||
*
|
||||
* MODULE : generation of uplink reference sequence for nr
|
||||
*
|
||||
* DESCRIPTION : function to generate uplink reference sequences
|
||||
* see 3GPP TS 38.211 5.2.2 Low-PAPR sequence generation
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "defs.h"
|
||||
|
||||
#define DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
#undef DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : base_sequence_less_3_RB
|
||||
*
|
||||
* PARAMETERS : M_ZC length of Zadoff Chu sequence
|
||||
* u sequence group number
|
||||
* scaling to apply
|
||||
*
|
||||
* RETURN : pointer to generated sequence
|
||||
*
|
||||
* DESCRIPTION : base sequence generation of less than 36 elements
|
||||
* see TS 38.211 5.2.2.2 Base sequences of length less than 36
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling)
|
||||
{
|
||||
char *phi_table;
|
||||
int16_t *rv_overbar;
|
||||
double x;
|
||||
unsigned int n;
|
||||
|
||||
switch(M_ZC) {
|
||||
case 6:
|
||||
phi_table = (char *)phi_M_ZC_6;
|
||||
break;
|
||||
case 12:
|
||||
phi_table = (char *)phi_M_ZC_12;
|
||||
break;
|
||||
case 18:
|
||||
phi_table = (char *)phi_M_ZC_18;
|
||||
break;
|
||||
case 24:
|
||||
phi_table = (char *)phi_M_ZC_24;
|
||||
break;
|
||||
case 30:
|
||||
break;
|
||||
default:
|
||||
printf("function base_sequence_less_than 36_: unsupported base sequence size : %d \n", M_ZC);
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
rv_overbar = malloc16(IQ_SIZE*M_ZC);
|
||||
|
||||
if (rv_overbar == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (M_ZC == 30) {
|
||||
for (n=0; n<M_ZC; n++) {
|
||||
x = -(M_PI * (u + 1) * (n + 1) * (n + 2))/(double)31;
|
||||
rv_overbar[2*n] =(int16_t)(floor(scaling*cos(x)));
|
||||
rv_overbar[2*n+1] =(int16_t)(floor(scaling*sin(x)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (n=0; n<M_ZC; n++) {
|
||||
x = (double)phi_table[n + u*M_ZC] * (M_PI/4);
|
||||
rv_overbar[2*n] = (int16_t)(floor(scaling*cos(x)));
|
||||
rv_overbar[2*n+1] = (int16_t)(floor(scaling*sin(x)));
|
||||
}
|
||||
}
|
||||
return rv_overbar;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : base_sequence_36_or_larger
|
||||
*
|
||||
* PARAMETERS : M_ZC length of Zadoff chu sequence
|
||||
* u sequence group number
|
||||
* scaling to apply
|
||||
*
|
||||
* RETURN : pointer to generated sequence
|
||||
*
|
||||
* DESCRIPTION : base sequence generation of less than 36 elements
|
||||
* 5.2.2.1 Base sequences of length 36 or larger
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, unsigned int u, unsigned int v, unsigned int scaling)
|
||||
{
|
||||
int16_t *rv_overbar;
|
||||
unsigned int N_ZC;
|
||||
double q_overbar, x;
|
||||
unsigned int q,m,n;
|
||||
unsigned int M_ZC = ul_allocated_re[Msc_RS];
|
||||
|
||||
rv_overbar = malloc16(IQ_SIZE*M_ZC);
|
||||
if (rv_overbar == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */
|
||||
|
||||
q_overbar = N_ZC * (u+1)/(double)31;
|
||||
|
||||
/* q = (q_overbar + 1/2) + v.(-1)^(2q_overbar) */
|
||||
if ((((int)floor(2*q_overbar))&1) == 0)
|
||||
q = (int)(floor(q_overbar+.5)) - v;
|
||||
else
|
||||
q = (int)(floor(q_overbar+.5)) + v;
|
||||
|
||||
for (n = 0; n < M_ZC; n++) {
|
||||
m=n%N_ZC;
|
||||
x = (double)q * m * (m+1)/N_ZC;
|
||||
rv_overbar[2*n] = (int16_t)(floor(scaling*cos(M_PI*x))); /* cos(-x) = cos(x) */
|
||||
rv_overbar[2*n+1] = -(int16_t)(floor(scaling*sin(M_PI*x))); /* sin(-x) = -sin(x) */
|
||||
}
|
||||
return rv_overbar;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : generate_ul_srs_sequences
|
||||
*
|
||||
* PARAMETERS : scaling to apply
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : uplink reference signal sequences generation
|
||||
* which are Low-PAPR base sequences
|
||||
* see TS 38.211 5.2.2 Low-PAPR sequence generation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void generate_ul_reference_signal_sequences(unsigned int scaling)
|
||||
{
|
||||
unsigned int u,v,Msc_RS;
|
||||
|
||||
#if 0
|
||||
|
||||
char output_file[255];
|
||||
char sequence_name[255];
|
||||
|
||||
#endif
|
||||
|
||||
for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) {
|
||||
v = 0;
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling);
|
||||
#if 0
|
||||
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
printf("u %d Msc_RS %d allocate memory %x of size %d \n", u, Msc_RS, rv_ul_ref_sig[u][v][Msc_RS], (IQ_SIZE* ul_allocated_re[Msc_RS]));
|
||||
write_output(output_file, sequence_name, rv_ul_ref_sig[u][v][Msc_RS], ul_allocated_re[Msc_RS], 1, 1);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < SRS_SB_CONF; Msc_RS++) {
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
|
||||
rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling);
|
||||
#if 0
|
||||
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]);
|
||||
printf("u %d Msc_RS %d allocate memory %x of size %d \n", u, Msc_RS, rv_ul_ref_sig[u][v][Msc_RS], (IQ_SIZE* ul_allocated_re[Msc_RS]));
|
||||
write_output(output_file, sequence_name, rv_ul_ref_sig[u][v][Msc_RS], ul_allocated_re[Msc_RS], 1, 1);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_ul_reference_signal_sequences
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : free of uplink reference signal sequences
|
||||
*
|
||||
*********************************************************************/
|
||||
void free_ul_reference_signal_sequences(void)
|
||||
{
|
||||
unsigned int u,v,Msc_RS;
|
||||
for (Msc_RS=0; Msc_RS < SRS_SB_CONF; Msc_RS++) {
|
||||
for (u=0; u < U_GROUP_NUMBER; u++) {
|
||||
for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) {
|
||||
if (rv_ul_ref_sig[u][v][Msc_RS])
|
||||
free16(rv_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*ul_allocated_re[Msc_RS]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : ul_ref_seq_nr.hh
|
||||
*
|
||||
* MODULE : generation of uplink reference sequence for nr
|
||||
*
|
||||
* DESCRIPTION : variables to generate sequences with low peak to average power
|
||||
* see 3GPP TS 38.211 5.2.2 Low-PAPR sequence generation
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifndef LOWPAPR_SEQUENCES_NR_H
|
||||
#define LOWPAPR_SEQUENCES_NR_H
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/types.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
|
||||
#ifdef DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
#define EXTERN
|
||||
#define INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************** DEFINE ********************************************/
|
||||
#define U_GROUP_NUMBER (30) /* maximum number of sequence-group */
|
||||
#define V_BASE_SEQUENCE_NUMBER (2) /* maximum number of base sequences */
|
||||
#define SRS_SB_CONF (71) /* maximum number of configuration for srs subcarrier allocation */
|
||||
|
||||
/************** VARIABLES *****************************************/
|
||||
|
||||
#define INDEX_SB_LESS_32 (4) /* index of dftsizes array for which subcarrier number is less than 36 */
|
||||
|
||||
const uint16_t ul_allocated_re[SRS_SB_CONF] /* number of uplink allocated resource elements */
|
||||
/* this table is derivated from TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration which gives m_SRS_b then all possible values of sequence length is */
|
||||
/* M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC with K_TC = 2 or K_TC = 4 as specified in TS 38.211 6.4.1.4.3 */
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= { /*
|
||||
K_TC 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
|
||||
m_SRS_b 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 */
|
||||
6, 12, 18, 24, 30, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240,
|
||||
/*
|
||||
K_TC 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 6 3 3
|
||||
m_SRS_b 84 88 92 96 100 104 108 112 116 120 128 132 136 144 152 160 168 176 184 192 100 208 216 */
|
||||
252, 264, 276, 288, 300, 312, 324, 336, 348, 360, 384, 396, 408, 432, 456, 480, 504, 528, 552, 576, 600, 624, 648,
|
||||
/*
|
||||
K_TC 3 6 3 3 3 3 6 6 6 6 6 6 6 6 6 6 6 6 6 6
|
||||
m_SRS_b 224 116, 240 256 264 272 144 152 160 168 176 184 192 208 216 224 240 256 264 272 */
|
||||
672, 696, 720, 768, 792, 816, 864, 912, 960, 1008, 1056, 1104, 1152, 1248, 1296, 1344, 1440, 1536, 1584, 1632,
|
||||
|
||||
/* below numbers have been added just to include all possible lengths already used for lte */
|
||||
540, 900, 972, 1080, 1200,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/* table of largest prime number lower than uplink allocated resource elements "ul_allocated_re" */
|
||||
const uint16_t ref_ul_primes[SRS_SB_CONF]
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/* 6, 12, 18, 24, 30, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, */
|
||||
5, 11, 17, 23, 29, 31, 47, 59, 71, 83, 89, 107, 113, 127, 139, 151, 167, 179, 191, 199, 211, 227, 239,
|
||||
|
||||
/* 252, 264, 276, 288, 300, 312, 324, 336, 348, 360, 384, 396, 408, 432, 456, 480, 504, 528, 552, 576, 600, 624, 648, */
|
||||
251, 263, 271, 283, 293, 311, 317, 331, 347, 359, 383, 389, 401, 431, 449, 479, 503, 523, 547, 571, 599, 619, 647,
|
||||
|
||||
/* 672, 696, 720, 768, 792, 816, 864, 912, 960, 1008, 1056, 1104, 1152, 1248, 1296, 1344, 1440, 1536, 1584, 1632, */
|
||||
661, 691, 719, 761, 787, 811, 863, 911, 953, 997, 1051, 1103, 1151, 1237, 1291, 1327, 1439, 1531, 1583, 1627,
|
||||
|
||||
/* 540, 900, 972, 1080, 1200, */
|
||||
523, 887, 971, 1069, 1193,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */
|
||||
int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
|
||||
|
||||
/* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */
|
||||
const char phi_M_ZC_6[6*U_GROUP_NUMBER]
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/* 0 1 2 3 4 5 */
|
||||
/* 0 */ -3, -1, 3, 3, -1, -3,
|
||||
/* 1 */ -3, 3, -1, -1, 3, -3,
|
||||
/* 2 */ -3, -3, -3, 3, 1, -3,
|
||||
/* 3 */ 1, 1, 1, 3, -1, -3,
|
||||
/* 4 */ 1, 1, 1, -3, -1, 3,
|
||||
/* 5 */ -3, 1, -1, -3, -3, -3,
|
||||
/* 6 */ -3, 1, 3, -3, -3, -3,
|
||||
/* 7 */ -3, -1, 1, -3, 1, -1,
|
||||
/* 8 */ -3, -1, -3, 1, -3, -3,
|
||||
/* 9 */ -3, -3, 1, -3, 3, -3,
|
||||
/* 10 */ -3, 1, 3, 1, -3, -3,
|
||||
/* 11 */ -3, -1, -3, 1, 1, -3,
|
||||
/* 12 */ 1, 1, 3, -1, -3, 3,
|
||||
/* 13 */ 1, 1, 3, 3, -1, 3,
|
||||
/* 14 */ 1, 1, 1, -3, 3, -1,
|
||||
/* 15 */ -1, 1, 1, -1, 3, -3,
|
||||
/* 16 */ -3, -1, -1, -1, 3, -1,
|
||||
/* 17 */ -3, -3, -1, 1, -1, -3,
|
||||
/* 18 */ -3, -3, -3, 1, -3, -1,
|
||||
/* 19 */ -3, 1, 1, -3, -1, -3,
|
||||
/* 20 */ -3, 3, -3, 1, 1, -3,
|
||||
/* 21 */ -3, 1, -3, -3, -3, -1,
|
||||
/* 22 */ 1, 1, -3, 3, 1, 3,
|
||||
/* 23 */ 1, 1, -3, -3, 1, -3,
|
||||
/* 24 */ 1, 1, 3, -1, 3, 3,
|
||||
/* 25 */ 1, 1, -3, 1, 3, 3,
|
||||
/* 26 */ 1, 1, -1, -1, 3, -1,
|
||||
/* 27 */ 1, 1, -1, 3, -1, -1,
|
||||
/* 28 */ 1, 1, -1, 3, -3, -1,
|
||||
/* 29 */ 1, 1, -3, 1, -1, -1,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
/* Table 5.2.2.2-2: Definition of phi ( n ) for M ZC = 12 */
|
||||
const char phi_M_ZC_12[12*U_GROUP_NUMBER]
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 10 11 */
|
||||
/* 0 */ 1, -1, 3, 1, 1, -1, -1, -1, 1, 3, -3, 1,
|
||||
/* 1 */ -1, -1, -1, -1, 1, -3, -1, 3, 3, -1, -3, 1,
|
||||
/* 2 */ -3, 1, -3, -3, -3, 3, -3, -1, 1, 1, 1, -3,
|
||||
/* 3 */ -3, 3, 1, 3, -3, 1, 1, 1, 1, 3, -3, 3,
|
||||
/* 4 */ -3, 1, 3, -1, -1, -3, -3, -1, -1, 3, 1, -3,
|
||||
/* 5 */ -1, 1, 1, -1, 1, 3, 3, -1, -1, -3, 1, -3,
|
||||
/* 6 */ -3, -3, -1, 3, 3, 3, -3, 3, -3, 1, -1, -3,
|
||||
/* 7 */ -3, 3, -3, 3, 3, -3, -1, -1, 3, 3, 1, -3,
|
||||
/* 8 */ -3, -1, -3, -1, -1, -3, 3, 3, -1, -1, 1, -3,
|
||||
/* 9 */ -3, 3, 3, 3, -1, -3, -3, -1, -3, 1, 3, -3,
|
||||
/* 10 */ 1, 3, -3, 1, 3, 3, 3, 1, -1, 1, -1, 3,
|
||||
/* 11 */ -1, -3, 3, -1, -3, -3, -3, -1, 1, -1, 1, -3,
|
||||
/* 12 */ 3, 1, 3, 1, 3, -3, -1, 1, 3, 1, -1, -3,
|
||||
/* 13 */ -3, -3, 3, 3, 3, -3, -1, 1, -3, 3, 1, -3,
|
||||
/* 14 */ -3, -1, 1, -3, 1, 3, 3, 3, -1, -3, 3, 3,
|
||||
/* 15 */ -3, -3, 3, 1, -3, -3, -3, -1, 3, -1, 1, 3,
|
||||
/* 16 */ -1, 1, 3, -3, 1, -1, 1, -1, -1, -3, 1, -1,
|
||||
/* 17 */ -3, -1, -1, 1, 3, 1, 1, -1, 1, -1, -3, 1,
|
||||
/* 18 */ -3, -1, 3, -3, -3, -1, -3, 1, -1, -3, 3, 3,
|
||||
/* 19 */ -3, -3, 3, -3, -1, 3, 3, 3, -1, -3, 1, -3,
|
||||
/* 20 */ -3, 1, -1, -1, 3, 3, -3, -1, -1, -3, -1, -3,
|
||||
/* 21 */ -3, 1, 3, 3, -1, -1, -3, 3, 3, -3, 3, -3,
|
||||
/* 22 */ -3, -1, -1, -3, -3, -1, -3, 3, 1, 3, -1, -3,
|
||||
/* 23 */ -3, -1, 3, 1, -3, -1, -3, 3, 1, 3, 3, 1,
|
||||
/* 24 */ -3, 3, 3, 1, -3, 3, -1, 1, 3, -3, 3, -3,
|
||||
/* 25 */ 3, -1, -3, 3, -3, -1, 3, 3, 3, -3, -1, -3,
|
||||
/* 26 */ 1, -1, 3, -1, -1, -1, -3, -1, 1, 1, 1, -3,
|
||||
/* 27 */ -3, 3, 1, -3, 1, 3, -1, -1, 1, 3, 3, 3,
|
||||
/* 28 */ -3, 3, -3, 3, -3, -3, 3, -1, -1, 1, 3, -3,
|
||||
/* 29 */ -3, 3, 1, -1, 3, 3, -3, 1, -1, 1, -1, 1,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Table 5.2.2.2-3: Definition of phi (n ) for M_ZC = 18 */
|
||||
const char phi_M_ZC_18[18*U_GROUP_NUMBER]
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 */
|
||||
/* 0 */ 3, -3, 3, -1, 1, 3, -3, -1, -3, -3, -1, -3, 3, 1, -1, 3, -3, 3,
|
||||
/* 1 */ 3, -3, 1, 1, 3, -1, 1, -1, -1, -3, 1, 1, -1, 3, 3, -3, 3, -1,
|
||||
/* 2 */ -3, 3, -1, -3, -1, -3, 1, 1, -3, -3, -1, -1, 3, -3, 1, 3, 1, 1,
|
||||
/* 3 */ 1, 1, -1, -1, -3, -1, 1, -3, -3, -3, 1, -3, -1, -1, 1, -1, 3, 1,
|
||||
/* 4 */ 1, 1, -3, 3, 3, 1, 3, -3, 3, -1, 1, 1, -1, 1, -3, -3, -1, 3,
|
||||
/* 5 */ -3, -3, 1, -3, 3, 3, 3, -1, 3, 1, 1, -3, -3, -3, 3, -3, -1, -1,
|
||||
/* 6 */ -1, 3, -1, -3, 3, 1, -3, -1, 3, -3, -1, -1, 1, 1, 1, -1, -1, -1,
|
||||
/* 7 */ -3, 1, -3, -3, 1, -3, -3, 3, 1, -3, -1, -3, -3, -3, -1, 1, 1, 3,
|
||||
/* 8 */ 1, -3, -1, -3, 3, 3, -1, -3, 1, -3, -3, -1, -3, -1, 1, 3, 3, 3,
|
||||
/* 9 */ -3, 3, 1, -1, -1, -1, -1, 1, -1, 3, 3, -3, -1, 1, 3, -1, 3, -1,
|
||||
/* 10 */ -3, -3, 1, -1, -1, 1, 1, -3, -1, 3, 3, 3, 3, -1, 3, 1, 3, 1,
|
||||
/* 11 */ -3, -3, 3, 3, -3, 1, 3, -1, -3, 1, -1, -3, 3, -3, -1, -1, -1, 3,
|
||||
/* 12 */ -3, -3, 3, 3, 3, 1, -3, 1, 3, 3, 1, -3, -3, 3, -1, -3, -1, 1,
|
||||
/* 13 */ -3, 3, -1, 1, 3, 1, -3, -1, 1, 1, -3, 1, 3, 3, -1, -3, -3, -3,
|
||||
/* 14 */ -3, 1, -3, -1, -1, 3, 1, -3, -3, -3, -1, -3, -3, 1, 1, 1, -1, -1,
|
||||
/* 15 */ -3, -3, 3, 3, 3, -1, -1, -3, -1, -1, -1, 3, 1, -3, -3, -1, 3, -1,
|
||||
/* 16 */ -3, -1, 3, 3, -1, 3, -1, -3, -1, 1, -1, -3, -1, -1, -1, 3, 3, 1,
|
||||
/* 17 */ -3, -1, -3, -1, -3, 1, 3, -3, -1, 3, 3, 3, 1, -1, -3, 3, -1, -3,
|
||||
/* 18 */ -3, 3, 1, -1, -1, 3, -3, -1, 1, 1, 1, 1, 1, -1, 3, -1, -3, -1,
|
||||
/* 19 */ 3, -1, -3, 1, -3, -3, -3, 3, 3, -1, 1, -3, -1, 3, 1, 1, 3, 3,
|
||||
/* 20 */ 3, 3, 3, -3, -1, -3, -1, 3, -1, 1, -1, -3, 1, -3, -3, -1, 3, 3,
|
||||
/* 21 */ 3, -1, 3, 1, -3, -3, -1, 1, -3, -3, 3, 3, 3, 1, 3, -3, 3, -3,
|
||||
/* 22 */ -3, 1, 1, -3, 1, 1, 3, -3, -1, -3, -1, 3, -3, 3, -1, -1, -1, -3,
|
||||
/* 23 */ -3, -1, -1, -3, 1, -3, 3, -1, -1, -3, 3, 3, -3, -1, 3, -1, -1, -1,
|
||||
/* 24 */ -3, -3, -3, 1, -3, 3, 1, 1, 3, -3, -3, 1, 3, -1, 3, -3, -3, 3,
|
||||
/* 25 */ 1, 1, -3, -3, -3, -3, 1, 3, -3, 3, 3, 1, -3, -1, 3, -1, -3, 1,
|
||||
/* 26 */ 3, -1, -1, 1, -3, -1, -3, -1, -3, -3, -1, -3, 1, 1, 1, -3, -3, 3,
|
||||
/* 27 */ 3, 1, -3, 1, -3, 3, 3, -1, -3, -3, -1, -3, -3, 3, -3, -1, 1, 3,
|
||||
/* 28 */ -1, -3, 1, -3, -3, -3, 1, 1, 3, 3, -3, 3, 3, -3, -1, 3, -3, 1,
|
||||
/* 29 */ -3, -1, -3, -3, 1, 1, -1, -3, -1, -3, -1, -1, 3, 3, -1, 3, 1, 3,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/* Table 5.2.2.2-4: Definition of phi (n ) for M_ZC = 24 */
|
||||
const char phi_M_ZC_24[24*U_GROUP_NUMBER]
|
||||
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
= {
|
||||
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 */
|
||||
/* 0 */ -1, -3, 3, 1, 1, -3, 1, -3, -3, 1, -3, -1, -1, 3, -3, 3, 3, 3, -3, 1, 3, 3, -3, -3,
|
||||
/* 1 */ -1, -3, 3, -1, 3, 1, 3, -1, 1, -3, -1, -3, -1, 1, 3, -3, -1, -3, 3, 3, 3, -3, -3, -3,
|
||||
/* 2 */ -3, 3, 1, 3, -1, 1, -3, 1, -3, 1, -1, -3, -1, -3, -3, -3, -3, -1, -1, -1, 1, 1, -3, -3,
|
||||
/* 3 */ 3, -1, 3, -1, 1, -3, 1, 1, -3, -3, 3, -3, -1, -1, -1, -1, -1, -3, -3, -1, 1, 1, -3, -3,
|
||||
/* 4 */ 1, -3, 3, -1, -3, -1, 3, 3, 1, -1, 1, 1, 3, -3, -1, -3, -3, -3, -1, 3, -3, -1, -3, -3,
|
||||
/* 5 */ 3, -1, 1, -1, 3, -3, 1, 1, 3, -1, -3, 3, 1, -3, 3, -1, -1, -1, -1, 1, -3, -3, -3, -3,
|
||||
/* 6 */ -3, 3, -1, 3, 1, -1, -1, -1, 3, 3, 1, 1, 1, 3, 3, 1, -3, -3, -1, 1, -3, 1, 3, -3,
|
||||
/* 7 */ -3, -1, 1, -3, -3, 1, 1, -3, 3, -1, -1, -3, 1, 3, 1, -1, -3, -1, -3, 1, -3, -3, -3, -3,
|
||||
/* 8 */ -3, 1, -3, 1, -3, -3, 1, -3, 1, -3, -3, -3, -3, -3, 1, -3, -3, 1, 1, -3, 1, 1, -3, -3,
|
||||
/* 9 */ 3, -3, -3, -1, 3, 3, -3, -1, 3, 1, 1, 1, 3, -1, 3, -3, -1, 3, -1, 3, 1, -1, -3, -3,
|
||||
/* 10 */ -3, -3, -1, -1, -1, -3, 1, -1, -3, -1, 3, -3, 1, -3, 3, -3, 3, 3, 1, -1, -1, 1, -3, -3,
|
||||
/* 11 */ -3, -3, 3, 3, 1, -1, -1, -1, 1, -3, -1, 1, -1, 3, -3, -1, -3, -1, -1, 1, -3, 3, -1, -3,
|
||||
/* 12 */ -3, -3, 1, -1, 3, 3, -3, -1, 1, -1, -1, 1, 1, -1, -1, 3, -3, 1, -3, 1, -1, -1, -1, -3,
|
||||
/* 13 */ -3, 1, -3, 3, -1, -1, -1, -3, 3, 1, -1, -3, -1, 1, 3, -1, 1, -1, 1, -3, -3, -3, -3, -3,
|
||||
/* 14 */ -3, -3, -3, -1, 3, -3, 3, 1, 3, 1, -3, -1, -1, -3, 1, 1, 3, 1, -1, -3, 3, 1, 3, -3,
|
||||
/* 15 */ 1, 1, -1, -3, -1, 1, 1, -3, 1, -1, 1, -3, 3, -3, -3, 3, -1, -3, 1, 3, -3, 1, -3, -3,
|
||||
/* 16 */ -3, 3, -1, 3, -1, 3, 3, 1, 1, -3, 1, 3, -3, 3, -3, -3, -1, 1, 3, -3, -1, -1, -3, -3,
|
||||
/* 17 */ -1, -3, -3, 1, -1, -1, -3, 1, 3, -1, -3, -1, -1, -3, 1, 1, 3, 1, -3, -1, -1, 3, -3, -3,
|
||||
/* 18 */ -3, 1, -3, 1, -3, 1, 1, 3, 1, -3, -3, -1, 1, 3, -1, -3, 3, 1, -1, -3, -3, -3, -3, -3,
|
||||
/* 19 */ 3, -3, 3, -1, -3, 1, 3, 1, -1, -1, -3, -1, 3, -3, 3, -1, -1, 3, 3, -3, -3, 3, -3, -3,
|
||||
/* 20 */ -1, 3, -3, -3, -1, 3, -1, -1, 1, 3, 1, 3, -1, -1, -3, 1, 3, 1, -1, -3, 1, -1, -3, -3,
|
||||
/* 21 */ -3, 1, -3, -1, -1, 3, 1, 3, -3, 1, -1, 3, 3, -1, -3, 3, -3, -1, -1, -3, -3, -3, 3, -3,
|
||||
/* 22 */ -3, -1, -1, -3, 1, -3, -3, -1, -1, 3, -1, 1, -1, 3, 1, -3, -1, 3, 1, 1, -1, -1, -3, -3,
|
||||
/* 23 */ -3, 1, -3, 3, -3, 1, -3, 3, 1, -1, -3, -1, -3, -3, -3, -3, 1, 3, -1, 1, 3, 3, 3, -3,
|
||||
/* 24 */ -3, -1, 1, -3, -1, -1, 1, 1, 1, 3, 3, -1, 1, -1, 1, -1, -1, -3, -3, -3, 3, 1, -1, -3,
|
||||
/* 25 */ 3, -3, -1, 1, 3, -1, -1, -3, -1, 3, -1, -3, -1, -3, 3, -1, 3, 1, 1, -3, 3, -3, -3, -3,
|
||||
/* 26 */ -3, 1, 3, -1, 1, -1, 3, -3, 3, -1, -3, -1, -3, 3, -1, -1, -1, -3, -1, -1, -3, 3, 3, -3,
|
||||
/* 27 */ -3, 3, -1, -3, -1, -1, -1, 3, -1, -1, 3, -3, -1, 3, -3, 3, -3, -1, 3, 1, 1, -1, -3, -3,
|
||||
/* 28 */ -3, 1, -1, -3, -3, -1, 1, -3, -1, -3, 1, 1, -1, 1, 1, 3, 3, 3, -1, 1, -1, 1, -1, -3,
|
||||
/* 29 */ -1, 3, -1, -1, 3, 3, -1, -1, -1, 3, -1, -3, 1, 3, 1, 1, -3, -3, -3, -1, -3, -1, -3, -3,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
/************** FUNCTION ******************************************/
|
||||
|
||||
int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling);
|
||||
int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
|
||||
/*!
|
||||
\brief This function generate the sounding reference symbol (SRS) for the uplink.
|
||||
@param tables of srs
|
||||
@param scaling amplitude of the reference signal
|
||||
*/
|
||||
void generate_ul_reference_signal_sequences(unsigned int scaling);
|
||||
void free_ul_reference_signal_sequences(void);
|
||||
|
||||
#undef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
|
||||
#undef EXTERN
|
||||
|
||||
#endif /* SSS_NR_H */
|
||||
@@ -0,0 +1,578 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* FILENAME : cic_filter_nr.c
|
||||
*
|
||||
* MODULE : generic functions for cic filters
|
||||
*
|
||||
* DESCRIPTION : generic functions useful for decimation based on cascaded integrator comb filter
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
#define DEFINE_VARIABLES_CIC_FILTER_NR_H
|
||||
#include "PHY/NR_UE_TRANSPORT/cic_filter_nr.h"
|
||||
#undef DEFINE_VARIABLES_CIC_FILTER_NR_H
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : integrator_stage
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
*
|
||||
* RETURN :
|
||||
*
|
||||
* DESCRIPTION : single stage of an integrator
|
||||
*
|
||||
* It is a single-pole IIR filter with a unity feedback coefficient
|
||||
*
|
||||
* y(n) = y(n-1) +x(n)*
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void integrator_stage(int32_t *input, int32_t *output, int length)
|
||||
{
|
||||
/* first sample is just copied */
|
||||
for (int i = 0; i < 1; i++) {
|
||||
output[2*i] = input[2*i];
|
||||
output[2*i+1] = input[2*i+1];
|
||||
}
|
||||
|
||||
/* then process all other samples */
|
||||
for (int i = 1; i < length; i++) {
|
||||
output[2*i] = output[2*(i-1)] + input[2*i];
|
||||
output[2*i+1] = output[2*(i-1)+1] + input[2*i+1];
|
||||
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < 20) {
|
||||
printf("output[%d] = output[%d] + input[%d] \n", (2*i), 2*(i-1), 2*i);
|
||||
printf("%d = %d + %d \n", output[2*i], output[2*(i-1)], input[2*i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : comb_stage
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
*
|
||||
* RETURN :
|
||||
*
|
||||
* DESCRIPTION : single stage of a comb filter which is an odd-symetric FIR filter
|
||||
*
|
||||
* y(n) = x(n) - x(n - M)
|
||||
*
|
||||
* M is called the differential delay. It can take any positive
|
||||
* integer but it is usually limited to 1 or 2.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void comb_stage(int32_t *input, int32_t *output, int length, int differential_delay)
|
||||
{
|
||||
/* first sample is just copied */
|
||||
for (int i = 0; i < differential_delay; i++) {
|
||||
output[2*i] = input[2*i];
|
||||
output[2*i+1] = input[2*i+1];
|
||||
}
|
||||
|
||||
/* then process all other samples */
|
||||
for (int i = differential_delay; i < length; i++) {
|
||||
output[2*i] = input[2*i] - input[2*(i-differential_delay)];
|
||||
output[2*i+1] = input[2*i+1] - input[2*(i-differential_delay)+1];
|
||||
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < 20) {
|
||||
printf("output[%d] = input[%d] - input[%d] \n", (2*i), (2*i), 2*(i-differential_delay));
|
||||
printf("%d = %d - %d \n", output[2*i], input[2*i], input[2*(i-differential_delay)]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : rate_change_stage
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : change sampling rate by a factor of R
|
||||
* just copy one samples over R from input to output buffer
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void rate_change_stage(int32_t *input, int32_t *output, int length, int rate_change)
|
||||
{
|
||||
for (int i = 0; (i*rate_change) < length; i++) {
|
||||
output[2*i] = input[2*i*rate_change];
|
||||
output[2*i+1] = input[(2*i*rate_change)+1];
|
||||
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < 20) {
|
||||
printf("input[%d] : %d \n", 2*i*rate_change, input[2*i*rate_change]);
|
||||
printf("output[%d] : %d \n", 2*i, output[2*i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : fir_filter
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : implement a fir filter with taps from an array
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void fir_filter_init(fir_filter_t* f, int taps_fir_number, int32_t *filter_taps) {
|
||||
int i;
|
||||
for(i = 0; i < taps_fir_number; ++i)
|
||||
f->history[i] = 0;
|
||||
f->last_index = 0;
|
||||
if (taps_fir_number > MAX_SAMPLEFILTER_TAP_NUM) {
|
||||
printf("Number of taps of this FIR filter %d exceeds maximum value %d \n", taps_fir_number, MAX_SAMPLEFILTER_TAP_NUM);
|
||||
assert(0);
|
||||
}
|
||||
f->filter_tap_number = taps_fir_number;
|
||||
f->filter_taps = filter_taps;
|
||||
}
|
||||
|
||||
void fir_filter_put(fir_filter_t* f, int32_t input) {
|
||||
f->history[f->last_index++] = input;
|
||||
if(f->last_index == f->filter_tap_number)
|
||||
f->last_index = 0;
|
||||
}
|
||||
|
||||
int32_t fir_filter_get(fir_filter_t* f, int scaling_shift) {
|
||||
long long acc = 0;
|
||||
int index = f->last_index, i;
|
||||
for(i = 0; i < f->filter_tap_number; ++i) {
|
||||
index = index != 0 ? index-1 : f->filter_tap_number-1;
|
||||
acc += (long long)f->history[index] * f->filter_taps[i];
|
||||
};
|
||||
return acc >> scaling_shift;
|
||||
}
|
||||
|
||||
void fir_filter_basic(int32_t *input, int32_t *output, int length, int taps_fir_number, int32_t *filter_taps, int scaling_shift)
|
||||
{
|
||||
fir_filter_t filter;
|
||||
|
||||
for (int j = 0; j < 2; j++) {
|
||||
|
||||
fir_filter_init(&filter, taps_fir_number, filter_taps);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
fir_filter_put(&filter, input[2*i+j]);
|
||||
output[2*i+j] = fir_filter_get(&filter, scaling_shift);
|
||||
//printf("i %d input %d output %d ", 2*i+j, input[2*i+j], output[2*i + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : fir_filter
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
*
|
||||
* RETURN :
|
||||
*
|
||||
* DESCRIPTION : single stage of a fir filter which is an odd-symetric FIR filter
|
||||
*
|
||||
* y(n) = SUM ( bi * x(n - i) )
|
||||
*
|
||||
* bi are tags of FIR filter
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void fir_filter(int32_t *input, int32_t *output, int length, int taps_fir_number, int *taps_fir, int scaling_shift)
|
||||
{
|
||||
int32_t current;
|
||||
|
||||
/* taps start from 1 to taps_fir_number */
|
||||
for (int i = 0; i < taps_fir_number; i++) {
|
||||
for (int j=0; j<2 ; j++) {
|
||||
current = 0;
|
||||
for (int taps_number = 0; taps_number < taps_fir_number; taps_number++) {
|
||||
if (i >= taps_number) {
|
||||
current += taps_fir[taps_number]*input[2*(i-taps_number)+j];
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
printf("current[%d] %d = taps[%d] : %d x input[%d] : %d \n", (2*i+j), current, taps_number, taps_fir[taps_number], (2*(i-taps_number)+j), input[2*(i-taps_number)+j]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
output[2*i+j] = current >> scaling_shift;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = taps_fir_number; i < length; i++) {
|
||||
for (int j=0; j<2 ; j++) {
|
||||
current = 0;
|
||||
for (int taps_number = 0; taps_number < taps_fir_number; taps_number++) {
|
||||
current += taps_fir[taps_number]*input[2*(i-taps_number)+j];
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < taps_fir_number + 16) {
|
||||
printf("current[%d] %d = taps[%d] : %d x input[%d] : %d \n", (2*i+j), current, taps_number, taps_fir[taps_number], (2*(i-taps_number)+j), input[2*(i-taps_number)+j]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
output[2*i+j] = current >> scaling_shift; // SHARPENED_FIR_SCALING_ACC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : cic_decimator
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
* length size of input buffer
|
||||
* decimation by a factor of R
|
||||
*
|
||||
* RETURN : result of decimator is the output buffer
|
||||
*
|
||||
* DESCRIPTION : Cascaded integrator-comb filter
|
||||
* rate change by a factor of R
|
||||
*
|
||||
* CIC filter with N stages is composed of:
|
||||
* - N cascaded integrator filters clocked at high sampling rate fs
|
||||
* - N cascaded comb stage running at fs/R
|
||||
*
|
||||
* +-----------+ +----------+ +----------+ +----+ +----------+ +----------+ +----------+ +--------------+
|
||||
* | Integrator| |Integrator| |Integrator| | R | | Comb | | Comb | | Comb | | Compensation |
|
||||
* input --->| stage |->| stage |->| stage |->| |->| stage |->| stage |->| stage |-------->| FIR Filter |---> output
|
||||
* +-----------+ +----------+ +----------+ +----+ +----------+ +----------+ +----------+ +--------------+
|
||||
* <----------------------------------------> | <-------------------------------------->
|
||||
* N cascaded integrator filters | N cascaded comb stage running at fs/R
|
||||
* clocked at high sampling rate fs V
|
||||
* downsampling
|
||||
* from fs to fs/R
|
||||
*
|
||||
* In order that cic filter works properly, some caution should be taken for getting good accuracy.
|
||||
* Firstly data should be in fixed point in order to balance integrator and comb stages. If does not work with data in floating point.
|
||||
*
|
||||
* k1 is the number of significant bits for input
|
||||
* k2 is the number of significant bits for output
|
||||
* m = k2 - k2 > N * log2(RM - 1) N number of stage, M differential delay and R rate change factor
|
||||
* for example with R=16 N=4 and M=1 with input data on 16 bits
|
||||
* output data should be on k2 = m + k1 > 31
|
||||
*
|
||||
* Additionally there is a bit growth so processing has a gain of
|
||||
* G = (RM)power(N)
|
||||
* For example with R=16 N=4 M=1 G=(16*1)power(4)=65536
|
||||
*
|
||||
* It gives size of output data with number of significant bit Bout = (N x log2(R x M)) + Bin
|
||||
* With R=16 N=4 M=1 Bin=16 => Bout = (4 x log2(16 x 1)) + 16 = (4 x 4) + 16 = 32 so output significant bits should be 32.
|
||||
* As a consequence, all computations are done with 32 bits up to the last stage (no rounding or truncation).
|
||||
* Except for the final result which can be casted from 32 bits to 16 bits.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void cic_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, int rate_change, int number_cic_stage, int set_scaling_factor, int fir_rate_change)
|
||||
{
|
||||
int32_t *buffer_one;
|
||||
int32_t *buffer_two;
|
||||
int32_t *input;
|
||||
int32_t *output;
|
||||
int32_t *tmp;
|
||||
int new_length;
|
||||
int current_rate_change;
|
||||
|
||||
/* for cic decimator, gain g of the output depends on rate change R, differential delay M and number of stage N */
|
||||
/* g = power(R x M, N) / power(2 , log2 (R x M) */
|
||||
/* so a scale factor should be applied to output in order to get a unity DC gain */
|
||||
|
||||
int scaling_factor = 0; // pow(2, log2(rate_change * M_DIFFERENTIAL_DELAY))/pow((rate_change * M_DIFFERENTIAL_DELAY), number_cic_stage);
|
||||
|
||||
if (set_scaling_factor != 0) {
|
||||
scaling_factor = set_scaling_factor;
|
||||
printf("Decimation with rate change of %d with set gain of %d \n", rate_change, scaling_factor);
|
||||
}
|
||||
|
||||
/* get working buffers */
|
||||
buffer_one = malloc(length*sizeof(int32_t) * 2); /* for i&q samples */
|
||||
if (buffer_one == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
buffer_two = malloc(length*sizeof(int32_t) * 2); /* for i&q samples */
|
||||
if (buffer_two == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* copy of input buffer from int16 to int32 */
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer_one[2*i] = input_buffer[2*i];
|
||||
buffer_one[2*i + 1] = input_buffer[2*i + 1];
|
||||
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < 10) {
|
||||
printf("buffer_one[%d] : %d %d \n", i, buffer_one[2*i], buffer_one[2*i + 1]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
input = buffer_one;
|
||||
output = buffer_two;
|
||||
|
||||
/* call of integrator stages running at Fs */
|
||||
for (int stage = 0; stage < number_cic_stage; stage++)
|
||||
{
|
||||
integrator_stage(input, output, length);
|
||||
|
||||
/* swap between output and input */
|
||||
tmp = input;
|
||||
input = output;
|
||||
output = tmp;
|
||||
|
||||
#if 0
|
||||
char output_file[255];
|
||||
char sequence_name[255];
|
||||
sprintf(output_file, "int_seq_%d.m", stage);
|
||||
sprintf(sequence_name, "int_seq_%d", stage);
|
||||
|
||||
printf("file %s signal %s\n", output_file, sequence_name);
|
||||
write_output(output_file, sequence_name, input, length, 1, 3); /* format = 3 is for int32_t */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* a sharpened Fir filter can be added which can provide also a rate change */
|
||||
current_rate_change = rate_change/fir_rate_change;
|
||||
|
||||
/* rate change from sampling frequency Fs to Fs/R */
|
||||
rate_change_stage(input, output, length, current_rate_change);
|
||||
|
||||
/* new length of samples should be computed based on the rate change factor R */
|
||||
new_length = length/current_rate_change;
|
||||
|
||||
/* swap between output and input */
|
||||
tmp = input;
|
||||
input = output;
|
||||
output = tmp;
|
||||
|
||||
/* call of comb stages running at Fs/R */
|
||||
for (int stage = 0; stage < number_cic_stage; stage++)
|
||||
{
|
||||
comb_stage(input, output, new_length, M_DIFFERENTIAL_DELAY);
|
||||
|
||||
/* swap between output and input */
|
||||
tmp = input;
|
||||
input = output;
|
||||
output = tmp;
|
||||
|
||||
#if 0
|
||||
char output_file[255];
|
||||
char sequence_name[255];
|
||||
sprintf(output_file, "comb_seq_%d.m", stage);
|
||||
sprintf(sequence_name, "comb_seq_%d", stage);
|
||||
printf("file %s signal %s\n", output_file, sequence_name);
|
||||
write_output(output_file, sequence_name, input, new_length, 1, 3); /* format = 3 for int32_t */
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
if (fir_rate_change > 1)
|
||||
{
|
||||
#define FIR_TAPS_SCALING (10000)
|
||||
|
||||
/* convert float taps of fir filter to int32 taps */
|
||||
int32_t *filter_taps_fixed_point = malloc(FIR_TAPS_NUMBER*sizeof(int32_t));
|
||||
if (filter_taps_fixed_point == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < FIR_TAPS_NUMBER; i++) {
|
||||
filter_taps_fixed_point[i] = (int32_t)(sharpened_fir_taps[i] * FIR_TAPS_SCALING);
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
/* compensation filter for equalizing the passband drop and perform a low rate change */
|
||||
fir_filter(input, output, new_length, FIR_TAPS_NUMBER, filter_taps_fixed_point, FIR_FITER_SCALING_ACC);
|
||||
|
||||
#else
|
||||
|
||||
fir_filter_basic(input, output, new_length, FIR_TAPS_NUMBER, filter_taps, SHARPENED_FIR_SCALING_ACC);
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
output = input;
|
||||
}
|
||||
|
||||
/* new length of samples should be computed based on the rate change */
|
||||
current_rate_change = fir_rate_change;
|
||||
new_length = new_length/current_rate_change;
|
||||
|
||||
/* filter has created a delay on the signal which can be compensated */
|
||||
//int delay = FIR_TAPS_NUMBER;
|
||||
int delay = 0;
|
||||
|
||||
for (int i = 0; (i*fir_rate_change) < new_length; i++) {
|
||||
output_buffer[2*i] = output[(2*i+delay)*current_rate_change]>> scaling_factor;
|
||||
output_buffer[2*i+1] = output[((2*i+delay)*current_rate_change)+1]>> scaling_factor;
|
||||
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < 10) {
|
||||
printf("output_buffer[%d] = output[%d] >> scaling_factor \n", (2*i), ((2*i+delay)*current_rate_change));
|
||||
printf(" %d = %d >> %d \n", output_buffer[2*i], output[((2*i+delay)*current_rate_change)], scaling_factor);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
scaling_factor = 0;
|
||||
|
||||
/* copy of final result from int32 to int16 with a scaling factor and a rate change */
|
||||
for (int i = 0; i < new_length; i++) {
|
||||
output_buffer[2*i] = input[2*i] >> scaling_factor;
|
||||
output_buffer[2*i + 1] = input[2*i + 1] >> scaling_factor;
|
||||
|
||||
#ifdef DBG_CIC_FILTER_NR
|
||||
if (i < 10) {
|
||||
printf("output_buffer[%d] : %d \n", (2*i), output_buffer[2*i]);
|
||||
printf("input[%d] : %d \n", 2*i, input[2*i] >> scaling_factor);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/* clear till end of the buffer */
|
||||
for (int i = new_length; i < length; i++) {
|
||||
output_buffer[2*i] = 0;
|
||||
output_buffer[2*i + 1] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : fir_decimator
|
||||
*
|
||||
* PARAMETERS : pointer to input complex data
|
||||
* pointer to output complex data
|
||||
* length size of input buffer
|
||||
* decimation by a factor of R
|
||||
*
|
||||
* RETURN : result of decimator is the output buffer
|
||||
*
|
||||
* DESCRIPTION : fir filter
|
||||
* rate change by a factor of R
|
||||
*
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void fir_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, int rate_change, int scaling_factor)
|
||||
{
|
||||
int32_t *buffer_one;
|
||||
int32_t *buffer_two;
|
||||
int32_t *input;
|
||||
int32_t *output;
|
||||
int new_length;
|
||||
|
||||
/* get working buffers */
|
||||
buffer_one = malloc(length*sizeof(int32_t) * 2); /* for i&q samples */
|
||||
if (buffer_one == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
buffer_two = malloc(length*sizeof(int32_t) * 2); /* for i&q samples */
|
||||
if (buffer_two == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* copy of input buffer from int16 to int32 */
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer_one[2*i] = input_buffer[2*i];
|
||||
buffer_one[2*i + 1] = input_buffer[2*i + 1];
|
||||
}
|
||||
|
||||
input = buffer_one;
|
||||
output = buffer_two;
|
||||
|
||||
#if 1
|
||||
|
||||
fir_filter(input, output, length, SAMPLEFILTER_TAP_NUM, filter_taps, FIR_SCALING_ACC);
|
||||
|
||||
#else
|
||||
|
||||
fir_filter_basic(input, output, length, SAMPLEFILTER_TAP_NUM, filter_taps, FIR_SCALING_ACC);
|
||||
|
||||
#endif
|
||||
|
||||
/* rate change from sampling frequency Fs to Fs/R */
|
||||
rate_change_stage(output, input, length, rate_change);
|
||||
|
||||
new_length = length/rate_change;
|
||||
|
||||
/* copy of final result from int32 to int16 with a scaling factor and a rate change */
|
||||
for (int i = 0; i < new_length; i++) {
|
||||
output_buffer[2*i] = input[2*i] >> scaling_factor;
|
||||
output_buffer[2*i + 1] = input[2*i + 1] >> scaling_factor;
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* clear till end of the buffer */
|
||||
for (int i = new_length; i < length; i++) {
|
||||
output_buffer[2*i] = 0;
|
||||
output_buffer[2*i + 1] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* FILENAME : cic_filter_nr.h
|
||||
*
|
||||
* MODULE : synchronisation signal
|
||||
*
|
||||
* DESCRIPTION : function related to nr synchronisation
|
||||
* It provides filters for sampling decimation
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifndef CIC_FILTER_NR_H
|
||||
#define CIC_FILTER_NR_H
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/types.h"
|
||||
|
||||
#ifdef DEFINE_VARIABLES_CIC_FILTER_NR_H
|
||||
#define EXTERN
|
||||
#define INIT_VARIABLES_CIC_FILTER_NR_H
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************** DEFINE ********************************************/
|
||||
|
||||
#define M_DIFFERENTIAL_DELAY (1)
|
||||
#define FIR_RATE_CHANGE (2)
|
||||
|
||||
/************** VARIABLES *****************************************/
|
||||
|
||||
#define FIR_TAPS_NUMBER (20)
|
||||
#define FIR_FITER_SCALING_ACC (14)
|
||||
|
||||
EXTERN double sharpened_fir_taps[FIR_TAPS_NUMBER]
|
||||
#ifdef INIT_VARIABLES_CIC_FILTER_NR_H
|
||||
= {
|
||||
/*
|
||||
cic filter and compensation FIR have been designed based on cic design tools provided at
|
||||
http://www.tsdconseil.fr/tutos/index.html
|
||||
-->cfir = cic_comp_design(4,4,1,30720000,2,1650000,20);
|
||||
R = 4.00, Fin = 30720000.00 Hz, Fout = 7680000.00 Hz.
|
||||
Attenuation for f > fout/2 : -14.82 dB.
|
||||
Attenuation at 1650000.00 Hz: -0.15 dB.
|
||||
Attenuation max. between 0 et 1650000.00 Hz: -0.15 dB.
|
||||
E.g. in linear scale : * 0.983
|
||||
Number of additionnal bits needed for implementation: 7.
|
||||
Fout = 7680000.00 Hz.
|
||||
index = 1026 / 4096.
|
||||
Correction Fint ?
|
||||
Filtre global :
|
||||
|
||||
-->cfir
|
||||
cfir =
|
||||
*/
|
||||
- 0.0059900,
|
||||
- 0.0056191,
|
||||
0.0107582,
|
||||
0.0266043,
|
||||
0.0130358,
|
||||
- 0.0331228,
|
||||
- 0.0680440,
|
||||
- 0.0278570,
|
||||
0.1106335,
|
||||
0.2897060,
|
||||
0.3607857,
|
||||
0.2607354,
|
||||
0.0983409,
|
||||
- 0.0243749,
|
||||
- 0.0583235,
|
||||
- 0.0276023,
|
||||
0.0104286,
|
||||
0.0199533,
|
||||
0.0071721,
|
||||
- 0.0028096,
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
#define MAX_SAMPLEFILTER_TAP_NUM (100)
|
||||
#define FIR_SCALING_ACC (15)
|
||||
|
||||
typedef struct {
|
||||
int32_t history[MAX_SAMPLEFILTER_TAP_NUM];
|
||||
int last_index;
|
||||
int filter_tap_number;
|
||||
int32_t *filter_taps;
|
||||
} fir_filter_t;
|
||||
|
||||
#define SAMPLEFILTER_TAP_NUM (59)
|
||||
|
||||
/*
|
||||
* This low pass filter was designed based on the tool at http://t-filter.engineerjs.com/
|
||||
* with below parameters
|
||||
* sampling frequency 30.72 MHz
|
||||
* from to gain ripple/att.
|
||||
* 0 Hz 1.9 MHz 1 0.5 dB
|
||||
* 2 MHz 15 MHz 0 -20 dB
|
||||
*/
|
||||
|
||||
EXTERN int filter_taps[SAMPLEFILTER_TAP_NUM]
|
||||
#ifdef INIT_VARIABLES_CIC_FILTER_NR_H
|
||||
= {
|
||||
-1572,
|
||||
65,
|
||||
-132,
|
||||
197,
|
||||
26,
|
||||
393,
|
||||
194,
|
||||
536,
|
||||
250,
|
||||
514,
|
||||
105,
|
||||
279,
|
||||
-234,
|
||||
-105,
|
||||
-646,
|
||||
-466,
|
||||
-924,
|
||||
-583,
|
||||
-856,
|
||||
-279,
|
||||
-321,
|
||||
492,
|
||||
639,
|
||||
1601,
|
||||
1812,
|
||||
2766,
|
||||
2872,
|
||||
3650,
|
||||
3503,
|
||||
3976,
|
||||
3503,
|
||||
3650,
|
||||
2872,
|
||||
2766,
|
||||
1812,
|
||||
1601,
|
||||
639,
|
||||
492,
|
||||
-321,
|
||||
-279,
|
||||
-856,
|
||||
-583,
|
||||
-924,
|
||||
-466,
|
||||
-646,
|
||||
-105,
|
||||
-234,
|
||||
279,
|
||||
105,
|
||||
514,
|
||||
250,
|
||||
536,
|
||||
194,
|
||||
393,
|
||||
26,
|
||||
197,
|
||||
-132,
|
||||
65,
|
||||
-1572
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
/************** FUNCTION ******************************************/
|
||||
|
||||
void integrator_stage(int32_t *input, int32_t *output, int length);
|
||||
|
||||
void comb_stage(int32_t *input, int32_t *output, int length, int differential_delay);
|
||||
|
||||
void rate_change_stage(int32_t *input, int32_t *output, int length, int rate_change);
|
||||
|
||||
void fir_filter(int32_t *input, int32_t *output, int length, int taps_fir_number, int32_t *taps_fir, int scaling_shift);
|
||||
|
||||
void cic_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, int rate_change, int number_cic_stage, int set_scaling_factor, int fir_rate_change);
|
||||
|
||||
void fir_decimator(int16_t *input_buffer, int16_t *output_buffer, int length, int rate_change, int scaling_factor);
|
||||
|
||||
#undef EXTERN
|
||||
#undef INIT_VARIABLES_CIC_FILTER_NR_H
|
||||
|
||||
#endif /* CIC_FILTER_NR_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* FILENAME : dmrs_nr.c
|
||||
*
|
||||
* MODULE : demodulation reference signals
|
||||
*
|
||||
* DESCRIPTION : generation of dmrs sequences
|
||||
* 3GPP TS 38.211
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
//#include "PHY/LTE_REFSIG/defs.h"
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pseudo_random_gold_sequence
|
||||
*
|
||||
* PARAMETERS :
|
||||
*
|
||||
* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence
|
||||
*
|
||||
* DESCRIPTION : 3GPP TS 38.211 5.2.1 Pseudo-random sequence generation
|
||||
* Sequence generation is a length-31 Gold sequence
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define NC (1600)
|
||||
#define GOLD_SEQUENCE_LENGTH (31)
|
||||
|
||||
int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit)
|
||||
{
|
||||
int n;
|
||||
int size_x = NC + GOLD_SEQUENCE_LENGTH + M_PN;
|
||||
uint32_t *x1;
|
||||
uint32_t *x2;
|
||||
|
||||
x1 = calloc(size_x, sizeof(uint32_t));
|
||||
|
||||
if (x1 == NULL) {
|
||||
msg("Fatal error: memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
x2 = calloc(size_x, sizeof(uint32_t));
|
||||
|
||||
if (x2 == NULL) {
|
||||
free(x1);
|
||||
msg("Fatal error: memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
x1[0] = 1; /* init first m sequence */
|
||||
|
||||
/* cinit allows to initialise second m-sequence x2 */
|
||||
for (n = 0; n < GOLD_SEQUENCE_LENGTH; n++) {
|
||||
x2[n] = (cinit >> n) & 0x1;
|
||||
}
|
||||
|
||||
for (n = 0; n < (NC + M_PN); n++) {
|
||||
x1[n+31] = (x1[n+3] + x1[n])%2;
|
||||
x2[n+31] = (x2[n+3] + x2[n+2] + x2[n+1] + x2[n])%2;
|
||||
}
|
||||
|
||||
for (int n = 0; n < M_PN; n++) {
|
||||
c[n] = (x1[n+NC] + x2[n+NC])%2;
|
||||
}
|
||||
|
||||
free(x1);
|
||||
free(x2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pseudo_random_sequence_optimised
|
||||
*
|
||||
* PARAMETERS :
|
||||
*
|
||||
* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence
|
||||
*
|
||||
* DESCRIPTION : 3GPP TS 38.211 5.2.1 Pseudo-random sequence generation
|
||||
* Sequence generation is a length-31 Gold sequence
|
||||
* This is an optimized function based on bitmap variables
|
||||
*
|
||||
* x1(0)=1,x1(1)=0,...x1(30)=0,x1(31)=1
|
||||
* x2 <=> cinit, x2(31) = x2(3)+x2(2)+x2(1)+x2(0)
|
||||
* x2 <=> cinit = sum_{i=0}^{30} x2(i)2^i
|
||||
* c(n) = x1(n+Nc) + x2(n+Nc) mod 2
|
||||
*
|
||||
* equivalent to
|
||||
* x1(n+31) = (x1(n+3)+x1(n))mod 2 <=> x1(n) = x1(n-28) + x1(n-31)
|
||||
* x2(n+31) = (x2(n+3)+x2(n+2)+x2(n+1)+x2(n))mod 2 <=> x2(n) = x2(n-28) + x2(n-29) + x2(n-30) + x2(n-31)
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void pseudo_random_sequence_optimised(unsigned int size, uint32_t *c, uint32_t cinit)
|
||||
{
|
||||
unsigned int n,x1,x2;
|
||||
|
||||
/* init of m-sequences */
|
||||
x1 = 1+ (1<<31);
|
||||
x2 = cinit;
|
||||
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
|
||||
|
||||
/* skip first 50 double words of uint32_t (1600 bits) */
|
||||
for (n=1; n<50; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
}
|
||||
|
||||
for (n=0; n<size; n++) {
|
||||
x1 = (x1>>1) ^ (x1>>4);
|
||||
x1 = x1 ^ (x1<<31) ^ (x1<<28);
|
||||
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
|
||||
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
|
||||
c[n] = x1^x2;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : lte_gold_new
|
||||
*
|
||||
* PARAMETERS :
|
||||
*
|
||||
* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence
|
||||
*
|
||||
* DESCRIPTION : This function is the same as "lte_gold" function in file lte_gold.c
|
||||
* It allows checking that optimization works fine.
|
||||
* generated sequence is given in an array as a bit map.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define CELL_DMRS_LENGTH (224*2)
|
||||
#define CHECK_GOLD_SEQUENCE
|
||||
|
||||
void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell)
|
||||
{
|
||||
unsigned char ns,l,Ncp=1-frame_parms->Ncp;
|
||||
uint32_t cinit;
|
||||
|
||||
#ifdef CHECK_GOLD_SEQUENCE
|
||||
|
||||
uint32_t dmrs_bitmap[20][2][14];
|
||||
uint32_t *dmrs_sequence = calloc(CELL_DMRS_LENGTH, sizeof(uint32_t));
|
||||
if (dmrs_sequence == NULL) {
|
||||
msg("Fatal error: memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Check of demodulation reference signal of pbch sequence \n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* for each slot number */
|
||||
for (ns=0; ns<20; ns++) {
|
||||
|
||||
/* for each ofdm position */
|
||||
for (l=0; l<2; l++) {
|
||||
|
||||
cinit = Ncp +
|
||||
(Nid_cell<<1) +
|
||||
(((1+(Nid_cell<<1))*(1 + (((frame_parms->Ncp==0)?4:3)*l) + (7*(1+ns))))<<10);
|
||||
|
||||
pseudo_random_sequence_optimised(14, &(lte_gold_table[ns][l][0]), cinit);
|
||||
|
||||
#ifdef CHECK_GOLD_SEQUENCE
|
||||
|
||||
pseudo_random_sequence(CELL_DMRS_LENGTH, dmrs_sequence, cinit);
|
||||
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
|
||||
/* format for getting bitmap from uint32_t */
|
||||
for (int i=0; i<14; i++) {
|
||||
dmrs_bitmap[ns][l][i] = 0;
|
||||
for (; j < k + 32; j++) {
|
||||
dmrs_bitmap[ns][l][i] |= (dmrs_sequence[j]<<j);
|
||||
}
|
||||
k = j;
|
||||
}
|
||||
|
||||
for (int i=0; i<14; i++) {
|
||||
if (lte_gold_table[ns][l][i] != dmrs_bitmap[ns][l][i]) {
|
||||
printf("Error in gold sequence computation for ns %d l %d and index %i : 0x%x 0x%x \n", ns, l, i, lte_gold_table[ns][l][i], dmrs_bitmap[ns][l][i]);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CHECK_GOLD_SEQUENCE
|
||||
free(dmrs_sequence);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : get_dmrs_pbch
|
||||
*
|
||||
* PARAMETERS : i_ssb : index of ssb/pbch beam
|
||||
* n_hf : number of the half frame in which PBCH is transmitted in frame
|
||||
*
|
||||
* RETURN : demodulation reference signal for PBCH
|
||||
*
|
||||
* DESCRIPTION : see TS 38.211 7.4.1.4 Demodulation reference signals for PBCH
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define CHECK_DMRS_PBCH_SEQUENCE
|
||||
|
||||
void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE], uint16_t Nid_cell)
|
||||
{
|
||||
uint32_t cinit;
|
||||
int i_ssb;
|
||||
int n_hf;
|
||||
int _i_ssb;
|
||||
|
||||
#ifdef CHECK_DMRS_PBCH_SEQUENCE
|
||||
|
||||
uint32_t dmrs_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_HF][DMRS_BITMAP_SIZE];
|
||||
uint32_t *dmrs_sequence = calloc(CELL_DMRS_LENGTH, sizeof(uint32_t));
|
||||
if (dmrs_sequence == NULL) {
|
||||
msg("Fatal error: memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Check of demodulation reference signal of pbch sequence \n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* for each slot number */
|
||||
for (i_ssb = 0; i_ssb<DMRS_PBCH_I_SSB; i_ssb++) {
|
||||
|
||||
/* for each ofdm position */
|
||||
for (n_hf=0; n_hf<DMRS_PBCH_N_HF; n_hf++) {
|
||||
|
||||
_i_ssb = i_ssb + 4*n_hf;
|
||||
|
||||
cinit = (((_i_ssb + 1)*((Nid_cell>>4) + 1))<<11) + ((_i_ssb + 1)<<6) + (Nid_cell%4);
|
||||
|
||||
pseudo_random_sequence_optimised(DMRS_BITMAP_SIZE, &(dmrs_pbch_bitmap[i_ssb][n_hf][0]), cinit);
|
||||
|
||||
#ifdef CHECK_DMRS_PBCH_SEQUENCE
|
||||
|
||||
/* it allows checking generated with standard generation code */
|
||||
pseudo_random_sequence(DMRS_BITMAP_SIZE*sizeof(uint32_t), dmrs_sequence, cinit);
|
||||
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
|
||||
/* format for getting bitmap from uint32_t */
|
||||
for (int i=0; i<DMRS_BITMAP_SIZE; i++) {
|
||||
dmrs_bitmap[i_ssb][n_hf][i] = 0;
|
||||
/* convert to bitmap */
|
||||
for (; j < k + 32; j++) {
|
||||
dmrs_bitmap[i_ssb][n_hf][i] |= (dmrs_sequence[j]<<j);
|
||||
}
|
||||
k = j;
|
||||
}
|
||||
|
||||
for (int i=0; i<DMRS_BITMAP_SIZE; i++) {
|
||||
if (dmrs_pbch_bitmap[i_ssb][n_hf][i] != dmrs_bitmap[i_ssb][n_hf][i]) {
|
||||
printf("Error in gold sequence computation for ns %d l %d and index %i : 0x%x 0x%x \n", i_ssb, n_hf, i, dmrs_pbch_bitmap[i_ssb][n_hf][i], dmrs_bitmap[i_ssb][n_hf][i]);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CHECK_DMRS_PBCH_SEQUENCE
|
||||
free(dmrs_sequence);
|
||||
#endif
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,335 @@
|
||||
/*
|
||||
* 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/defs.h
|
||||
* \brief data structures for PDSCH/DLSCH/PUSCH/ULSCH physical and transport channel descriptors (TX/RX)
|
||||
* \author R. Knopp
|
||||
* \date 2011
|
||||
* \version 0.1
|
||||
* \company Eurecom
|
||||
* \email: raymond.knopp@eurecom.fr, florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#ifndef __NR_TRANSPORT_UE__H__
|
||||
#define __NR_TRANSPORT_UE__H__
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "../LTE_TRANSPORT/dci.h"
|
||||
//#include "../LTE_TRANSPORT/mdci.h"
|
||||
//#include "../LTE_TRANSPORT/uci_common.h"
|
||||
//#include "../LTE_TRANSPORT/transport_common.h"
|
||||
#ifndef STANDALONE_COMPILE
|
||||
#include "UTIL/LISTS/list.h"
|
||||
#endif
|
||||
|
||||
//#include "../LTE_TRANSPORT/transport_common.h"
|
||||
|
||||
// structures below implement 36-211 and 36-212
|
||||
|
||||
/** @addtogroup _PHY_TRANSPORT_
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define SHRT_MAX 32767
|
||||
|
||||
typedef struct {
|
||||
/// Indicator of first transmission
|
||||
uint8_t first_tx;
|
||||
/// Last Ndi received for this process on DCI (used for C-RNTI only)
|
||||
uint8_t DCINdi;
|
||||
/// Flag indicating that this ULSCH has a new packet (start of new round)
|
||||
// uint8_t Ndi;
|
||||
/// Status Flag indicating for this ULSCH (idle,active,disabled)
|
||||
SCH_status_t status;
|
||||
/// Subframe scheduling indicator (i.e. Transmission opportunity indicator)
|
||||
uint8_t subframe_scheduling_flag;
|
||||
/// Subframe cba scheduling indicator (i.e. Transmission opportunity indicator)
|
||||
uint8_t subframe_cba_scheduling_flag;
|
||||
/// First Allocated RB
|
||||
uint16_t first_rb;
|
||||
/// Current Number of RBs
|
||||
uint16_t nb_rb;
|
||||
/// Last TPC command
|
||||
uint8_t TPC;
|
||||
/// Transport block size
|
||||
uint32_t TBS;
|
||||
/// The payload + CRC size in bits, "B" from 36-212
|
||||
uint32_t B;
|
||||
/// Length of ACK information (bits)
|
||||
uint8_t O_ACK;
|
||||
/// Pointer to the payload
|
||||
uint8_t *b;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS];
|
||||
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
|
||||
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS];
|
||||
/// Index of current HARQ round for this ULSCH
|
||||
uint8_t round;
|
||||
/// MCS format of this ULSCH
|
||||
uint8_t mcs;
|
||||
/// Redundancy-version of the current sub-frame
|
||||
uint8_t rvidx;
|
||||
/// Turbo-code outputs (36-212 V8.6 2009-03, p.12
|
||||
uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))];
|
||||
/// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17)
|
||||
uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144];
|
||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||
uint32_t C;
|
||||
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cminus;
|
||||
/// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cplus;
|
||||
/// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kminus;
|
||||
/// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kplus;
|
||||
/// Total number of bits across all segments
|
||||
uint32_t sumKr;
|
||||
/// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t F;
|
||||
/// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27)
|
||||
uint16_t Msc_initial;
|
||||
/// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27)
|
||||
uint8_t Nsymb_initial;
|
||||
/// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2)
|
||||
uint8_t n_DMRS;
|
||||
/// n_DMRS2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1)
|
||||
uint8_t n_DMRS2;
|
||||
/// Flag to indicate that this is a control only ULSCH (i.e. no MAC SDU)
|
||||
uint8_t control_only;
|
||||
/// Flag to indicate that this is a calibration ULSCH (i.e. no MAC SDU and filled with TDD calibration information)
|
||||
// int calibration_flag;
|
||||
/// Number of soft channel bits
|
||||
uint32_t G;
|
||||
|
||||
// decode phich
|
||||
uint8_t decode_phich;
|
||||
} NR_UL_UE_HARQ_t;
|
||||
|
||||
typedef struct {
|
||||
/// Current Number of Symbols
|
||||
uint8_t Nsymb_pusch;
|
||||
/// SRS active flag
|
||||
uint8_t srs_active;
|
||||
/// Pointers to 8 HARQ processes for the ULSCH
|
||||
NR_UL_UE_HARQ_t *harq_processes[8];
|
||||
/// Pointer to CQI data (+1 for 8 bits crc)
|
||||
uint8_t o[1+MAX_CQI_BYTES];
|
||||
/// Length of CQI data (bits)
|
||||
uint8_t O;
|
||||
/// Format of CQI data
|
||||
UCI_format_t uci_format;
|
||||
/// Rank information
|
||||
uint8_t o_RI[2];
|
||||
/// Length of rank information (bits)
|
||||
uint8_t O_RI;
|
||||
/// Pointer to ACK
|
||||
uint8_t o_ACK[4];
|
||||
/// Minimum number of CQI bits for PUSCH (36-212 r8.6, Sec 5.2.4.1 p. 37)
|
||||
uint8_t O_CQI_MIN;
|
||||
/// ACK/NAK Bundling flag
|
||||
uint8_t bundling;
|
||||
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
||||
uint8_t e[MAX_NUM_CHANNEL_BITS];
|
||||
/// Interleaved "h"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
|
||||
uint8_t h[MAX_NUM_CHANNEL_BITS];
|
||||
/// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||
uint8_t b_tilde[MAX_NUM_CHANNEL_BITS];
|
||||
/// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14)
|
||||
int32_t d[MAX_NUM_RE];
|
||||
/// Transform-coded "z"-sequences (for definition see 36-211 V8.6 2009-03, p.14-15)
|
||||
int32_t z[MAX_NUM_RE];
|
||||
/// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27)
|
||||
uint8_t q[MAX_CQI_PAYLOAD];
|
||||
/// coded and interleaved CQI bits
|
||||
uint8_t o_w[(MAX_CQI_BITS+8)*3];
|
||||
/// coded CQI bits
|
||||
uint8_t o_d[96+((MAX_CQI_BITS+8)*3)];
|
||||
/// coded ACK bits
|
||||
uint8_t q_ACK[MAX_ACK_PAYLOAD];
|
||||
/// coded RI bits
|
||||
uint8_t q_RI[MAX_RI_PAYLOAD];
|
||||
/// beta_offset_cqi times 8
|
||||
uint16_t beta_offset_cqi_times8;
|
||||
/// beta_offset_ri times 8
|
||||
uint16_t beta_offset_ri_times8;
|
||||
/// beta_offset_harqack times 8
|
||||
uint16_t beta_offset_harqack_times8;
|
||||
/// power_offset
|
||||
uint8_t power_offset;
|
||||
// for cooperative communication
|
||||
uint8_t cooperation_flag;
|
||||
/// RNTI attributed to this ULSCH
|
||||
uint16_t rnti;
|
||||
/// f_PUSCH parameter for PUSCH power control
|
||||
int16_t f_pusch;
|
||||
/// Po_PUSCH - target output power for PUSCH
|
||||
int16_t Po_PUSCH;
|
||||
/// PHR - current power headroom (based on last PUSCH transmission)
|
||||
int16_t PHR;
|
||||
/// Po_SRS - target output power for SRS
|
||||
int16_t Po_SRS;
|
||||
/// num active cba group
|
||||
uint8_t num_active_cba_groups;
|
||||
/// num dci found for cba
|
||||
uint8_t num_cba_dci[10];
|
||||
/// allocated CBA RNTI
|
||||
uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP];
|
||||
/// UL max-harq-retransmission
|
||||
uint8_t Mlimit;
|
||||
} NR_UE_ULSCH_t;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Indicator of first transmission
|
||||
uint8_t first_tx;
|
||||
/// Last Ndi received for this process on DCI (used for C-RNTI only)
|
||||
uint8_t DCINdi;
|
||||
/// DLSCH status flag indicating
|
||||
SCH_status_t status;
|
||||
/// Transport block size
|
||||
uint32_t TBS;
|
||||
/// The payload + CRC size in bits
|
||||
uint32_t B;
|
||||
/// Pointer to the payload
|
||||
uint8_t *b;
|
||||
/// Pointers to transport block segments
|
||||
uint8_t *c[MAX_NUM_DLSCH_SEGMENTS];
|
||||
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
|
||||
uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS];
|
||||
/// Index of current HARQ round for this DLSCH
|
||||
uint8_t round;
|
||||
/// MCS format for this DLSCH
|
||||
uint8_t mcs;
|
||||
/// Qm (modulation order) for this DLSCH
|
||||
uint8_t Qm;
|
||||
/// Redundancy-version of the current sub-frame
|
||||
uint8_t rvidx;
|
||||
/// MIMO mode for this DLSCH
|
||||
MIMO_mode_t mimo_mode;
|
||||
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
int16_t w[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
|
||||
/// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
double w_abs[MAX_NUM_DLSCH_SEGMENTS][3*(6144+64)];
|
||||
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
|
||||
int16_t *d[MAX_NUM_DLSCH_SEGMENTS];
|
||||
/// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9)
|
||||
uint32_t C;
|
||||
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cminus;
|
||||
/// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Cplus;
|
||||
/// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kminus;
|
||||
/// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t Kplus;
|
||||
/// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10)
|
||||
uint32_t F;
|
||||
/// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17)
|
||||
uint8_t Nl;
|
||||
/// current delta_pucch
|
||||
int8_t delta_PUCCH;
|
||||
/// Number of soft channel bits
|
||||
uint32_t G;
|
||||
/// Current Number of RBs
|
||||
uint16_t nb_rb;
|
||||
/// Current subband PMI allocation
|
||||
uint16_t pmi_alloc;
|
||||
/// Current RB allocation (even slots)
|
||||
uint32_t rb_alloc_even[4];
|
||||
/// Current RB allocation (odd slots)
|
||||
uint32_t rb_alloc_odd[4];
|
||||
/// distributed/localized flag
|
||||
vrb_t vrb_type;
|
||||
/// downlink power offset field
|
||||
uint8_t dl_power_off;
|
||||
/// trials per round statistics
|
||||
uint32_t trials[8];
|
||||
/// error statistics per round
|
||||
uint32_t errors[8];
|
||||
/// codeword this transport block is mapped to
|
||||
uint8_t codeword;
|
||||
} NR_DL_UE_HARQ_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// HARQ process id
|
||||
uint8_t harq_id;
|
||||
/// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX
|
||||
uint8_t ack;
|
||||
/// send status (for PUCCH)
|
||||
uint8_t send_harq_status;
|
||||
/// nCCE (for PUCCH)
|
||||
uint8_t nCCE;
|
||||
/// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched
|
||||
uint8_t vDAI_DL;
|
||||
/// DAI value detected from DCI0/4. 0xff indicates not touched
|
||||
uint8_t vDAI_UL;
|
||||
} nr_harq_status_t;
|
||||
|
||||
typedef struct {
|
||||
/// RNTI
|
||||
uint16_t rnti;
|
||||
/// Active flag for DLSCH demodulation
|
||||
uint8_t active;
|
||||
/// Transmission mode
|
||||
uint8_t mode1_flag;
|
||||
/// amplitude of PDSCH (compared to RS) in symbols without pilots
|
||||
int16_t sqrt_rho_a;
|
||||
/// amplitude of PDSCH (compared to RS) in symbols containing pilots
|
||||
int16_t sqrt_rho_b;
|
||||
/// Current HARQ process id threadRx Odd and threadRx Even
|
||||
uint8_t current_harq_pid;
|
||||
/// Current subband antenna selection
|
||||
uint32_t antenna_alloc;
|
||||
/// Current subband RI allocation
|
||||
uint32_t ri_alloc;
|
||||
/// Current subband CQI1 allocation
|
||||
uint32_t cqi_alloc1;
|
||||
/// Current subband CQI2 allocation
|
||||
uint32_t cqi_alloc2;
|
||||
/// saved subband PMI allocation from last PUSCH/PUCCH report
|
||||
uint16_t pmi_alloc;
|
||||
/// HARQ-ACKs
|
||||
nr_harq_status_t harq_ack[10];
|
||||
/// Pointers to up to 8 HARQ processes
|
||||
NR_DL_UE_HARQ_t *harq_processes[8];
|
||||
/// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17
|
||||
uint8_t Mdlharq;
|
||||
/// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17)
|
||||
uint8_t Kmimo;
|
||||
/// Nsoft parameter related to UE Category
|
||||
uint32_t Nsoft;
|
||||
/// Maximum number of Turbo iterations
|
||||
uint8_t max_turbo_iterations;
|
||||
/// number of iterations used in last turbo decoding
|
||||
uint8_t last_iteration_cnt;
|
||||
/// accumulated tx power adjustment for PUCCH
|
||||
int8_t g_pucch;
|
||||
} NR_UE_DLSCH_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/**@}*/
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* FILENAME : pbch_nr.c
|
||||
*
|
||||
* MODULE : broacast channel
|
||||
*
|
||||
* DESCRIPTION : generation of pbch
|
||||
* 3GPP TS 38.211 7.3.3 Physical broadcast channel
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "PHY/defs.h"
|
||||
|
||||
#define DEFINE_VARIABLES_PBCH_NR_H
|
||||
#include "PHY/NR_REFSIG/pbch_nr.h"
|
||||
#undef DEFINE_VARIABLES_PBCH_NR_H
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pseudo_random_gold_sequence
|
||||
*
|
||||
* PARAMETERS :
|
||||
*
|
||||
* RETURN : generate pseudo-random sequence which is a length-31 Gold sequence
|
||||
*
|
||||
* DESCRIPTION : 3GPP TS 38.211 5.2.1 Pseudo-random sequence generation
|
||||
* Sequence generation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define NC (1600)
|
||||
#define GOLD_LENGTH (31)
|
||||
|
||||
uint32_t *pseudo_random_gold_sequence(length M_PN, uint32_t cinit)
|
||||
{
|
||||
int size = M_PN * sizeof(uint32_t);
|
||||
int size_x = (sizeof(int)*M_PN + size;
|
||||
int *x1 = malloc(size_x);
|
||||
int *x2 = malloc(size_x);
|
||||
|
||||
if ((x1 == NULL) || (x2 == NULL)) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
else {
|
||||
bzero(x1, size_x);
|
||||
bzero(x2, size_x);
|
||||
}
|
||||
|
||||
x1[0] = 1;
|
||||
|
||||
for (n = 0; n < 31; n++) {
|
||||
x2[n] = (cinit >> n) & 0x1;
|
||||
}
|
||||
|
||||
for (int n = 0; n < (NC+M_PN); n++) {
|
||||
x1(n+31) = (x1(n+3) + x1(n))%2;
|
||||
x2(n+31) = (x2(n+3) + x2(n+2) + x2(n+1) + x2(n))%2;
|
||||
}
|
||||
|
||||
int *c = calloc(size);
|
||||
if (c != NULL) {
|
||||
bzero(c, size);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for (int n = 0; n < M_PN; n++) {
|
||||
c(i) = (x1(n+NC) + x2(n+NC))%2;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -0,0 +1,873 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* FILENAME : pss_nr.c
|
||||
*
|
||||
* MODULE : synchronisation signal
|
||||
*
|
||||
* DESCRIPTION : generation of pss
|
||||
* 3GPP TS 38.211 7.4.2.2 Primary synchronisation signal
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
|
||||
#define DEFINE_VARIABLES_PSS_NR_H
|
||||
#include "PHY/NR_REFSIG/pss_nr.h"
|
||||
#undef DEFINE_VARIABLES_PSS_NR_H
|
||||
|
||||
#include "PHY/NR_REFSIG/sss_nr.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/cic_filter_nr.h"
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : get_idft
|
||||
*
|
||||
* PARAMETERS : size of ofdm symbol
|
||||
*
|
||||
* RETURN : function idft
|
||||
*
|
||||
* DESCRIPTION : get idft function depending of ofdm size
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void *get_idft(int ofdm_symbol_size)
|
||||
{
|
||||
void (*idft)(int16_t *,int16_t *, int);
|
||||
|
||||
switch (ofdm_symbol_size) {
|
||||
case 128:
|
||||
idft = idft128;
|
||||
break;
|
||||
|
||||
case 256:
|
||||
idft = idft256;
|
||||
break;
|
||||
|
||||
case 512:
|
||||
idft = idft512;
|
||||
break;
|
||||
|
||||
case 1024:
|
||||
idft = idft1024;
|
||||
break;
|
||||
|
||||
case 1536:
|
||||
idft = idft1536;
|
||||
break;
|
||||
|
||||
case 2048:
|
||||
idft = idft2048;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("function get_idft : unsupported ofdm symbol size \n");
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return idft;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : get_dft
|
||||
*
|
||||
* PARAMETERS : size of ofdm symbol
|
||||
*
|
||||
* RETURN : function for discrete fourier transform
|
||||
*
|
||||
* DESCRIPTION : get dft function depending of ofdm size
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void *get_dft(int ofdm_symbol_size)
|
||||
{
|
||||
void (*dft)(int16_t *,int16_t *, int);
|
||||
|
||||
switch (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;
|
||||
|
||||
default:
|
||||
printf("function get_dft : unsupported ofdm symbol size \n");
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return dft;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : generate_pss_nr
|
||||
*
|
||||
* PARAMETERS : N_ID_2 : element 2 of physical layer cell identity
|
||||
* value : { 0, 1, 2}
|
||||
*
|
||||
* RETURN : generate binary pss sequence (this is a m-sequence)
|
||||
*
|
||||
* DESCRIPTION : 3GPP TS 38.211 7.4.2.2 Primary synchronisation signal
|
||||
* Sequence generation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void generate_pss_nr(int N_ID_2, int ofdm_symbol_size)
|
||||
{
|
||||
int16_t d_pss[LENGTH_PSS_NR];
|
||||
int16_t x[LENGTH_PSS_NR];
|
||||
int16_t *primary_synchro_time = primary_synchro_time_nr[N_ID_2];
|
||||
unsigned int length = ofdm_symbol_size;
|
||||
unsigned int size = length * IQ_SIZE; /* i & q */
|
||||
int16_t *primary_synchro = primary_synchro_nr[N_ID_2]; /* pss in complex with alternatively i then q */
|
||||
void (*idft)(int16_t *,int16_t *, int);
|
||||
|
||||
#define INITIAL_PSS_NR (7)
|
||||
const int x_initial[INITIAL_PSS_NR] = {0, 1, 1 , 0, 1, 1, 1};
|
||||
|
||||
assert(N_ID_2 < NUMBER_PSS_SEQUENCE);
|
||||
assert(size <= SYNCF_TMP_SIZE);
|
||||
assert(size <= SYNC_TMP_SIZE);
|
||||
|
||||
bzero(synchroF_tmp, size);
|
||||
bzero(synchro_tmp, size);
|
||||
|
||||
for (int i=0; i < INITIAL_PSS_NR; i++) {
|
||||
x[i] = x_initial[i];
|
||||
}
|
||||
|
||||
for (int i=0; i < (LENGTH_PSS_NR - INITIAL_PSS_NR); i++) {
|
||||
x[i+INITIAL_PSS_NR] = (x[i + 4] + x[i])%(2);
|
||||
}
|
||||
|
||||
for (int n=0; n < LENGTH_PSS_NR; n++) {
|
||||
int m = (n + 43*N_ID_2)%(LENGTH_PSS_NR);
|
||||
d_pss[n] = 1 - 2*x[m];
|
||||
}
|
||||
|
||||
/* PSS is directly mapped to subcarrier without modulation 38.211 */
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
#if 1
|
||||
primary_synchro[2*i] = (d_pss[i] * SHRT_MAX)>>SCALING_PSS_NR; /* Maximum value for type short int ie int16_t */
|
||||
primary_synchro[2*i+1] = 0;
|
||||
#else
|
||||
primary_synchro[2*i] = d_pss[i] * AMP;
|
||||
primary_synchro[2*i+1] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
if (N_ID_2 == 0) {
|
||||
char output_file[255];
|
||||
char sequence_name[255];
|
||||
sprintf(output_file, "pss_seq_%d_%d.m", N_ID_2, length);
|
||||
sprintf(sequence_name, "pss_seq_%d_%d", N_ID_2, length);
|
||||
printf("file %s sequence %s\n", output_file, sequence_name);
|
||||
|
||||
write_output(output_file, sequence_name, primary_synchro, LENGTH_PSS_NR, 1, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* call of IDFT should be done with ordered input as below
|
||||
*
|
||||
* n input samples
|
||||
* <------------------------------------------------>
|
||||
* 0 n
|
||||
* are written into input buffer for IFFT
|
||||
* -------------------------------------------------
|
||||
* |xxxxxxx N/2 xxxxxxxx|
|
||||
* --------------------------------------------------
|
||||
* ^ ^ ^ ^ ^
|
||||
* | | | | |
|
||||
* n/2 end of n=0 start of n/2-1
|
||||
* pss pss
|
||||
*
|
||||
* Frequencies
|
||||
* positives negatives
|
||||
* 0 (+N/2)(-N/2)
|
||||
* |-----------------------><-------------------------|
|
||||
*
|
||||
* sample 0 is for continuous frequency which is used here
|
||||
*/
|
||||
|
||||
unsigned int k = length - (LENGTH_PSS_NR/2+1);
|
||||
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
synchroF_tmp[2*k] = primary_synchro[2*i];
|
||||
synchroF_tmp[2*k+1] = primary_synchro[2*i+1];
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= length) {
|
||||
k++;
|
||||
k-=length;
|
||||
}
|
||||
}
|
||||
|
||||
/* IFFT will give temporal signal of Pss */
|
||||
|
||||
idft = get_idft(length);
|
||||
|
||||
idft(synchroF_tmp, /* complex input */
|
||||
synchro_tmp, /* complex output */
|
||||
1); /* scaling factor */
|
||||
|
||||
/* then get final pss in time */
|
||||
for (unsigned int i=0; i<length; i++) {
|
||||
((int32_t *)primary_synchro_time)[i] = ((int32_t *)synchro_tmp)[i];
|
||||
}
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
if (N_ID_2 == 0) {
|
||||
char output_file[255];
|
||||
char sequence_name[255];
|
||||
sprintf(output_file, "%s%d_%d%s","pss_seq_t_", N_ID_2, length, ".m");
|
||||
sprintf(sequence_name, "%s%d_%d","pss_seq_t_", N_ID_2, length);
|
||||
|
||||
printf("file %s sequence %s\n", output_file, sequence_name);
|
||||
|
||||
write_output(output_file, sequence_name, primary_synchro_time, length, 1, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* it allows checking that process of idft on a signal and then dft gives same signal with limited errors */
|
||||
|
||||
if ((N_ID_2 == 0) && (length == 256)) {
|
||||
|
||||
write_output("pss_f00.m","pss_f00",synchro_tmp,length,1,1);
|
||||
|
||||
|
||||
bzero(synchroF_tmp, size);
|
||||
|
||||
void (*dft)(int16_t *,int16_t *, int) = get_dft(length);
|
||||
|
||||
/* get pss in the time domain by applying an inverse FFT */
|
||||
dft(synchro_tmp, /* complex input */
|
||||
synchroF_tmp, /* complex output */
|
||||
1); /* scaling factor */
|
||||
|
||||
if ((N_ID_2 == 0) && (length == 256)) {
|
||||
write_output("pss_f_0.m","pss_f_0",synchroF_tmp,length,1,1);
|
||||
}
|
||||
|
||||
/* check Pss */
|
||||
k = length - (LENGTH_PSS_NR/2);
|
||||
|
||||
#define LIMIT_ERROR_FFT (10)
|
||||
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
if (abs(synchroF_tmp[2*k] - primary_synchro[2*i]) > LIMIT_ERROR_FFT) {
|
||||
printf("Pss Error[%d] Compute %d Reference %d \n", k, synchroF_tmp[2*k], primary_synchro[2*i]);
|
||||
}
|
||||
|
||||
if (abs(synchroF_tmp[2*k+1] - primary_synchro[2*i+1]) > LIMIT_ERROR_FFT) {
|
||||
printf("Pss Error[%d] Compute %d Reference %d\n", (2*k+1), synchroF_tmp[2*k+1], primary_synchro[2*i+1]);
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= length) {
|
||||
k-=length;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : init_context_pss_nr
|
||||
*
|
||||
* PARAMETERS : structure NR_DL_FRAME_PARMS give frame parameters
|
||||
*
|
||||
* RETURN : generate binary pss sequences (this is a m-sequence)
|
||||
*
|
||||
* DESCRIPTION : 3GPP TS 38.211 7.4.2.2 Primary synchronisation signal
|
||||
* Sequence generation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void init_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
{
|
||||
int ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size;
|
||||
int sizePss = LENGTH_PSS_NR * IQ_SIZE; /* complex value i & q signed 16 bits */
|
||||
int size = ofdm_symbol_size * IQ_SIZE; /* i and q samples signed 16 bits */
|
||||
int16_t *p = NULL;
|
||||
int *q = NULL;
|
||||
|
||||
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
|
||||
|
||||
p = malloc16(sizePss); /* pss in complex with alternatively i then q */
|
||||
if (p != NULL) {
|
||||
primary_synchro_nr[i] = p;
|
||||
bzero( primary_synchro_nr[i], sizePss);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
p = malloc16(size);
|
||||
if (p != NULL) {
|
||||
primary_synchro_time_nr[i] = p;
|
||||
bzero( primary_synchro_time_nr[i], size);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
size = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms_ue->samples_per_subframe;
|
||||
q = malloc16(size);
|
||||
if (q != NULL) {
|
||||
pss_corr_ue[i] = q;
|
||||
bzero( pss_corr_ue[i], size);
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
generate_pss_nr(i, ofdm_symbol_size);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_context_pss_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : free context related to pss
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void free_context_pss_nr(void)
|
||||
{
|
||||
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
|
||||
|
||||
if (primary_synchro_time_nr[i] != NULL) {
|
||||
free(primary_synchro_time_nr[i]);
|
||||
primary_synchro_time_nr[i] = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (primary_synchro_nr[i] != NULL) {
|
||||
free(primary_synchro_nr[i]);
|
||||
primary_synchro_nr[i] = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (pss_corr_ue[i] != NULL) {
|
||||
free(pss_corr_ue[i]);
|
||||
pss_corr_ue[i] = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : init_context_synchro_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : generate context for pss and sss
|
||||
*
|
||||
* DESCRIPTION : initialise contexts and buffers for synchronisation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void init_context_synchro_nr(NR_DL_FRAME_PARMS *frame_parms_ue)
|
||||
{
|
||||
#ifndef STATIC_SYNC_BUFFER
|
||||
|
||||
/* initialise global buffers for synchronisation */
|
||||
synchroF_tmp = malloc16(SYNCF_TMP_SIZE);
|
||||
if (synchroF_tmp == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
synchro_tmp = malloc16(SYNC_TMP_SIZE);
|
||||
if (synchro_tmp == NULL) {
|
||||
msg("Fatal memory allocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
init_context_pss_nr(frame_parms_ue);
|
||||
|
||||
init_context_sss_nr(AMP);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : free_context_synchro_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : free context for pss and sss
|
||||
*
|
||||
* DESCRIPTION : deallocate memory of synchronisation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void free_context_synchro_nr(void)
|
||||
{
|
||||
#ifndef STATIC_SYNC_BUFFER
|
||||
|
||||
if (synchroF_tmp != NULL) {
|
||||
free(synchroF_tmp);
|
||||
synchroF_tmp = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (synchro_tmp != NULL) {
|
||||
free(synchro_tmp);
|
||||
synchro_tmp = NULL;
|
||||
}
|
||||
else {
|
||||
msg("Fatal memory deallocation problem \n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
free_context_pss_nr();
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : set_frame_context_pss_nr
|
||||
*
|
||||
* PARAMETERS : configuration for UE with new FFT size
|
||||
*
|
||||
* RETURN : 0 if OK else error
|
||||
*
|
||||
* DESCRIPTION : initialisation of UE contexts
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change)
|
||||
{
|
||||
/* set new value according to rate_change */
|
||||
frame_parms_ue->ofdm_symbol_size = (frame_parms_ue->ofdm_symbol_size / rate_change);
|
||||
frame_parms_ue->samples_per_tti = (frame_parms_ue->samples_per_tti / rate_change);
|
||||
frame_parms_ue->samples_per_subframe = (frame_parms_ue->samples_per_subframe / rate_change);
|
||||
|
||||
free_context_pss_nr();
|
||||
|
||||
/* pss reference have to be rebuild with new parameters ie ofdm symbol size */
|
||||
init_context_synchro_nr(frame_parms_ue);
|
||||
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
set_pss_nr(frame_parms_ue->ofdm_symbol_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : restore_frame_context_pss_nr
|
||||
*
|
||||
* PARAMETERS : configuration for UE and eNB with new FFT size
|
||||
*
|
||||
* RETURN : 0 if OK else error
|
||||
*
|
||||
* DESCRIPTION : initialisation of UE and eNode contexts
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change)
|
||||
{
|
||||
frame_parms_ue->ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size * rate_change;
|
||||
frame_parms_ue->samples_per_tti = frame_parms_ue->samples_per_tti * rate_change;
|
||||
frame_parms_ue->samples_per_subframe = frame_parms_ue->samples_per_subframe * rate_change;
|
||||
|
||||
free_context_pss_nr();
|
||||
|
||||
/* pss reference have to be rebuild with new parameters ie ofdm symbol size */
|
||||
init_context_synchro_nr(frame_parms_ue);
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
set_pss_nr(frame_parms_ue->ofdm_symbol_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
*
|
||||
* NAME : decimation_synchro_nr
|
||||
*
|
||||
* INPUT : UE context
|
||||
* for first and second pss sequence
|
||||
* - position of pss in the received UE buffer
|
||||
* - number of pss sequence
|
||||
*
|
||||
* RETURN : 0 if OK else error
|
||||
*
|
||||
* DESCRIPTION : detect pss sequences in the received UE buffer
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **rxdata)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
|
||||
int samples_for_frame = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
|
||||
|
||||
#if TEST_SYNCHRO_TIMING_PSS
|
||||
|
||||
opp_enabled = 1;
|
||||
|
||||
start_meas(&generic_time[TIME_RATE_CHANGE]);
|
||||
|
||||
#endif
|
||||
|
||||
/* build with cic filter does not work properly. Performances are significantly deteriorated */
|
||||
#ifdef CIC_DECIMATOR
|
||||
|
||||
cic_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][0]), (int16_t *)&(rxdata[0][0]),
|
||||
samples_for_frame, rate_change, CIC_FILTER_STAGE_NUMBER, 0, FIR_RATE_CHANGE);
|
||||
#else
|
||||
|
||||
fir_decimator((int16_t *)&(PHY_vars_UE->common_vars.rxdata[0][0]), (int16_t *)&(rxdata[0][0]),
|
||||
samples_for_frame, rate_change, 0);
|
||||
|
||||
#endif
|
||||
|
||||
set_frame_context_pss_nr(frame_parms, rate_change);
|
||||
|
||||
#if TEST_SYNCHRO_TIMING_PSS
|
||||
|
||||
stop_meas(&generic_time[TIME_RATE_CHANGE]);
|
||||
|
||||
printf("Rate change execution duration %5.2f \n", generic_time[TIME_RATE_CHANGE].p_time/(cpuf*1000.0));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pss_synchro_nr
|
||||
*
|
||||
* PARAMETERS : int rate_change
|
||||
*
|
||||
* RETURN : position of detected pss
|
||||
*
|
||||
* DESCRIPTION : pss search can be done with sampling decimation.*
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms);
|
||||
int synchro_position;
|
||||
int **rxdata = NULL;
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
int samples_for_frame = frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
|
||||
write_output("rxdata0_rand.m","rxd0_rand", &PHY_vars_UE->common_vars.rxdata[0][0], samples_for_frame, 1, 1);
|
||||
|
||||
#endif
|
||||
|
||||
if (rate_change != 1) {
|
||||
|
||||
rxdata = (int32_t**)malloc16(frame_parms->nb_antennas_rx*sizeof(int32_t*));
|
||||
|
||||
for (int aa=0; aa < frame_parms->nb_antennas_rx; aa++) {
|
||||
rxdata[aa] = (int32_t*) malloc16_clear( (frame_parms->samples_per_subframe*10+2048)*sizeof(int32_t));
|
||||
}
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
|
||||
decimation_synchro_nr(PHY_vars_UE, rate_change, rxdata);
|
||||
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
|
||||
rxdata = PHY_vars_UE->common_vars.rxdata;
|
||||
}
|
||||
|
||||
#ifdef DBG_PSS_NR
|
||||
|
||||
write_output("rxdata0_des.m","rxd0_des", &rxdata[0][0], samples_for_frame,1,1);
|
||||
|
||||
#endif
|
||||
|
||||
#if TEST_SYNCHRO_TIMING_PSS
|
||||
|
||||
opp_enabled = 1;
|
||||
|
||||
start_meas(&generic_time[TIME_PSS]);
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
|
||||
synchro_position = pss_search_time_nr(rxdata,
|
||||
frame_parms,
|
||||
(int *)&PHY_vars_UE->common_vars.eNb_id);
|
||||
|
||||
#else
|
||||
|
||||
synchro_position = lte_sync_time(rxdata,
|
||||
frame_parms,
|
||||
(int *)&PHY_vars_UE->common_vars.eNb_id);
|
||||
#endif
|
||||
|
||||
#if TEST_SYNCHRO_TIMING_PSS
|
||||
|
||||
stop_meas(&generic_time[TIME_PSS]);
|
||||
|
||||
printf("PSS execution duration %5.2f \n", generic_time[TIME_PSS].p_time/(cpuf*1000.0));
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SYNCHRO_DECIMAT
|
||||
|
||||
if (rate_change != 1) {
|
||||
|
||||
if (rxdata[0] != NULL) {
|
||||
|
||||
for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) {
|
||||
free(rxdata[aa]);
|
||||
}
|
||||
|
||||
free(rxdata);
|
||||
}
|
||||
|
||||
restore_frame_context_pss_nr(frame_parms, rate_change);
|
||||
}
|
||||
#endif
|
||||
|
||||
return synchro_position;
|
||||
}
|
||||
|
||||
static inline int abs32(int x)
|
||||
{
|
||||
return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pss_search_time_nr
|
||||
*
|
||||
* PARAMETERS : received buffer
|
||||
* frame parameters
|
||||
*
|
||||
* RETURN : position of detected pss
|
||||
*
|
||||
* DESCRIPTION : Synchronisation on pss sequence is based on a time domain correlation between received samples and pss sequence
|
||||
* A maximum likelihood detector finds the timing offset (position) that corresponds to the maximum correlation
|
||||
* Length of received buffer should be a minimum of 2 frames (see TS 38.213 4.1 Cell search)
|
||||
* Search pss in the received buffer is done each 4 samples which ensures a memory alignment to 128 bits (32 bits x 4).
|
||||
* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors
|
||||
* Correlation computation is based on a a dot product which is realized thank to SIMS extensions
|
||||
*
|
||||
* (x frames)
|
||||
* <--------------------------------------------------------------------------->
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
* | Received UE data buffer |
|
||||
* ----------------------------------------------------------------------------
|
||||
* -------------
|
||||
* <--------->| pss |
|
||||
* position -------------
|
||||
* ^
|
||||
* |
|
||||
* peak position
|
||||
* given by maximum of correlation result
|
||||
* position matches beginning of first ofdm symbol of pss sequence
|
||||
*
|
||||
* Remark: memory position should be aligned on a multiple of 4 due to I & Q samples of int16
|
||||
* An OFDM symbol is composed of x number of received samples depending of Rf front end sample rate.
|
||||
*
|
||||
* I & Q storage in memory
|
||||
*
|
||||
* First samples Second samples
|
||||
* ------------------------- ------------------------- ...
|
||||
* | I1 | Q1 | I2 | Q2 |
|
||||
* --------------------------------------------------- ...
|
||||
* ^ 16 bits 16 bits ^
|
||||
* | |
|
||||
* --------------------------------------------------- ...
|
||||
* | sample 1 | sample 2 |
|
||||
* ---------------------------------------------------- ...
|
||||
* ^
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define DOT_PRODUCT_SCALING_SHIFT (17)
|
||||
|
||||
int pss_search_time_nr(int **rxdata, ///rx data in time domain
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int *eNB_id)
|
||||
{
|
||||
unsigned int n, ar, peak_position, peak_value, pss_source;
|
||||
int result;
|
||||
int synchro_out;
|
||||
unsigned int tmp[NUMBER_PSS_SEQUENCE];
|
||||
unsigned int length = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe*frame_parms->samples_per_tti); /* 1 frame for now, it should be 2 TODO_NR */
|
||||
|
||||
for (int i = 0; i < NUMBER_PSS_SEQUENCE; i++) {
|
||||
tmp[i] = 0;
|
||||
if (pss_corr_ue[i] == NULL) {
|
||||
msg("[SYNC TIME] pss_corr_ue[%d] not yet allocated! Exiting.\n", i);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
peak_value = 0;
|
||||
peak_position = 0;
|
||||
pss_source = 0;
|
||||
|
||||
/* Search pss in the received buffer each 4 samples which ensures a memory alignment on 128 bits (32 bits x 4 ) */
|
||||
/* This is required by SIMD (single instruction Multiple Data) Extensions of Intel processors. */
|
||||
/* Correlation computation is based on a a dot product which is realized thank to SIMS extensions */
|
||||
for (n=0; n < length; n+=4) {
|
||||
|
||||
#ifdef RTAI_ENABLED
|
||||
|
||||
// This is necessary since the sync takes a long time and it seems to block all other threads thus screwing up RTAI. If we pause it for a little while during its execution we give RTAI a chance to catch up with its other tasks.
|
||||
if ((n%frame_parms->samples_per_subframe == 0) && (n>0) && (openair_daq_vars.sync_state==0)) {
|
||||
#ifdef DEBUG_PHY
|
||||
msg("[SYNC TIME] pausing for 1000ns, n=%d\n",n);
|
||||
#endif
|
||||
rt_sleep(nano2count(1000));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
for (int pss_index = 0; pss_index < NUMBER_PSS_SEQUENCE; pss_index++) {
|
||||
|
||||
pss_corr_ue[pss_index][n] = 0; /* clean correlation for position n */
|
||||
|
||||
synchro_out = 0;
|
||||
|
||||
if ( n < (length - frame_parms->ofdm_symbol_size)) {
|
||||
|
||||
/* calculate dot product of primary_synchro_time_nr and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n]; */
|
||||
for (ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
|
||||
|
||||
/* perform correlation of rx data and pss sequence ie it is a dot product */
|
||||
result = dot_product((short*)primary_synchro_time_nr[pss_index], (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, DOT_PRODUCT_SCALING_SHIFT);
|
||||
|
||||
((short*)pss_corr_ue[pss_index])[2*n] += ((short*) &result)[0]; /* real part */
|
||||
((short*)pss_corr_ue[pss_index])[2*n+1] += ((short*) &result)[1]; /* imaginary part */
|
||||
((short*)&synchro_out)[0] += ((short*) &result)[0]; /* real part */
|
||||
((short*)&synchro_out)[1] += ((short*) &result)[1]; /* imaginary part */
|
||||
}
|
||||
}
|
||||
|
||||
pss_corr_ue[pss_index][n] = abs32(pss_corr_ue[pss_index][n]);
|
||||
|
||||
/* calculate the absolute value of sync_corr[n] */
|
||||
tmp[pss_index] = (abs32(synchro_out)) ;
|
||||
|
||||
if (tmp[pss_index] > peak_value) {
|
||||
peak_value = tmp[pss_index];
|
||||
peak_position = n;
|
||||
pss_source = pss_index;
|
||||
|
||||
//printf("pss_index %d: n %6d peak_value %10d, synchro_out (% 6d,% 6d) \n", pss_index, n, abs32(synchro_out),((int16_t*)&synchro_out)[0],((int16_t*)&synchro_out)[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*eNB_id = pss_source;
|
||||
|
||||
LOG_I(PHY,"[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n", pss_source, peak_position, peak_value, dB_fixed(peak_value)/2);
|
||||
|
||||
#ifdef DEBUG_PSS_NR
|
||||
|
||||
#define PSS_DETECTION_FLOOR_NR (31)
|
||||
if ((dB_fixed(peak_value)/2) > PSS_DETECTION_FLOOR_NR) {
|
||||
|
||||
printf("[UE] nr_synchro_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n", pss_source, peak_position, peak_value,dB_fixed(peak_value)/2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_PHY
|
||||
|
||||
if (debug_cnt == 0) {
|
||||
write_output("pss_corr_ue0.m","pss_corr_ue0",pss_corr_ue[0],length,1,2);
|
||||
write_output("pss_corr_ue1.m","pss_corr_ue1",pss_corr_ue[1],length,1,2);
|
||||
write_output("pss_corr_ue2.m","pss_corr_ue2",pss_corr_ue[2],length,1,2);
|
||||
write_output("rxdata0.m","rxd0",rxdata[0],length,1,1);
|
||||
} else {
|
||||
debug_cnt++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return(peak_position);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : srs_modulation_nr_nr.c
|
||||
*
|
||||
* MODULE :
|
||||
*
|
||||
* DESCRIPTION : function to set uplink reference symbols
|
||||
* see TS 38211 6.4.1.4 Sounding reference signal
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define DEFINE_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
#undef DEFINE_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
//#include "extern.h"
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
#include "PHY/NR_REFSIG/dmrs_nr.h"
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
|
||||
#define DEFINE_VARIABLES_SRS_MODULATION_NR_H
|
||||
#include "PHY/NR_UE_TRANSPORT/srs_modulation_nr.h"
|
||||
#undef DEFINE_VARIABLES_SRS_MODULATION_NR_H
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : generate_srs
|
||||
*
|
||||
* PARAMETERS : pointer to resource set
|
||||
* pointer to transmit buffer
|
||||
* amplitude scaling for this physical signal
|
||||
* slot number of transmission
|
||||
* RETURN : 0 if srs sequence has been successfully generated
|
||||
* -1 if sequence can not be properly generated
|
||||
*
|
||||
* DESCRIPTION : generate/map srs symbol into transmit buffer
|
||||
* see TS 38211 6.4.1.4 Sounding reference signal
|
||||
*
|
||||
* FFS_TODO_NR
|
||||
* Current supported configuration:
|
||||
* - single resource per resource set
|
||||
* - single port antenna
|
||||
* - 1 symbol for SRS
|
||||
* - no symbol offset
|
||||
* - periodic mode
|
||||
* - no hopping
|
||||
* - no carrier switching
|
||||
* - no antenna switching*
|
||||
*
|
||||
*********************************************************************/
|
||||
int32_t generate_srs_nr(SRS_ResourceSet_t *p_srs_resource_set,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *txptr,
|
||||
int16_t amp,
|
||||
UE_nr_rxtx_proc_t *proc)
|
||||
{
|
||||
uint8_t n_SRS_cs_max;
|
||||
uint8_t u, v_nu;
|
||||
uint32_t f_gh = 0;
|
||||
SRS_Resource_t *p_SRS_Resource;
|
||||
int frame_number = proc->frame_tx;
|
||||
int slot_number = proc->nr_tti_tx;
|
||||
uint16_t n_SRS, n_SRS_cs_i;
|
||||
double alpha_i;
|
||||
uint8_t K_TC_p;
|
||||
uint16_t n_b[B_SRS_NUMBER], F_b, subcarrier;
|
||||
uint8_t N_b, k_0_overbar_p;
|
||||
|
||||
if (p_srs_resource_set->p_srs_ResourceList[0] == NULL) {
|
||||
LOG_E(PHY,"generate_srs: No resource associated with the SRS resource set!\n");
|
||||
return (-1);
|
||||
}
|
||||
else {
|
||||
if (p_srs_resource_set->number_srs_Resource <= MAX_NR_OF_SRS_RESOURCES_PER_SET) {
|
||||
p_SRS_Resource = p_srs_resource_set->p_srs_ResourceList[0];
|
||||
}
|
||||
else {
|
||||
LOG_E(PHY,"generate_srs: resource number of this resource set %d exceeds maximum supported value %d!\n", p_srs_resource_set->number_srs_Resource, MAX_NR_OF_SRS_RESOURCES_PER_SET);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_srs_resource_set->resourceType != periodic) {
|
||||
LOG_E(PHY,"generate_srs: only SRS periodic is supported up to now!\n");
|
||||
return (-1);
|
||||
}
|
||||
/* get parameters from SRS resource configuration */
|
||||
uint8_t B_SRS = p_SRS_Resource->freqHopping_b_SRS;
|
||||
uint8_t C_SRS = p_SRS_Resource->freqHopping_c_SRS;
|
||||
uint8_t b_hop = p_SRS_Resource->freqHopping_b_hop;
|
||||
uint8_t K_TC = p_SRS_Resource->transmissionComb;
|
||||
uint8_t K_TC_overbar = p_SRS_Resource->combOffset; /* FFS_TODO_NR is this parameter for K_TC_overbar ?? */
|
||||
uint8_t n_SRS_cs = p_SRS_Resource->cyclicShift;
|
||||
uint8_t n_ID_SRS = p_SRS_Resource->sequenceId;
|
||||
uint8_t n_shift = p_SRS_Resource->freqDomainPosition; /* it adjusts the SRS allocation to align with the common resource block grid in multiples of four */
|
||||
uint8_t n_RRC = p_SRS_Resource->freqDomainShift;
|
||||
uint8_t groupOrSequenceHopping = p_SRS_Resource->groupOrSequenceHopping;
|
||||
|
||||
uint8_t l_offset = p_SRS_Resource->resourceMapping_startPosition;
|
||||
|
||||
uint16_t T_SRS = srs_period[p_SRS_Resource->SRS_Periodicity];
|
||||
uint16_t T_offset = p_SRS_Resource->SRS_Offset;; /* FFS_TODO_NR to check interface with RRC */
|
||||
uint8_t R = p_SRS_Resource->resourceMapping_repetitionFactor;
|
||||
|
||||
/* TS 38.211 6.4.1.4.1 SRS resource */
|
||||
uint8_t N_ap = (uint8_t)p_SRS_Resource->nrof_SrsPorts; /* antenna port for transmission */
|
||||
uint8_t N_symb_SRS = p_SRS_Resource->resourceMapping_nrofSymbols; /* consecutive OFDM symbols */
|
||||
uint8_t l0 = N_SYMB_SLOT - 1 - l_offset; /* starting position in the time domain */
|
||||
uint8_t k_0_p; /* frequency domain starting position */
|
||||
|
||||
if (N_ap != port1) {
|
||||
LOG_E(PHY, "generate_srs: this number of antenna ports %d is not yet supported!\n", N_ap);
|
||||
return (-1);
|
||||
}
|
||||
if (N_symb_SRS != 1) {
|
||||
LOG_E(PHY, "generate_srs: this number of srs symbol %d is not yet supported!\n", N_symb_SRS);
|
||||
return (-1);
|
||||
}
|
||||
if (groupOrSequenceHopping != neitherHopping) {
|
||||
LOG_E(PHY, "generate_srs: sequence hopping is not yet supported!\n");
|
||||
return (-1);
|
||||
}
|
||||
if (R == 0) {
|
||||
LOG_E(PHY, "generate_srs: this parameter repetition factor %d is not consistent !\n", R);
|
||||
return (-1);
|
||||
}
|
||||
else if (R > N_symb_SRS) {
|
||||
LOG_E(PHY, "generate_srs: R %d can not be greater than N_symb_SRS %d !\n", R, N_symb_SRS);
|
||||
return (-1);
|
||||
}
|
||||
/* see 38211 6.4.1.4.2 Sequence generation */
|
||||
if (K_TC == 4) {
|
||||
n_SRS_cs_max = 12;
|
||||
// delta = 2; /* delta = log2(K_TC) */
|
||||
}
|
||||
else if (K_TC == 2) {
|
||||
n_SRS_cs_max = 8;
|
||||
// delta = 1; /* delta = log2(K_TC) */
|
||||
}
|
||||
else {
|
||||
LOG_E(PHY, "generate_srs: SRS unknown value for K_TC %d !\n", K_TC);
|
||||
return (-1);
|
||||
}
|
||||
if (n_SRS_cs >= n_SRS_cs_max) {
|
||||
LOG_E(PHY, "generate_srs: inconsistent parameter n_SRS_cs %d >= n_SRS_cs_max %d !\n", n_SRS_cs, n_SRS_cs_max);
|
||||
return (-1);
|
||||
}
|
||||
if (T_SRS == 0) {
|
||||
LOG_E(PHY, "generate_srs: inconsistent parameter T_SRS %d can not be equal to zero !\n", T_SRS);
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
while (srs_periodicity[index] != T_SRS) {
|
||||
index++;
|
||||
if (index == SRS_PERIODICITY) {
|
||||
LOG_E(PHY, "generate_srs: inconsistent parameter T_SRS %d not specified !\n", T_SRS);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; /* m_SRS_b is given by TS 38211 clause 6.4.1.4.3 */
|
||||
uint16_t M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC; /* length of the sounding reference signal sequence */
|
||||
|
||||
/* for each antenna ports for transmission */
|
||||
for (int p_index = 0; p_index < N_ap; p_index++) {
|
||||
|
||||
/* see TS 38.211 6.4.1.4.2 Sequence generation */
|
||||
|
||||
n_SRS_cs_i = (n_SRS_cs + (n_SRS_cs_max * (SRS_antenna_port[p_index] - 1000)/N_ap))%n_SRS_cs_max;
|
||||
alpha_i = 2 * M_PI * ((double)n_SRS_cs_i / (double)n_SRS_cs_max);
|
||||
|
||||
/* for each SRS symbol which should be managed by SRS configuration */
|
||||
/* from TS 38.214 6.2.1.1 UE SRS frequency hopping procedure */
|
||||
/* A UE may be configured to transmit an SRS resource on adjacent symbols within the last six symbols of a slot, */
|
||||
/* where all antenna ports of the SRS resource are mapped to each symbol of the resource */
|
||||
|
||||
|
||||
uint8_t l = p_index;
|
||||
if (l >= N_symb_SRS) {
|
||||
LOG_E(PHY, "generate_srs: number of antenna ports %d and number of srs symbols %d are different !\n", N_ap, N_symb_SRS);
|
||||
}
|
||||
|
||||
switch(groupOrSequenceHopping) {
|
||||
case neitherHopping:
|
||||
{
|
||||
f_gh = 0;
|
||||
v_nu = 0;
|
||||
break;
|
||||
}
|
||||
case groupHopping:
|
||||
{
|
||||
uint8_t c_last_index = 8 * (slot_number * N_SYMB_SLOT + l0 + l) + 7; /* compute maximum value of the random sequence */
|
||||
uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t));
|
||||
uint32_t cinit = n_ID_SRS/30;
|
||||
pseudo_random_sequence(c_last_index+1, c_sequence, cinit);
|
||||
for (int m = 0; m < 8; m++) {
|
||||
f_gh += c_sequence[8 * (slot_number * N_SYMB_SLOT + l0 + l) + m]<<m;
|
||||
}
|
||||
free(c_sequence);
|
||||
f_gh = f_gh%30;
|
||||
v_nu = 0;
|
||||
break;
|
||||
}
|
||||
case sequenceHopping:
|
||||
{
|
||||
f_gh = 0;
|
||||
if (M_sc_b_SRS > 6 * N_SC_RB) {
|
||||
uint8_t c_last_index = (slot_number * N_SYMB_SLOT + l0 + l); /* compute maximum value of the random sequence */
|
||||
uint32_t *c_sequence = calloc(c_last_index+1, sizeof(uint32_t));
|
||||
uint32_t cinit = n_ID_SRS;
|
||||
pseudo_random_sequence(c_last_index+1, c_sequence, cinit);
|
||||
v_nu = c_sequence[c_last_index];
|
||||
free(c_sequence);
|
||||
}
|
||||
else {
|
||||
v_nu = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOG_E(PHY, "generate_srs: unknown hopping setting %d !\n", groupOrSequenceHopping);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* u is the sequence-group number defined in section 6.4.1.4.1 */
|
||||
u = (f_gh + n_ID_SRS)%U_GROUP_NUMBER; /* 30 */
|
||||
|
||||
/* TS 38.211 6.4.1.4.3 Mapping to physical resources */
|
||||
|
||||
if((n_SRS_cs >= n_SRS_cs_max/2)&&(n_SRS_cs < n_SRS_cs_max)&&(N_ap == 4) && ((SRS_antenna_port[p_index] == 1001) || (SRS_antenna_port[p_index] == 1003))) {
|
||||
K_TC_p = (K_TC_overbar + K_TC/2)%K_TC;
|
||||
}
|
||||
else {
|
||||
K_TC_p = K_TC_overbar;
|
||||
}
|
||||
|
||||
for (int b = 0; b <= B_SRS; b++) {
|
||||
N_b = srs_bandwidth_config[C_SRS][b][1];
|
||||
if (b_hop >= B_SRS) {
|
||||
n_b[b] = (4 * n_RRC/m_SRS_b)%N_b; /* frequency hopping is disabled and the frequency position index n_b remains constant */
|
||||
}
|
||||
else {
|
||||
if (b == b_hop) {
|
||||
N_b = 1;
|
||||
}
|
||||
/* periodicity and offset */
|
||||
if (p_srs_resource_set->resourceType == aperiodic) {
|
||||
n_SRS = l/R;
|
||||
}
|
||||
else {
|
||||
int8_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe;
|
||||
n_SRS = ((N_slot_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l/R);
|
||||
}
|
||||
|
||||
uint16_t product_N_b = 1; /* for b_hop to b-1 */
|
||||
for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) { /* product for b_hop to b-1 */
|
||||
if (b_prime != b_hop) {
|
||||
product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1];
|
||||
}
|
||||
}
|
||||
|
||||
if (N_b & 1) { /* Nb odd */
|
||||
F_b = (N_b/2)*(n_SRS/product_N_b);
|
||||
}
|
||||
else { /* Nb even */
|
||||
uint16_t product_N_b_B_SRS = product_N_b;
|
||||
product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */
|
||||
F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b);
|
||||
}
|
||||
|
||||
if (b <= b_hop) {
|
||||
n_b[b] = (4 * n_RRC/m_SRS_b)%N_b;
|
||||
}
|
||||
else {
|
||||
n_b[b] = (F_b + (4 * n_RRC/m_SRS_b))%N_b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k_0_overbar_p = n_shift * N_SC_RB + K_TC_p;
|
||||
|
||||
k_0_p = k_0_overbar_p; /* it is the frequency-domain starting position */
|
||||
|
||||
for (int b = 0; b <= B_SRS; b++) {
|
||||
k_0_p += K_TC * M_sc_b_SRS * n_b[b];
|
||||
}
|
||||
|
||||
subcarrier = (frame_parms->first_carrier_offset) + k_0_p;
|
||||
if (subcarrier>frame_parms->ofdm_symbol_size) {
|
||||
subcarrier -= frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
/* find index of table which is for this srs length */
|
||||
unsigned int M_sc_b_SRS_index = 0;
|
||||
while((ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) && (M_sc_b_SRS_index < SRS_SB_CONF)){
|
||||
M_sc_b_SRS_index++;
|
||||
}
|
||||
|
||||
if (ul_allocated_re[M_sc_b_SRS_index] != M_sc_b_SRS) {
|
||||
LOG_E(PHY, "generate_srs: srs uplink allocation %d can not be found! \n", M_sc_b_SRS);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
char output_file[255];
|
||||
char sequence_name[255];
|
||||
sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v_nu, ul_allocated_re[M_sc_b_SRS_index]);
|
||||
sprintf(sequence_name, "rv_seq_%d_%d_%d", u, v_nu, ul_allocated_re[M_sc_b_SRS_index]);
|
||||
write_output(output_file, sequence_name, rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index], ul_allocated_re[M_sc_b_SRS_index], 1, 1);
|
||||
|
||||
#endif
|
||||
|
||||
for (int k=0; k < M_sc_b_SRS; k++) {
|
||||
|
||||
double real_shift = cos(alpha_i*k);
|
||||
double imag_shift = sin(alpha_i*k);
|
||||
|
||||
/* cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
|
||||
double real = ((real_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k]) - (imag_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]))/sqrt(N_ap);
|
||||
/* sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
|
||||
double imag = ((imag_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k]) + (real_shift*rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]))/sqrt(N_ap);
|
||||
|
||||
int32_t real_amp = ((int32_t)round((double) amp * real)) >> 15;
|
||||
int32_t imag_amp = ((int32_t)round((double) amp * imag)) >> 15;
|
||||
|
||||
#if 0
|
||||
printf("subcarrier %5d srs[%3d] r: %4d i: %4d reference[%d][%d][%d] r: %6d i: %6d\n", subcarrier, k, real_amp, imag_amp,
|
||||
u, v_nu, M_sc_b_SRS_index,
|
||||
rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k],
|
||||
rv_ul_ref_sig[u][v_nu][M_sc_b_SRS_index][2*k+1]);
|
||||
#endif
|
||||
|
||||
txptr[subcarrier] = (real_amp & 0xFFFF) + ((imag_amp<<16)&0xFFFF0000);
|
||||
|
||||
subcarrier += (K_TC); /* subcarrier increment */
|
||||
|
||||
if (subcarrier >= frame_parms->ofdm_symbol_size)
|
||||
subcarrier=subcarrier-frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
/* process next symbol */
|
||||
txptr = txptr + frame_parms->ofdm_symbol_size;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : is_srs_period_nr
|
||||
*
|
||||
* PARAMETERS : pointer to resource set
|
||||
* pointer to transmit buffer
|
||||
* amplitude scaling for this physical signal
|
||||
* slot number of transmission
|
||||
* RETURN : 0 if it is a valid slot for transmitting srs
|
||||
* -1 if srs should not be transmitted
|
||||
*
|
||||
* DESCRIPTION : for periodic,
|
||||
*
|
||||
*********************************************************************/
|
||||
int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource, NR_DL_FRAME_PARMS *frame_parms, int frame_tx, int slot_tx)
|
||||
{
|
||||
uint16_t T_SRS = srs_period[p_SRS_Resource->SRS_Periodicity];
|
||||
uint16_t T_offset = p_SRS_Resource->SRS_Offset; /* FFS_TODO_NR to check interface */
|
||||
|
||||
if (T_offset > T_SRS) {
|
||||
LOG_E(PHY,"is_srs_occasion_nr: T_offset %d is greater than T_SRS %d!\n", T_offset, T_SRS);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe;
|
||||
if ((N_slot_frame*frame_tx + slot_tx - T_offset)%T_SRS == 0) {
|
||||
return (0);
|
||||
}
|
||||
else {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : ue_srs_procedure_nr
|
||||
*
|
||||
* PARAMETERS : pointer to ue context
|
||||
* pointer to rxtx context*
|
||||
*
|
||||
* RETURN : 0 if it is a valid slot for transmitting srs
|
||||
* -1 if srs should not be transmitted
|
||||
*
|
||||
* DESCRIPTION : ue srs procedure
|
||||
* send srs according to current configuration
|
||||
*
|
||||
*********************************************************************/
|
||||
int ue_srs_procedure_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id)
|
||||
{
|
||||
NR_DL_FRAME_PARMS *frame_parms = &(ue->frame_parms);
|
||||
SRS_NR *p_srs_nr = &(ue->frame_parms.srs_nr);
|
||||
SRS_ResourceSet_t *p_srs_resource_set = frame_parms->srs_nr.p_SRS_ResourceSetList[p_srs_nr->active_srs_Resource_Set];
|
||||
int generate_srs = 0;
|
||||
|
||||
/* is there any resource set which has been configurated ? */
|
||||
if (p_srs_nr->number_srs_Resource_Set != 0) {
|
||||
|
||||
/* what is the current active resource set ? */
|
||||
if (p_srs_nr->active_srs_Resource_Set > MAX_NR_OF_SRS_RESOURCE_SET) {
|
||||
LOG_W(PHY,"phy_procedures_UE_TX: srs active %d greater than maximum %d!\n", p_srs_nr->active_srs_Resource_Set, MAX_NR_OF_SRS_RESOURCE_SET);
|
||||
}
|
||||
else {
|
||||
/* SRS resource set configurated ? */
|
||||
if (p_srs_resource_set != NULL) {
|
||||
|
||||
SRS_Resource_t *p_srs_resource = frame_parms->srs_nr.p_SRS_ResourceSetList[p_srs_nr->active_srs_Resource_Set]->p_srs_ResourceList[0];
|
||||
|
||||
/* SRS resource configurated ? */
|
||||
if (p_srs_resource != NULL) {
|
||||
if (p_srs_resource_set->resourceType == periodic) {
|
||||
if (is_srs_period_nr(p_srs_resource, frame_parms, proc->frame_tx, proc->nr_tti_tx) == 0) {
|
||||
generate_srs = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_W(PHY,"phy_procedures_UE_TX: no configurated srs resource!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (generate_srs == 1) {
|
||||
int16_t txptr = AMP;
|
||||
uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12;
|
||||
uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((proc->nr_tti_tx*nsymb)+(nsymb-1));
|
||||
if (generate_srs_nr(p_srs_resource_set, frame_parms, &ue->common_vars.txdataF[eNB_id][symbol_offset], txptr, proc) == 0) {
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : srs_modulation_nr.h
|
||||
*
|
||||
* MODULE :
|
||||
*
|
||||
* DESCRIPTION : function to generate uplink reference sequences
|
||||
* see 3GPP TS 38.211 6.4.1.4 Sounding reference signal
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifndef SRS_MODULATION_NR_H
|
||||
#define SRS_MODULATION_NR_H
|
||||
|
||||
#ifdef DEFINE_VARIABLES_SRS_MODULATION_NR_H
|
||||
#define EXTERN
|
||||
#define INIT_VARIABLES_SRS_MODULATION_NR_H
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#undef INIT_VARIABLES_SRS_MODULATION_NR_H
|
||||
#endif
|
||||
|
||||
|
||||
/************** DEFINE ********************************************/
|
||||
|
||||
#define C_SRS_NUMBER (64)
|
||||
#define B_SRS_NUMBER (4)
|
||||
|
||||
/************** VARIABLES *****************************************/
|
||||
|
||||
/* TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration */
|
||||
EXTERN const unsigned short srs_bandwidth_config[C_SRS_NUMBER][B_SRS_NUMBER][2]
|
||||
#ifdef INIT_VARIABLES_SRS_MODULATION_NR_H
|
||||
= {
|
||||
/* B_SRS = 0 B_SRS = 1 B_SRS = 2 B_SRS = 3 */
|
||||
/* C SRS m_srs0 N_0 m_srs1 N_1 m_srs2 N_2 m_srs3 N_3 */
|
||||
/* 0 */ { { 4, 1 },{ 4, 1 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 1 */ { { 8, 1 },{ 4, 2 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 2 */ { { 12, 1 },{ 4, 3 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 3 */ { { 16, 1 },{ 4, 4 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 4 */ { { 16, 1 },{ 8, 2 },{ 4, 2 },{ 4, 1 } },
|
||||
/* 5 */ { { 20, 1 },{ 4, 5 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 6 */ { { 24, 1 },{ 4, 6 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 7 */ { { 24, 1 },{ 12, 2 },{ 4, 3 },{ 4, 1 } },
|
||||
/* 8 */ { { 28, 1 },{ 4, 7 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 9 */ { { 32, 1 },{ 16, 2 },{ 8, 2 },{ 4, 2 } },
|
||||
/* 10 */ { { 36, 1 },{ 12, 3 },{ 4, 3 },{ 4, 1 } },
|
||||
/* 11 */ { { 40, 1 },{ 20, 2 },{ 4, 5 },{ 4, 1 } },
|
||||
/* 12 */ { { 48, 1 },{ 16, 3 },{ 8, 2 },{ 4, 2 } },
|
||||
/* 13 */ { { 48, 1 },{ 24, 2 },{ 12, 2 },{ 4, 3 } },
|
||||
/* 14 */ { { 52, 1 },{ 4, 13 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 15 */ { { 56, 1 },{ 28, 2 },{ 4, 7 },{ 4, 1 } },
|
||||
/* 16 */ { { 60, 1 },{ 20, 3 },{ 4, 5 },{ 4, 1 } },
|
||||
/* 17 */ { { 64, 1 },{ 32, 2 },{ 16, 2 },{ 4, 4 } },
|
||||
/* 18 */ { { 72, 1 },{ 24, 3 },{ 12, 2 },{ 4, 3 } },
|
||||
/* 19 */ { { 72, 1 },{ 36, 2 },{ 12, 3 },{ 4, 3 } },
|
||||
/* 20 */ { { 76, 1 },{ 4, 19 },{ 4, 1 },{ 4, 1 } },
|
||||
/* 21 */ { { 80, 1 },{ 40, 2 },{ 20, 2 },{ 4, 5 } },
|
||||
/* 22 */ { { 88, 1 },{ 44, 2 },{ 4, 11 },{ 4, 1 } },
|
||||
/* 23 */ { { 96, 1 },{ 32, 3 },{ 16, 2 },{ 4, 4 } },
|
||||
/* 24 */ { { 96, 1 },{ 48, 2 },{ 24, 2 },{ 4, 6 } },
|
||||
/* 25 */ { { 104, 1 },{ 52, 2 },{ 4, 13 },{ 4, 1 } },
|
||||
/* 26 */ { { 112, 1 },{ 56, 2 },{ 28, 2 },{ 4, 7 } },
|
||||
/* 27 */ { { 120, 1 },{ 60, 2 },{ 20, 3 },{ 4, 5 } },
|
||||
/* 28 */ { { 120, 1 },{ 40, 3 },{ 8, 5 },{ 4, 2 } },
|
||||
/* 29 */ { { 120, 1 },{ 24, 5 },{ 12, 2 },{ 4, 3 } },
|
||||
/* 30 */ { { 128, 1 },{ 64, 2 },{ 32, 2 },{ 4, 8 } },
|
||||
/* 31 */ { { 128, 1 },{ 64, 2 },{ 16, 4 },{ 4, 4 } },
|
||||
/* 32 */ { { 128, 1 },{ 16, 8 },{ 8, 2 },{ 4, 2 } },
|
||||
/* 33 */ { { 132, 1 },{ 44, 3 },{ 4, 11 },{ 4, 1 } },
|
||||
/* 34 */ { { 136, 1 },{ 68, 2 },{ 4, 17 },{ 4, 1 } },
|
||||
/* 35 */ { { 144, 1 },{ 72, 2 },{ 36, 2 },{ 4, 9 } },
|
||||
/* 36 */ { { 144, 1 },{ 48, 3 },{ 24, 2 },{ 12, 2 } },
|
||||
/* 37 */ { { 144, 1 },{ 48, 3 },{ 16, 3 },{ 4, 4 } },
|
||||
/* 38 */ { { 144, 1 },{ 16, 9 },{ 8, 2 },{ 4, 2 } },
|
||||
/* 39 */ { { 152, 1 },{ 76, 2 },{ 4, 19 },{ 4, 1 } },
|
||||
/* 40 */ { { 160, 1 },{ 80, 2 },{ 40, 2 },{ 4, 10 } },
|
||||
/* 41 */ { { 160, 1 },{ 80, 2 },{ 20, 4 },{ 4, 5 } },
|
||||
/* 42 */ { { 160, 1 },{ 32, 5 },{ 16, 2 },{ 4, 4 } },
|
||||
/* 43 */ { { 168, 1 },{ 84, 2 },{ 28, 3 },{ 4, 7 } },
|
||||
/* 44 */ { { 176, 1 },{ 88, 2 },{ 44, 2 },{ 4, 11 } },
|
||||
/* 45 */ { { 184, 1 },{ 92, 2 },{ 4, 23 },{ 4, 1 } },
|
||||
/* 46 */ { { 192, 1 },{ 96, 2 },{ 48, 2 },{ 4, 12 } },
|
||||
/* 47 */ { { 192, 1 },{ 96, 2 },{ 24, 4 },{ 4, 6 } },
|
||||
/* 48 */ { { 192, 1 },{ 64, 3 },{ 16, 4 },{ 4, 4 } },
|
||||
/* 49 */ { { 192, 1 },{ 24, 8 },{ 8, 3 },{ 4, 2 } },
|
||||
/* 50 */ { { 208, 1 },{ 104, 2 },{ 52, 2 },{ 4, 13 } },
|
||||
/* 51 */ { { 216, 1 },{ 108, 2 },{ 36, 3 },{ 4, 9 } },
|
||||
/* 52 */ { { 224, 1 },{ 112, 2 },{ 56, 2 },{ 4, 14 } },
|
||||
/* 53 */ { { 240, 1 },{ 120, 2 },{ 60, 2 },{ 4, 15 } },
|
||||
/* 54 */ { { 240, 1 },{ 80, 3 },{ 20, 4 },{ 4, 5 } },
|
||||
/* 55 */ { { 240, 1 },{ 48, 5 },{ 16, 3 },{ 8, 2 } },
|
||||
/* 56 */ { { 240, 1 },{ 24, 10 },{ 12, 2 },{ 4, 3 } },
|
||||
/* 57 */ { { 256, 1 },{ 128, 2 },{ 64, 2 },{ 4, 16 } },
|
||||
/* 58 */ { { 256, 1 },{ 128, 2 },{ 32, 4 },{ 4, 8 } },
|
||||
/* 59 */ { { 256, 1 },{ 16, 16 },{ 8, 2 },{ 4, 2 } },
|
||||
/* 60 */ { { 264, 1 },{ 132, 2 },{ 44, 3 },{ 4, 11 } },
|
||||
/* 61 */ { { 272, 1 },{ 136, 2 },{ 68, 2 },{ 4, 17 } },
|
||||
/* 62 */ { { 272, 1 },{ 68, 4 },{ 4, 17 },{ 4, 1 } },
|
||||
/* 63 */ { { 272, 1 },{ 16, 17 },{ 8, 2 },{ 4, 2 } },
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
#define SRS_PERIODICITY (17)
|
||||
|
||||
EXTERN const uint16_t srs_periodicity[SRS_PERIODICITY]
|
||||
#ifdef INIT_VARIABLES_SRS_MODULATION_NR_H
|
||||
= { 1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}
|
||||
#endif
|
||||
;
|
||||
|
||||
/*************** FUNCTIONS *****************************************/
|
||||
|
||||
/** \brief This function generates the sounding reference symbol (SRS) for the uplink according to 38.211 6.4.1.4 Sounding reference signal
|
||||
@param frame_parms NR DL Frame parameters
|
||||
@param txdataF pointer to the frequency domain TX signal
|
||||
@param amp amplitude of generated signal
|
||||
@param proc pointer to the transmit parameters
|
||||
@returns 0 on success -1 on error with message */
|
||||
|
||||
int32_t generate_srs_nr(SRS_ResourceSet_t *p_srs_resource_set,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int32_t *txptr,
|
||||
int16_t amp,
|
||||
UE_nr_rxtx_proc_t *proc);
|
||||
|
||||
/** \brief This function checks for periodic srs if srs should be transmitted in this slot
|
||||
* @param p_SRS_Resource pointer to active resource
|
||||
@param frame_parms NR DL Frame parameters
|
||||
@param txdataF pointer to the frequency domain TX signal
|
||||
@returns 0 if srs should be transmitted -1 on error with message */
|
||||
|
||||
int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
int frame_tx, int slot_tx);
|
||||
/** \brief This function processes srs configuration
|
||||
* @param ue context
|
||||
@param rxtx context
|
||||
@param current eNB identifier
|
||||
@returns 0 if srs is transmitted -1 otherwise */
|
||||
|
||||
int ue_srs_procedure_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id);
|
||||
|
||||
#undef EXTERN
|
||||
#undef INIT_VARIABLES_SRS_MODULATION_NR_H
|
||||
|
||||
#endif /* SRS_MODULATION_NR_H */
|
||||
@@ -0,0 +1,603 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* FILENAME : sss_nr.c
|
||||
*
|
||||
* MODULE : Functions for secundary synchronisation signal
|
||||
*
|
||||
* DESCRIPTION : generation of sss
|
||||
* 3GPP TS 38.211 7.4.2.3 Secondary synchronisation signal
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/MODULATION/modulation_UE.h"
|
||||
|
||||
#include "PHY/NR_REFSIG/ss_pbch_nr.h"
|
||||
|
||||
#define DEFINE_VARIABLES_SSS_NR_H
|
||||
#include "PHY/NR_REFSIG/sss_nr.h"
|
||||
#undef DEFINE_VARIABLES_SSS_NR_H
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : init_context_sss_nr
|
||||
*
|
||||
* PARAMETERS : N_ID_2 : element 2 of physical layer cell identity
|
||||
* value : { 0, 1, 2 }
|
||||
*
|
||||
* RETURN : generate binary sss sequence (this is a m-sequence)
|
||||
* d_sss is a third dimension array depending on
|
||||
* Cell identity elements:
|
||||
* - N_ID_1 : value from 0 to 335
|
||||
* - N_ID_2 : value from 0 to 2
|
||||
*
|
||||
* DESCRIPTION : 3GPP TS 38.211 7.4.2.3 Secundary synchronisation signal
|
||||
* Sequence generation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#define INITIAL_SSS_NR (7)
|
||||
|
||||
void init_context_sss_nr(int amp)
|
||||
{
|
||||
int16_t x0[LENGTH_SSS_NR];
|
||||
int16_t x1[LENGTH_SSS_NR];
|
||||
int16_t dss_current;
|
||||
int m0, m1;
|
||||
|
||||
const int x0_initial[INITIAL_SSS_NR] = { 1, 0, 0, 0, 0, 0, 0 };
|
||||
const int x1_initial[INITIAL_SSS_NR] = { 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
for (int i=0; i < INITIAL_SSS_NR; i++) {
|
||||
x0[i] = x0_initial[i];
|
||||
x1[i] = x1_initial[i];
|
||||
}
|
||||
|
||||
for (int i=0; i < (LENGTH_SSS_NR - INITIAL_SSS_NR); i++) {
|
||||
x0[i+7] = (x0[i + 4] + x0[i])%(2);
|
||||
x1[i+7] = (x1[i + 1] + x1[i])%(2);
|
||||
}
|
||||
|
||||
for (int N_ID_2 = 0; N_ID_2 < N_ID_2_NUMBER; N_ID_2++) {
|
||||
|
||||
for (int N_ID_1 = 0; N_ID_1 < N_ID_1_NUMBER; N_ID_1++) {
|
||||
|
||||
m0 = 15*(N_ID_1/112) + (5*N_ID_2);
|
||||
m1 = N_ID_1%112;
|
||||
|
||||
for (int n = 0; n < LENGTH_SSS_NR; n++) {
|
||||
|
||||
dss_current = (1 - 2*x0[(n + m0)%(LENGTH_SSS_NR)])*(1 - 2*x1[(n + m1)%(LENGTH_SSS_NR)]);
|
||||
|
||||
/* Modulation of SSS is a BPSK TS 36.211 chapter 5.1.2 BPSK */
|
||||
#if 1
|
||||
d_sss[N_ID_2][N_ID_1][n] = dss_current * amp;
|
||||
#else
|
||||
(void) amp;
|
||||
d_sss[N_ID_2][N_ID_1][n] = (dss_current * SHRT_MAX)>>SCALING_PSS_NR;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
printf("sss ref[%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : insert_sss_nr
|
||||
*
|
||||
* PARAMETERS : pointer to input buffer for which sss in inserted
|
||||
* amp amplitude applied to input
|
||||
* frame parameters for cell identity
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : Allow to generate a reference sss sequence according to cell identity
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
void insert_sss_nr(int16_t *sss_time,
|
||||
NR_DL_FRAME_PARMS *frame_parms)
|
||||
{
|
||||
unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
unsigned int size = ofdm_symbol_size * IQ_SIZE; /* i & q */
|
||||
|
||||
assert(size <= SYNCF_TMP_SIZE);
|
||||
assert(size <= SYNC_TMP_SIZE);
|
||||
|
||||
bzero(synchroF_tmp, size);
|
||||
bzero(synchro_tmp, size);
|
||||
|
||||
int Nid2 = GET_NID2(frame_parms->Nid_cell);
|
||||
int Nid1 = GET_NID1(frame_parms->Nid_cell);
|
||||
|
||||
/* call of IDFT should be done with ordered input as below
|
||||
*
|
||||
* n input samples
|
||||
* <------------------------------------------------>
|
||||
* 0 n
|
||||
* are written into input buffer for IFFT in this order
|
||||
* -------------------------------------------------
|
||||
* |xxxxxxx N/2 xxxxxxxx|
|
||||
* --------------------------------------------------
|
||||
* ^ ^ ^ ^ ^
|
||||
* | | | | |
|
||||
* n/2 end of n=0 start of n/2-1
|
||||
* sss sss
|
||||
*
|
||||
* Frequencies
|
||||
* positives negatives
|
||||
* 0 (+N/2)(-N/2)
|
||||
* |-----------------------><-------------------------|
|
||||
*
|
||||
* sample 0 is for continuous frequency which is not used here
|
||||
*/
|
||||
|
||||
unsigned int k = ofdm_symbol_size - ((LENGTH_SSS_NR/2)+1);
|
||||
|
||||
/* SSS is directly mapped to subcarrier */
|
||||
for (int i=0; i<LENGTH_SSS_NR; i++) {
|
||||
synchroF_tmp[2*k] = d_sss[Nid2][Nid1][i];
|
||||
synchroF_tmp[2*k+1] = 0;
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= ofdm_symbol_size) {
|
||||
k++;
|
||||
k-=ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
|
||||
/* get sss in the frequency domain by applying an inverse FFT */
|
||||
idft2048(synchroF_tmp, /* complex input */
|
||||
synchro_tmp, /* complex output */
|
||||
1); /* scaling factor */
|
||||
|
||||
/* then get final sss in time */
|
||||
for (unsigned int i=0; i<ofdm_symbol_size; i++) {
|
||||
((int32_t *)sss_time)[i] = ((int32_t *)synchro_tmp)[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : pss_ch_est
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : pss channel estimation
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
|
||||
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
|
||||
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR])
|
||||
{
|
||||
int16_t *pss;
|
||||
int16_t *pss_ext2,*sss_ext2,*sss_ext3,tmp_re,tmp_im,tmp_re2,tmp_im2;
|
||||
uint8_t aarx,i;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
|
||||
pss = primary_synchro_nr[ue->common_vars.eNb_id];
|
||||
|
||||
sss_ext3 = (int16_t*)&sss_ext[0][0];
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
sss_ext2 = (int16_t*)&sss_ext[aarx][0];
|
||||
pss_ext2 = (int16_t*)&pss_ext[aarx][0];
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
int16_t *p = pss;
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" pss ref [%d] %d %d at address %p\n", i, p[2*i], p[2*i+1], &p[2*i]);
|
||||
printf(" pss ext [%d] %d %d at address %p\n", i, pss_ext2[2*i], pss_ext2[2*i+1], &pss_ext2[2*i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" sss ext 2 [%d] %d %d at address %p\n", i, sss_ext2[2*i], sss_ext2[2*i+1], &sss_ext2[2*i]);
|
||||
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i], &d_sss[0][0][i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
for (i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
|
||||
// This is H*(PSS) = R* \cdot PSS
|
||||
tmp_re = (int16_t)(((pss_ext2[i*2] * (int32_t)pss[i*2])>>SCALING_CE_PSS_NR) + ((pss_ext2[i*2+1] * (int32_t)pss[i*2+1])>>SCALING_CE_PSS_NR));
|
||||
tmp_im = (int16_t)(((pss_ext2[i*2] * (int32_t)pss[i*2+1])>>SCALING_CE_PSS_NR) - ((pss_ext2[i*2+1] * (int32_t)pss[i*2])>>SCALING_CE_PSS_NR));
|
||||
//printf("H*(%d,%d) : (%d,%d)\n",aarx,i,tmp_re,tmp_im);
|
||||
//printf("pss(%d,%d) : (%d,%d)\n",aarx,i,pss[2*i],pss[2*i+1]);
|
||||
//printf("pss_ext(%d,%d) : (%d,%d)\n",aarx,i,pss_ext2[2*i],pss_ext2[2*i+1]);
|
||||
|
||||
// This is R(SSS) \cdot H*(PSS)
|
||||
tmp_re2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2])>>SCALING_CE_PSS_NR) - ((tmp_im * (int32_t)sss_ext2[i*2+1]>>SCALING_CE_PSS_NR)));
|
||||
tmp_im2 = (int16_t)(((tmp_re * (int32_t)sss_ext2[i*2+1])>>SCALING_CE_PSS_NR) + ((tmp_im * (int32_t)sss_ext2[i*2]>>SCALING_CE_PSS_NR)));
|
||||
|
||||
// printf("SSSi(%d,%d) : (%d,%d)\n",aarx,i,sss_ext2[i<<1],sss_ext2[1+(i<<1)]);
|
||||
// printf("SSSo(%d,%d) : (%d,%d)\n",aarx,i,tmp_re2,tmp_im2);
|
||||
// MRC on RX antennas
|
||||
if (aarx==0) {
|
||||
sss_ext3[i<<1] = tmp_re2;
|
||||
sss_ext3[1+(i<<1)] = tmp_im2;
|
||||
} else {
|
||||
sss_ext3[i<<1] += tmp_re2;
|
||||
sss_ext3[1+(i<<1)] += tmp_im2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" sss ext 2 [%d] %d %d at address %p\n", i, sss_ext2[2*i], sss_ext2[2*i+1]);
|
||||
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i]);
|
||||
printf(" sss ext 3 [%d] %d %d at address %p\n", i, sss_ext3[2*i], sss_ext3[2*i+1]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// sss_ext now contains the compensated SSS
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : do_pss_sss_extract
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION : it allows extracting sss from samples buffer
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
|
||||
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
|
||||
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
|
||||
uint8_t doPss, uint8_t doSss,
|
||||
uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both
|
||||
{
|
||||
uint8_t aarx;
|
||||
int32_t *pss_rxF,*pss_rxF_ext;
|
||||
int32_t *sss_rxF,*sss_rxF_ext;
|
||||
uint8_t pss_symbol, sss_symbol;
|
||||
int32_t **rxdataF;
|
||||
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
|
||||
#if 1
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
pss_symbol = PSS_SYMBOL_NB; /* symbol position */
|
||||
sss_symbol = SSS_SYMBOL_NB;
|
||||
|
||||
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
|
||||
|
||||
unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
|
||||
|
||||
pss_rxF = &rxdataF[aarx][pss_symbol*ofdm_symbol_size];
|
||||
sss_rxF = &rxdataF[aarx][sss_symbol*ofdm_symbol_size];
|
||||
|
||||
pss_rxF_ext = &pss_ext[aarx][0];
|
||||
sss_rxF_ext = &sss_ext[aarx][0];
|
||||
|
||||
unsigned int k = ofdm_symbol_size - ((LENGTH_PSS_NR/2)+1);
|
||||
|
||||
for (int i=0; i < LENGTH_PSS_NR; i++) {
|
||||
if (doPss) {
|
||||
pss_rxF_ext[i] = pss_rxF[k];
|
||||
}
|
||||
|
||||
if (doSss) {
|
||||
sss_rxF_ext[i] = sss_rxF[k];
|
||||
}
|
||||
|
||||
k++;
|
||||
|
||||
if (k >= ofdm_symbol_size) {
|
||||
k++;
|
||||
k-=ofdm_symbol_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int16_t *p = (int16_t *)sss_rxF_ext;
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" sss ext 2 [%d] %d %d at address %p\n", i, p[2*i], p[2*i+1], &p[2*i]);
|
||||
printf(" sss ref [%d] %d %d at address %p\n", i, d_sss[0][0][i], d_sss[0][0][i], &d_sss[0][0][i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
int16_t *p2 = (int16_t *)pss_rxF_ext;
|
||||
|
||||
for (int i = 0; i < LENGTH_PSS_NR; i++) {
|
||||
printf(" pss_rxF_ext [%d] %d %d at address %p\n", i, p2[2*i], p2[2*i+1], &p2[2*i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* same method as LTE implementation */
|
||||
|
||||
uint16_t rb,nb_rb = N_RB_SS_PBCH_BLOCK;
|
||||
|
||||
int rx_offset = frame_parms->ofdm_symbol_size - (LENGTH_SSS_NR/2);
|
||||
|
||||
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
|
||||
pss_symbol = PSS_SYMBOL_NB;
|
||||
sss_symbol = SSS_SYMBOL_NB;
|
||||
|
||||
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
|
||||
pss_rxF = &rxdataF[aarx][(rx_offset + (pss_symbol*(frame_parms->ofdm_symbol_size)))];
|
||||
sss_rxF = &rxdataF[aarx][(rx_offset + (sss_symbol*(frame_parms->ofdm_symbol_size)))];
|
||||
|
||||
//printf("extract_rbs: symbol_mod=%d, rx_offset=%d, ch_offset=%d\n",symbol_mod,
|
||||
// (rx_offset + (symbol*(frame_parms->ofdm_symbol_size)))*2,
|
||||
// LTE_CE_OFFSET+ch_offset+(symbol_mod*(frame_parms->ofdm_symbol_size)));
|
||||
|
||||
pss_rxF_ext = &pss_ext[aarx][0];
|
||||
sss_rxF_ext = &sss_ext[aarx][0];
|
||||
|
||||
for (rb=0; rb<nb_rb; rb++) {
|
||||
|
||||
for (int i=0; i<N_SC_RB; i++) {
|
||||
if (doPss) {pss_rxF_ext[i] = pss_rxF[i];}
|
||||
if (doSss) {sss_rxF_ext[i] = sss_rxF[i];}
|
||||
}
|
||||
|
||||
pss_rxF += N_SC_RB;
|
||||
sss_rxF += N_SC_RB;
|
||||
pss_rxF_ext += N_SC_RB;
|
||||
sss_rxF_ext += N_SC_RB;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : rx_sss_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : none
|
||||
*
|
||||
* DESCRIPTION :
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
|
||||
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
|
||||
uint8_t subframe)
|
||||
{
|
||||
return do_pss_sss_extract_nr(phy_vars_ue, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* NAME : rx_sss_nr
|
||||
*
|
||||
* PARAMETERS : none
|
||||
*
|
||||
* RETURN : Set Nid_cell in ue context
|
||||
*
|
||||
* DESCRIPTION : Determine element Nid1 of cell identity
|
||||
* so Nid_cell in ue context is set according to Nid1 & Nid2
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max)
|
||||
{
|
||||
uint8_t i;
|
||||
int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
|
||||
int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR];
|
||||
uint8_t Nid2 = GET_NID2(ue->common_vars.eNb_id);
|
||||
uint16_t Nid1;
|
||||
uint8_t phase;
|
||||
int16_t *sss;
|
||||
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
|
||||
int32_t metric, metric_re;
|
||||
int16_t *d;
|
||||
|
||||
/* slop_fep function works for lte and takes into account begining of frame with prefix for subframe 0 */
|
||||
/* for NR this is not the case but slot_fep is still used for computing FFT of samples */
|
||||
/* in order to achieve correct processing for NR prefix samples is forced to 0 and then restored after function call */
|
||||
/* symbol number are from beginning of SS/PBCH blocks as below: */
|
||||
/* Signal PSS PBCH SSS PBCH */
|
||||
/* symbol number 0 1 2 3 */
|
||||
/* time samples in buffer rxdata are used as input of FFT -> FFT results are stored in the frequency buffer rxdataF */
|
||||
/* rxdataF stores SS/PBCH from beginning of buffers in the same symbol order as in time domain */
|
||||
|
||||
int nb_prefix_samples0 = frame_parms->nb_prefix_samples0;
|
||||
frame_parms->nb_prefix_samples0 = 0;
|
||||
|
||||
// Do FFTs for SSS/PSS
|
||||
// SSS
|
||||
slot_fep_pbch(ue,
|
||||
SSS_SYMBOL_NB, // symbol number
|
||||
0, // Ns slot number
|
||||
ue->rx_offset, // sample_offset of int16_t
|
||||
0, // no_prefix
|
||||
1); // reset frequency estimation
|
||||
|
||||
// PSS
|
||||
slot_fep_pbch(ue,
|
||||
PSS_SYMBOL_NB,
|
||||
0,
|
||||
ue->rx_offset,
|
||||
0,
|
||||
1);
|
||||
|
||||
frame_parms->nb_prefix_samples0 = nb_prefix_samples0;
|
||||
|
||||
// pss sss extraction
|
||||
pss_sss_extract_nr(ue,
|
||||
pss_ext,
|
||||
sss_ext,
|
||||
0); /* subframe */
|
||||
|
||||
#ifdef DEBUG_PLOT_SSS
|
||||
|
||||
write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_tti,1,1);
|
||||
write_output("rxdataF0.m","rxF0",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0],frame_parms->ofdm_symbol_size,2,1);
|
||||
write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
write_output("sss_ext.m","sss_ext",sss_ext,LENGTH_SSS_NR,1,1);
|
||||
write_output("sss_ref.m","sss_ref", d_sss,LENGTH_SSS_NR,1,1);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int16_t *p = (int16_t *)sss_ext[0];
|
||||
int16_t *p2 = (int16_t *)pss_ext[0];
|
||||
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
|
||||
printf("sss ext [%i] : %d %d \n", i, p[2*i], p[2*i+1]);
|
||||
|
||||
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr[0][2*i], primary_synchro_nr[0][2*i+1]);
|
||||
printf("pss ext [%i] : %d %d \n", i, p2[2*i], p2[2*i+1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// get conjugated channel estimate from PSS, H* = R* \cdot PSS
|
||||
// and do channel estimation and compensation based on PSS
|
||||
|
||||
pss_ch_est_nr(ue,
|
||||
pss_ext,
|
||||
sss_ext);
|
||||
|
||||
// now do the SSS detection based on the precomputed sequences in PHY/LTE_TRANSPORT/sss.h
|
||||
*tot_metric = INT_MIN;
|
||||
|
||||
sss = (int16_t*)&sss_ext[0][0];
|
||||
|
||||
#if 0
|
||||
|
||||
/* simulate of a phase shift on the signal */
|
||||
|
||||
int phase_shift_index = 0;
|
||||
|
||||
phase_shift_samples(sss, LENGTH_SSS_NR, phase_re_nr[phase_shift_index], phase_im_nr[phase_shift_index]);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int16_t *ps = (int16_t *)pss_ext;
|
||||
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
printf("sss ref [%i] : %d %d \n", i, d_sss[0][0][i], d_sss[0][0][i]);
|
||||
printf("sss ext [%i] : %d %d \n", i, sss[2*i], sss[2*i+1]);
|
||||
|
||||
printf("pss ref [%i] : %d %d \n", i, primary_synchro_nr[0][2*i], primary_synchro_nr[0][2*i+1]);
|
||||
printf("pss ext [%i] : %d %d \n", i, ps[2*i], ps[2*i+1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for phase evaluation, one uses an array of possible phase shifts */
|
||||
/* then a correlation is done between received signal with a shift pĥase and the reference signal */
|
||||
/* Computation of signal with shift phase is based on below formula */
|
||||
/* cosinus cos(x + y) = cos(x)cos(y) - sin(x)sin(y) */
|
||||
/* sinus sin(x + y) = sin(x)cos(y) + cos(x)sin(y) */
|
||||
|
||||
for (phase=0; phase < PHASE_HYPOTHESIS_NUMBER; phase++) { // phase offset between PSS and SSS
|
||||
for (Nid1 = 0 ; Nid1 < N_ID_1_NUMBER; Nid1++) { // all possible Nid1 values
|
||||
|
||||
metric = 0;
|
||||
metric_re = 0;
|
||||
|
||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||
|
||||
// This is the inner product using one particular value of each unknown parameter
|
||||
for (i=0; i < LENGTH_SSS_NR; i++) {
|
||||
|
||||
metric_re += d[i]*(((phase_re_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) - ((phase_im_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR))
|
||||
+ d[i]*(((phase_im_nr[phase]*sss[2*i])>>SCALING_METRIC_SSS_NR) + ((phase_re_nr[phase]*sss[2*i+1])>>SCALING_METRIC_SSS_NR));
|
||||
}
|
||||
|
||||
metric = metric_re;
|
||||
|
||||
// if the current metric is better than the last save it
|
||||
if (metric > *tot_metric) {
|
||||
*tot_metric = metric;
|
||||
ue->frame_parms.Nid_cell = Nid2+(3*Nid1);
|
||||
*phase_max = phase;
|
||||
|
||||
#ifdef DEBUG_SSS_NR
|
||||
|
||||
printf("(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",phase, Nid1, metric, *tot_metric, *phase_max);
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SSS_NR
|
||||
|
||||
#define SSS_METRIC_FLOOR_NR (30000)
|
||||
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
|
||||
Nid2 = GET_NID2(frame_parms->Nid_cell);
|
||||
Nid1 = GET_NID1(frame_parms->Nid_cell);
|
||||
printf("Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
|
||||
}
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
+1016
-5
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,7 @@
|
||||
#define __PHY_DEFS_NR_COMMON__H__
|
||||
|
||||
#include "defs_common.h"
|
||||
#include "impl_defs_nr.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
|
||||
#define nr_subframe_t lte_subframe_t
|
||||
@@ -73,6 +74,14 @@ typedef enum{
|
||||
} nr_ssb_type_e;
|
||||
|
||||
typedef struct NR_DL_FRAME_PARMS {
|
||||
/// Number of resource blocks (RB) in DL
|
||||
uint8_t N_RB_DL;
|
||||
/// Number of resource blocks (RB) in UL
|
||||
uint8_t N_RB_UL;
|
||||
/// total Number of Resource Block Groups: this is ceil(N_PRB/P)
|
||||
uint8_t N_RBG;
|
||||
/// Total Number of Resource Block Groups SubSets: this is P
|
||||
uint8_t N_RBGS;
|
||||
/// EUTRA Band
|
||||
uint8_t eutra_band;
|
||||
/// DL carrier frequency
|
||||
@@ -84,6 +93,13 @@ typedef struct NR_DL_FRAME_PARMS {
|
||||
/// RX attenuation
|
||||
uint32_t att_rx;
|
||||
/// total Number of Resource Block Groups: this is ceil(N_PRB/P)
|
||||
/// Frame type (0 FDD, 1 TDD)
|
||||
lte_frame_type_t frame_type;
|
||||
/// TDD subframe assignment (0-7) (default = 3) (254=RX only, 255=TX only)
|
||||
uint8_t tdd_config;
|
||||
/// TDD S-subframe configuration (0-9)
|
||||
/// Cell ID
|
||||
uint16_t Nid_cell;
|
||||
uint32_t subcarrier_spacing;
|
||||
/// 3/4 sampling
|
||||
uint8_t threequarter_fs;
|
||||
@@ -101,14 +117,45 @@ typedef struct NR_DL_FRAME_PARMS {
|
||||
uint16_t slots_per_subframe;
|
||||
/// Number of samples in a subframe
|
||||
uint32_t samples_per_subframe;
|
||||
/// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL)
|
||||
uint16_t symbols_per_tti;
|
||||
/// Number of samples in a radio frame
|
||||
uint32_t samples_per_frame;
|
||||
/// Number of samples in a subframe without CP
|
||||
uint32_t samples_per_subframe_wCP;
|
||||
/// Number of samples in a radio frame without CP
|
||||
uint32_t samples_per_frame_wCP;
|
||||
/// Number of samples in a tti (same as subrame in LTE, depending on numerology in NR)
|
||||
uint32_t samples_per_tti;
|
||||
/// NR numerology index [0..5] as specified in 38.211 Section 4 (mu). 0=15khZ SCS, 1=30khZ, 2=60kHz, etc
|
||||
uint8_t numerology_index;
|
||||
/// NR number of ttis per subframe deduced from numerology (cf 38.211): 1, 2, 4, 8(not supported),16(not supported),32(not supported)
|
||||
uint8_t ttis_per_subframe;
|
||||
/// NR number of slots per tti . Assumption only 2 Slot per TTI is supported (Slot Config 1 in 38.211)
|
||||
uint8_t slots_per_tti;
|
||||
//#endif
|
||||
/// Number of Physical transmit antennas in node
|
||||
uint8_t nb_antennas_tx;
|
||||
/// Number of Receive antennas in node
|
||||
uint8_t nb_antennas_rx;
|
||||
/// Number of common transmit antenna ports in eNodeB (1 or 2)
|
||||
uint8_t nb_antenna_ports_eNB;
|
||||
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
|
||||
lte_prefix_type_t Ncp;
|
||||
/// SRS configuration from TS 38.331 RRC
|
||||
SRS_NR srs_nr;
|
||||
|
||||
//SSB related params
|
||||
/// for NR TDD management
|
||||
TDD_UL_DL_configCommon_t *p_tdd_UL_DL_Configuration;
|
||||
|
||||
TDD_UL_DL_configCommon_t *p_tdd_UL_DL_ConfigurationCommon2;
|
||||
|
||||
TDD_UL_DL_SlotConfig_t *p_TDD_UL_DL_ConfigDedicated;
|
||||
|
||||
/// TDD configuration
|
||||
uint16_t tdd_uplink_nr[MAX_NR_OF_SLOTS]; /* this is a bitmap of symbol of each slot given for 2 frames */
|
||||
|
||||
//SSB related params
|
||||
/// Start in Subcarrier index of the SSB block
|
||||
uint16_t ssb_start_subcarrier;
|
||||
/// SSB type
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : impl_defs_nr.h
|
||||
*
|
||||
* MODULE :
|
||||
*
|
||||
* DESCRIPTION : NR Physical channel configuration and variable structure definitions
|
||||
* This is an interface between ue physical layer and RRC message from network
|
||||
* see TS 38.336 Radio Resource Control (RRC) protocol specification
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifndef PHY_IMPL_DEFS_NR_H
|
||||
#define PHY_IMPL_DEFS_NR_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#ifdef DEFINE_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
#define EXTERN
|
||||
#define INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#undef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
#endif
|
||||
|
||||
#ifdef PHY_DBG_DEV_TST
|
||||
#define PHY_DBG_DEV_TST_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PHY_DBG_DEV_TST_PRINTF(...)
|
||||
#endif
|
||||
|
||||
/* to set for UE capabilities */
|
||||
#define MAX_NR_OF_SRS_RESOURCE_SET (1)
|
||||
#define MAX_NR_OF_SRS_RESOURCES_PER_SET (1)
|
||||
|
||||
#define NR_NUMBER_OF_SUBFRAMES_PER_FRAME (10)
|
||||
#define MAX_NROFSRS_PORTS (4)
|
||||
|
||||
/* TS 38.211 Table 4.3.2-1: Number of OFDM symbols per slot, slots per frame, and slots per subframe for normal cyclic prefix */
|
||||
#define MU_NUMBER (5)
|
||||
EXTERN const uint8_t N_slot_subframe[MU_NUMBER]
|
||||
#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
= { 1, 2, 4, 8, 16}
|
||||
#endif
|
||||
;
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FUNCTIONALITY : Time Division Duplex
|
||||
*
|
||||
* DESCRIPTION : interface for FDD/TDD configuration
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#define MAX_NR_OF_SLOTS (320) /* maximum number of slots for tdd configuration which is periodic */
|
||||
|
||||
#define NR_TDD_DOWNLINK_SLOT (0x0000)
|
||||
#define NR_TDD_UPLINK_SLOT (0x3FFF) /* uplink bitmap for each symbol, there are 14 symbols per slots */
|
||||
#define NR_TDD_SET_ALL_SYMBOLS (0x3FFF)
|
||||
|
||||
#define FRAME_DURATION_MICRO_SEC (10000) /* frame duration in microsecond */
|
||||
|
||||
typedef enum {
|
||||
SLOT_DL = 0,
|
||||
SLOT_UL = 1,
|
||||
} nr_slot_t;
|
||||
|
||||
typedef enum {
|
||||
ms0p5 = 500, /* duration is given in microsecond */
|
||||
ms0p625 = 625,
|
||||
ms1 = 1000,
|
||||
ms1p25 = 1250,
|
||||
ms2 = 2000,
|
||||
ms2p5 = 2500,
|
||||
ms5 = 5000,
|
||||
ms10 = 10000,
|
||||
} dl_UL_TransmissionPeriodicity_t;
|
||||
|
||||
typedef struct {
|
||||
/// Reference SCS used to determine the time domain boundaries in the UL-DL pattern which must be common across all subcarrier specific
|
||||
/// virtual carriers, i.e., independent of the actual subcarrier spacing using for data transmission.
|
||||
/// Only the values 15 or 30 kHz (<6GHz), 60 or 120 kHz (>6GHz) are applicable.
|
||||
/// Corresponds to L1 parameter 'reference-SCS' (see 38.211, section FFS_Section)
|
||||
/// \ subcarrier spacing
|
||||
uint8_t referenceSubcarrierSpacing;
|
||||
/// \ Periodicity of the DL-UL pattern. Corresponds to L1 parameter 'DL-UL-transmission-periodicity' (see 38.211, section FFS_Section)
|
||||
dl_UL_TransmissionPeriodicity_t dl_UL_TransmissionPeriodicity;
|
||||
/// \ Number of consecutive full DL slots at the beginning of each DL-UL pattern.
|
||||
/// Corresponds to L1 parameter 'number-of-DL-slots' (see 38.211, Table 4.3.2-1)
|
||||
uint8_t nrofDownlinkSlots;
|
||||
/// \ Number of consecutive DL symbols in the beginning of the slot following the last full DL slot (as derived from nrofDownlinkSlots).
|
||||
/// If the field is absent or released, there is no partial-downlink slot.
|
||||
/// Corresponds to L1 parameter 'number-of-DL-symbols-common' (see 38.211, section FFS_Section).
|
||||
uint8_t nrofDownlinkSymbols;
|
||||
/// \ Number of consecutive full UL slots at the end of each DL-UL pattern.
|
||||
/// Corresponds to L1 parameter 'number-of-UL-slots' (see 38.211, Table 4.3.2-1)
|
||||
uint8_t nrofUplinkSlots;
|
||||
/// \ Number of consecutive UL symbols in the end of the slot preceding the first full UL slot (as derived from nrofUplinkSlots).
|
||||
/// If the field is absent or released, there is no partial-uplink slot.
|
||||
/// Corresponds to L1 parameter 'number-of-UL-symbols-common' (see 38.211, section FFS_Section)
|
||||
uint8_t nrofUplinkSymbols;
|
||||
/// \ for setting a sequence
|
||||
struct TDD_UL_DL_configCommon_t *p_next_TDD_UL_DL_configCommon_t;
|
||||
} TDD_UL_DL_configCommon_t;
|
||||
|
||||
typedef struct {
|
||||
/// \ Identifies a slot within a dl-UL-TransmissionPeriodicity (given in tdd-UL-DL-configurationCommon)
|
||||
uint16_t slotIndex;
|
||||
/// \ The direction (downlink or uplink) for the symbols in this slot. "allDownlink" indicates that all symbols in this slot are used
|
||||
/// for downlink; "allUplink" indicates that all symbols in this slot are used for uplink; "explicit" indicates explicitly how many symbols
|
||||
/// in the beginning and end of this slot are allocated to downlink and uplink, respectively.
|
||||
/// Number of consecutive DL symbols in the beginning of the slot identified by slotIndex.
|
||||
/// If the field is absent the UE assumes that there are no leading DL symbols.
|
||||
/// Corresponds to L1 parameter 'number-of-DL-symbols-dedicated' (see 38.211, section FFS_Section)
|
||||
uint16_t nrofDownlinkSymbols;
|
||||
/// Number of consecutive UL symbols in the end of the slot identified by slotIndex.
|
||||
/// If the field is absent the UE assumes that there are no trailing UL symbols.
|
||||
/// Corresponds to L1 parameter 'number-of-UL-symbols-dedicated' (see 38.211, section FFS_Section)
|
||||
uint16_t nrofUplinkSymbols;
|
||||
/// \ for setting a sequence
|
||||
struct TDD_UL_DL_SlotConfig_t *p_next_TDD_UL_DL_SlotConfig;
|
||||
} TDD_UL_DL_SlotConfig_t;
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FUNCTIONALITY : Sounding Reference Signal
|
||||
*
|
||||
* DESCRIPTION : interface description for managing uplink SRS signals from UE
|
||||
* SRS are generated by UE and transmit to network
|
||||
* depending on configuration
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
EXTERN const int16_t SRS_antenna_port[MAX_NROFSRS_PORTS]
|
||||
#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
= { 1000, 1001, 1002, 1003 }
|
||||
#endif
|
||||
;
|
||||
|
||||
typedef enum {
|
||||
port1 = 1,
|
||||
port2 = 2,
|
||||
port4 = 4
|
||||
} nrof_Srs_Ports_t;
|
||||
|
||||
typedef enum {
|
||||
neitherHopping = 0,
|
||||
groupHopping = 1,
|
||||
sequenceHopping = 2
|
||||
} groupOrSequenceHopping_t;
|
||||
|
||||
typedef enum {
|
||||
aperiodic = 0,
|
||||
semi_persistent = 1,
|
||||
periodic = 2
|
||||
} resourceType_t;
|
||||
|
||||
typedef enum {
|
||||
sl1 = 0,
|
||||
sl2 = 1,
|
||||
sl4 = 2,
|
||||
sl5 = 3,
|
||||
sl8 = 4,
|
||||
sl10 = 5,
|
||||
sl16 = 6,
|
||||
sl20 = 7,
|
||||
sl32 = 8,
|
||||
sl40 = 9,
|
||||
sl64 = 10,
|
||||
sl80 = 11,
|
||||
sl160 = 12,
|
||||
sl320 = 13,
|
||||
sl640 = 14,
|
||||
sl1280 = 15,
|
||||
sl2560 = 16
|
||||
} SRS_Periodicity_t;
|
||||
|
||||
#define NB_SRS_PERIOD (17)
|
||||
|
||||
const uint16_t srs_period[NB_SRS_PERIOD]
|
||||
#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
= { 1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}
|
||||
#endif
|
||||
;
|
||||
|
||||
/// SRS_Resource of SRS_Config information element from 38.331 RRC specifications
|
||||
typedef struct {
|
||||
/// \brief srs resource identity.
|
||||
uint8_t srs_ResourceId;
|
||||
/// \brief number of srs ports.
|
||||
nrof_Srs_Ports_t nrof_SrsPorts;
|
||||
/// \brief index of prts port index.
|
||||
uint8_t ptrs_PortIndex;
|
||||
/// \brief srs transmission comb see parameter SRS-TransmissionComb 38.214 section &6.2.1.
|
||||
uint8_t transmissionComb;
|
||||
/// \brief comb offset.
|
||||
uint8_t combOffset;
|
||||
/// \brief cyclic shift configuration - see parameter SRS-CyclicShiftConfig 38.214 &6.2.1.
|
||||
uint8_t cyclicShift;
|
||||
/// \brief OFDM symbol location of the SRS resource within a slot.
|
||||
// Corresponds to L1 parameter 'SRS-ResourceMapping' (see 38.214, section 6.2.1 and 38.211, section 6.4.1.4).
|
||||
// startPosition (SRSSymbolStartPosition = 0..5; "0" refers to the last symbol, "1" refers to the second last symbol.
|
||||
uint8_t resourceMapping_startPosition;
|
||||
/// \brief number of OFDM symbols (N = 1, 2 or 4 per SRS resource).
|
||||
uint8_t resourceMapping_nrofSymbols;
|
||||
/// \brief RepetitionFactor (r = 1, 2 or 4).
|
||||
uint8_t resourceMapping_repetitionFactor;
|
||||
/// \brief Parameter(s) defining frequency domain position and configurable shift to align SRS allocation to 4 PRB grid.
|
||||
// Corresponds to L1 parameter 'SRS-FreqDomainPosition' (see 38.214, section 6.2.1)
|
||||
uint8_t freqDomainPosition; // INTEGER (0..67),
|
||||
uint16_t freqDomainShift; // INTEGER (0..268),
|
||||
/// \brief Includes parameters capturing SRS frequency hopping
|
||||
// Corresponds to L1 parameter 'SRS-FreqHopping' (see 38.214, section 6.2.1)
|
||||
uint8_t freqHopping_c_SRS; // INTEGER (0..63),
|
||||
uint8_t freqHopping_b_SRS; // INTEGER (0..3),
|
||||
uint8_t freqHopping_b_hop; // INTEGER (0..3)
|
||||
// Parameter(s) for configuring group or sequence hopping
|
||||
// Corresponds to L1 parameter 'SRS-GroupSequenceHopping' see 38.211
|
||||
groupOrSequenceHopping_t groupOrSequenceHopping;
|
||||
/// \brief Time domain behavior of SRS resource configuration.
|
||||
// Corresponds to L1 parameter 'SRS-ResourceConfigType' (see 38.214, section 6.2.1).
|
||||
// For codebook based uplink transmission, the network configures SRS resources in the same resource set with the same
|
||||
// time domain behavior on periodic, aperiodic and semi-persistent SRS
|
||||
SRS_Periodicity_t SRS_Periodicity;
|
||||
uint16_t SRS_Offset;
|
||||
/// \brief Sequence ID used to initialize psedo random group and sequence hopping.
|
||||
// Corresponds to L1 parameter 'SRS-SequenceId' (see 38.214, section 6.2.1).
|
||||
uint16_t sequenceId; // BIT STRING (SIZE (10))
|
||||
/// \brief Configuration of the spatial relation between a reference RS and the target SRS. Reference RS can be SSB/CSI-RS/SRS.
|
||||
// Corresponds to L1 parameter 'SRS-SpatialRelationInfo' (see 38.214, section 6.2.1)
|
||||
uint8_t spatialRelationInfo_ssb_Index; // SSB-Index,
|
||||
uint8_t spatialRelationInfo_csi_RS_Index; // NZP-CSI-RS-ResourceId,
|
||||
uint8_t spatialRelationInfo_srs_Id; // SRS-ResourceId
|
||||
} SRS_Resource_t;
|
||||
|
||||
typedef enum {
|
||||
beamManagement = 0,
|
||||
codebook = 1,
|
||||
nonCodebook = 2,
|
||||
antennaSwitching = 3,
|
||||
} SRS_resourceSet_usage_t;
|
||||
|
||||
typedef enum {
|
||||
sameAsFci2 = 0,
|
||||
separateClosedLoop = 1
|
||||
} srs_PowerControlAdjustmentStates_t;
|
||||
|
||||
typedef enum {
|
||||
ssb_Index = 0,
|
||||
csi_RS_Index = 1,
|
||||
} pathlossReferenceRS_t;
|
||||
|
||||
// SRS_Config information element from 38.331 RRC specifications from 38.331 RRC specifications.
|
||||
typedef struct {
|
||||
/// \brief The ID of this resource set. It is unique in the context of the BWP in which the parent SRS-Config is defined.
|
||||
uint8_t srs_ResourceSetId;
|
||||
/// \brief number of resources in the resource set
|
||||
uint8_t number_srs_Resource;
|
||||
/// \brief The IDs of the SRS-Resources used in this SRS-ResourceSet.
|
||||
/// in fact this is an array of pointers to resource structures
|
||||
SRS_Resource_t *p_srs_ResourceList[MAX_NR_OF_SRS_RESOURCES_PER_SET];
|
||||
resourceType_t resourceType;
|
||||
/// \brief The DCI "code point" upon which the UE shall transmit SRS according to this SRS resource set configuration.
|
||||
// Corresponds to L1 parameter 'AperiodicSRS-ResourceTrigger' (see 38.214, section 6.1.1.2)
|
||||
uint8_t aperiodicSRS_ResourceTrigger; // INTEGER (0..maxNrofSRS-TriggerStates-1) : [0:3]
|
||||
/// \brief ID of CSI-RS resource associated with this SRS resource set. (see 38.214, section 6.1.1.2).
|
||||
uint8_t NZP_CSI_RS_ResourceId;
|
||||
/// \brief An offset in number of slots between the triggering DCI and the actual transmission of this SRS-ResourceSet.
|
||||
// If the field is absent the UE applies no offset (value 0)
|
||||
uint8_t aperiodic_slotOffset; // INTEGER (1..8)
|
||||
/// \brief Indicates if the SRS resource set is used for beam management vs. used for either codebook based or non-codebook based transmission.
|
||||
// Corresponds to L1 parameter 'SRS-SetUse' (see 38.214, section 6.2.1)
|
||||
// FFS_CHECK: Isn't codebook/noncodebook already known from the ulTxConfig in the SRS-Config? If so, isn't the only distinction
|
||||
// in the set between BeamManagement, AtennaSwitching and "Other”? Or what happens if SRS-Config=Codebook but a Set=NonCodebook?
|
||||
SRS_resourceSet_usage_t usage;
|
||||
/// \brief alpha value for SRS power control. Corresponds to L1 parameter 'alpha-srs' (see 38.213, section 7.3).
|
||||
// When the field is absent the UE applies the value 1
|
||||
uint8_t alpha;
|
||||
/// \brief P0 value for SRS power control. The value is in dBm. Only even values (step size 2) are allowed.
|
||||
// Corresponds to L1 parameter 'p0-srs' (see 38.213, section 7.3)
|
||||
int8_t p0; // INTEGER (-202..24)
|
||||
/// \brief A reference signal (e.g. a CSI-RS config or a SSblock) to be used for SRS path loss estimation.
|
||||
/// Corresponds to L1 parameter 'srs-pathlossReference-rs-config' (see 38.213, section 7.3)
|
||||
pathlossReferenceRS_t pathlossReferenceRS_t;
|
||||
uint8_t path_loss_SSB_Index;
|
||||
uint8_t path_loss_NZP_CSI_RS_ResourceId;
|
||||
/// \brief Indicates whether hsrs,c(i) = fc(i,1) or hsrs,c(i) = fc(i,2) (if twoPUSCH-PC-AdjustmentStates are configured)
|
||||
/// or separate close loop is configured for SRS. This parameter is applicable only for Uls on which UE also transmits PUSCH.
|
||||
/// If absent or release, the UE applies the value sameAs-Fci1
|
||||
/// Corresponds to L1 parameter 'srs-pcadjustment-state-config' (see 38.213, section 7.3)
|
||||
srs_PowerControlAdjustmentStates_t srs_PowerControlAdjustmentStates;
|
||||
} SRS_ResourceSet_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t active_srs_Resource_Set; /* ue implementation specific */
|
||||
uint8_t number_srs_Resource_Set; /* ue implementation specific */
|
||||
SRS_ResourceSet_t *p_SRS_ResourceSetList[MAX_NR_OF_SRS_RESOURCE_SET]; /* ue implementation specific */
|
||||
} SRS_NR;
|
||||
|
||||
//#define RX_NB_TH_MAX 3
|
||||
//#define RX_NB_TH 3
|
||||
|
||||
#define LTE_SLOTS_PER_SUBFRAME 2
|
||||
|
||||
#define LTE_NUMBER_OF_SUBFRAMES_PER_FRAME 10
|
||||
#define LTE_SLOTS_PER_FRAME 20
|
||||
#define LTE_CE_FILTER_LENGTH 5
|
||||
#define LTE_CE_OFFSET LTE_CE_FILTER_LENGTH
|
||||
#define TX_RX_SWITCH_SYMBOL (NUMBER_OF_SYMBOLS_PER_FRAME>>1)
|
||||
#define PBCH_PDU_SIZE 3 //bytes
|
||||
|
||||
#define PRACH_SYMBOL 3 //position of the UL PSS wrt 2nd slot of special subframe
|
||||
|
||||
#define NUMBER_OF_FREQUENCY_GROUPS (lte_frame_parms->N_RB_DL)
|
||||
|
||||
#define SSS_AMP 1148
|
||||
|
||||
#define MAX_NUM_PHICH_GROUPS 56 //110 RBs Ng=2, p.60 36-212, Sec. 6.9
|
||||
|
||||
#define MAX_MBSFN_AREA 8
|
||||
|
||||
#undef EXTERN
|
||||
#undef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
|
||||
#endif /* PHY_IMPL_DEFS_NR_H */
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 __PHY_EXTERN_UE__H__
|
||||
#define __PHY_EXTERN_UE__H__
|
||||
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "common/ran_context.h"
|
||||
|
||||
extern char* namepointer_chMag ;
|
||||
extern char* namepointer_log2;
|
||||
extern char fmageren_name2[512];
|
||||
|
||||
extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX];
|
||||
extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
|
||||
|
||||
#include "PHY/LTE_TRANSPORT/transport_extern.h"
|
||||
|
||||
extern int number_of_cards;
|
||||
|
||||
|
||||
#ifndef OCP_FRAMEWORK
|
||||
extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
|
||||
extern NR_DL_FRAME_PARMS *lte_frame_parms_g;
|
||||
#else
|
||||
#define MAX_UE 10
|
||||
#define MAX_eNB 20
|
||||
|
||||
extern PHY_VARS_NR_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs];
|
||||
#endif
|
||||
|
||||
extern short primary_synch0[144];
|
||||
extern short primary_synch1[144];
|
||||
extern short primary_synch2[144];
|
||||
extern unsigned char primary_synch0_tab[72];
|
||||
extern unsigned char primary_synch1_tab[72];
|
||||
extern unsigned char primary_synch2_tab[72];
|
||||
extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
|
||||
extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
|
||||
extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
|
||||
extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
|
||||
extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
|
||||
extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
|
||||
|
||||
extern int flagMag;
|
||||
//extern short **txdataF_rep_tmp;
|
||||
|
||||
extern char mode_string[4][20];
|
||||
|
||||
extern unsigned char NB_RU;
|
||||
|
||||
#ifndef OPENAIR2
|
||||
extern unsigned char NB_eNB_INST;
|
||||
extern unsigned char NB_UE_INST;
|
||||
extern unsigned char NB_RN_INST;
|
||||
#endif
|
||||
|
||||
extern unsigned int ULSCH_max_consecutive_errors;
|
||||
extern int flag_LA;
|
||||
extern double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
|
||||
extern double sinr_bler_map_up[MCS_COUNT][2][16];
|
||||
extern int table_length[MCS_COUNT];
|
||||
extern double sinr_to_cqi[4][16];
|
||||
extern int cqi_to_mcs[16];
|
||||
|
||||
//for MU-MIMO abstraction using MIESM
|
||||
//this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
|
||||
extern double MI_map_4qam[3][162];
|
||||
extern double MI_map_16qam[3][197];
|
||||
extern double MI_map_64qam[3][227];
|
||||
|
||||
extern double beta1_dlsch_MI[6][MCS_COUNT];
|
||||
extern double beta2_dlsch_MI[6][MCS_COUNT];
|
||||
|
||||
extern double q_qpsk[8];
|
||||
extern double q_qam16[8];
|
||||
extern double q_qam64[8];
|
||||
|
||||
extern double p_qpsk[8];
|
||||
extern double p_qam16[8];
|
||||
extern double p_qam64[8];
|
||||
|
||||
extern double beta1_dlsch[6][MCS_COUNT];
|
||||
extern double beta2_dlsch[6][MCS_COUNT];
|
||||
|
||||
extern char eNB_functions[6][20];
|
||||
extern char eNB_timing[2][20];
|
||||
extern char ru_if_types[MAX_RU_IF_TYPES][20];
|
||||
|
||||
extern int16_t unscrambling_lut[65536*16];
|
||||
extern uint8_t scrambling_lut[65536*16];
|
||||
|
||||
extern unsigned short msrsb_6_40[8][4];
|
||||
extern unsigned short msrsb_41_60[8][4];
|
||||
extern unsigned short msrsb_61_80[8][4];
|
||||
extern unsigned short msrsb_81_110[8][4];
|
||||
extern unsigned short Nb_6_40[8][4];
|
||||
extern unsigned short Nb_41_60[8][4];
|
||||
extern unsigned short Nb_61_80[8][4];
|
||||
extern unsigned short Nb_81_110[8][4];
|
||||
|
||||
extern uint16_t hundred_times_log10_NPRB[100];
|
||||
extern uint8_t alpha_lut[8];
|
||||
extern uint8_t max_turbo_iterations;
|
||||
#endif /*__PHY_EXTERN_H__ */
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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 __PHY_VARS_NR_H__
|
||||
#define __PHY_VARS_NR_H__
|
||||
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/phy_vars_nr_ue.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
|
||||
char* namepointer_chMag ;
|
||||
char fmageren_name2[512];
|
||||
char* namepointer_log2;
|
||||
|
||||
|
||||
#include "PHY/LTE_REFSIG/primary_synch.h"
|
||||
int16_t *primary_synch0_time;
|
||||
int16_t *primary_synch1_time;
|
||||
int16_t *primary_synch2_time;
|
||||
|
||||
|
||||
#include "PHY/CODING/coding_vars.h"
|
||||
|
||||
//PHY_VARS *PHY_vars;
|
||||
#ifndef OCP_FRAMEWORK
|
||||
PHY_VARS_NR_UE ***PHY_vars_UE_g;
|
||||
LTE_DL_FRAME_PARMS *lte_frame_parms_g;
|
||||
#else
|
||||
PHY_VARS_NR_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]={NULL};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
unsigned short rev[2048],rev_times4[8192],rev_half[1024];
|
||||
unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
|
||||
|
||||
|
||||
char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
|
||||
|
||||
|
||||
|
||||
#include "SIMULATION/ETH_TRANSPORT/vars.h"
|
||||
|
||||
unsigned char NB_RU=0;
|
||||
|
||||
#ifndef OPENAIR2
|
||||
unsigned char NB_eNB_INST=0;
|
||||
unsigned char NB_UE_INST=0;
|
||||
unsigned char NB_RN_INST=0;
|
||||
unsigned char NB_INST=0;
|
||||
#endif
|
||||
|
||||
unsigned int ULSCH_max_consecutive_errors = 20;
|
||||
|
||||
int number_of_cards;
|
||||
|
||||
|
||||
int flag_LA=0;
|
||||
int flagMag;
|
||||
//extern channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
|
||||
//extern double ABS_SINR_eff_BLER_table[MCS_COUNT][9][9];
|
||||
//extern double ABS_beta[MCS_COUNT];odi
|
||||
double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
|
||||
int table_length[MCS_COUNT];
|
||||
//double sinr_bler_map_up[MCS_COUNT][2][16];
|
||||
|
||||
//for MU-MIMO abstraction using MIESM
|
||||
//this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
|
||||
double MI_map_4qam[3][162];
|
||||
double MI_map_16qam[3][197];
|
||||
double MI_map_64qam[3][227];
|
||||
|
||||
// here the first index is for transmission mode 1, 2, 5 and 6 whereas the second index is for the 16 sinr vaues corresponding to 16 CQIs
|
||||
double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281, 17.2424, 17.2424, 17.2424},
|
||||
{-2.2360, -2.2360, -1.3919, -0.0218, 1.5319, 2.9574, 4.3234, 6.3387, 8.9879, 9.5096, 12.6609, 14.0116, 16.4984, 18.1572, 18.1572, 18.1572},
|
||||
{-1, -1.0000, -0.4198, -0.0140, 1.0362, 2.3520, 3.5793, 6.1136, 8.4836, 9.0858, 12.4723, 13.9128, 16.2054, 17.7392, 17.7392, 17.7392},
|
||||
{ -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
|
||||
};
|
||||
|
||||
//int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
|
||||
int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
|
||||
|
||||
//for SNR to MI conversion 7 th order Polynomial coeff
|
||||
double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
|
||||
double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
|
||||
double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
|
||||
|
||||
//for MI to SNR conversion 7 th order Polynomial coeff
|
||||
double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
|
||||
double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
|
||||
double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
|
||||
|
||||
// ideal CE MIESM
|
||||
|
||||
double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
|
||||
double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
|
||||
|
||||
//real CE MIESM
|
||||
/*
|
||||
double beta1_dlsch_MI[6][MCS_COUNT] = { {1.32955, 0.59522, 0.54024, 0.98698, 0.81305, 0.76976, 0.69258, 0.69713, 0.70546, 0.69111, 0.81904, 0.72664, 0.79491, 0.72562, 0.53980, 0.33134, 0.50550, 0.40602,0.40281,0.47012,0.50510,0.23540,0.32045,1}, {0.59632, 1.08475, 1.02431, 1.07020, 0.90170, 0.97719, 0.95464, 0.92764, 0.86721, 0.85986, 0.64558, 0.80631, 0.82673, 0.82888, 0.87122, 0.77245, 0.29771, 0.43477, 0.55321, 0.61027, 0.56111, 0.57292, 0.39737,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.77532, 1.07544, 1.10571, 1.04099, 0.91638, 0.88644, 0.96405, 0.86709, 0.94066, 0.84430, 1.24478, 1.09665, 1.42604, 0.79541, 0.71847, 0.71604, 0.74561, 0.36431, 0.41536, 0.52175, 0.47096, 0.49977, 0.59728,1}};
|
||||
double beta2_dlsch_MI[6][MCS_COUNT] = { {1.36875, 0.59304, 0.53870, 0.98239, 0.81637, 0.76847, 0.69842, 0.69885, 0.69967, 0.69826, 0.82660, 0.70559, 0.78404, 0.70670, 0.55393, 0.36893, 0.52225, 0.39752, 0.40494, 0.46239, 0.49247,0.26900,0.34504,1}, {0.43775, 0.78208, 0.72875, 0.77458, 0.64485, 0.69174, 0.66097, 0.63289, 0.59652, 0.61175, 0.44551, 0.56047, 0.57314, 0.57553, 0.58849, 0.52159, 0.21241, 0.30139, 0.37373, 0.32029, 0.37067, 0.36706, 0.27118,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.54448, 0.73731, 0.79165, 0.74407, 0.68042, 0.64906, 0.71349, 0.62109, 0.65815, 0.60940, 0.90549, 0.78708, 1.03176, 0.58431, 0.53379, 0.51224, 0.52767, 0.26848, 0.29642, 0.36879, 0.34148, 0.35279,0.40633,1}};
|
||||
*/
|
||||
//ideal channel estimation values
|
||||
//double beta1_dlsch[6][MCS_COUNT] = { {2.3814, 0.4956, 0.5273, 1.1708, 0.8014, 0.7889, 0.8111, 0.8139, 0.8124, 0.8479, 1.9280, 1.9664, 2.3857, 2.5147, 2.4511, 3.0158, 2.8643, 5.3013, 5.8594, 6.5372, 7.8073, 7.8030, 7.5295, 7.1320}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
|
||||
//double beta2_dlsch[6][MCS_COUNT] = { {2.3639, 0.4952, 0.5207, 1.1572, 0.8026, 0.7864, 0.7996, 0.8034, 0.8200, 0.8367, 1.8701, 1.9212, 2.2947, 2.4472, 2.4091, 2.9479, 2.8973, 5.0591, 5.5134, 6.1483, 7.2166, 7.5177, 7.5704, 7.2248}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
|
||||
double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
|
||||
double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
|
||||
|
||||
//real channel estimation valus
|
||||
/*
|
||||
double beta1_dlsch[6][MCS_COUNT] = { {2.50200, 0.84047, 0.78195, 1.37929, 1.16871, 1.11906, 1.06303, 1.07447, 1.11403, 1.09223, 2.82502, 2.87556, 3.51254, 3.62920, 3.53638, 2.35980, 3.74126, 8.66532, 7.31772, 9.86882, 10.64939, 6.75208, 9.50664, 13.63057}, {0.92257, 1, 1.80445, 1.43175, 1.42093, 1.37381, 1.45392, 1.47255, 1.47451, 1.41235, 3.9079, 3.38557, 4.13059, 4.93355, 4.97277, 6.04951, 5.88896, 8.68076, 10.23746, 12.37069, 5.50538, 17.29612, 17.95050, 13.27095}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79255, 1.88213, 4.44226, 2.25150, 1.93710, 2.18504, 2.57389, 1.94322, 1.78515, 2.09265, 2.37459, 1.74442, 1.74346, 1.19705, 1.56149, 1.59604, 1.6, 1,1,1,1,1,1,1}, {0.93374, 1.40389, 1.36670, 1.38679, 1.35707, 1.26353, 1.32360, 1.40164, 1.51843, 1.34863, 3.45839, 3.13726, 3.94768, 4.21966, 4.60750, 4.97894, 5.40755, 8.12814, 10.59221, 12.96427, 13.37323, 14.27206, 16.61779, 17.19656}};
|
||||
double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.16829, 1.11186, 1.06287, 1.07292, 1.09946, 1.10650, 2.79174, 2.75655, 3.36651, 3.49011, 3.60903, 2.73517, 3.84009, 8.20312, 7.41739, 9.64081, 10.40911, 8.11765, 10.41923, 9.34300}, {0.67252, 0.8600, 1.28633, 1.01624, 1.03066, 0.97590, 1.02560, 1.01840, 1.00547, 0.97093, 2.72573, 2.33283, 2.86181, 3.40452, 3.47957, 4.08916, 3.97628, 6.14541, 7.11017, 8.42369, 4.04812, 11.42082, 11.57171, 9.28462}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.85784, 0.90361, 2.09766, 1.08385, 0.96300, 1.04432, 1.22763, 0.99249, 0.95544, 1.12333, 1.37924, 1.12913, 1.30644, 1.19253, 1.75488, 2.13813, 2.10636, 1,1,1,1,1,1,1}, {0.66288, 0.96402, 0.98545, 0.99386, 0.99981, 0.92678, 0.98978, 0.99600, 1.05538, 0.97777, 2.52504, 2.29338, 2.89631, 3.10812, 3.41916, 3.58671, 3.84166, 6.05254, 7.45821, 9.15812, 9.66330, 10.17852, 11.50519, 11.16299}};
|
||||
|
||||
*/
|
||||
|
||||
#ifdef OCP_FRAMEWORK
|
||||
#include <enums.h>
|
||||
#else
|
||||
char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",};
|
||||
char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
|
||||
char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"};
|
||||
#endif
|
||||
|
||||
/// lookup table for unscrambling in RX
|
||||
int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
|
||||
/// lookup table for scrambling in TX
|
||||
uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
|
||||
|
||||
uint8_t max_turbo_iterations=4;
|
||||
#endif /*__PHY_VARS_H__ */
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* FILENAME : phy_frame_configuration_nr.h
|
||||
*
|
||||
* DESCRIPTION : functions related to FDD/TDD configuration for NR
|
||||
* see TS 38.213 11.1 Slot configuration
|
||||
* and TS 38.331 for RRC configuration
|
||||
*
|
||||
************************************************************************/
|
||||
|
||||
#ifndef PHY_FRAME_CONFIG_NR_H
|
||||
#define PHY_FRAME_CONFIG_NR_H
|
||||
|
||||
/************** DEFINE ********************************************/
|
||||
|
||||
#define TDD_CONFIG_NB_FRAMES (2)
|
||||
|
||||
/*************** FUNCTIONS *****************************************/
|
||||
|
||||
/** \brief This function processes tdd dedicated configuration for nr
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
* @param dl_UL_TransmissionPeriodicity periodicity
|
||||
* @param nrofDownlinkSlots number of downlink slots
|
||||
* @param nrofDownlinkSymbols number of downlink symbols
|
||||
* @param nrofUplinkSlots number of uplink slots
|
||||
* @param nrofUplinkSymbols number of uplink symbols
|
||||
@returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */
|
||||
|
||||
int set_tdd_config_nr(NR_DL_FRAME_PARMS *frame_parms, int dl_UL_TransmissionPeriodicity,
|
||||
int nrofDownlinkSlots, int nrofDownlinkSymbols,
|
||||
int nrofUplinkSlots, int nrofUplinkSymbols);
|
||||
|
||||
/** \brief This function adds a slot configuration to current dedicated configuration for nr
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
* @param slotIndex
|
||||
* @param nrofDownlinkSymbols
|
||||
* @param nrofUplinkSymbols
|
||||
@returns none */
|
||||
|
||||
void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slotIndex,
|
||||
int nrofDownlinkSymbols, int nrofUplinkSymbols);
|
||||
|
||||
/** \brief This function processes tdd dedicated configuration for nr
|
||||
* @param frame_parms nr frame parameters
|
||||
* @param dl_UL_TransmissionPeriodicity periodicity
|
||||
* @param nrofDownlinkSlots number of downlink slots
|
||||
* @param nrofDownlinkSymbols number of downlink symbols
|
||||
* @param nrofUplinkSlots number of uplink slots
|
||||
* @param nrofUplinkSymbols number of uplink symbols
|
||||
@returns 0 if tdd dedicated configuration has been properly set or -1 on error with message */
|
||||
|
||||
int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/** \brief This function checks nr slot direction : downlink or uplink
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
* @param nr_frame : frame number
|
||||
* @param nr_tti : slot number
|
||||
@returns nr_slot_t : downlink or uplink */
|
||||
|
||||
nr_slot_t slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti);
|
||||
|
||||
/** \brief This function frees tdd configuration for nr
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
@returns none */
|
||||
|
||||
void free_tdd_configuration_nr(NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
/** \brief This function frees tdd dedicated configuration for nr
|
||||
* @param frame_parms NR DL Frame parameters
|
||||
@returns none */
|
||||
|
||||
void free_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms);
|
||||
|
||||
#endif /* PHY_FRAME_CONFIG_NR_H */
|
||||
|
||||
@@ -211,6 +211,14 @@ typedef struct {
|
||||
int iq_rxrescale;
|
||||
//! Configuration file for LMS7002M
|
||||
char *configFilename;
|
||||
//! remote IP/MAC addr for Ethernet interface
|
||||
char *remote_addr;
|
||||
//! remote port number for Ethernet interface
|
||||
unsigned int remote_port;
|
||||
//! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
|
||||
char *my_addr;
|
||||
//! local port number for Ethernet interface (eNB/BBU, UE)
|
||||
unsigned int my_port;
|
||||
#if defined(USRP_REC_PLAY)
|
||||
unsigned short sf_mode; // 1=record, 2=replay
|
||||
char sf_filename[1024]; // subframes file path
|
||||
|
||||
@@ -9,6 +9,12 @@ typedef struct threads_s {
|
||||
int slot1_proc_one;
|
||||
int slot1_proc_two;
|
||||
int slot1_proc_three;
|
||||
int dlsch_td_one;
|
||||
int dlsch_td_two;
|
||||
int dlsch_td_three;
|
||||
int dlsch_td1_one;
|
||||
int dlsch_td1_two;
|
||||
int dlsch_td1_three;
|
||||
} threads_t;
|
||||
|
||||
#endif /* _THREADS_T_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,83 @@
|
||||
#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 "rt_wrapper.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 "rt_wrapper.h"
|
||||
#include "../../ARCH/COMMON/common_lib.h"
|
||||
#undef MALLOC
|
||||
#include "assertions.h"
|
||||
#include "msc.h"
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "SIMULATION/ETH_TRANSPORT/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
|
||||
|
||||
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
|
||||
|
||||
#include "threads_t.h"
|
||||
extern threads_t threads;
|
||||
|
||||
extern void exit_fun(const char* s);
|
||||
|
||||
// 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);
|
||||
extern void init_UE(int);
|
||||
extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name);
|
||||
extern void reset_opp_meas(void);
|
||||
extern void print_opp_meas(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user