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

PBCH generation/coding/Modulation

parent 860c9907
...@@ -257,8 +257,8 @@ main() ...@@ -257,8 +257,8 @@ main()
{ {
unsigned char test[] = "Thebigredfox"; unsigned char test[] = "Thebigredfox";
crcTableInit(); crcTableInit();
printf("%x\n", crcbit(test, sizeof(test) - 1, poly24a)); //printf("%x\n", crcbit(test, sizeof(test) - 1, poly24a));
printf("%x\n", crc24a(test, (sizeof(test) - 1)*8)); //printf("%x\n", crc24a(test, (sizeof(test) - 1)*8));
printf("%x\n", crcbit(test, sizeof(test) - 1, poly6)); printf("%x\n", crcbit(test, sizeof(test) - 1, poly6));
printf("%x\n", crc6(test, (sizeof(test) - 1)*8)); printf("%x\n", crc6(test, (sizeof(test) - 1)*8));
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef __NR_POLAR_PBCH_DEFS__H__ #ifndef __NR_POLAR_PBCH_DEFS__H__
#define __NR_POLAR_PBCH_DEFS__H__ #define __NR_POLAR_PBCH_DEFS__H__
#define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t #define NR_POLAR_PBCH_PAYLOAD_BITS 32 //uint16_t
#define NR_POLAR_PBCH_CRC_PARITY_BITS 24 #define NR_POLAR_PBCH_CRC_PARITY_BITS 24
#define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3 #define NR_POLAR_PBCH_CRC_ERROR_CORRECTION_BITS 3
......
...@@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB) ...@@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB)
for (n_hf = 0; n_hf < N_hf; n_hf++) { for (n_hf = 0; n_hf < N_hf; n_hf++) {
for (l = 0; l < Lmax ; l++) { for (l = 0; l < Lmax ; l++) {
i_ssb = l & Lmax; i_ssb = l & (Lmax-1);
i_ssb2 = (i_ssb<<2) + n_hf; i_ssb2 = (i_ssb<<2) + n_hf;
x1 = 1 + (1<<31); x1 = 1 + (1<<31);
......
...@@ -30,11 +30,13 @@ ...@@ -30,11 +30,13 @@
* \warning * \warning
*/ */
#include "PHY/defs_gNB.h"
#include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport.h"
#include "PHY/phy_extern.h" #include "PHY/phy_extern.h"
#include "PHY/sse_intrin.h" #include "PHY/sse_intrin.h"
//#define DEBUG_PBCH //#define DEBUG_PBCH
//#define DEBUG_PBCH_ENCODING
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT]; extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
...@@ -42,7 +44,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -42,7 +44,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t **txdataF, int32_t **txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, uint8_t ssb_start_symbol,
uint8_t nu, uint8_t nushift,
nfapi_config_request_t* config, nfapi_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms) NR_DL_FRAME_PARMS *frame_parms)
{ {
...@@ -50,7 +52,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -50,7 +52,7 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int16_t a; int16_t a;
int16_t mod_dmrs[2 * NR_PBCH_DMRS_LENGTH]; 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 /// BPSK modulation
for (int m=0; m<NR_PBCH_DMRS_LENGTH; m++) { for (int m=0; m<NR_PBCH_DMRS_LENGTH; m++) {
...@@ -67,9 +69,9 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -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++) 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 // PBCH DMRS are mapped within the SSB block on every fourth subcarrier starting from nushift of symbols 1, 2, 3
///symbol 1 [0+nu:4:236+nu] -- 60 mod symbols ///symbol 1 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nu; k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l = ssb_start_symbol + 1; l = ssb_start_symbol + 1;
for (int m = 0; m < 60; m++) { for (int m = 0; m < 60; m++) {
...@@ -84,8 +86,8 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -84,8 +86,8 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
k-=frame_parms->ofdm_symbol_size; k-=frame_parms->ofdm_symbol_size;
} }
///symbol 2 [0+u:4:44+nu ; 192+nu:4:236+nu] -- 24 mod symbols ///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 + nu; k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++; l++;
for (int m = 60; m < 84; m++) { for (int m = 60; m < 84; m++) {
...@@ -100,8 +102,8 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -100,8 +102,8 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
k-=frame_parms->ofdm_symbol_size; k-=frame_parms->ofdm_symbol_size;
} }
///symbol 3 [0+nu:4:236+nu] -- 60 mod symbols ///symbol 3 [0+nushift:4:236+nushift] -- 60 mod symbols
k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nu; k = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier + nushift;
l++; l++;
for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) { for (int m = 84; m < NR_PBCH_DMRS_LENGTH; m++) {
...@@ -125,23 +127,141 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -125,23 +127,141 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
return 0; 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, int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t *pbch_pdu, uint8_t *pbch_pdu,
int32_t **txdataF, int32_t **txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, 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, nfapi_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms) NR_DL_FRAME_PARMS *frame_parms)
{ {
int m,k,l; int m,k,l;
int a, aa; int16_t a;
int16_t mod_payload[2 * NR_PBCH_LENGTH]; int16_t mod_pbch_e[NR_POLAR_PBCH_E<<1];
uint8_t sfn_4lsb, idx=0;
LOG_I(PHY, "PBCH generation started\n"); 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; return 0;
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#define NR_PBCH_PDU_BITS 24
/*! /*!
\fn int nr_generate_pss \fn int nr_generate_pss
...@@ -61,10 +62,19 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs, ...@@ -61,10 +62,19 @@ int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
int32_t **txdataF, int32_t **txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, uint8_t ssb_start_symbol,
uint8_t nu, uint8_t nushift,
nfapi_config_request_t* config, nfapi_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms); 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 \fn int nr_generate_pbch
\brief Generation of the PBCH \brief Generation of the PBCH
...@@ -76,7 +86,10 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -76,7 +86,10 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
int32_t **txdataF, int32_t **txdataF,
int16_t amp, int16_t amp,
uint8_t ssb_start_symbol, 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, nfapi_config_request_t* config,
NR_DL_FRAME_PARMS *frame_parms); NR_DL_FRAME_PARMS *frame_parms);
......
...@@ -34,10 +34,12 @@ ...@@ -34,10 +34,12 @@
#include "defs_eNB.h" #include "defs_eNB.h"
#include "defs_nr_common.h" #include "defs_nr_common.h"
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
typedef struct { 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; } NR_gNB_PBCH;
typedef struct { typedef struct {
......
...@@ -122,24 +122,32 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) { ...@@ -122,24 +122,32 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
int **txdataF = gNB->common_vars.txdataF; int **txdataF = gNB->common_vars.txdataF;
uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t *pbch_pdu=&gNB->pbch_pdu[0];
int ss_subframe = (cfg->sch_config.half_frame_index.value)? 5 : 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); LOG_D(PHY,"common_signal_procedures: frame %d, subframe %d\n",frame,subframe);
int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp); int ssb_start_symbol = nr_get_ssb_start_symbol(cfg, fp);
nr_set_ssb_first_subcarrier(cfg, fp); nr_set_ssb_first_subcarrier(cfg, fp);
Lmax = (fp->dl_CarrierFreq < 3e9)? 4:8; 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) if (subframe == ss_subframe)
{ {
// Current implementation is based on SSB in first half frame, first candidate // 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); 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_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_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);
} }
} }
......
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