Commit 951318c4 authored by Raghavendra Dinavahi's avatar Raghavendra Dinavahi

PSBCH RX TX and SLSS search procedures

	- RX/TX Phy processing accg to 38.211, 38.212 Rel16
	- PSBCH simulator used to validate TX/RX phy processing
	- PSBCH SLSS Search procedures
	- PSBCH SIM also tests SLSS SEARCH
parent 3f3a9869
......@@ -718,6 +718,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
......@@ -1086,8 +1087,11 @@ set(PHY_SRC_UE
${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/nr_initial_sync.c
${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.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
......@@ -2244,6 +2248,22 @@ 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
)
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_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -lz -Wl,--end-group
m pthread ${T_LIB} ITTI dl shlib_loader
)
target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
#PUCCH ---> Prashanth
add_executable(nr_pucchsim
......
......@@ -511,4 +511,16 @@
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
<testCase id="NR-Sidelink">
<desc>NR-Sidelink Test cases. (Test1: SLSS Search),
(Test2: PSBCH TxRx)</desc>
<main_exec>nr_psbchsim</main_exec>
<main_exec_args>-I
-n 10</main_exec_args>
<tags>test1 test2</tags>
<search_expr_true>PSBCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
</testCase>
</testCaseList>
......@@ -320,7 +320,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)
......
/*
* 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;
......@@ -191,7 +192,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 + 2;
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);
}
......
......@@ -32,7 +32,6 @@
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "openair2/COMMON/prs_nr_paramdef.h"
#include "SCHED_NR_UE/harq_nr.h"
......@@ -384,6 +383,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 +497,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) {
......@@ -702,3 +712,35 @@ void phy_term_nr_top(void)
free_ul_reference_signal_sequences();
free_context_synchro_nr();
}
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
......@@ -428,7 +428,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);
}
......@@ -61,4 +61,5 @@ void init_delay_table(uint16_t ofdm_symbol_size,
int max_ofdm_symbol_size,
c16_t delay_table[][max_ofdm_symbol_size]);
void sl_ue_phy_init(PHY_VARS_NR_UE *UE);
#endif
......@@ -49,9 +49,17 @@ 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,
const 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 sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns,
uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]);
int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
......
......@@ -34,12 +34,107 @@
#define LOG_I(A,B...) printf(A)
#endif*/
int sl_nr_slot_fep(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
unsigned char Ns,
uint32_t sample_offset,
c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP])
{
NR_DL_FRAME_PARMS *frame_params = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
NR_UE_COMMON *common_vars = &ue->common_vars;
AssertFatal(symbol < frame_params->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_params->symbols_per_slot-1);
AssertFatal(Ns < frame_params->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_params->slots_per_frame-1);
unsigned int nb_prefix_samples = frame_params->nb_prefix_samples;
unsigned int nb_prefix_samples0 = frame_params->nb_prefix_samples0;
dft_size_idx_t dftsize = get_dft(frame_params->ofdm_symbol_size);
// This is for misalignment issues
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
unsigned int rx_offset = frame_params->get_samples_slot_timestamp(Ns,frame_params,0);
unsigned int abs_symbol = Ns * frame_params->symbols_per_slot + symbol;
rx_offset += sample_offset;
rx_offset += ue->rx_offset;
for (int idx_symb = Ns*frame_params->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++)
rx_offset += (idx_symb%(0x7<<frame_params->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0;
rx_offset += frame_params->ofdm_symbol_size * symbol;
// use OFDM symbol from within 1/8th of the CP to avoid ISI
rx_offset -= (nb_prefix_samples / frame_params->ofdm_offset_divisor);
#ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100)
LOG_I(PHY, "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u\n",
Ns, symbol, nb_prefix_samples, nb_prefix_samples0, rx_offset);
#endif
for (unsigned char aa=0; aa<frame_params->nb_antennas_rx; aa++) {
memset(&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],0,frame_params->ofdm_symbol_size*sizeof(int32_t));
int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
// if input to dft is not 256-bit aligned
if ((rx_offset & 7) != 0) {
memcpy((void *)&tmp_dft_in[0],
(void *)&common_vars->rxdata[aa][rx_offset],
frame_params->ofdm_symbol_size * sizeof(int32_t));
rxdata_ptr = (int16_t *)tmp_dft_in;
}
dft(dftsize,
rxdata_ptr,
(int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
1);
int symb_offset = (Ns%frame_params->slots_per_subframe)*frame_params->symbols_per_slot;
int32_t rot2 = ((uint32_t*)frame_params->symbol_rotation[1])[symbol+symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
#ifdef SL_DEBUG_SLOT_FEP
// if (ue->frame <100)
LOG_I(PHY, "slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset,
symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
#endif
rotate_cpx_vector((c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
(c16_t *)&rot2,
(c16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
frame_params->ofdm_symbol_size,
15);
int16_t *shift_rot = (int16_t *)frame_params->timeshift_symbol_rotation;
multadd_cpx_vector((int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
shift_rot,
(int16_t *)&rxdataF[aa][frame_params->ofdm_symbol_size*symbol],
1,
frame_params->ofdm_symbol_size,
15);
}
LOG_D(PHY, "SIDELINK RX: Slot FEP: done for symbol:%d\n", symbol);
return 0;
}
int nr_slot_fep(PHY_VARS_NR_UE *ue,
NR_DL_FRAME_PARMS *frame_parms,
const 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 +193,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
......
......@@ -20,6 +20,7 @@
*/
#include "refsig_defs_ue.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
void nr_gold_pbch(PHY_VARS_NR_UE* ue)
{
......@@ -154,3 +155,65 @@ void init_nr_gold_prs(PHY_VARS_NR_UE* ue)
} // for rsc
} // for gnb
}
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
}
}
}
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
}
......@@ -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
......@@ -69,5 +70,11 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
void init_nr_gold_prs(PHY_VARS_NR_UE* ue);
void sl_generate_pss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint8_t n_sl_id2, uint16_t scaling);
void sl_generate_pss_ifft_samples(sl_nr_ue_phy_params_t *sl_ue_params, SL_NR_UE_INIT_PARAMS_t *sl_init_params);
void sl_generate_sss(SL_NR_UE_INIT_PARAMS_t *sl_init_params, uint16_t slss_id, uint16_t scaling);
void sl_init_psbch_dmrs_gold_sequences(PHY_VARS_NR_UE *UE);
void sl_generate_psbch_dmrs_qpsk_sequences(PHY_VARS_NR_UE *UE,
struct complex16 *modulated_dmrs_sym,
uint16_t slss_id);
#endif
......@@ -658,7 +658,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++) {
......@@ -779,15 +779,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],
const 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)));
......@@ -798,24 +801,49 @@ 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;
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, num_rbs = 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;
num_rbs = SL_NR_NUM_PSBCH_RBS_IN_ONE_SYMBOL;
} else {
nushift = fp->Nid_cell%4;
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;
num_rbs = 20;
}
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) {
......@@ -851,7 +879,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;
......@@ -898,20 +926,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
......@@ -930,7 +958,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++)
......@@ -948,7 +976,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);
......@@ -963,11 +991,11 @@ 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;
for (pilot_cnt=3; pilot_cnt<(3*20); pilot_cnt += 3) {
for (pilot_cnt=3; pilot_cnt<(3*num_rbs); pilot_cnt += 3) {
// if (pilot_cnt == 30)
// rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k)];
......@@ -975,7 +1003,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;
}
......@@ -994,7 +1022,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)];
......@@ -1009,7 +1037,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);
......@@ -1024,13 +1052,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);
......@@ -1041,13 +1069,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);
......
......@@ -65,15 +65,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],
const 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,
const UE_nr_rxtx_proc_t *proc,
......@@ -137,5 +140,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
NR_UE_DLSCH_t dlsch[2]);
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
......@@ -309,3 +309,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
......@@ -153,8 +153,8 @@ int nr_pbch_detection(const UE_nr_rxtx_proc_t *proc,
__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};
......
This diff is collapsed.
......@@ -230,12 +230,13 @@ 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],
struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER_SYMBOL],
int nb_re,
struct complex16 rxdataF_comp[][PBCH_MAX_RE_PER_SYMBOL],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t output_shift) {
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],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t output_shift)
{
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
simde__m128i *dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[aarx];
simde__m128i *rxdataF128 = (simde__m128i *)rxdataF_ext[aarx];
......@@ -272,7 +273,7 @@ void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
simde_m_empty();
}
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,
......@@ -334,7 +335,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.
......@@ -423,6 +423,21 @@ 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);
int sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, int num_frames);
/**@}*/
#endif
......@@ -696,3 +696,106 @@ static int pss_search_time_nr(c16_t **rxdata, PHY_VARS_NR_UE *ue, int fo_flag, i
return peak_position;
}
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
}
// This cannot be done at init time as ofdm symbol size, ssb start subcarrier depends on configuration
// done at SLSS read time.
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);
}
......@@ -535,3 +535,54 @@ bool rx_sss_nr(PHY_VARS_NR_UE *ue,
return true;
}
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
}
......@@ -237,6 +237,13 @@ extern "C" {
};
}
__attribute__((always_inline)) inline c16_t c16xmulConstShift(const c16_t a, const int b, const int Shift) {
return (c16_t) {
.r = (int16_t)((a.r * b) >> Shift),
.i = (int16_t)((a.i * b) >> Shift)
};
}
__attribute__((always_inline)) inline c32_t c32x16maddShift(const c16_t a, const c16_t b, const c32_t c, const int Shift) {
return (c32_t) {
.r = ((a.r * b.r - a.i * b.i) >> Shift) + c.r,
......
......@@ -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>
......@@ -612,6 +613,10 @@ typedef struct PHY_VARS_NR_UE_s {
uint8_t *phy_sim_dlsch_b;
notifiedFIFO_t phy_config_ind;
notifiedFIFO_t tx_resume_ind_fifo[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 {
......@@ -633,11 +638,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
......
......@@ -168,8 +168,6 @@ struct NR_DL_FRAME_PARMS {
/// Frame type (0 FDD, 1 TDD)
frame_type_t frame_type;
uint8_t tdd_config;
/// Sidelink Cell ID
uint16_t Nid_SL;
/// Cell ID
uint16_t Nid_cell;
/// subcarrier spacing (15,30,60,120)
......
/*
* 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_SYNC_PARAMS {
// Indicating start of SSB block in the initial set of samples
uint32_t ssb_offset;
// Freq Offset calculated
int32_t freq_offset;
uint32_t remaining_frames;
uint32_t rx_offset;
uint32_t slot_offset;
uint16_t N_sl_id2; //id2 determined from PSS during sync ref UE selection
uint16_t N_sl_id1; //id2 determined from SSS during sync ref UE selection
uint16_t N_sl_id; //ID calculated from ID1 and ID2
int32_t psbch_rsrp; //rsrp of the decoded psbch during sync ref ue selection
uint32_t DFN; // DFN calculated after sync ref UE search
} SL_NR_SYNC_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;
SL_NR_SYNC_PARAMS_t sync_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
......@@ -165,5 +165,28 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
const 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);
/*! \brief This function prepares the sl indication to pass to the MAC
*/
void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind,
sl_nr_rx_indication_t *rx_ind,
sl_nr_sci_indication_t *sci_ind,
UE_nr_rxtx_proc_t *proc,
PHY_VARS_NR_UE *ue,
void *phy_data);
void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind,
uint8_t pdu_type,
PHY_VARS_NR_UE *ue,
uint16_t n_pdus,
UE_nr_rxtx_proc_t *proc,
void *typeSpecific,
uint16_t rx_slss_id);
#endif
/** @}*/
......@@ -885,12 +885,15 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
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,
......@@ -899,7 +902,9 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
i-1,
ssb_index&7,
ssb_slot_2 == nr_slot_rx,
rxdataF);
rxdataF,
false,
fp->Nid_cell);
stop_meas(&ue->dlsch_channel_estimation_stats);
}
......@@ -949,9 +954,11 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
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(gNB_id, rsc_id, i, ue, proc, fp, rxdataF);
}
......@@ -983,9 +990,11 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr
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.
......@@ -1042,9 +1051,11 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
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);
......@@ -1133,7 +1144,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
}
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);
......@@ -1144,7 +1155,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
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.
......@@ -787,12 +787,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.
......@@ -98,7 +98,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