Commit 6143fc30 authored by Guy De Souza's avatar Guy De Souza

PBCH payload restructuring gNB

parent fd92827a
...@@ -154,25 +154,26 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, ...@@ -154,25 +154,26 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
uint8_t nushift, uint8_t nushift,
uint16_t M, uint16_t M,
uint16_t length, uint16_t length,
uint8_t encoded) uint8_t encoded,
uint32_t unscrambling_mask)
{ {
uint8_t reset, offset; uint8_t reset, offset;
uint32_t x1, x2, s=0; uint32_t x1, x2, s=0;
uint32_t *pbch_e = pbch->pbch_e; uint32_t *pbch_e = pbch->pbch_e;
uint32_t unscrambling_mask = 0x100006D; //uint32_t unscrambling_mask = 0x100006D;
reset = 1; reset = 1;
// x1 is set in lte_gold_generic // x1 is set in lte_gold_generic
x2 = Nid; x2 = Nid;
// The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words // The Gold sequence is shifted by nushift* M, so we skip (nushift*M /32) double words
for (int i=0; i<(uint16_t)ceil(((float)nushift*M)/32); i++) { for (int i=0; i<CEILIDIV(nushift*M,32); i++) {
s = lte_gold_generic(&x1, &x2, reset); s = lte_gold_generic(&x1, &x2, reset);
reset = 0; reset = 0;
} }
// Scrambling is now done with offset (nushift*M)%32 // Scrambling is now done with offset (nushift*M)%32
offset = (nushift*M)&0x1f; offset = (nushift*M)&0x1f;
#ifdef DEBUG_PBCH_ENCODING //#ifdef DEBUG_PBCH_ENCODING
printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d\n", nushift, M, length, encoded, offset); printf("Scrambling params: nushift %d M %d length %d encoded %d offset %d mask 0x%08x\n", nushift, M, length, encoded, offset, unscrambling_mask);
#endif //#endif
for (int i=0; i<length; i++) { for (int i=0; i<length; i++) {
if (((i+offset)&0x1f)==0) { if (((i+offset)&0x1f)==0) {
...@@ -180,7 +181,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, ...@@ -180,7 +181,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
reset = 0; reset = 0;
} }
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("s: %04x\t", s); printf("i %d (i+offset)&0x1f %d s: %04x\n",i, (i+offset)&0x1f, s);
#endif #endif
if (!encoded) if (!encoded)
pbch->pbch_a_prime ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_interleaved>>i)&1)<<i : (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i; pbch->pbch_a_prime ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_interleaved>>i)&1)<<i : (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
...@@ -195,15 +196,17 @@ uint8_t nr_init_pbch_interleaver(uint8_t *interleaver) { ...@@ -195,15 +196,17 @@ uint8_t nr_init_pbch_interleaver(uint8_t *interleaver) {
memset((void*)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS); memset((void*)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
if (i<6) //Sfn bits:6 if (!i) // choice bit:1
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
else if (i<7) //Sfn bits:6
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
else if (i<24) // other else if (i<24) // other:17
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
else if (i<28) // Sfn:4 else if (i<28) // Sfn:4
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
else if (i==28) // Hrf bit else if (i==28) // Hrf bit:1
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf);
else // Ssb bits else // Ssb bits:3
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++); *(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++);
} }
...@@ -228,51 +231,43 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -228,51 +231,43 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
uint8_t idx=0; uint8_t idx=0;
uint16_t M; uint16_t M;
uint8_t nushift; uint8_t nushift;
uint8_t *xbyte = pbch->pbch_a; uint32_t unscrambling_mask;
memset((void*) xbyte, 0, 1);
//uint8_t pbch_a_b[32];
// LOG_D(PHY, "PBCH generation started\n"); LOG_I(PHY, "PBCH generation started\n");
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
///Payload generation ///Payload generation
// Fix byte endian
if (!(sfn&7)) memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
for (int i=0; i<(NR_PBCH_PDU_BITS>>3); i++) pbch->pbch_a=0;
pbch->pbch_a[(NR_POLAR_PBCH_PAYLOAD_BITS>>3)-i-1] = pbch_pdu[i]; for (int i=0; i<NR_PBCH_PDU_BITS; i++)
#ifdef DEBUG_PBCH_ENCODING pbch->pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<<i;
printf("Byte endian fix:\n"); //#ifdef DEBUG_PBCH_ENCODING
for (int i=0; i<4; i++) for (int i=0; i<3; i++)
printf("pbch_a[%d]: 0x%02x\n", i, pbch->pbch_a[i]); printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]);
#endif printf("PBCH payload = 0x%08x\n",pbch->pbch_a);
//#endif
// Extra byte generation // Extra byte generation
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
(*xbyte) ^= ((sfn>>i)&1)<<i; // 4 lsb of sfn pbch->pbch_a |= ((sfn>>(3-i))&1)<<(24+i); // resp. 4th, 3rd, 2nd ans 1st lsb of sfn
(*xbyte) ^= n_hf<<4; // half frame index bit pbch->pbch_a |= n_hf<<28; // half frame index bit
if (Lmax == 64) if (Lmax == 64)
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
(*xbyte) ^= ((ssb_index>>(3+i))&1)<<(5+i); // resp. 4th, 5th and 6th bits of ssb_index pbch->pbch_a |= ((ssb_index>>(5-i))&1)<<(29+i); // resp. 6th, 5th and 4th bits of ssb_index
else else
(*xbyte) ^= ((config->sch_config.ssb_subcarrier_offset.value>>5)&1)<<5; //MSB of k_SSB pbch->pbch_a |= ((config->sch_config.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4)
#ifdef DEBUG_PBCH_ENCODING
printf("Extra byte:\n");
for (int i=0; i<4; i++)
printf("pbch_a[%d]: 0x%02x\n", i, pbch->pbch_a[i]);
#endif
// Payload interleaving LOG_I(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a);
uint32_t in=0;
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
in |= (uint32_t)(pbch->pbch_a[i]<<((3-i)<<3));
// Payload interleaving
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) { for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) {
pbch->pbch_a_interleaved |= ((in>>i)&1)<<(*(interleaver+i)); pbch->pbch_a_interleaved |= ((pbch->pbch_a>>i)&1)<<(*(interleaver+i));
#ifdef DEBUG_PBCH_ENCODING //#ifdef DEBUG_PBCH_ENCODING
printf("i %d in 0x%08x out 0x%08x ilv %d (in>>i)&1) %d\n", i, in, pbch->pbch_a_interleaved, *(interleaver+i), (in>>i)&1); printf("i %d out 0x%08x ilv %d (in>>i)&1) %d\n", i, pbch->pbch_a_interleaved, *(interleaver+i), (pbch->pbch_a>>i)&1);
#endif //#endif
} }
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
...@@ -281,10 +276,11 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -281,10 +276,11 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
#endif #endif
// Scrambling // Scrambling
unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000021;
M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3); M = (Lmax == 64)? (NR_POLAR_PBCH_PAYLOAD_BITS - 6) : (NR_POLAR_PBCH_PAYLOAD_BITS - 3);
nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1); nushift = (((sfn>>2)&1)<<1) ^ ((sfn>>1)&1);
pbch->pbch_a_prime = 0; pbch->pbch_a_prime = 0;
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0); nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_PAYLOAD_BITS, 0, unscrambling_mask);
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("Payload scrambling: nushift %d M %d sfn3 %d sfn2 %d\n", nushift, M, (sfn>>2)&1, (sfn>>1)&1); printf("Payload scrambling: nushift %d M %d sfn3 %d sfn2 %d\n", nushift, M, (sfn>>2)&1, (sfn>>1)&1);
printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime); printf("pbch_a_prime: 0x%08x\n", pbch->pbch_a_prime);
...@@ -302,7 +298,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, ...@@ -302,7 +298,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
/// Scrambling /// Scrambling
M = NR_POLAR_PBCH_E; M = NR_POLAR_PBCH_E;
nushift = (Lmax==4)? ssb_index&3 : ssb_index&7; nushift = (Lmax==4)? ssb_index&3 : ssb_index&7;
nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1); nr_pbch_scrambling(pbch, (uint32_t)config->sch_config.physical_cell_id.value, nushift, M, NR_POLAR_PBCH_E, 1, 0);
#ifdef DEBUG_PBCH_ENCODING #ifdef DEBUG_PBCH_ENCODING
printf("Scrambling:\n"); printf("Scrambling:\n");
for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++) for (int i=0; i<NR_POLAR_PBCH_E_DWORD; i++)
......
...@@ -75,7 +75,8 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch, ...@@ -75,7 +75,8 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
uint8_t nushift, uint8_t nushift,
uint16_t M, uint16_t M,
uint16_t length, uint16_t length,
uint8_t encoded); uint8_t encoded,
uint32_t unscrambling_mask);
/*! /*!
\fn int nr_generate_pbch \fn int nr_generate_pbch
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include <stdint.h> #include <stdint.h>
#include "PHY/sse_intrin.h" #include "PHY/sse_intrin.h"
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
struct complex { struct complex {
double x; double x;
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
#define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB
typedef struct { typedef struct {
uint8_t pbch_a[NR_POLAR_PBCH_PAYLOAD_BITS>>3]; uint32_t pbch_a;
uint32_t pbch_a_interleaved; uint32_t pbch_a_interleaved;
uint32_t pbch_a_prime; uint32_t pbch_a_prime;
uint32_t pbch_e[NR_POLAR_PBCH_E_DWORD]; uint32_t pbch_e[NR_POLAR_PBCH_E_DWORD];
......
...@@ -259,6 +259,16 @@ RUs = ( ...@@ -259,6 +259,16 @@ RUs = (
} }
); );
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
NETWORK_CONTROLLER : NETWORK_CONTROLLER :
{ {
FLEXRAN_ENABLED = "no"; FLEXRAN_ENABLED = "no";
......
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