Merge remote-tracking branch 'origin/develop-nr' into nr_pdsch
This commit is contained in:
@@ -144,6 +144,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
|
nr_init_pdcch_dmrs(gNB, cfg->sch_config.physical_cell_id.value);
|
||||||
|
nr_init_pbch_interleaver(gNB->nr_pbch_interleaver);
|
||||||
|
|
||||||
|
|
||||||
//PDSCH DMRS init
|
//PDSCH DMRS init
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
/*! \file PHY/NR_TRANSPORT/nr_pbch.c
|
/*! \file PHY/NR_TRANSPORT/nr_pbch.c
|
||||||
* \brief Top-level routines for generating the PBCH/BCH physical/transport channel V15.1 03/2018
|
* \brief Top-level routines for generating the PBCH/BCH physical/transport channel V15.1 03/2018
|
||||||
* \author Guy De Souza
|
* \author Guy De Souza
|
||||||
|
* \thanks Special Thanks to Son Dang for helpfull contributions and testing
|
||||||
* \date 2018
|
* \date 2018
|
||||||
* \version 0.1
|
* \version 0.1
|
||||||
* \company Eurecom
|
* \company Eurecom
|
||||||
@@ -41,6 +42,9 @@
|
|||||||
|
|
||||||
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
|
extern short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT];
|
||||||
|
|
||||||
|
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
|
||||||
|
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
|
||||||
|
|
||||||
int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
int nr_generate_pbch_dmrs(uint32_t *gold_pbch_dmrs,
|
||||||
int32_t **txdataF,
|
int32_t **txdataF,
|
||||||
int16_t amp,
|
int16_t amp,
|
||||||
@@ -151,66 +155,83 @@ 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;
|
|
||||||
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<(uint16_t)ceil(((float)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\n", nushift, M, length, encoded, offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i=0; i<length; i++) {
|
|
||||||
if (((i+offset)&0x1f)==0) {
|
|
||||||
s = lte_gold_generic(&x1, &x2, reset);
|
|
||||||
reset = 0;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_PBCH_ENCODING
|
#ifdef DEBUG_PBCH_ENCODING
|
||||||
printf("s: %04x\t", s);
|
printf("s: %04x\t", s);
|
||||||
#endif
|
#endif
|
||||||
if (!encoded)
|
int k = 0;
|
||||||
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;
|
|
||||||
|
if (!encoded) {
|
||||||
|
/// 1st Scrambling
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
if ((unscrambling_mask>>i)&1)
|
||||||
|
pbch->pbch_a_prime ^= ((pbch->pbch_a_interleaved>>i)&1)<<i;
|
||||||
|
else {
|
||||||
|
if (((k+offset)&0x1f)==0) {
|
||||||
|
s = lte_gold_generic(&x1, &x2, reset);
|
||||||
|
reset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pbch->pbch_a_prime ^= (((pbch->pbch_a_interleaved>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
|
||||||
|
k++; /// k increase only when payload bit is not special bit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/// 2nd Scrambling
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
if (((i+offset)&0x1f)==0) {
|
||||||
|
s = lte_gold_generic(&x1, &x2, reset);
|
||||||
|
reset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
else
|
|
||||||
pbch_e[i>>5] ^= (((s>>((i+offset)&0x1f))&1)<<(i&0x1f));
|
pbch_e[i>>5] ^= (((s>>((i+offset)&0x1f))&1)<<(i&0x1f));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This portion of code is temporarily kept until the optimized version is validated
|
|
||||||
uint8_t nr_pbch_payload_interleaving_pattern[32] = {16, 23, 18, 17, 8, 30, 10, 6, 24, 7, 0, 5, 3, 2, 1, 4,
|
|
||||||
9, 11, 12, 13, 14, 15, 19, 20, 21, 22, 25, 26, 27, 28, 29, 31};
|
|
||||||
|
|
||||||
uint8_t nr_pbch_payload_interleaver(uint8_t i) {
|
void nr_init_pbch_interleaver(uint8_t *interleaver) {
|
||||||
uint8_t j_sfn=6, j_hrf=10, j_ssb=11, j_other=14;
|
uint8_t j_sfn=0, j_hrf=10, j_ssb=11, j_other=14;
|
||||||
|
memset((void*)interleaver,0, NR_POLAR_PBCH_PAYLOAD_BITS);
|
||||||
|
|
||||||
if (24<=i && i<=27) //Sfn bits
|
for (uint8_t i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
|
||||||
return nr_pbch_payload_interleaving_pattern[j_sfn + i -24];
|
if (!i) // choice bit:1
|
||||||
else if (i==28) // Hrf bit
|
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
|
||||||
return nr_pbch_payload_interleaving_pattern[j_hrf];
|
else if (i<7) //Sfn bits:6
|
||||||
else if (29<=i) // Ssb bits
|
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
|
||||||
return nr_pbch_payload_interleaving_pattern[j_ssb + (i-29)];
|
else if (i<24) // other:17
|
||||||
else
|
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_other++);
|
||||||
return nr_pbch_payload_interleaving_pattern[(j_other + i)&0x1f];
|
else if (i<28) // Sfn:4
|
||||||
|
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_sfn++);
|
||||||
|
else if (i==28) // Hrf bit:1
|
||||||
|
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_hrf);
|
||||||
|
else // Ssb bits:3
|
||||||
|
*(interleaver+i) = *(nr_pbch_payload_interleaving_pattern+j_ssb++);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*This pattern takes into account the adjustments for the field specific counters j_sfn, j_hrf, j_ssb and j_other*/
|
|
||||||
//uint8_t nr_pbch_payload_interleaving_pattern[32] = {1,4,9,11,12,13,14,15,19,20,21,22,25,26,27,28,
|
|
||||||
// 29,31,16,23,18,17,8,30,10,6,24,7,0,5,3,2};
|
|
||||||
|
|
||||||
int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
||||||
t_nrPolar_paramsPtr polar_params,
|
t_nrPolar_paramsPtr polar_params,
|
||||||
uint8_t *pbch_pdu,
|
uint8_t *pbch_pdu,
|
||||||
|
uint8_t *interleaver,
|
||||||
int32_t **txdataF,
|
int32_t **txdataF,
|
||||||
int16_t amp,
|
int16_t amp,
|
||||||
uint8_t ssb_start_symbol,
|
uint8_t ssb_start_symbol,
|
||||||
@@ -228,50 +249,42 @@ 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");
|
||||||
|
|
||||||
|
///Payload generation
|
||||||
|
|
||||||
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
|
memset((void*)pbch, 0, sizeof(NR_gNB_PBCH));
|
||||||
///Payload generation
|
pbch->pbch_a=0;
|
||||||
// Fix byte endian
|
for (int i=0; i<NR_PBCH_PDU_BITS; i++)
|
||||||
if (!(sfn&7))
|
pbch->pbch_a |= ((pbch_pdu[2-(i>>3)]>>(7-(i&7)))&1)<<i;
|
||||||
for (int i=0; i<(NR_PBCH_PDU_BITS>>3); i++)
|
|
||||||
pbch->pbch_a[(NR_POLAR_PBCH_PAYLOAD_BITS>>3)-i-1] = pbch_pdu[i];
|
|
||||||
#ifdef DEBUG_PBCH_ENCODING
|
#ifdef DEBUG_PBCH_ENCODING
|
||||||
printf("Byte endian fix:\n");
|
for (int i=0; i<3; i++)
|
||||||
for (int i=0; i<4; i++)
|
printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]);
|
||||||
printf("pbch_a[%d]: 0x%02x\n", i, pbch->pbch_a[i]);
|
printf("PBCH payload = 0x%08x\n",pbch->pbch_a);
|
||||||
#endif
|
#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");
|
LOG_I(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a);
|
||||||
for (int i=0; i<4; i++)
|
|
||||||
printf("pbch_a[%d]: 0x%02x\n", i, pbch->pbch_a[i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Payload interleaving
|
// Payload interleaving
|
||||||
uint32_t in=0;
|
|
||||||
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
|
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++) {
|
||||||
in |= (uint32_t)(pbch->pbch_a[i]<<((3-i)<<3));
|
pbch->pbch_a_interleaved |= ((pbch->pbch_a>>i)&1)<<(*(interleaver+i));
|
||||||
|
|
||||||
for (int i=0; i<32; i++) {
|
|
||||||
pbch->pbch_a_interleaved |= ((in>>i)&1)<<(nr_pbch_payload_interleaver(i));//nr_pbch_payload_interleaving_pattern[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, nr_pbch_payload_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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,10 +294,11 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Scrambling
|
// Scrambling
|
||||||
|
unscrambling_mask = (Lmax ==64)? 0x100006D:0x1000041;
|
||||||
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 +316,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,
|
|||||||
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
|
||||||
@@ -86,6 +87,7 @@ void nr_pbch_scrambling(NR_gNB_PBCH *pbch,
|
|||||||
int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
||||||
t_nrPolar_paramsPtr polar_params,
|
t_nrPolar_paramsPtr polar_params,
|
||||||
uint8_t *pbch_pdu,
|
uint8_t *pbch_pdu,
|
||||||
|
uint8_t *interleaver,
|
||||||
int32_t **txdataF,
|
int32_t **txdataF,
|
||||||
int16_t amp,
|
int16_t amp,
|
||||||
uint8_t ssb_start_symbol,
|
uint8_t ssb_start_symbol,
|
||||||
@@ -102,7 +104,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
|||||||
@param bit index i of the input payload
|
@param bit index i of the input payload
|
||||||
@returns the bit index of the output
|
@returns the bit index of the output
|
||||||
*/
|
*/
|
||||||
uint8_t nr_pbch_payload_interleaver(uint8_t i);
|
void nr_init_pbch_interleaver(uint8_t *interleaver);
|
||||||
|
|
||||||
NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
|
NR_gNB_DLSCH_t *new_gNB_dlsch(unsigned char Kmimo,
|
||||||
unsigned char Mdlharq,
|
unsigned char Mdlharq,
|
||||||
|
|||||||
@@ -437,14 +437,14 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
|
|||||||
uint8_t nushift,
|
uint8_t nushift,
|
||||||
uint16_t M,
|
uint16_t M,
|
||||||
uint16_t length,
|
uint16_t length,
|
||||||
uint8_t bitwise)
|
uint8_t bitwise,
|
||||||
|
uint32_t unscrambling_mask)
|
||||||
{
|
{
|
||||||
uint8_t reset, offset;
|
uint8_t reset, offset;
|
||||||
uint32_t x1, x2, s=0;
|
uint32_t x1, x2, s=0;
|
||||||
|
uint8_t k=0;
|
||||||
int16_t *demod_pbch_e = pbch->llr;
|
int16_t *demod_pbch_e = pbch->llr;
|
||||||
|
|
||||||
uint32_t unscrambling_mask = 0x100006D;
|
|
||||||
|
|
||||||
|
|
||||||
reset = 1;
|
reset = 1;
|
||||||
// x1 is set in first call to lte_gold_generic
|
// x1 is set in first call to lte_gold_generic
|
||||||
@@ -470,7 +470,8 @@ void nr_pbch_unscrambling(NR_UE_PBCH *pbch,
|
|||||||
#endif
|
#endif
|
||||||
if (bitwise) {
|
if (bitwise) {
|
||||||
|
|
||||||
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((i+offset)&0x1f))&1))<<i;
|
(pbch->pbch_a_interleaved) ^= ((unscrambling_mask>>i)&1)? ((pbch->pbch_a_prime>>i)&1)<<i : (((pbch->pbch_a_prime>>i)&1) ^ ((s>>((k+offset)&0x1f))&1))<<i;
|
||||||
|
k+=!((unscrambling_mask>>i)&1);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
@@ -508,7 +509,7 @@ unsigned char sign(int8_t x) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,1,29,25,27,22,2,24,3,4,5,6,7,18,21,20,8,9,10,11,19,26,12,13,14,15,16,23,17};
|
uint8_t pbch_deinterleaving_pattern[32] = {28,0,31,30,7,29,25,27,5,8,24,9,10,11,12,13,1,4,3,14,15,16,17,2,26,18,19,20,21,22,30,23};
|
||||||
|
|
||||||
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||||
UE_nr_rxtx_proc_t *proc,
|
UE_nr_rxtx_proc_t *proc,
|
||||||
@@ -647,7 +648,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
//un-scrambling
|
//un-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_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0);
|
uint32_t unscrambling_mask = (Lmax==64)?0x100006D:0x1000041;
|
||||||
|
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_E,0,0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -664,18 +666,18 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
if(decoderState == -1)
|
if(decoderState == -1)
|
||||||
return(decoderState);
|
return(decoderState);
|
||||||
|
|
||||||
//printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
|
printf("polar decoder output 0x%08x\n",nr_ue_pbch_vars->pbch_a_prime);
|
||||||
|
|
||||||
//payload un-scrambling
|
//payload un-scrambling
|
||||||
memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
|
memset(&nr_ue_pbch_vars->pbch_a_interleaved, 0, sizeof(uint32_t) );
|
||||||
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 = ((nr_ue_pbch_vars->pbch_a_prime>>6)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>24)&1)<<1);
|
nushift = ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) ^ (((nr_ue_pbch_vars->pbch_a_prime>>6)&1)<<1);
|
||||||
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1);
|
nr_pbch_unscrambling(nr_ue_pbch_vars,frame_parms->Nid_cell,nushift,M,NR_POLAR_PBCH_PAYLOAD_BITS,1,unscrambling_mask);
|
||||||
|
printf("nushift %d sfn 3rd %d 2nd %d", nushift,((nr_ue_pbch_vars->pbch_a_prime>>6)&1), ((nr_ue_pbch_vars->pbch_a_prime>>24)&1) );
|
||||||
|
|
||||||
//payload deinterleaving
|
//payload deinterleaving
|
||||||
//uint32_t in=0;
|
//uint32_t in=0;
|
||||||
uint32_t out=0;
|
uint32_t out=0;
|
||||||
|
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
|
out |= ((nr_ue_pbch_vars->pbch_a_interleaved>>i)&1)<<(pbch_deinterleaving_pattern[i]);
|
||||||
#ifdef DEBUG_PBCH
|
#ifdef DEBUG_PBCH
|
||||||
@@ -683,14 +685,18 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS>>3; i++)
|
uint32_t payload = 0;
|
||||||
decoded_output[i] = (uint8_t)((out>>(i<<3))&0xff);
|
uint8_t xtra_byte = 0;
|
||||||
|
xtra_byte = (out>>24)&0xff;
|
||||||
|
|
||||||
|
for (int i=0; i<NR_POLAR_PBCH_PAYLOAD_BITS; i++)
|
||||||
|
payload |= ((out>>i)&1)<<(NR_POLAR_PBCH_PAYLOAD_BITS-i-1);
|
||||||
|
|
||||||
|
for (int i=0; i<3; i++)
|
||||||
|
decoded_output[i] = (uint8_t)((payload>>((3-i)<<3))&0xff);
|
||||||
|
|
||||||
// Fix byte endian
|
|
||||||
// for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++)
|
|
||||||
// decoded_output[(NR_POLAR_PBCH_PAYLOAD_BITS>>3)-i-1] = pbch_a[i];
|
|
||||||
|
|
||||||
#ifdef DEBUG_PBCH
|
#ifdef DEBUG_PBCH
|
||||||
|
printf("xtra_byte %x payload %x\n", xtra_byte, payload);
|
||||||
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
|
for (i=0; i<(NR_POLAR_PBCH_PAYLOAD_BITS>>3); i++){
|
||||||
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
|
// printf("unscrambling pbch_a[%d] = %x \n", i,pbch_a[i]);
|
||||||
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
|
printf("[PBCH] decoder payload[%d] = %x\n",i,decoded_output[i]);
|
||||||
@@ -703,7 +709,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
|||||||
ue->rx_ind.rx_indication_body = (fapi_nr_rx_indication_body_t *)malloc(sizeof(fapi_nr_rx_indication_body_t));
|
ue->rx_ind.rx_indication_body = (fapi_nr_rx_indication_body_t *)malloc(sizeof(fapi_nr_rx_indication_body_t));
|
||||||
ue->rx_ind.rx_indication_body->pdu_type = FAPI_NR_RX_PDU_TYPE_MIB;
|
ue->rx_ind.rx_indication_body->pdu_type = FAPI_NR_RX_PDU_TYPE_MIB;
|
||||||
ue->rx_ind.rx_indication_body->mib_pdu.pdu = &decoded_output[0];
|
ue->rx_ind.rx_indication_body->mib_pdu.pdu = &decoded_output[0];
|
||||||
ue->rx_ind.rx_indication_body->mib_pdu.additional_bits = decoded_output[3];
|
ue->rx_ind.rx_indication_body->mib_pdu.additional_bits = xtra_byte;
|
||||||
ue->rx_ind.rx_indication_body->mib_pdu.ssb_index = ssb_index; // confirm with TCL
|
ue->rx_ind.rx_indication_body->mib_pdu.ssb_index = ssb_index; // confirm with TCL
|
||||||
ue->rx_ind.rx_indication_body->mib_pdu.ssb_length = Lmax; // confirm with TCL
|
ue->rx_ind.rx_indication_body->mib_pdu.ssb_length = Lmax; // confirm with TCL
|
||||||
ue->rx_ind.rx_indication_body->mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
|
ue->rx_ind.rx_indication_body->mib_pdu.cell_id = frame_parms->Nid_cell; // confirm with TCL
|
||||||
|
|||||||
@@ -42,7 +42,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];
|
||||||
@@ -410,6 +410,9 @@ typedef struct PHY_VARS_gNB_s {
|
|||||||
/// PBCH DMRS sequence
|
/// PBCH DMRS sequence
|
||||||
uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
uint32_t nr_gold_pbch_dmrs[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
|
||||||
|
|
||||||
|
/// PBCH interleaver
|
||||||
|
uint8_t nr_pbch_interleaver[NR_POLAR_PBCH_PAYLOAD_BITS];
|
||||||
|
|
||||||
/// PDCCH DMRS sequence
|
/// PDCCH DMRS sequence
|
||||||
uint32_t ***nr_gold_pdcch_dmrs;
|
uint32_t ***nr_gold_pdcch_dmrs;
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,15 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int subframe) {
|
|||||||
gNB->pbch_configured = 0;
|
gNB->pbch_configured = 0;
|
||||||
}
|
}
|
||||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],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, cfg, fp);
|
||||||
nr_generate_pbch(&gNB->pbch, gNB->nrPolar_params, pbch_pdu, txdataF, AMP_OVER_2, ssb_start_symbol, n_hf, Lmax, ssb_index, frame, cfg, fp);
|
nr_generate_pbch(&gNB->pbch,
|
||||||
|
gNB->nrPolar_params,
|
||||||
|
pbch_pdu,
|
||||||
|
gNB->nr_pbch_interleaver,
|
||||||
|
txdataF,
|
||||||
|
AMP_OVER_2,
|
||||||
|
ssb_start_symbol,
|
||||||
|
n_hf,Lmax,ssb_index,
|
||||||
|
frame, cfg, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
|
|||||||
printf("dmrs type A position: %d\n", phy_config->config_req.pbch_config.dmrs_type_a_position);
|
printf("dmrs type A position: %d\n", phy_config->config_req.pbch_config.dmrs_type_a_position);
|
||||||
printf("pdcch config sib1: %d\n", phy_config->config_req.pbch_config.pdcch_config_sib1);
|
printf("pdcch config sib1: %d\n", phy_config->config_req.pbch_config.pdcch_config_sib1);
|
||||||
printf("cell barred: %d\n", phy_config->config_req.pbch_config.cell_barred);
|
printf("cell barred: %d\n", phy_config->config_req.pbch_config.cell_barred);
|
||||||
printf("intra frequcney reselection: %d\n", phy_config->config_req.pbch_config.intra_frequency_reselection);
|
printf("intra frequency reselection: %d\n", phy_config->config_req.pbch_config.intra_frequency_reselection);
|
||||||
printf("system frame number: %d\n", phy_config->config_req.pbch_config.system_frame_number);
|
printf("system frame number: %d\n", phy_config->config_req.pbch_config.system_frame_number);
|
||||||
printf("ssb index: %d\n", phy_config->config_req.pbch_config.ssb_index);
|
printf("ssb index: %d\n", phy_config->config_req.pbch_config.ssb_index);
|
||||||
printf("half frame bit: %d\n", phy_config->config_req.pbch_config.half_frame_bit);
|
printf("half frame bit: %d\n", phy_config->config_req.pbch_config.half_frame_bit);
|
||||||
|
|||||||
@@ -210,12 +210,14 @@ int8_t nr_ue_decode_mib(
|
|||||||
|
|
||||||
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
|
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
|
||||||
//if(mac->mib != NULL){
|
//if(mac->mib != NULL){
|
||||||
uint32_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused);
|
uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused);
|
||||||
uint32_t frame_number_4lsb = (uint32_t)(extra_bits & 0xf); // extra bits[0:3]
|
uint16_t frame_number_4lsb = 0;
|
||||||
uint32_t half_frame_bit = (uint32_t)(( extra_bits >> 4 ) & 0x1 ); // extra bits[4]
|
for (int i=0; i<4; i++)
|
||||||
uint32_t ssb_subcarrier_offset_msb = (uint32_t)(( extra_bits >> 5 ) & 0x1 ); // extra bits[5]
|
frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
|
||||||
|
uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4]
|
||||||
|
uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
|
||||||
|
|
||||||
uint32_t ssb_subcarrier_offset = mac->mib->ssb_SubcarrierOffset;
|
uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset;
|
||||||
|
|
||||||
//uint32_t ssb_index = 0; // TODO: ssb_index should obtain from L1 in case Lssb != 64
|
//uint32_t ssb_index = 0; // TODO: ssb_index should obtain from L1 in case Lssb != 64
|
||||||
|
|
||||||
@@ -238,7 +240,7 @@ int8_t nr_ue_decode_mib(
|
|||||||
printf("dmrs type A position: %d\n", (int)mac->mib->dmrs_TypeA_Position);
|
printf("dmrs type A position: %d\n", (int)mac->mib->dmrs_TypeA_Position);
|
||||||
printf("pdcch config sib1: %d\n", (int)mac->mib->pdcch_ConfigSIB1);
|
printf("pdcch config sib1: %d\n", (int)mac->mib->pdcch_ConfigSIB1);
|
||||||
printf("cell barred: %d\n", (int)mac->mib->cellBarred);
|
printf("cell barred: %d\n", (int)mac->mib->cellBarred);
|
||||||
printf("intra frequcney reselection: %d\n", (int)mac->mib->intraFreqReselection);
|
printf("intra frequency reselection: %d\n", (int)mac->mib->intraFreqReselection);
|
||||||
printf("half frame bit(extra bits): %d\n", (int)half_frame_bit);
|
printf("half frame bit(extra bits): %d\n", (int)half_frame_bit);
|
||||||
printf("ssb index(extra bits): %d\n", (int)ssb_index);
|
printf("ssb index(extra bits): %d\n", (int)ssb_index);
|
||||||
#endif
|
#endif
|
||||||
@@ -254,7 +256,6 @@ int8_t nr_ue_decode_mib(
|
|||||||
}else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
|
}else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
|
||||||
scs_pdcch = scs_30kHz;
|
scs_pdcch = scs_30kHz;
|
||||||
}
|
}
|
||||||
scs_pdcch = 2;
|
|
||||||
|
|
||||||
channel_bandwidth_t min_channel_bw = bw_40MHz; // deafult for testing
|
channel_bandwidth_t min_channel_bw = bw_40MHz; // deafult for testing
|
||||||
|
|
||||||
|
|||||||
@@ -167,4 +167,8 @@ typedef struct gNB_MAC_INST_s {
|
|||||||
time_stats_t schedule_pch;
|
time_stats_t schedule_pch;
|
||||||
} gNB_MAC_INST;
|
} gNB_MAC_INST;
|
||||||
|
|
||||||
|
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||||
|
frame_t frameP,
|
||||||
|
sub_frame_t subframeP);
|
||||||
|
|
||||||
#endif /*__LAYER2_NR_MAC_GNB_H__ */
|
#endif /*__LAYER2_NR_MAC_GNB_H__ */
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ int otg_enabled;
|
|||||||
|
|
||||||
|
|
||||||
//static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
|
//static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
|
||||||
static nfapi_nr_config_request_t *config[MAX_NUM_CCs];
|
//static nfapi_nr_config_request_t *config[MAX_NUM_CCs];
|
||||||
uint32_t target_dl_mcs = 28; //maximum allowed mcs
|
uint32_t target_dl_mcs = 28; //maximum allowed mcs
|
||||||
uint32_t target_ul_mcs = 20;
|
uint32_t target_ul_mcs = 20;
|
||||||
uint32_t timing_advance = 0;
|
uint32_t timing_advance = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user