Commit 745cc733 authored by Raghavendra Dinavahi's avatar Raghavendra Dinavahi

PSBCH RX TX changes

	- RX/TX Phy processing accg to 38.211, 38.212 Rel16
	- Rate matching fix from Ralf to address 1782 bits
		- do not try to group the last bits, process them manually
	- PSBCH simulator used to validate TX/RX phy processing
parent b6780803
......@@ -689,6 +689,7 @@ target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
set(SCHED_SRC_NR_UE
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue_sl.c
${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c
${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c
${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c
......@@ -1062,6 +1063,8 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_rx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_psbch_tx.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
......@@ -2225,6 +2228,24 @@ target_link_libraries(nr_pbchsim PRIVATE
)
target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_psbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${NR_UE_RRC_DIR}/rrc_nsa.c
${NFAPI_USER_DIR}/nfapi.c
${NFAPI_USER_DIR}/gnb_ind_vars.c
${PHY_INTERFACE_DIR}/queue_t.c
${T_SOURCE}
${SHLIB_LOADER_SOURCES}
)
target_link_libraries(nr_psbchsim PRIVATE
-Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl shlib_loader
)
target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
#PUCCH ---> Prashanth
add_executable(nr_pucchsim
......
......@@ -315,7 +315,7 @@ function main() {
-P | --phy_simulators)
SIMUS_PHY=1
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim"
TARGET_LIST="$TARGET_LIST dlsim ulsim ldpctest polartest smallblocktest nr_pbchsim nr_dlschsim nr_ulschsim nr_dlsim nr_ulsim nr_pucchsim nr_prachsim nr_psbchsim"
echo_info "Will compile dlsim, ulsim, ..."
shift;;
-s | --check)
......
......@@ -304,6 +304,7 @@ void nr_polar_rm_interleaving_cb(void *in, void *out, uint16_t E)
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) __attribute__((always_inline));
static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void *in,void *out) {
int i = 0;
// handle rate matching with a single 128 bit word using bit shuffling
// can be done with SIMD intrisics if needed
......@@ -343,15 +344,20 @@ static inline void polar_rate_matching(const t_nrPolar_params *polarParams,void
}
// These are based on LUTs for byte and short word groups
else if (polarParams->groupsize == 8)
for (int i=0; i<polarParams->encoderLength>>3; i++) ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
for (i=0; i<polarParams->encoderLength>>3; i++) ((uint8_t *)out)[i] = ((uint8_t *)in)[polarParams->rm_tab[i]];
else // groupsize==16
for (int i=0; i<polarParams->encoderLength>>4; i++) {
for (i=0; i<polarParams->encoderLength>>4; i++) {
((uint16_t *)out)[i] = ((uint16_t *)in)[polarParams->rm_tab[i]];
}
if (polarParams->i_bil == 1) {
nr_polar_rm_interleaving_cb(out, out, polarParams->encoderLength);
}
// handle remaining bits which do not fill a full group
for(i=i*polarParams->groupsize; i<polarParams->encoderLength; i++) {
uint8_t pi = polarParams->rate_matching_pattern[i];
((uint8_t *)out)[i>>3] |= ( ((((uint8_t *)in)[pi >> 3] >> (pi & 7)) & 1) << (i&7));
}
}
void build_polar_tables(t_nrPolar_params *polarParams) {
......@@ -448,8 +454,8 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
}
#ifdef DEBUG_POLAR_ENCODER
groupcnt++;
#endif
if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
#endif
//if ((ccnt+1)<mingroupsize) mingroupsize=ccnt+1;
#ifdef DEBUG_POLAR_ENCODER
printf("group %d (size %d): (%d:%d) => (%d:%d)\n",groupcnt,ccnt+1,
firstingroup_in,firstingroup_in+ccnt,
......@@ -477,8 +483,7 @@ void build_polar_tables(t_nrPolar_params *polarParams) {
break;
}
polarParams->rm_tab = (int *)malloc(sizeof(int) * (polarParams->encoderLength >> shift));
polarParams->rm_tab=(int *)malloc(sizeof(int)*((polarParams->encoderLength+mingroupsize-1)/mingroupsize));
// rerun again to create groups
int tcnt = 0;
for (int outpos = 0; outpos < polarParams->encoderLength; outpos += mingroupsize, tcnt++)
......@@ -707,7 +712,7 @@ void polar_encoder_fast(uint64_t *A,
printf("\n");
#endif
memset((void*)out,0,polarParams->encoderLength>>3);
memset((void*)out,0,(polarParams->encoderLength + 7)>>3);
polar_rate_matching(polarParams,(void *)D, out);
#ifdef POLAR_CODING_DEBUG
......
/*
* 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/CODING/nrPolar_tools/nr_polar_psbch_defs.h
\brief Polar definitions required for Sidelink PSBCH
\author
\date
\version
\company: Fraunhofer
\email:
\note
\warning
*/
#ifndef __NR_POLAR_PSBCH_DEFS__H__
#define __NR_POLAR_PSBCH_DEFS__H__
//PSBCH related polar parameters.
//PSBCH symbols sent in 11RBS, 9 symbols. 11*9*(12-3(for DMRS))*2bits = 1782 bits
#define SL_NR_POLAR_PSBCH_E_NORMAL_CP 1782
//PSBCH symbols sent in 11RBS, 7 symbols. 11*7*(12-3(for DMRS))*2bits = 1386 bits
#define SL_NR_POLAR_PSBCH_E_EXT_CP 1386
// SL_NR_POLAR_PSBCH_E_NORMAL_CP/32
#define SL_NR_POLAR_PSBCH_E_DWORD 56
#define SL_NR_POLAR_PSBCH_MESSAGE_TYPE (NR_POLAR_UCI_PUCCH_MESSAGE_TYPE + 1)
#define SL_NR_POLAR_PSBCH_PAYLOAD_BITS 32
#define SL_NR_POLAR_PSBCH_AGGREGATION_LEVEL 0
#define SL_NR_POLAR_PSBCH_N_MAX 9
#define SL_NR_POLAR_PSBCH_I_IL 1
#define SL_NR_POLAR_PSBCH_I_SEG 0
#define SL_NR_POLAR_PSBCH_N_PC 0
#define SL_NR_POLAR_PSBCH_N_PC_WM 0
#define SL_NR_POLAR_PSBCH_I_BIL 0
#define SL_NR_POLAR_PSBCH_CRC_PARITY_BITS 24
#define SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS 3
#endif
......@@ -32,6 +32,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "nrPolar_tools/nr_polar_psbch_defs.h"
#define PolarKey ((messageType<<24)|(messageLength<<8)|aggregation_level)
static t_nrPolar_params * PolarList=NULL;
......@@ -194,7 +195,19 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->payloadBits = messageLength;
newPolarInitNode->crcCorrectionBits = NR_POLAR_PUCCH_CRC_ERROR_CORRECTION_BITS;
//LOG_D(PHY,"New polar node, encoderLength %d, aggregation_level %d\n",newPolarInitNode->encoderLength,aggregation_level);
} else if (messageType == SL_NR_POLAR_PSBCH_MESSAGE_TYPE) { //PSBCH
newPolarInitNode->n_max = SL_NR_POLAR_PSBCH_N_MAX;
newPolarInitNode->i_il = SL_NR_POLAR_PSBCH_I_IL;
newPolarInitNode->i_seg = SL_NR_POLAR_PSBCH_I_SEG;
newPolarInitNode->n_pc = SL_NR_POLAR_PSBCH_N_PC;
newPolarInitNode->n_pc_wm = SL_NR_POLAR_PSBCH_N_PC_WM;
newPolarInitNode->i_bil = SL_NR_POLAR_PSBCH_I_BIL;
newPolarInitNode->crcParityBits = SL_NR_POLAR_PSBCH_CRC_PARITY_BITS;
newPolarInitNode->payloadBits = SL_NR_POLAR_PSBCH_PAYLOAD_BITS;
newPolarInitNode->encoderLength = SL_NR_POLAR_PSBCH_E_NORMAL_CP;
newPolarInitNode->crcCorrectionBits = SL_NR_POLAR_PSBCH_CRC_ERROR_CORRECTION_BITS;
newPolarInitNode->crc_generator_matrix = crc24c_generator_matrix(newPolarInitNode->payloadBits);//G_P
LOG_D(PHY,"SIDELINK: Initializing polar parameters for PSBCH (K %d, E %d)\n",newPolarInitNode->payloadBits,newPolarInitNode->encoderLength);
} else {
AssertFatal(1 == 0, "[nr_polar_init] Incorrect Message Type(%d)", messageType);
}
......
......@@ -35,6 +35,7 @@
#include "PHY/MODULATION/nr_modulation.h"
#include "openair2/COMMON/prs_nr_paramdef.h"
#include "SCHED_NR_UE/harq_nr.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
void RCconfig_nrUE_prs(void *cfg)
{
......@@ -384,6 +385,15 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
return 0;
}
static void sl_ue_free(PHY_VARS_NR_UE *UE) {
if (UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) {
free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0]);
free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1]);
free_and_zero(UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation);
}
}
void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
{
const NR_DL_FRAME_PARMS* fp = &ue->frame_parms;
......@@ -489,6 +499,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
free_and_zero(ue->prs_vars[idx]);
}
sl_ue_free(ue);
}
void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb) {
......@@ -686,3 +698,248 @@ void phy_term_nr_top(void)
free_ul_reference_signal_sequences();
free_context_synchro_nr();
}
static void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE)
{
unsigned int x1, x2;
uint16_t slss_id;
uint8_t reset;
for (slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) {
reset = 1;
x2 = slss_id;
#ifdef SL_DEBUG_INIT
printf("\nPSBCH DMRS GOLD SEQ for SLSSID :%d :\n", slss_id);
#endif
for (uint8_t n=0; n<SL_NR_NUM_PSBCH_DMRS_RE_DWORD; n++) {
UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id][n] = lte_gold_generic(&x1, &x2, reset);
reset = 0;
#ifdef SL_DEBUG_INIT_DATA
printf("%x\n",SL_UE_INIT_PARAMS.sl_psbch_dmrs_gold_sequences[slss_id][n]);
#endif
}
}
}
static void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE,
struct complex16 *modulated_dmrs_sym,
uint16_t slss_id) {
uint8_t idx = 0;
uint32_t *sl_dmrs_sequence = UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_gold_sequences[slss_id];
#ifdef SL_DEBUG_INIT
printf("SIDELINK INIT: PSBCH DMRS Generation with slss_id:%d\n", slss_id);
#endif
/// QPSK modulation
for (int m=0; m<SL_NR_NUM_PSBCH_DMRS_RE; m++) {
idx = (((sl_dmrs_sequence[(m<<1)>>5])>>((m<<1)&0x1f))&3);
modulated_dmrs_sym[m].r = nr_qpsk_mod_table[2*idx];
modulated_dmrs_sym[m].i = nr_qpsk_mod_table[(2*idx) + 1];
#ifdef SL_DEBUG_INIT_DATA
printf("m:%d gold seq: %d b0-b1: %d-%d DMRS Symbols: %d %d\n", m, sl_dmrs_sequence[(m<<1)>>5], (((sl_dmrs_sequence[(m<<1)>>5])>>((m<<1)&0x1f))&1),
(((sl_dmrs_sequence[((m<<1)+1)>>5])>>(((m<<1)+1)&0x1f))&1), modulated_dmrs_sym[m].r, modulated_dmrs_sym[m].i);
printf("idx:%d, qpsk_table.r:%d, qpsk_table.i:%d\n", idx, nr_qpsk_mod_table[2*idx], nr_qpsk_mod_table[(2*idx) + 1]);
#endif
}
#ifdef SL_DUMP_INIT_SAMPLES
char filename[40], varname[25];
sprintf(filename,"sl_psbch_dmrs_slssid_%d.m", slss_id);
sprintf(varname,"sl_dmrs_id_%d.m", slss_id);
LOG_M(filename, varname, (void*)modulated_dmrs_sym, SL_NR_NUM_PSBCH_DMRS_RE, 1, 1);
#endif
}
static void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling) {
int i = 0, m = 0;
int16_t x[SL_NR_PSS_SEQUENCE_LENGTH];
const int x_initial[7] = {0, 1, 1 , 0, 1, 1, 1};
int16_t *sl_pss = sl_init_params->sl_pss[n_sl_id2];
int16_t *sl_pss_for_sync = sl_init_params->sl_pss_for_sync[n_sl_id2];
LOG_D(PHY, "SIDELINK PSBCH INIT: PSS Generation with N_SL_id2:%d\n", n_sl_id2);
#ifdef SL_DEBUG_INIT
printf("SIDELINK: PSS Generation with N_SL_id2:%d\n", n_sl_id2);
#endif
/// Sequence generation
for (i=0; i < 7; i++)
x[i] = x_initial[i];
for (i=0; i < (SL_NR_PSS_SEQUENCE_LENGTH - 7); i++) {
x[i+7] = (x[i + 4] + x[i]) %2;
}
for (i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) {
m = (i + 22 + 43*n_sl_id2) % SL_NR_PSS_SEQUENCE_LENGTH;
sl_pss_for_sync[i] = (1 - 2*x[m]);
sl_pss[i] = sl_pss_for_sync[i] * scaling;
#ifdef SL_DEBUG_INIT_DATA
printf("m:%d, sl_pss[%d]:%d\n", m, i, sl_pss[i]);
#endif
}
#ifdef SL_DUMP_INIT_SAMPLES
LOG_M("sl_pss_seq.m", "sl_pss", (void*)sl_pss, SL_NR_PSS_SEQUENCE_LENGTH, 1, 0);
#endif
}
static void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling) {
int i = 0;
int m0, m1;
int n_sl_id1, n_sl_id2;
int16_t *sl_sss = sl_init_params->sl_sss[slss_id];
int16_t *sl_sss_for_sync = sl_init_params->sl_sss_for_sync[slss_id];
int16_t x0[SL_NR_SSS_SEQUENCE_LENGTH], x1[SL_NR_SSS_SEQUENCE_LENGTH];
const int x_initial[7] = { 1, 0, 0, 0, 0, 0, 0 };
n_sl_id1 = slss_id % 336;
n_sl_id2 = slss_id / 336;
LOG_D(PHY, "SIDELINK INIT: SSS Generation with N_SL_id1:%d N_SL_id2:%d\n", n_sl_id1, n_sl_id2);
#ifdef SL_DEBUG_INIT
printf("SIDELINK: SSS Generation with slss_id:%d, N_SL_id1:%d, N_SL_id2:%d\n", slss_id, n_sl_id1, n_sl_id2);
#endif
for ( i=0 ; i < 7 ; i++) {
x0[i] = x_initial[i];
x1[i] = x_initial[i];
}
for ( i=0 ; i < SL_NR_SSS_SEQUENCE_LENGTH - 7 ; i++) {
x0[i+7] = (x0[i + 4] + x0[i]) % 2;
x1[i+7] = (x1[i + 1] + x1[i]) % 2;
}
m0 = 15*(n_sl_id1/112) + (5*n_sl_id2);
m1 = n_sl_id1 % 112;
for (i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH ; i++) {
sl_sss_for_sync[i] = (1 - 2*x0[(i + m0) % SL_NR_SSS_SEQUENCE_LENGTH] ) * (1 - 2*x1[(i + m1) % SL_NR_SSS_SEQUENCE_LENGTH] );
sl_sss[i] = sl_sss_for_sync[i] * scaling;
#ifdef SL_DEBUG_INIT_DATA
printf("m0:%d, m1:%d, sl_sss_for_sync[%d]:%d, sl_sss[%d]:%d\n", m0, m1, i, sl_sss_for_sync[i], i, sl_sss[i]);
#endif
}
#ifdef SL_DUMP_PSBCH_TX_SAMPLES
LOG_M("sl_sss_seq.m", "sl_sss", (void*)sl_sss, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0);
LOG_M("sl_sss_forsync_seq.m", "sl_sss_for_sync", (void*)sl_sss_for_sync, SL_NR_SSS_SEQUENCE_LENGTH, 1, 0);
#endif
}
// This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration
// done at SLSS read time.
static void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params) {
uint8_t id2 = 0;
int16_t *sl_pss = NULL;
NR_DL_FRAME_PARMS *sl_fp = &sl_ue_params->sl_frame_params;
int16_t scaling_factor = AMP;
int16_t *pss_F = NULL; // IQ samples in freq domain
int32_t *pss_T = NULL;
uint16_t k = 0;
pss_F = malloc16_clear(2*sizeof(int16_t) * sl_fp->ofdm_symbol_size);
LOG_I(PHY, "SIDELINK INIT: Generation of PSS time domain samples. scaling_factor:%d\n", scaling_factor);
for (id2 = 0; id2 < SL_NR_NUM_IDs_IN_PSS; id2++) {
k = sl_fp->first_carrier_offset + sl_fp->ssb_start_subcarrier + 2; // PSS in from REs 2-129
if (k >= sl_fp->ofdm_symbol_size) k -= sl_fp->ofdm_symbol_size;
pss_T = &sl_init_params->sl_pss_for_correlation[id2][0];
sl_pss = sl_init_params->sl_pss[id2];
memset(pss_T, 0, sl_fp->ofdm_symbol_size * sizeof(pss_T[0]));
memset(pss_F, 0, sl_fp->ofdm_symbol_size * 2 * sizeof(pss_F[0]));
for (int i=0; i < SL_NR_PSS_SEQUENCE_LENGTH; i++) {
pss_F[2*k] = (sl_pss[i] * scaling_factor) >> 15;
//pss_F[2*k] = (sl_pss[i]/23170) * 4192;
//pss_F[2*k+1] = 0;
#ifdef SL_DEBUG_INIT_DATA
printf("id:%d, k:%d, pss_F[%d]:%d, sl_pss[%d]:%d\n", id2, k, 2*k, pss_F[2*k], i, sl_pss[i]);
#endif
k++;
if (k == sl_fp->ofdm_symbol_size) k=0;
}
idft((int16_t)get_idft(sl_fp->ofdm_symbol_size),
pss_F, /* complex input */
(int16_t *)&pss_T[0], /* complex output */
1); /* scaling factor */
}
#ifdef SL_DUMP_PSBCH_TX_SAMPLES
LOG_M("sl_pss_TD_id0.m", "pss_TD_0", (void*)sl_init_params->sl_pss_for_correlation[0], sl_fp->ofdm_symbol_size, 1, 1);
LOG_M("sl_pss_TD_id1.m", "pss_TD_1", (void*)sl_init_params->sl_pss_for_correlation[1], sl_fp->ofdm_symbol_size, 1, 1);
#endif
free(pss_F);
}
void sl_ue_phy_init(PHY_VARS_NR_UE *UE) {
uint16_t scaling_value = ONE_OVER_SQRT2_Q15;
NR_DL_FRAME_PARMS *sl_fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params;
if (!UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation) {
UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation = (int32_t **)malloc16_clear(SL_NR_NUM_IDs_IN_PSS *sizeof(int32_t *) );
UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[0] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size);
UE->SL_UE_PHY_PARAMS.init_params.sl_pss_for_correlation[1] = (int32_t *)malloc16_clear( sizeof(int32_t)*sl_fp->ofdm_symbol_size);
}
LOG_I(PHY, "SIDELINK INIT: GENERATE PSS, SSS, GOLD SEQUENCES AND PSBCH DMRS SEQUENCES FOR ALL possible SLSS IDs 0- 671\n");
// Generate PSS sequences for IDs 0,1 used in PSS
sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,0, scaling_value);
sl_generate_pss(&UE->SL_UE_PHY_PARAMS.init_params,1, scaling_value);
// Generate psbch dmrs Gold Sequences and modulated dmrs symbols
sl_init_psbch_dmrs_gold_sequences(UE);
for (int slss_id = 0; slss_id < SL_NR_NUM_SLSS_IDs; slss_id++) {
sl_generate_psbch_dmrs_qpsk_sequences(UE, UE->SL_UE_PHY_PARAMS.init_params.psbch_dmrs_modsym[slss_id], slss_id);
sl_generate_sss(&UE->SL_UE_PHY_PARAMS.init_params, slss_id, scaling_value);
}
// Generate PSS time domain samples used for correlation during SLSS reception.
sl_generate_pss_ifft_samples(&UE->SL_UE_PHY_PARAMS, &UE->SL_UE_PHY_PARAMS.init_params);
init_symbol_rotation(sl_fp);
init_timeshift_rotation(sl_fp);
}
\ No newline at end of file
......@@ -426,7 +426,8 @@ void nr_dump_frame_parms(NR_DL_FRAME_PARMS *fp)
LOG_I(PHY,"fp->samples_per_frame=%d\n",fp->samples_per_frame);
LOG_I(PHY,"fp->dl_CarrierFreq=%lu\n",fp->dl_CarrierFreq);
LOG_I(PHY,"fp->ul_CarrierFreq=%lu\n",fp->ul_CarrierFreq);
LOG_I(PHY,"fp->Nid_cell=%d\n",fp->Nid_cell);
LOG_I(PHY,"fp->first_carrier_offset=%d\n",fp->first_carrier_offset);
LOG_I(PHY,"fp->ssb_start_subcarrier=%d\n",fp->ssb_start_subcarrier);
}
......@@ -56,5 +56,7 @@ void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES],
void phy_init_nr_top(PHY_VARS_NR_UE *ue);
void phy_term_nr_top(void);
void sl_ue_phy_init(PHY_VARS_NR_UE *UE);
void sl_ue_phy_init(PHY_VARS_NR_UE *UE);
#endif
......@@ -49,9 +49,11 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
int reset_freq_est);
int nr_slot_fep(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *frame_parms,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint32_t linktype);
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
......
......@@ -35,11 +35,13 @@
#endif*/
int nr_slot_fep(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *frame_parms,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint32_t linktype)
{
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
NR_UE_COMMON *common_vars = &ue->common_vars;
int Ns = proc->nr_slot_rx;
......@@ -98,7 +100,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
apply_nr_rotation_RX(frame_parms,
rxdataF[aa],
frame_parms->symbol_rotation[0],
frame_parms->symbol_rotation[linktype],
Ns,
frame_parms->N_RB_DL,
0,
......
......@@ -197,22 +197,30 @@ int nr_pdcch_dmrs_rx(PHY_VARS_NR_UE *ue,
int nr_pbch_dmrs_rx(int symbol,
unsigned int *nr_gold_pbch,
int32_t *output)
int32_t *output,
bool sidelink)
{
int m,m0,m1;
uint8_t idx=0;
AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol);
if (symbol == 0) {
m0=0;
m1=60;
}
else if (symbol == 1) {
m0=60;
m1=84;
}
else {
m0=84;
m1=144;
if (sidelink) {
AssertFatal(symbol== 0 || (symbol>=5 && symbol <=12),"illegal symbol %d\n",symbol);
m0 = (symbol) ? (symbol - 4) * 33 : 0;
m1 = (symbol) ? (symbol - 3) * 33 : 33;
} else {
AssertFatal(symbol>=0 && symbol <3,"illegal symbol %d\n",symbol);
if (symbol == 0) {
m0=0;
m1=60;
}
else if (symbol == 1) {
m0=60;
m1=84;
}
else {
m0=84;
m1=144;
}
}
// printf("Generating pilots symbol %d, m0 %d, m1 %d\n",symbol,m0,m1);
/// QPSK modulation
......
......@@ -33,7 +33,8 @@
*/
int nr_pbch_dmrs_rx(int dmrss,
unsigned int *nr_gold_pbch,
int32_t *output);
int32_t *output,
bool sidelink);
/*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS.
@param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables
......
......@@ -608,7 +608,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
#endif
// generate pilot
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0],0);
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
......@@ -729,15 +729,18 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
}
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *fp,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][ue->frame_parms.ofdm_symbol_size],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink,
uint16_t Nid)
{
int Ns = proc->nr_slot_rx;
int pilot[200] __attribute__((aligned(16)));
......@@ -748,25 +751,48 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int ch_offset,symbol_offset;
//int slot_pbch;
uint8_t nushift;
nushift = ue->frame_parms.Nid_cell%4;
ue->frame_parms.nushift = nushift;
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size;
uint8_t nushift = 0, lastsymbol = 0;
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
uint32_t *gold_seq = NULL;
AssertFatal(dmrss >= 0 && dmrss < 3,
if (sidelink) {
AssertFatal(dmrss == 0 || (dmrss >= 5 && dmrss <= 12),
"symbol %d is illegal for PSBCH DM-RS \n",
dmrss);
sl_nr_ue_phy_params_t *sl_phy_params = &ue->SL_UE_PHY_PARAMS;
LOG_D(PHY,"PSBCH Channel Estimation SLSSID:%d\n", Nid);
gold_seq = sl_phy_params->init_params.psbch_dmrs_gold_sequences[Nid];
lastsymbol = 12;
} else {
nushift = fp->Nid_cell%4;
fp->nushift = nushift;
AssertFatal(dmrss >= 0 && dmrss < 3,
"symbol %d is illegal for PBCH DM-RS \n",
dmrss);
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
gold_seq = ue->nr_gold_pbch[n_hf][ssb_index];
lastsymbol = 2;
}
unsigned int ssb_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier;
if (ssb_offset>= fp->ofdm_symbol_size) ssb_offset-= fp->ofdm_symbol_size;
ch_offset = fp->ofdm_symbol_size*symbol;
symbol_offset = fp->ofdm_symbol_size*symbol;
k = nushift;
#ifdef DEBUG_PBCH
printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, fp->ofdm_symbol_size, fp->Ncp, Ns, k, symbol);
#endif
switch (k) {
......@@ -802,7 +828,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
idft_size_idx_t idftsizeidx;
switch (ue->frame_parms.ofdm_symbol_size) {
switch (fp->ofdm_symbol_size) {
case 128:
idftsizeidx = IDFT_128;
break;
......@@ -849,20 +875,20 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
}
// generate pilot
nr_pbch_dmrs_rx(dmrss,ue->nr_gold_pbch[n_hf][ssb_index], &pilot[0]);
nr_pbch_dmrs_rx(dmrss,gold_seq, &pilot[0], sidelink);
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
for (int aarx=0; aarx<fp->nb_antennas_rx; aarx++) {
int re_offset = ssb_offset;
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,sizeof(struct complex16)*(ue->frame_parms.ofdm_symbol_size));
memset(dl_ch,0,sizeof(struct complex16)*(fp->ofdm_symbol_size));
#ifdef DEBUG_PBCH
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], ue->frame_parms.N_RB_DL);
printf("k %d, first_carrier %d\n",k,ue->frame_parms.first_carrier_offset);
printf("pbch ch est pilot addr %p RB_DL %d\n",&pilot[0], fp->N_RB_DL);
printf("k %d, first_carrier %d\n",k,fp->first_carrier_offset);
printf("rxF addr %p\n", rxF);
printf("dl_ch addr %p\n",dl_ch);
#endif
......@@ -881,7 +907,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+4) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
//for (int i= 0; i<8; i++)
......@@ -899,7 +925,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+4) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
......@@ -914,7 +940,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+4) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 24;
......@@ -926,7 +952,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset+144) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+144) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 288;
}
......@@ -945,7 +971,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
// printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+4) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
......@@ -960,7 +986,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+4) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
......@@ -975,13 +1001,13 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
dl_ch,
16);
pil += 2;
re_offset = (re_offset+4) % ue->frame_parms.ofdm_symbol_size;
re_offset = (re_offset+4) % fp->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+re_offset)];
dl_ch += 24;
}
if( dmrss == 2) // update time statistics for last PBCH symbol
if( dmrss == lastsymbol) // update time statistics for last PBCH symbol
{
// do ifft of channel estimate
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
......@@ -992,13 +1018,13 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
}
}
if (dmrss == 2)
if (!sidelink && dmrss == lastsymbol)
UEscopeCopy(ue,
pbchDlChEstimateTime,
(void *)dl_ch_estimates_time,
sizeof(c16_t),
ue->frame_parms.nb_antennas_rx,
ue->frame_parms.ofdm_symbol_size,
fp->nb_antennas_rx,
fp->ofdm_symbol_size,
0);
return(0);
......
......@@ -68,15 +68,18 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *fp,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
struct complex16 dl_ch_estimates_time[][ue->frame_parms.ofdm_symbol_size],
struct complex16 dl_ch_estimates_time[][fp->ofdm_symbol_size],
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
int dmrss,
uint8_t ssb_index,
uint8_t n_hf,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink,
uint16_t Nid);
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
......@@ -141,4 +144,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS);
#endif
......@@ -313,3 +313,56 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.n0_power_tot_dB + 30 - 10*log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset));
}
//PSBCH RSRP calculations according to 38.215 section 5.1.22
void nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
NR_DL_FRAME_PARMS *fp,
c16_t rxdataF[][fp->samples_per_slot_wCP],
bool use_SSS)
{
SL_NR_UE_PSBCH_t *psbch_rx = &sl_phy_params->psbch;
uint8_t numsym = (fp->Ncp) ? SL_NR_NUM_SYMBOLS_SSB_EXT_CP
: SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP;
uint32_t re_offset = fp->first_carrier_offset + fp->ssb_start_subcarrier;
uint32_t rsrp = 0, num_re = 0;
LOG_D(PHY, "PSBCH RSRP MEAS: numsym:%d, re_offset:%d\n",numsym, re_offset);
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++) {
//Calculate PSBCH RSRP based from DMRS REs
for (uint8_t symbol=0; symbol<numsym;) {
struct complex16 *rxF = &rxdataF[aarx][symbol*fp->ofdm_symbol_size];
for (int re=0;re<SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL;re++) {
if (re%4 == 0) { //DMRS RE
uint16_t offset = (re_offset + re) % fp->ofdm_symbol_size;
rsrp += rxF[offset].r*rxF[offset].r + rxF[offset].i*rxF[offset].i;
num_re++;
}
}
symbol = (symbol == 0) ? 5 : symbol+1;
}
}
if (use_SSS) {
//TBD...
//UE can decide between using only PSBCH DMRS or PSBCH DMRS and SSS for PSBCH RSRP computation.
//If needed this can be implemented. Reference Spec 38.215
}
psbch_rx->rsrp_dB_per_RE = 10*log10(rsrp / num_re);
psbch_rx->rsrp_dBm_per_RE = psbch_rx->rsrp_dB_per_RE +
30 - 10*log10(pow(2,30)) -
((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) -
dB_fixed(fp->ofdm_symbol_size);
LOG_I(PHY, "PSBCH RSRP (DMRS REs): numREs:%d RSRP :%d dB/RE ,RSRP:%d dBm/RE\n",
num_re, psbch_rx->rsrp_dB_per_RE, psbch_rx->rsrp_dBm_per_RE);
}
\ No newline at end of file
......@@ -151,8 +151,8 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
__attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size];
for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time,
proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF);
nr_pbch_channel_estimation(ue,&ue->frame_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time,
proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF,false, frame_parms->Nid_cell);
stop_meas(&ue->dlsch_channel_estimation_stats);
fapiPbch_t result = {0};
......
......@@ -244,7 +244,7 @@ int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER
return(avg2);
}
static void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
void nr_pbch_channel_compensation(struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
int nb_re,
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
......@@ -300,7 +300,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
#endif
}
static void nr_pbch_unscrambling(int16_t *demod_pbch_e,
void nr_pbch_unscrambling(int16_t *demod_pbch_e,
uint16_t Nid,
uint8_t nushift,
uint16_t M,
......@@ -362,7 +362,7 @@ static void nr_pbch_unscrambling(int16_t *demod_pbch_e,
}
}
static void nr_pbch_quantize(int16_t *pbch_llr8,
void nr_pbch_quantize(int16_t *pbch_llr8,
int16_t *pbch_llr,
uint16_t len) {
for (int i=0; i<len; i++) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -410,6 +410,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid);
void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb);
int nr_rx_psbch(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t *decoded_output,
c16_t rxdataF[][frame_parms->samples_per_slot_wCP],
uint16_t slss_id);
void nr_tx_psbch(PHY_VARS_NR_UE *UE, uint32_t frame_tx, uint32_t slot_tx,
sl_nr_tx_config_psbch_pdu_t *psbch_vars,
c16_t **txdataF);
/**@}*/
#endif
......@@ -39,6 +39,7 @@
#include "defs_nr_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
#include "PHY/defs_nr_sl_UE.h"
#include <stdio.h>
#include <stdlib.h>
......@@ -649,6 +650,10 @@ typedef struct {
notifiedFIFO_t phy_config_ind;
notifiedFIFO_t *tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME];
//Sidelink parameters
sl_nr_sidelink_mode_t sl_mode;
sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
} PHY_VARS_NR_UE;
typedef struct {
......@@ -670,11 +675,20 @@ typedef struct {
typedef struct nr_phy_data_tx_s {
NR_UE_ULSCH_t ulsch;
NR_UE_PUCCH pucch_vars;
//Sidelink Rx action decided by MAC
sl_nr_tx_config_type_enum_t sl_tx_action;
sl_nr_tx_config_psbch_pdu_t psbch_vars;
} nr_phy_data_tx_t;
typedef struct nr_phy_data_s {
NR_UE_PDCCH_CONFIG phy_pdcch_config;
NR_UE_DLSCH_t dlsch[2];
//Sidelink Rx action decided by MAC
sl_nr_rx_config_type_enum_t sl_rx_action;
} nr_phy_data_t;
/* this structure is used to pass both UE phy vars and
* proc to the function UE_thread_rxn_txnp4
......
/*
* 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/defs_nr_sl_UE.h
\brief Top-level defines and structure definitions
\author
\date
\version
\company Fraunhofer
\email:
\note
\warning
*/
#ifndef _DEFS_NR_SL_UE_H_
#define _DEFS_NR_SL_UE_H_
#include "PHY/types.h"
#include "PHY/defs_nr_common.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h"
#include "common/utils/time_meas.h"
// (33*(13-4))
// Normal CP - NUM_SSB_Symbols = 13. 4 symbols for PSS, SSS
#define SL_NR_NUM_PSBCH_DMRS_RE 297
//ceil(2(QPSK)*SL_NR_NUM_PSBCH_DMRS_RE/32)
#define SL_NR_NUM_PSBCH_DMRS_RE_DWORD 20
//11 RBs for PSBCH in one symbol * 12 REs
#define SL_NR_NUM_PSBCH_RE_IN_ONE_SYMBOL 132
//3 DMRS REs per RB * 11 RBS in one symbol
#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_SYMBOL 33
//9 PSBCH DATA REs * 11 RBS in one symbol
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_SYMBOL 99
#define SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL 11
// SL_NR_POLAR_PSBCH_E_NORMAL_CP/2 bits because QPSK used for PSBCH.
// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH
#define SL_NR_NUM_PSBCH_MODULATED_SYMBOLS 891
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ONE_RB 9
#define SL_NR_NUM_PSBCH_DMRS_RE_IN_ONE_RB 3
// 11 * (12-3 DMRS REs) * 9 symbols for PSBCH
#define SL_NR_NUM_PSBCH_DATA_RE_IN_ALL_SYMBOLS 891
#define SL_NR_NUM_SYMBOLS_SSB_NORMAL_CP 13
#define SL_NR_NUM_SYMBOLS_SSB_EXT_CP 11
#define SL_NR_NUM_PSS_SYMBOLS 2
#define SL_NR_NUM_SSS_SYMBOLS 2
#define SL_NR_PSS_START_SYMBOL 1
#define SL_NR_SSS_START_SYMBOL 3
#define SL_NR_NUM_PSS_OR_SSS_SYMBOLS 2
#define SL_NR_PSS_SEQUENCE_LENGTH 127
#define SL_NR_SSS_SEQUENCE_LENGTH 127
#define SL_NR_NUM_IDs_IN_PSS 2
#define SL_NR_NUM_IDs_IN_SSS 336
#define SL_NR_NUM_SLSS_IDs 672
typedef enum sl_nr_sidelink_mode {
SL_NOT_SUPPORTED = 0,
SL_MODE1_SUPPORTED,
SL_MODE2_SUPPORTED
} sl_nr_sidelink_mode_t;
//(11*(12-3 DMRS REs) * 2 (QPSK used)
#define SL_NR_NUM_PSBCH_DATA_BITS_IN_ONE_SYMBOL 198
typedef struct SL_NR_UE_INIT_PARAMS {
//gold sequences for PSBCH DMRS
uint32_t psbch_dmrs_gold_sequences[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE_DWORD]; // Gold sequences for PSBCH DMRS
//PSBCH DMRS QPSK modulated symbols for all possible SLSS Ids
struct complex16 psbch_dmrs_modsym[SL_NR_NUM_SLSS_IDs][SL_NR_NUM_PSBCH_DMRS_RE];
// Scaled values
int16_t sl_pss[SL_NR_NUM_IDs_IN_PSS][SL_NR_PSS_SEQUENCE_LENGTH];
int16_t sl_sss[SL_NR_NUM_SLSS_IDs][SL_NR_SSS_SEQUENCE_LENGTH];
// Contains Not scaled values just the simple generated sequence
int16_t sl_pss_for_sync[SL_NR_NUM_IDs_IN_PSS][SL_NR_PSS_SEQUENCE_LENGTH];
int16_t sl_sss_for_sync[SL_NR_NUM_SLSS_IDs][SL_NR_SSS_SEQUENCE_LENGTH];
int32_t **sl_pss_for_correlation; // IFFT samples for correlation
} SL_NR_UE_INIT_PARAMS_t;
typedef struct SL_NR_UE_PSBCH {
// AVG POWER OF PSBCH DMRS in dB/RE
int16_t rsrp_dB_per_RE;
// AVG POWER OF PSBCH DMRS in dBm/RE
int16_t rsrp_dBm_per_RE;
// STATS - CRC Errors observed during PSBCH reception
uint16_t rx_errors;
// STATS - Receptions with CRC OK
uint16_t rx_ok;
// STATS - transmissions of PSBCH by the UE
uint16_t num_psbch_tx;
} SL_NR_UE_PSBCH_t;
typedef struct sl_nr_ue_phy_params {
SL_NR_UE_INIT_PARAMS_t init_params;
// Sidelink PHY PARAMETERS USED FOR PSBCH reception/Txn
SL_NR_UE_PSBCH_t psbch;
//Configuration parameters from MAC
sl_nr_phy_config_request_t sl_config;
NR_DL_FRAME_PARMS sl_frame_params;
time_stats_t phy_proc_sl_tx;
time_stats_t phy_proc_sl_rx;
time_stats_t channel_estimation_stats;
time_stats_t ue_sl_indication_stats;
} sl_nr_ue_phy_params_t;
#endif
\ No newline at end of file
......@@ -191,5 +191,12 @@ int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t r
void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
void psbch_pscch_processing(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_t *phy_data);
int phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
nr_phy_data_tx_t *phy_data);
#endif
......@@ -875,12 +875,15 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
for (int i=1; i<4; i++) {
nr_slot_fep(ue,
fp,
proc,
(ssb_start_symbol+i)%(fp->symbols_per_slot),
rxdataF);
rxdataF,
link_type_dl);
start_meas(&ue->dlsch_channel_estimation_stats);
nr_pbch_channel_estimation(ue,
&ue->frame_parms,
estimateSz,
dl_ch_estimates,
dl_ch_estimates_time,
......@@ -889,7 +892,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
i-1,
ssb_index&7,
ssb_slot_2 == nr_slot_rx,
rxdataF);
rxdataF,
false,
fp->Nid_cell);
stop_meas(&ue->dlsch_channel_estimation_stats);
}
......@@ -939,9 +944,11 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
for(int j = prs_config->SymbolStart; j < (prs_config->SymbolStart+prs_config->NumPRSSymbols); j++)
{
nr_slot_fep(ue,
fp,
proc,
(j%fp->symbols_per_slot),
rxdataF);
rxdataF,
link_type_dl);
}
nr_prs_channel_estimation(rsc_id,
i,
......@@ -978,9 +985,11 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue,
start_meas(&ue->ofdm_demod_stats);
nr_slot_fep(ue,
fp,
proc,
l,
rxdataF);
rxdataF,
link_type_dl);
}
// Hold the channel estimates in frequency domain.
......@@ -1039,9 +1048,11 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){
nr_slot_fep(ue,
&ue->frame_parms,
proc,
m, //to be updated from higher layer
rxdataF);
rxdataF,
link_type_dl);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT);
......@@ -1116,7 +1127,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
}
l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx];
if(nr_slot_fep_done == false) {
nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF);
nr_slot_fep(ue, &ue->frame_parms, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF, link_type_dl);
}
}
nr_ue_csi_im_procedures(ue, proc, rxdataF);
......@@ -1127,7 +1138,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue,
if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) {
for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) {
nr_slot_fep(ue, proc, symb, rxdataF);
nr_slot_fep(ue, &ue->frame_parms, proc, symb, rxdataF, link_type_dl);
}
}
nr_ue_csi_rs_procedures(ue, proc, rxdataF);
......
This diff is collapsed.
......@@ -797,12 +797,13 @@ int main(int argc, char **argv)
proc.gNB_id = 0;
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
nr_slot_fep(UE,
frame_parms,
&proc,
i%frame_parms->symbols_per_slot,
rxdataF);
rxdataF, link_type_dl);
nr_pbch_channel_estimation(UE,estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc,
i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf,rxdataF);
nr_pbch_channel_estimation(UE,&UE->frame_parms, estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc,
i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf,rxdataF,false,frame_parms->Nid_cell);
}
fapiPbch_t result;
......
This diff is collapsed.
......@@ -118,7 +118,7 @@ typedef struct {
uint32_t gNB_index;
/// component carrier id
int cc_id;
/// frame
/// frame rx
frame_t frame_rx;
/// slot rx
uint32_t slot_rx;
......
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