diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c b/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c index 1d3fa5ebf4414aedbebec18c764b95d13baf8f31..b59414716903022c5a012d9cbfa9ec4d3d296292 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_crc_byte.c @@ -257,8 +257,8 @@ main() { unsigned char test[] = "Thebigredfox"; crcTableInit(); - printf("%x\n", crcbit(test, sizeof(test) - 1, poly24a)); - printf("%x\n", crc24a(test, (sizeof(test) - 1)*8)); + //printf("%x\n", crcbit(test, sizeof(test) - 1, poly24a)); + //printf("%x\n", crc24a(test, (sizeof(test) - 1)*8)); printf("%x\n", crcbit(test, sizeof(test) - 1, poly6)); printf("%x\n", crc6(test, (sizeof(test) - 1)*8)); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h index 1fc0f254b32739f62e2aba71854915856d43b07f..5f6dcce19d4a6e6063df5b28aa12c70331414551 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h @@ -5,7 +5,6 @@ #ifndef __NR_POLAR_PBCH_DEFS__H__ #define __NR_POLAR_PBCH_DEFS__H__ - #define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t #define NR_POLAR_PBCH_CRC_PARITY_BITS 24 #define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3 diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index b070749fa128fe3d45c8494e832ba42d7bcd5c82..dca4089e6a09d53c39ebf73b6b6e93c5725ff420 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) for (n_hf = 0; n_hf < N_hf; n_hf++) { for (l = 0; l < Lmax ; l++) { - i_ssb = l & Lmax; + i_ssb = l & (Lmax-1); i_ssb2 = (i_ssb<<2) + n_hf; x1 = 1 + (1<<31); diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 34facbc7e1ee10574f592e730c5607392ed257f3..f25873c77f3bc49581d64ae87194ed48d7d03c57 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -30,11 +30,13 @@ * \warning */ +#include "PHY/defs_gNB.h" #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/phy_extern.h" #include "PHY/sse_intrin.h" //#define DEBUG_PBCH +//#define DEBUG_PBCH_ENCODING extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; @@ -42,7 +44,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int32_t **txdataF, int16_t amp, uint8_t ssb_start_symbol, - uint8_t nu, + uint8_t nushift, nfapi_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms) { @@ -50,7 +52,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int16_t a; int16_t mod_dmrs[2 * NR_PBCH_DMRS_LENGTH]; - LOG_I(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nu); + LOG_I(PHY, "PBCH DMRS mapping started at symbol %d shift %d\n", ssb_start_symbol+1, nushift); /// BPSK modulation for (int m=0; m<NR_PBCH_DMRS_LENGTH; m++) { @@ -67,9 +69,9 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, for (int aa = 0; aa < config->rf_config.tx_antenna_ports.value; aa++) { - // PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nu of symbols 1, 2, 3 - ///symbol 1 [0+nu:4:236+nu] -- 60 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nu; + // PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3 + ///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols + k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; l = ssb_start_symbol + 1; for (int m = 0; m < 60; m++) { @@ -84,8 +86,8 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, k-=frame_parms->ofdm_symbol_size; } - ///symbol 2 [0+u:4:44+nu ; 192+nu:4:236+nu] -- 24 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nu; + ///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols + k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; l++; for (int m = 60; m < 84; m++) { @@ -100,8 +102,8 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, k-=frame_parms->ofdm_symbol_size; } - ///symbol 3 [0+nu:4:236+nu] -- 60 mod symbols - k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nu; + ///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols + k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; l++; for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) { @@ -125,23 +127,141 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, return 0; } -#define NR_PBCH_LENGTH 1000 +void nr_pbch_scrambling(uint32_t Nid, + uint8_t *pbch_a, + uint32_t length) +{ + uint8_t reset; + uint32_t x1, x2, s=0; + + reset = 1; + // x1 is set in lte_gold_generic + x2 = Nid; + + for (int i=0; i<length; i++) { + if ((i&0x1f)==0) { + s = lte_gold_generic(&x1, &x2, reset); + reset = 0; + } + pbch_a[i] = (pbch_a[i]&1) ^ ((s>>(i&0x1f))&1); + } +} + int nr_generate_pbch(NR_gNB_PBCH *pbch, uint8_t *pbch_pdu, int32_t **txdataF, int16_t amp, uint8_t ssb_start_symbol, - uint8_t nu, + uint8_t nushift, + uint8_t n_hf, + int sfn, + int frame_mod8, nfapi_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms) { int m,k,l; - int a, aa; - int16_t mod_payload[2 * NR_PBCH_LENGTH]; + int16_t a; + int16_t mod_pbch_e[NR_POLAR_PBCH_E<<1]; + uint8_t sfn_4lsb, idx=0; LOG_I(PHY, "PBCH generation started\n"); + ///Payload generation + // Fix byte endian + if (!frame_mod8) + for (int i=0; i<NR_PBCH_PDU_BITS; i++) + pbch->pbch_a[NR_PBCH_PDU_BITS-i-1] = pbch_pdu[i]; + + // Extra bits generation + sfn_4lsb = sfn&3; + for (int i=0; i<4; i++) + pbch->pbch_a[NR_PBCH_PDU_BITS+i] = (sfn_4lsb>>i)&1; // 4 lsb of sfn + + pbch->pbch_a[NR_PBCH_PDU_BITS+4] = n_hf; // half frame index bit + + pbch->pbch_a[NR_PBCH_PDU_BITS+5] = (config->sch_config.ssb_subcarrier_offset.value>>5)&1; //MSB of k0 -- Note the case Lssb=64 is not supported (FR2) + + // Scrambling + nr_pbch_scrambling((uint32_t)config->sch_config.physical_cell_id.value, pbch->pbch_a, NR_POLAR_PBCH_PAYLOAD_BITS); + + /// CRC, coding and rate matching + polar_encoder (pbch->pbch_a, pbch->pbch_e, &frame_parms->pbch_polar_params); + + /// QPSK modulation + for (int i=0; i<NR_POLAR_PBCH_E>>2; i++){ + idx = (pbch->pbch_e[i<<2]&1) ^ ((pbch->pbch_e[(i<<2)+1]&1)<<1); + mod_pbch_e[i<<2] = nr_mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; + mod_pbch_e[(i<<2)+1] = nr_mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1)+1]; + +#ifdef DEBUG_PBCH + printf("i %d mod_pbch %d %d\n", i, mod_pbch_e[2*i], mod_pbch_e[2*i+1]); +#endif + } + + /// Resource mapping +/* a = (config->rf_config.tx_antenna_ports.value == 1) ? amp : (amp*ONE_OVER_SQRT2_Q15)>>15; + + for (int aa = 0; aa < config->rf_config.tx_antenna_ports.value; aa++) + { + + // PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3 + ///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols + k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; + l = ssb_start_symbol + 1; + + for (int m = 0; m < 60; m++) { +#ifdef DEBUG_PBCH + printf("m %d at k %d of l %d\n", m, k, l); +#endif + ((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15; + ((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15; + k+=4; + + if (k >= frame_parms->ofdm_symbol_size) + k-=frame_parms->ofdm_symbol_size; + } + + ///symbol 2 [0+u:4:44+nushift ; 192+nu:4:236+nushift] -- 24 mod symbols + k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; + l++; + + for (int m = 60; m < 84; m++) { +#ifdef DEBUG_PBCH + printf("m %d at k %d of l %d\n", m, k, l); +#endif + ((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15; + ((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15; + k+=(m==71)?148:4; // Jump from 44+nu to 192+nu + + if (k >= frame_parms->ofdm_symbol_size) + k-=frame_parms->ofdm_symbol_size; + } + + ///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols + k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift; + l++; + + for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) { +#ifdef DEBUG_PBCH + printf("m %d at k %d of l %d\n", m, k, l); +#endif + ((int16_t*)txdataF[aa])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (a * mod_dmrs[m<<1]) >> 15; + ((int16_t*)txdataF[aa])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (a * mod_dmrs[(m<<1) + 1]) >> 15; + k+=4; + + if (k >= frame_parms->ofdm_symbol_size) + k-=frame_parms->ofdm_symbol_size; + } + + } + + +#ifdef DEBUG_PBCH + write_output("txdataF.m", "txdataF", txdataF[0], frame_parms->samples_per_frame_wCP>>1, 1, 1); +#endif + +*/ return 0; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport.h b/openair1/PHY/NR_TRANSPORT/nr_transport.h index cc83734bd7cc45e399502903a1874cf29fe617ac..736526218a869ebeac9acbbb9a159b86ec351843 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport.h @@ -24,6 +24,7 @@ #include "PHY/defs_gNB.h" +#define NR_PBCH_PDU_BITS 24 /*! \fn int nr_generate_pss @@ -61,10 +62,19 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, int32_t **txdataF, int16_t amp, uint8_t ssb_start_symbol, - uint8_t nu, + uint8_t nushift, nfapi_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms); +/*! +\fn int nr_pbch_scrambling +\brief PBCH scrambling function +@param + */ +void nr_pbch_scrambling(uint32_t Nid, + uint8_t *pbch_a, + uint32_t length); + /*! \fn int nr_generate_pbch \brief Generation of the PBCH @@ -76,7 +86,10 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, int32_t **txdataF, int16_t amp, uint8_t ssb_start_symbol, - uint8_t nu, + uint8_t nushift, + uint8_t n_hf, + int sfn, + int frame_mod8, nfapi_config_request_t* config, NR_DL_FRAME_PARMS *frame_parms); diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 0d12dcb1628bd424e2fad8ccd56a2d5c550e7c83..20f58409b1fbd9b7de8548d9025dfb5e03c91cef 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -34,10 +34,12 @@ #include "defs_eNB.h" #include "defs_nr_common.h" +#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h" typedef struct { - uint8_t pbch_d[100]; + uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS]; + uint8_t pbch_e[NR_POLAR_PBCH_E]; } NR_gNB_PBCH; typedef struct { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 5a3d0699c6f2b68f4333422c8cd470c441bd7472..a2099b82cb8c3afa17d2ce20837ae993eb25074d 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -122,24 +122,32 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) { int **txdataF = gNB->common_vars.txdataF; uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; int ss_subframe = (cfg->sch_config.half_frame_index.value)? 5 : 0; - uint8_t Lmax, nu, ssb_index=0, n_hf=0; + int sfn = 10*frame + subframe; + int frame_mod8 = frame&7; + uint8_t Lmax, nushift, ssb_index=0, n_hf=0; LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d\n",frame,subframe); int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp); nr_set_ssb_first_subcarrier(cfg, fp); Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8; - nu = (Lmax < 8)? ssb_index&3 : ssb_index&7; + nushift = (Lmax < 8)? ssb_index&3 : ssb_index&7; if (subframe == ss_subframe) { // Current implementation is based on SSB in first half frame, first candidate LOG_I(PHY,"SS TX: frame %d, subframe %d, start_symbol %d\n",frame,subframe, ssb_start_symbol); + nr_generate_pss(gNB->d_pss, txdataF, AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(gNB->d_sss, txdataF, AMP_OVER_2, ssb_start_symbol, cfg, fp); - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF, AMP_OVER_2, ssb_start_symbol, nu, cfg, fp); - nr_generate_pbch(&gNB->pbch, pbch_pdu, txdataF, AMP_OVER_2, ssb_start_symbol, nu, cfg, fp); + + /*if ((frame_mod8) == 0){ + if (gNB->pbch_configured != 1)return; + gNB->pbch_configured = 0; + }*/ + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF, AMP_OVER_2, ssb_start_symbol, nushift, cfg, fp); + nr_generate_pbch(&gNB->pbch, pbch_pdu, txdataF, AMP_OVER_2, ssb_start_symbol, nushift, sfn, n_hf, frame_mod8, cfg, fp); } }