Commit 2cb411c5 authored by Guy De Souza's avatar Guy De Souza

Merge branch 'nr_initialsync' of...

Merge branch 'nr_initialsync' of https://gitlab.eurecom.fr/oai/openairinterface5g into nr_initialsync
parents 4f662347 8aa8b6ca
......@@ -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,
......
/*
* 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]);
}
}
}
}
This diff is collapsed.
This diff is collapsed.
/*
* 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 */
/*
* 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
}
This diff is collapsed.
This diff is collapsed.
/*
* 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;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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,12 +117,43 @@ 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;
/// 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
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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_ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment