Commit 3bb1407e authored by cig's avatar cig

NR PRACH generation fixes for correct reception of msg1

parent 6982e6f4
...@@ -19,13 +19,13 @@ ...@@ -19,13 +19,13 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file PHY/LTE_TRANSPORT/prach_common.c /*! \file PHY/NR_TRANSPORT/nr_prach.c
* \brief Common routines for UE/eNB PRACH physical channel V8.6 2009-03 * \brief Routines for UE PRACH physical channel
* \author R. Knopp * \author R. Knopp, G. Casati
* \date 2011 * \date 2019
* \version 0.1 * \version 0.2
* \company Eurecom * \company Eurecom, Fraunhofer IIS
* \email: knopp@eurecom.fr * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note * \note
* \warning * \warning
*/ */
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "PHY/impl_defs_nr.h" #include "PHY/impl_defs_nr.h"
#include "PHY/defs_nr_UE.h" #include "PHY/defs_nr_UE.h"
#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
...@@ -57,69 +58,74 @@ extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; ...@@ -57,69 +58,74 @@ extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10]; extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838]; extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839]; extern int16_t nr_ru[2*839];
const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"};
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) // Note:
{ // - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt
// WIP todo:
// - take prach start symbol into account
// - idft for short sequence assumes we are transmitting starting in symbol 0 of a PRACH slot
// - Assumes that PRACH SCS is same as PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below
// - Preamble index different from 0 is not detected by gNB
int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
//lte_frame_type_t frame_type = ue->frame_parms.frame_type;
//uint8_t tdd_config = ue->frame_parms.tdd_config;
NR_DL_FRAME_PARMS *fp=&ue->frame_parms; NR_DL_FRAME_PARMS *fp=&ue->frame_parms;
uint16_t rootSequenceIndex = fp->prach_config_common.rootSequenceIndex; fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_id];
uint8_t restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
uint16_t prach_fmt = ue->prach_resources[gNB_id]->prach_format;
uint8_t preamble_index = ue->prach_resources[gNB_id]->ra_PreambleIndex;
//uint8_t tdd_mapindex = ue->prach_resources[gNB_id]->ra_TDD_map_index;
int16_t *prachF = ue->prach_vars[gNB_id]->prachF;
int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
int16_t *prach = prach_tmp;
int16_t *prach2;
int16_t amp = ue->prach_vars[gNB_id]->amp;
int16_t Ncp;
uint16_t NCS=0;
uint16_t *prach_root_sequence_map;
uint16_t preamble_offset,preamble_shift;
uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar;
uint16_t d_start,numshift;
//uint8_t Nsp=2;
//uint8_t f_ra,t1_ra;
uint16_t N_ZC = (prach_fmt<4)?839:139;
uint8_t not_found;
int16_t *Xu;
uint16_t u;
int32_t Xu_re,Xu_im;
uint16_t offset,offset2;
int prach_start;
int i, prach_len=0;
uint16_t first_nonzero_root_idx=0;
#if defined(OAI_USRP)
prach_start = (ue->rx_offset+subframe*fp->samples_per_subframe-ue->hw_timing_advance-ue->N_TA_offset);
#ifdef NR_PRACH_DEBUG
LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
prach_start,
ue->rx_offset,
ue->hw_timing_advance,
ue->N_TA_offset);
#endif
if (prach_start<0) uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found;
prach_start+=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset;
uint16_t preamble_shift, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx;
int16_t prach_tmp[98304*2*4] __attribute__((aligned(32)));
int16_t Ncp, amp, *prach, *prach2, *prachF, *Xu;
int32_t Xu_re, Xu_im, samp_count;
int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k;
//int restricted_Type;
prach = prach_tmp;
prachF = ue->prach_vars[gNB_id]->prachF;
amp = ue->prach_vars[gNB_id]->amp;
Mod_id = ue->Mod_id;
prach_sequence_length = nrUE_config->prach_config.prach_sequence_length;
N_ZC = (prach_sequence_length == 0) ? 839:139;
mu = nrUE_config->prach_config.prach_sub_c_spacing;
restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
NCS = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
prach_fmt_id = prach_resources->prach_format;
preamble_index = 0; //prach_resources->ra_PreambleIndex // temporary hardcoded
fd_occasion = 0;
prach_len = 0;
dftlen = 0;
first_nonzero_root_idx = 0;
kbar = 1;
K = 24;
k = 12*n_ra_prb - 6*fp->N_RB_UL;
//prachStartSymbol = prach_config_pdu->prach_start_symbol
//restricted_Type = 0;
compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
ue->X_u);
if (mu == 0)
samp_count = fp->samples_per_subframe;
else
samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0;
if (prach_start>=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) #if defined (OAI_USRP)
prach_start-=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset);
#else //normal case (simulation) if (prach_start<0)
prach_start = subframe*(fp->samples_per_subframe)-ue->N_TA_offset; prach_start += (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
prach_start,
ue->rx_offset,
ue->hw_timing_advance,
ue->N_TA_offset);
#endif
if (prach_start >= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME))
prach_start -= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME);
#else //normal case (simulation)
prach_start = slot*(fp->samples_per_subframe)-ue->N_TA_offset;
#endif
// First compute physical root sequence // First compute physical root sequence
/************************************************************************ /************************************************************************
...@@ -129,28 +135,29 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -129,28 +135,29 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
* NOTE: Restricted set type B is not implemented * NOTE: Restricted set type B is not implemented
*************************************************************************/ *************************************************************************/
int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME // restricted type is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME
if (prach_fmt<3){ // uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
if (restricted_set == 0) { // if (prach_fmt_id<3){
NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config]; // if (restricted_set == 0) {
} else { // NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config];
if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME // } else {
if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME // if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME
} // if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME
} // }
if (prach_fmt==3){ // }
if (restricted_set == 0) { // if (prach_fmt_id==3){
NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config]; // if (restricted_set == 0) {
} else { // NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config];
if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME // } else {
if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME // if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME
} // if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME
} // }
if (prach_fmt>3){ // }
NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config]; // if (prach_fmt_id>3){
} // NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config];
// }
prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
prach_root_sequence_map = (prach_sequence_length == 0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc;
// This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS)));
...@@ -161,9 +168,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -161,9 +168,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
preamble_shift *= NCS; preamble_shift *= NCS;
} else { // This is the high-speed case } else { // This is the high-speed case
#ifdef NR_PRACH_DEBUG #ifdef NR_PRACH_DEBUG
LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config); LOG_I(PHY, "PRACH [UE %d] High-speed mode, NCS %d\n", Mod_id, NCS);
#endif #endif
not_found = 1; not_found = 1;
preamble_index0 = preamble_index; preamble_index0 = preamble_index;
...@@ -174,8 +181,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -174,8 +181,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
while (not_found == 1) { while (not_found == 1) {
// current root depending on rootSequenceIndex and preamble_offset // current root depending on rootSequenceIndex and preamble_offset
int index = (rootSequenceIndex + preamble_offset) % N_ZC; int index = (rootSequenceIndex + preamble_offset) % N_ZC;
uint16_t n_group_ra = 0;
if (prach_fmt<4) { if (prach_fmt_id<4) {
// prach_root_sequence_map points to prach_root_sequence_map0_3 // prach_root_sequence_map points to prach_root_sequence_map0_3
DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) ); DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) );
} else { } else {
...@@ -185,8 +193,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -185,8 +193,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
u = prach_root_sequence_map[index]; u = prach_root_sequence_map[index];
uint16_t n_group_ra = 0;
if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) { if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) {
n_shift_ra = nr_du[u]/NCS; n_shift_ra = nr_du[u]/NCS;
d_start = (nr_du[u]<<1) + (n_shift_ra * NCS); d_start = (nr_du[u]<<1) + (n_shift_ra * NCS);
...@@ -219,50 +225,53 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -219,50 +225,53 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
} }
} }
// now generate PRACH signal preamble_offset = 0;
#ifdef NR_PRACH_DEBUG preamble_shift = 0;
// now generate PRACH signal
#ifdef NR_PRACH_DEBUG
if (NCS>0) if (NCS>0)
LOG_I(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %x, NCS %d (NCS_config %d, N_ZC/NCS %d): Preamble_offset %d, Preamble_shift %d\n", LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id,
rootSequenceIndex, rootSequenceIndex,
preamble_index, preamble_index,
prach_fmt, prachfmt[prach_fmt_id],
NCS, NCS,
Ncs_config, N_ZC,
N_ZC/NCS,
preamble_offset, preamble_offset,
preamble_shift); preamble_shift);
#endif
#endif
// nsymb = (frame_parms->Ncp==0) ? 14:12; // nsymb = (frame_parms->Ncp==0) ? 14:12;
// subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*subframe*nsymb; // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*slot*nsymb;
int kbar = 1;
int K = 24;
if (prach_fmt == 3) {
K=4;
kbar=10;
}
else if (prach_fmt > 3) {
// Note: Assumes that PRACH SCS is same as PUSCH SCS
K=1;
kbar=2;
}
int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart;
int k = (12*n_ra_prb) - 6*fp->N_RB_UL;
k = (12*n_ra_prb) - 6*fp->N_RB_UL; if (prach_sequence_length == 0 && prach_fmt_id == 3) {
K = 4;
kbar = 10;
} else if (prach_sequence_length == 1) {
K = 1;
kbar = 2;
}
if (k<0) k+=fp->ofdm_symbol_size; if (k<0)
k += fp->ofdm_symbol_size;
k*=K; k *= K;
k+=kbar; k += kbar;
k *= 2;
LOG_I(PHY,"placing prach in position %d\n",k); LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d, preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id,
k*=2; slot,
k,
n_ra_prb,
preamble_offset,
first_nonzero_root_idx);
Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx];
#if defined (PRACH_WRITE_OUTPUT_DEBUG)
LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1);
#endif
/******************************************************** /********************************************************
* *
* In function init_prach_tables: * In function init_prach_tables:
...@@ -277,10 +286,86 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -277,10 +286,86 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
* *
*********************************************************/ *********************************************************/
AssertFatal(prach_fmt>=3,"prach_fmt<=3: Fix this for other formats\n"); if (fp->N_RB_UL <= 100)
int dftlen=2048; AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL);
if (fp->N_RB_UL >= 137) dftlen=4096; else if (fp->N_RB_UL < 137) {
if (fp->threequarter_fs==1) dftlen=(3*dftlen)/4; if (fp->threequarter_fs == 0) {
//40 MHz @ 61.44 Ms/s
//50 MHz @ 61.44 Ms/s
if (prach_sequence_length == 0) {
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
dftlen = 49152;
if (prach_fmt_id == 3)
dftlen = 12288;
} // 839 sequence
else {
switch (mu){
case 1:
dftlen = 2048;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
}
} else { // threequarter sampling
// 40 MHz @ 46.08 Ms/s
if (prach_sequence_length == 0) {
AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n");
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
dftlen = 36864;
if (prach_fmt_id == 3)
dftlen = 9216;
} else {
switch (mu){
case 1:
dftlen = 1536;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
} // short format
} // 3/4 sampling
} // <=50 MHz BW
else if (fp->N_RB_UL <= 273) {
if (fp->threequarter_fs == 0) {
//80,90,100 MHz @ 122.88 Ms/s
if (prach_sequence_length == 0) {
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
dftlen = 98304;
if (prach_fmt_id == 3)
dftlen = 24576;
}
} else { // threequarter sampling
switch (mu){
case 1:
dftlen = 4096;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
}
} else {
AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n");
// 80 MHz @ 92.16 Ms/s
if (prach_sequence_length == 0) {
if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2)
dftlen = 73728;
if (prach_fmt_id == 3)
dftlen = 18432;
} else {
switch (mu){
case 1:
dftlen = 3072;
break;
default:
AssertFatal(1 == 0, "Shouldn't get here\n");
break;
}
}
}
for (offset=0,offset2=0; offset<N_ZC; offset++,offset2+=preamble_shift) { for (offset=0,offset2=0; offset<N_ZC; offset++,offset2+=preamble_shift) {
...@@ -291,127 +376,96 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -291,127 +376,96 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15); Xu_im = (((int32_t)Xu[1+(offset<<1)]*amp)>>15);
prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15; prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15;
prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15; prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15;
if (k==dftlen) k=0; if (k==dftlen) k=0;
} }
switch (fp->N_RB_UL) { #if defined (PRACH_WRITE_OUTPUT_DEBUG)
case 6: LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1);
memset((void*)prachF,0,4*1536); LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1);
break; #endif
case 15: if (prach_sequence_length == 0) {
memset((void*)prachF,0,4*3072);
break;
case 25: AssertFatal(prach_fmt_id < 4, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id);
memset((void*)prachF,0,4*6144);
break;
case 50: switch (prach_fmt_id) {
memset((void*)prachF,0,4*12288);
break;
case 75:
memset((void*)prachF,0,4*18432);
break;
case 100:
if (fp->threequarter_fs == 0)
memset((void*)prachF,0,4*24576);
else
memset((void*)prachF,0,4*18432);
break;
/*case 106:
memset((void*)prachF,0,4*24576);
break;*/
}
int mu = 1; // numerology is hardcoded. FIXME!!!
switch (prach_fmt) {
case 0: case 0:
Ncp = 3168; Ncp = 3168;
break; break;
case 1: case 1:
Ncp = 21024; Ncp = 21024;
break; break;
case 2: case 2:
Ncp = 4688; Ncp = 4688;
break; break;
case 3: case 3:
Ncp = 3168; Ncp = 3168;
break; break;
}
} else {
//LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol);
case 0xa1: switch (prach_fmt_id) {
case 0: //A1
Ncp = 288/(1<<mu); Ncp = 288/(1<<mu);
break; break;
case 1: //A2
case 0xa2:
Ncp = 576/(1<<mu); Ncp = 576/(1<<mu);
break; break;
case 2: //A3
case 0xa3:
Ncp = 864/(1<<mu); Ncp = 864/(1<<mu);
break; break;
case 3: //B1
case 0xb1:
Ncp = 216/(1<<mu); Ncp = 216/(1<<mu);
break; break;
case 4: //B2
case 0xb2:
Ncp = 360/(1<<mu); Ncp = 360/(1<<mu);
break; break;
case 5: //B3
case 0xb3:
Ncp = 504/(1<<mu); Ncp = 504/(1<<mu);
break; break;
case 6: //B4
case 0xb4:
Ncp = 936/(1<<mu); Ncp = 936/(1<<mu);
break; break;
case 7: //C0
case 0xc0:
Ncp = 1240/(1<<mu); Ncp = 1240/(1<<mu);
break; break;
case 8: //C2
case 0xc2:
Ncp = 2048/(1<<mu); Ncp = 2048/(1<<mu);
break; break;
default: default:
Ncp = 3168; AssertFatal(1==0,"Unknown PRACH format ID %d\n", prach_fmt_id);
break; break;
} }
}
LOG_D(PHY, "PRACH [UE %d] Ncp %d, dftlen %d \n", Mod_id, Ncp, dftlen);
if (fp->N_RB_UL <= 100) if (fp->N_RB_UL <= 100)
AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL); AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL);
else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s
if (fp->threequarter_fs==0) { //61.44 Ms/s if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s
Ncp<<=1; Ncp<<=1;
// This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s // This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s if (prach_sequence_length == 0){
if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
idft49152(prachF,prach2,1); idft49152(prachF,prach2,1);
// here we have |empty | Prach49152| // here we have |empty | Prach49152|
memmove(prach,prach+(49152<<1),(Ncp<<2)); memmove(prach,prach+(49152<<1),(Ncp<<2));
// here we have |Prefix | Prach49152| // here we have |Prefix | Prach49152|
prach_len = 49152+Ncp; prach_len = 49152+Ncp;
dftlen=49152; } else if (prach_fmt_id == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
}
else if (prach_fmt == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
idft49152(prachF,prach2,1); idft49152(prachF,prach2,1);
memmove(prach2+(49152<<1),prach2,(49152<<2)); memmove(prach2+(49152<<1),prach2,(49152<<2));
// here we have |empty | Prach49152 | Prach49152| // here we have |empty | Prach49152 | Prach49152|
memmove(prach,prach+(49152<<2),(Ncp<<2)); memmove(prach,prach+(49152<<2),(Ncp<<2));
// here we have |Prefix | Prach49152 | Prach49152| // here we have |Prefix | Prach49152 | Prach49152|
prach_len = (49152*2)+Ncp; prach_len = (49152*2)+Ncp;
dftlen=49152; } else if (prach_fmt_id == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
}
else if (prach_fmt == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s
idft49152(prachF,prach2,1); idft49152(prachF,prach2,1);
memmove(prach2+(49152<<1),prach2,(49152<<2)); memmove(prach2+(49152<<1),prach2,(49152<<2));
// here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152 // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152
...@@ -420,9 +474,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -420,9 +474,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(49152<<3),(Ncp<<2)); memmove(prach,prach+(49152<<3),(Ncp<<2));
// here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152 // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152
prach_len = (49152*4)+Ncp; prach_len = (49152*4)+Ncp;
dftlen=49152; } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
}
else if (prach_fmt == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s
idft12288(prachF,prach2,1); idft12288(prachF,prach2,1);
memmove(prach2+(12288<<1),prach2,(12288<<2)); memmove(prach2+(12288<<1),prach2,(12288<<2));
// here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288 // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288
...@@ -431,27 +483,24 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -431,27 +483,24 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(12288<<3),(Ncp<<2)); memmove(prach,prach+(12288<<3),(Ncp<<2));
// here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288 // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288
prach_len = (12288*4)+Ncp; prach_len = (12288*4)+Ncp;
dftlen=12288;
} }
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { } else { // short PRACH sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1); idft2048(prachF,prach2,1);
dftlen=2048;
// here we have |empty | Prach2048 | // here we have |empty | Prach2048 |
if (prach_fmt != 0xc0) { if (prach_fmt_id != 7) {
memmove(prach2+(2048<<1),prach2,(2048<<2)); memmove(prach2+(2048<<1),prach2,(2048<<2));
prach_len = (2048*2)+Ncp; prach_len = (2048*2)+Ncp;
} }
else prach_len = (2048*1)+Ncp; else prach_len = (2048*1)+Ncp;
memmove(prach,prach+(2048<<1),(Ncp<<2)); memmove(prach,prach+(2048<<1),(Ncp<<2));
// here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) | // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) |
} } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x2048
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1); idft2048(prachF,prach2,1);
dftlen=2048;
// here we have |empty | Prach2048 | // here we have |empty | Prach2048 |
memmove(prach2+(2048<<1),prach2,(2048<<2)); memmove(prach2+(2048<<1),prach2,(2048<<2));
// here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 |
...@@ -460,12 +509,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -460,12 +509,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(2048<<1),(Ncp<<2)); memmove(prach,prach+(2048<<1),(Ncp<<2));
// here we have |Prefix | Prach2048 | // here we have |Prefix | Prach2048 |
prach_len = (2048*4)+Ncp; prach_len = (2048*4)+Ncp;
} } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x2048
Ncp+=32; Ncp+=32;
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1); idft2048(prachF,prach2,1);
dftlen=2048;
// here we have |empty | Prach2048 | // here we have |empty | Prach2048 |
memmove(prach2+(2048<<1),prach2,(2048<<2)); memmove(prach2+(2048<<1),prach2,(2048<<2));
// here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
...@@ -476,12 +523,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -476,12 +523,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(2048<<1),(Ncp<<2)); memmove(prach,prach+(2048<<1),(Ncp<<2));
// here we have |Prefix | Prach2048 | // here we have |Prefix | Prach2048 |
prach_len = (2048*6)+Ncp; prach_len = (2048*6)+Ncp;
} } else if (prach_fmt_id == 6) { // 12x2048
else if (prach_fmt == 0xb4) { // 12x2048
Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft2048(prachF,prach2,1); idft2048(prachF,prach2,1);
dftlen=2048;
// here we have |empty | Prach2048 | // here we have |empty | Prach2048 |
memmove(prach2+(2048<<1),prach2,(2048<<2)); memmove(prach2+(2048<<1),prach2,(2048<<2));
// here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048
...@@ -495,31 +540,26 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -495,31 +540,26 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
// here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048|
prach_len = (2048*12)+Ncp; prach_len = (2048*12)+Ncp;
} }
} }
else { // 46.08 Ms/s } else { // threequarter sampling @ 46.08 Ms/s
Ncp = (Ncp*3)/2; Ncp = (Ncp*3)/2;
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
if (prach_fmt == 0) { if (prach_sequence_length == 0){
if (prach_fmt_id == 0) {
idft36864(prachF,prach2,1); idft36864(prachF,prach2,1);
dftlen=36864;
// here we have |empty | Prach73728| // here we have |empty | Prach73728|
memmove(prach,prach+(36864<<1),(Ncp<<2)); memmove(prach,prach+(36864<<1),(Ncp<<2));
// here we have |Prefix | Prach73728| // here we have |Prefix | Prach73728|
prach_len = (36864*1)+Ncp; prach_len = (36864*1)+Ncp;
} } else if (prach_fmt_id == 1) {
else if (prach_fmt == 1) {
idft36864(prachF,prach2,1); idft36864(prachF,prach2,1);
dftlen=36864;
memmove(prach2+(36864<<1),prach2,(36864<<2)); memmove(prach2+(36864<<1),prach2,(36864<<2));
// here we have |empty | Prach73728 | Prach73728| // here we have |empty | Prach73728 | Prach73728|
memmove(prach,prach+(36864<<2),(Ncp<<2)); memmove(prach,prach+(36864<<2),(Ncp<<2));
// here we have |Prefix | Prach73728 | Prach73728| // here we have |Prefix | Prach73728 | Prach73728|
prach_len = (36864*2)+Ncp; prach_len = (36864*2)+Ncp;
} } else if (prach_fmt_id == 2) {
if (prach_fmt == 2) {
idft36864(prachF,prach2,1); idft36864(prachF,prach2,1);
dftlen=36864;
memmove(prach2+(36864<<1),prach2,(36864<<2)); memmove(prach2+(36864<<1),prach2,(36864<<2));
// here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
memmove(prach2+(36864<<2),prach2,(36864<<3)); memmove(prach2+(36864<<2),prach2,(36864<<3));
...@@ -527,10 +567,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -527,10 +567,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(36864<<3),(Ncp<<2)); memmove(prach,prach+(36864<<3),(Ncp<<2));
// here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
prach_len = (36864*4)+Ncp; prach_len = (36864*4)+Ncp;
} } else if (prach_fmt_id == 3) {
else if (prach_fmt == 3) {
idft9216(prachF,prach2,1); idft9216(prachF,prach2,1);
dftlen=36864;
memmove(prach2+(9216<<1),prach2,(9216<<2)); memmove(prach2+(9216<<1),prach2,(9216<<2));
// here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216 // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216
memmove(prach2+(9216<<2),prach2,(9216<<3)); memmove(prach2+(9216<<2),prach2,(9216<<3));
...@@ -539,26 +577,28 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -539,26 +577,28 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
// here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216 // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216
prach_len = (9216*4)+Ncp; prach_len = (9216*4)+Ncp;
} }
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { } else { // short sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1); idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 | // here we have |empty | Prach1536 |
if (prach_fmt != 0xc0) { if (prach_fmt_id != 7) {
memmove(prach2+(1536<<1),prach2,(1536<<2)); memmove(prach2+(1536<<1),prach2,(1536<<2));
prach_len = (1536*2)+Ncp; prach_len = (1536*2)+Ncp;
} } else prach_len = (1536*1)+Ncp;
else prach_len = (1536*1)+Ncp;
memmove(prach,prach+(1536<<1),(Ncp<<2)); memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) | // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) |
} } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x1536
printf(" CHECK 3/4 sampling prachFormat == 0xa2\n");
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1); idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 | // here we have |empty | Prach1536 |
memmove(prach2+(1536<<1),prach2,(1536<<2)); memmove(prach2+(1536<<1),prach2,(1536<<2));
// here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 |
...@@ -567,12 +607,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -567,12 +607,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(1536<<1),(Ncp<<2)); memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 | // here we have |Prefix | Prach1536 |
prach_len = (1536*4)+Ncp; prach_len = (1536*4)+Ncp;
} } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1); idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 | // here we have |empty | Prach1536 |
memmove(prach2+(1536<<1),prach2,(1536<<2)); memmove(prach2+(1536<<1),prach2,(1536<<2));
// here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
...@@ -583,12 +621,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -583,12 +621,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(1536<<1),(Ncp<<2)); memmove(prach,prach+(1536<<1),(Ncp<<2));
// here we have |Prefix | Prach1536 | // here we have |Prefix | Prach1536 |
prach_len = (1536*6)+Ncp; prach_len = (1536*6)+Ncp;
} } else if (prach_fmt_id == 6) { // 12x1536
else if (prach_fmt == 0xb4) { // 12x1536
Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft1536(prachF,prach2,1); idft1536(prachF,prach2,1);
dftlen=1536;
// here we have |empty | Prach1536 | // here we have |empty | Prach1536 |
memmove(prach2+(1536<<1),prach2,(1536<<2)); memmove(prach2+(1536<<1),prach2,(1536<<2));
// here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536
...@@ -604,30 +640,26 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -604,30 +640,26 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
} }
} }
} }
else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s
if (fp->threequarter_fs==0) { //122.88 Ms/s if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s
Ncp<<=2; Ncp<<=2;
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s if (prach_sequence_length == 0){
if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s
idft98304(prachF,prach2,1); idft98304(prachF,prach2,1);
dftlen=98304;
// here we have |empty | Prach98304| // here we have |empty | Prach98304|
memmove(prach,prach+(98304<<1),(Ncp<<2)); memmove(prach,prach+(98304<<1),(Ncp<<2));
// here we have |Prefix | Prach98304| // here we have |Prefix | Prach98304|
prach_len = (98304*1)+Ncp; prach_len = (98304*1)+Ncp;
} } else if (prach_fmt_id == 1) {
else if (prach_fmt == 1) {
idft98304(prachF,prach2,1); idft98304(prachF,prach2,1);
dftlen=98304;
memmove(prach2+(98304<<1),prach2,(98304<<2)); memmove(prach2+(98304<<1),prach2,(98304<<2));
// here we have |empty | Prach98304 | Prach98304| // here we have |empty | Prach98304 | Prach98304|
memmove(prach,prach+(98304<<2),(Ncp<<2)); memmove(prach,prach+(98304<<2),(Ncp<<2));
// here we have |Prefix | Prach98304 | Prach98304| // here we have |Prefix | Prach98304 | Prach98304|
prach_len = (98304*2)+Ncp; prach_len = (98304*2)+Ncp;
} } else if (prach_fmt_id == 2) {
else if (prach_fmt == 2) {
idft98304(prachF,prach2,1); idft98304(prachF,prach2,1);
dftlen=98304;
memmove(prach2+(98304<<1),prach2,(98304<<2)); memmove(prach2+(98304<<1),prach2,(98304<<2));
// here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304 // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304
memmove(prach2+(98304<<2),prach2,(98304<<3)); memmove(prach2+(98304<<2),prach2,(98304<<3));
...@@ -635,10 +667,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -635,10 +667,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(98304<<3),(Ncp<<2)); memmove(prach,prach+(98304<<3),(Ncp<<2));
// here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304 // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304
prach_len = (98304*4)+Ncp; prach_len = (98304*4)+Ncp;
} } else if (prach_fmt_id == 3) { // 4x6144, Ncp 3168
else if (prach_fmt == 3) { // 4x6144, Ncp 3168
idft24576(prachF,prach2,1); idft24576(prachF,prach2,1);
dftlen=24576;
memmove(prach2+(24576<<1),prach2,(24576<<2)); memmove(prach2+(24576<<1),prach2,(24576<<2));
// here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576 // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576
memmove(prach2+(24576<<2),prach2,(24576<<3)); memmove(prach2+(24576<<2),prach2,(24576<<3));
...@@ -647,26 +677,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -647,26 +677,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
// here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576 // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576
prach_len = (24576*4)+Ncp; prach_len = (24576*4)+Ncp;
} }
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { } else { // short sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1); idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 | // here we have |empty | Prach4096 |
if (prach_fmt != 0xc0) { if (prach_fmt_id != 7) {
memmove(prach2+(4096<<1),prach2,(4096<<2)); memmove(prach2+(4096<<1),prach2,(4096<<2));
prach_len = (4096*2)+Ncp; prach_len = (4096*2)+Ncp;
} } else prach_len = (4096*1)+Ncp;
else prach_len = (4096*1)+Ncp;
memmove(prach,prach+(4096<<1),(Ncp<<2)); memmove(prach,prach+(4096<<1),(Ncp<<2));
// here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) | // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) |
} else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096
}
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1); idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 | // here we have |empty | Prach4096 |
memmove(prach2+(4096<<1),prach2,(4096<<2)); memmove(prach2+(4096<<1),prach2,(4096<<2));
// here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 |
...@@ -675,12 +701,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -675,12 +701,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(4096<<1),(Ncp<<2)); memmove(prach,prach+(4096<<1),(Ncp<<2));
// here we have |Prefix | Prach4096 | // here we have |Prefix | Prach4096 |
prach_len = (4096*4)+Ncp; prach_len = (4096*4)+Ncp;
} } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1); idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 | // here we have |empty | Prach4096 |
memmove(prach2+(4096<<1),prach2,(4096<<2)); memmove(prach2+(4096<<1),prach2,(4096<<2));
// here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
...@@ -691,12 +715,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -691,12 +715,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(4096<<1),(Ncp<<2)); memmove(prach,prach+(4096<<1),(Ncp<<2));
// here we have |Prefix | Prach4096 | // here we have |Prefix | Prach4096 |
prach_len = (4096*6)+Ncp; prach_len = (4096*6)+Ncp;
} } else if (prach_fmt_id == 6) { // 12x4096
else if (prach_fmt == 0xb4) { // 12x4096
Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft4096(prachF,prach2,1); idft4096(prachF,prach2,1);
dftlen=4096;
// here we have |empty | Prach4096 | // here we have |empty | Prach4096 |
memmove(prach2+(4096<<1),prach2,(4096<<2)); memmove(prach2+(4096<<1),prach2,(4096<<2));
// here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096
...@@ -711,29 +733,25 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -711,29 +733,25 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
prach_len = (4096*12)+Ncp; prach_len = (4096*12)+Ncp;
} }
} }
else { // 92.16 Ms/s } else { // three quarter sampling @ 92.16 Ms/s
Ncp = (Ncp*3); Ncp = (Ncp*3);
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
if (prach_fmt == 0) { if (prach_sequence_length == 0){
if (prach_fmt_id == 0) {
idft73728(prachF,prach2,1); idft73728(prachF,prach2,1);
dftlen=73728;
// here we have |empty | Prach73728| // here we have |empty | Prach73728|
memmove(prach,prach+(73728<<1),(Ncp<<2)); memmove(prach,prach+(73728<<1),(Ncp<<2));
// here we have |Prefix | Prach73728| // here we have |Prefix | Prach73728|
prach_len = (73728*1)+Ncp; prach_len = (73728*1)+Ncp;
} } else if (prach_fmt_id == 1) {
else if (prach_fmt == 1) {
idft73728(prachF,prach2,1); idft73728(prachF,prach2,1);
dftlen=73728;
memmove(prach2+(73728<<1),prach2,(73728<<2)); memmove(prach2+(73728<<1),prach2,(73728<<2));
// here we have |empty | Prach73728 | Prach73728| // here we have |empty | Prach73728 | Prach73728|
memmove(prach,prach+(73728<<2),(Ncp<<2)); memmove(prach,prach+(73728<<2),(Ncp<<2));
// here we have |Prefix | Prach73728 | Prach73728| // here we have |Prefix | Prach73728 | Prach73728|
prach_len = (73728*2)+Ncp; prach_len = (73728*2)+Ncp;
} } if (prach_fmt_id == 2) {
if (prach_fmt == 2) {
idft73728(prachF,prach2,1); idft73728(prachF,prach2,1);
dftlen=73728;
memmove(prach2+(73728<<1),prach2,(73728<<2)); memmove(prach2+(73728<<1),prach2,(73728<<2));
// here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728
memmove(prach2+(73728<<2),prach2,(73728<<3)); memmove(prach2+(73728<<2),prach2,(73728<<3));
...@@ -741,10 +759,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -741,10 +759,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(73728<<3),(Ncp<<2)); memmove(prach,prach+(73728<<3),(Ncp<<2));
// here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728
prach_len = (73728*4)+Ncp; prach_len = (73728*4)+Ncp;
} } else if (prach_fmt_id == 3) {
else if (prach_fmt == 3) {
idft18432(prachF,prach2,1); idft18432(prachF,prach2,1);
dftlen=18432;
memmove(prach2+(18432<<1),prach2,(18432<<2)); memmove(prach2+(18432<<1),prach2,(18432<<2));
// here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432 // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432
memmove(prach2+(18432<<2),prach2,(18432<<3)); memmove(prach2+(18432<<2),prach2,(18432<<3));
...@@ -753,25 +769,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -753,25 +769,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
// here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432 // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432
prach_len = (18432*4)+Ncp; prach_len = (18432*4)+Ncp;
} }
else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { } else { // short sequence
if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) {
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1); idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 | // here we have |empty | Prach3072 |
if (prach_fmt != 0xc0) { if (prach_fmt_id != 7) {
memmove(prach2+(3072<<1),prach2,(3072<<2)); memmove(prach2+(3072<<1),prach2,(3072<<2));
prach_len = (3072*2)+Ncp; prach_len = (3072*2)+Ncp;
} } else prach_len = (3072*1)+Ncp;
else prach_len = (3072*1)+Ncp;
memmove(prach,prach+(3072<<1),(Ncp<<2)); memmove(prach,prach+(3072<<1),(Ncp<<2));
// here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) |
} } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072
else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1); idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 | // here we have |empty | Prach3072 |
memmove(prach2+(3072<<1),prach2,(3072<<2)); memmove(prach2+(3072<<1),prach2,(3072<<2));
// here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
...@@ -782,12 +795,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -782,12 +795,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(3072<<1),(Ncp<<2)); memmove(prach,prach+(3072<<1),(Ncp<<2));
// here we have |Prefix | Prach3072 | // here we have |Prefix | Prach3072 |
prach_len = (3072*6)+Ncp; prach_len = (3072*6)+Ncp;
} } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072
else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1); idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 | // here we have |empty | Prach3072 |
memmove(prach2+(3072<<1),prach2,(3072<<2)); memmove(prach2+(3072<<1),prach2,(3072<<2));
// here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 |
...@@ -796,12 +807,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -796,12 +807,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
memmove(prach,prach+(3072<<1),(Ncp<<2)); memmove(prach,prach+(3072<<1),(Ncp<<2));
// here we have |Prefix | Prach3072 | // here we have |Prefix | Prach3072 |
prach_len = (3072*4)+Ncp; prach_len = (3072*4)+Ncp;
} } else if (prach_fmt_id == 6) { // 12x3072
else if (prach_fmt == 0xb4) { // 12x3072
Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling
prach2 = prach+(Ncp<<1); prach2 = prach+(Ncp<<1);
idft3072(prachF,prach2,1); idft3072(prachF,prach2,1);
dftlen=3072;
// here we have |empty | Prach3072 | // here we have |empty | Prach3072 |
memmove(prach2+(3072<<1),prach2,(3072<<2)); memmove(prach2+(3072<<1),prach2,(3072<<2));
// here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072
...@@ -817,43 +826,55 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe) ...@@ -817,43 +826,55 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe)
} }
} }
} }
}
#ifdef NR_PRACH_DEBUG
LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", Mod_id,
fp->N_RB_UL,
prach_start,
prach_len,
ue->rx_offset,
ue->hw_timing_advance,
ue->N_TA_offset);
#endif
#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
int j, overflow = prach_start + prach_len - NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
#ifdef NR_PRACH_DEBUG
LOG_I( PHY, "PRACH [UE %d] overflow = %d\n", Mod_id, overflow);
#endif
#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) // prach_start=414.730, overflow=-39470 prach_len=6600 fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME 460.800 prach_start+prach_len 421.330 fp->samples_per_subframe 46080
int j;
int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe;
LOG_D( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow );
for (i=prach_start,j=0; i<min(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { // from prach_start=414.730 to prach_start+prach_len 421.330
for (i = prach_start, j = 0; i < min(fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME, prach_start + prach_len); i++, j++) {
((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
} }
for (i=0; i<overflow; i++,j++) { for (i = 0; i < overflow; i++,j++) {
((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j];
((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1];
} }
#else #else // simulators
LOG_D( PHY, "prach_start=%d\n", prach_start);
for (i=0; i<prach_len; i++) { for (i=0; i<prach_len; i++) {
((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i] = prach[2*i];
((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1];
} }
#endif #endif
//printf("----------------------\n");
//for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){
// printf("PRACH rx data[%d] = %d\n", ii, ue->common_vars.txdata[0][ii]);
//}
//printf(" \n");
#if defined(PRACH_WRITE_OUTPUT_DEBUG) #if defined(PRACH_WRITE_OUTPUT_DEBUG)
LOG_M("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1); LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1);
LOG_M("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1); LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1)
LOG_M("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]),fp->samples_per_subframe,1,1); #endif
exit(-1);
#endif
return signal_energy( (int*)prach, 256 ); return signal_energy((int*)prach, 256);
} }
...@@ -20,10 +20,10 @@ ...@@ -20,10 +20,10 @@
*/ */
/*! \file nr_l1_helper.c /*! \file nr_l1_helper.c
* \brief PHY helper function adapted to NR * \brief PHY helper functions for PRACH adapted to NR
* \author Guido Casati * \author Guido Casati
* \date 2019 * \date 2019
* \version 1.0 * \version 2.0
* \email guido.casati@iis.fraunhofer.de * \email guido.casati@iis.fraunhofer.de
* @ingroup _mac * @ingroup _mac
...@@ -41,15 +41,14 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma ...@@ -41,15 +41,14 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_ServingCellConfigCommon_t *scc = mac->scc; NR_ServingCellConfigCommon_t *scc = mac->scc;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
int prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1;
uint8_t prachConfigIndex, mu;
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
uint8_t prachConfigIndex, mu;
// SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211 // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211
NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
switch (scs){ switch (scs){
case NR_SubcarrierSpacing_kHz15: case NR_SubcarrierSpacing_kHz15:
mu = 0; mu = 0;
...@@ -91,7 +90,10 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma ...@@ -91,7 +90,10 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma
prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
if (prach_sequence_length == 0) {
switch (prach_format) { switch (prach_format) {
AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format);
// long preamble formats // long preamble formats
case 0: case 0:
case 3: case 3:
...@@ -102,30 +104,32 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma ...@@ -102,30 +104,32 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma
case 2: case 2:
return -6; return -6;
}
// short preamble formats } else {
case 0xa1: switch (prach_format) { // short preamble formats
case 0xb1: case 0:
case 3:
return 8 + 3*mu; return 8 + 3*mu;
case 0xa2: case 1:
case 0xb2: case 4:
case 0xc2: case 8:
return 5 + 3*mu; return 5 + 3*mu;
case 0xa3: case 2:
case 0xb3: case 5:
return 3 + 3*mu; return 3 + 3*mu;
case 0xb4: case 6:
return 3*mu; return 3*mu;
case 0xc0: case 7:
return 5 + 3*mu; return 5 + 3*mu;
default: default:
AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex); AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex);
} }
}
} }
/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */ /* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */
......
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