Commit ad98f5aa authored by knopp's avatar knopp
Browse files

L1/L2 scheduling extensions for BL/CE operation, BR random-access procedure,...

L1/L2 scheduling extensions for BL/CE operation, BR random-access procedure, BR PRACH detection. Still untested, but compilation succeeds. Missing elements in L2 - PUSCH programming for Msg3, Msg4 retransmission programming for BL/CE. DLSCH/ULSCH programming for UE-specific DLSCH/ULSCH for BL/CE
parent 1fc67381
This diff is collapsed.
......@@ -43,12 +43,15 @@ const uint8_t lin2alaw_if4p5[65536] = {213, 213, 213, 213, 213, 213, 213, 213, 2
void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
void *tx_buffer = ru->ifbuffer.tx[subframe&1];
void *tx_buffer_prach = ru->ifbuffer.tx_prach;
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
#ifdef Rel14
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
#endif
void *tx_buffer = ru->ifbuffer.tx[subframe&1];
void *tx_buffer_prach = ru->ifbuffer.tx_prach;
uint16_t symbol_id=0, element_id=0;
......@@ -175,7 +178,8 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) {
perror("ETHERNET write for IF4p5_PULFFT\n");
}
}
} else if (packet_type == IF4p5_PRACH) {
} else if (packet_type >= IF4p5_PRACH &&
packet_type <= IF4p5_PRACH+4) {
// FIX: hard coded prach samples length
LOG_D(PHY,"IF4p5_PRACH: frame %d, subframe %d\n",frame,subframe);
db_fulllength = PRACH_NUM_SAMPLES;
......@@ -189,13 +193,24 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) {
}
gen_IF4p5_prach_header(packet_header, frame, subframe);
int16_t *rxF;
#ifdef Rel14
if (packet_type > IF4p5_PRACH)
rxF = &prach_rxsigF_br[packet_type - IF4p5_PRACH - 1][0][0];
else
#else
rxF = &prach_rxsigF[0][0];
#endif
if (eth->flags == ETH_RAW_IF4p5_MODE) {
memcpy((int16_t*)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t),
(&prach_rxsigF[0][0]),
PRACH_BLOCK_SIZE_BYTES);
memcpy((void *)(tx_buffer_prach + MAC_HEADER_SIZE_BYTES + sizeof_IF4p5_header_t),
(void*)rxF,
PRACH_BLOCK_SIZE_BYTES);
} else {
memcpy((int16_t*)(tx_buffer_prach + sizeof_IF4p5_header_t),
(&prach_rxsigF[0][0]),
memcpy((void *)(tx_buffer_prach + sizeof_IF4p5_header_t),
(void *)rxF,
PRACH_BLOCK_SIZE_BYTES);
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 1 );
......@@ -204,7 +219,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) {
&tx_buffer_prach,
db_fulllength,
1,
IF4p5_PRACH)) < 0) {
packet_type)) < 0) {
perror("ETHERNET write for IF4p5_PRACH\n");
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF, 0 );
......@@ -217,11 +232,14 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) {
}
void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint32_t *symbol_number) {
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
void *rx_buffer = ru->ifbuffer.rx;
LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
#ifdef Rel14
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
#endif
void *rx_buffer = ru->ifbuffer.rx;
uint16_t element_id;
uint16_t db_fulllength, db_halflength;
......@@ -308,18 +326,28 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint
//if (element_id==0) LOG_I(PHY,"recv_if4p5: symbol %d rxdata0 = (%u,%u)\n",*symbol_number,*i,*(i+1));
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 );
} else if (*packet_type == IF4p5_PRACH) {
} else if (*packet_type >= IF4p5_PRACH &&
*packet_type <= IF4p5_PRACH + 4) {
int16_t *rxF;
#ifdef Rel14
if (*packet_type > IF4p5_PRACH)
rxF = &prach_rxsigF_br[*packet_type - IF4p5_PRACH - 1][0][0];
else
#else
rxF = &prach_rxsigF[0][0];
#endif
// FIX: hard coded prach samples length
db_fulllength = PRACH_NUM_SAMPLES;
if (eth->flags == ETH_RAW_IF4p5_MODE) {
memcpy((&prach_rxsigF[0][0]),
memcpy(rxF,
(int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4p5_header_t),
PRACH_BLOCK_SIZE_BYTES);
} else {
memcpy((&prach_rxsigF[0][0]),
memcpy(rxF,
(int16_t*) (rx_buffer+sizeof_IF4p5_header_t),
PRACH_BLOCK_SIZE_BYTES);
}
......
......@@ -39,7 +39,11 @@
#define IF4p5_PULFFT 0x0019
#define IF4p5_PDLFFT 0x0020
#define IF4p5_PRACH 0x0021
#define IF4p5_PULTICK 0x0022
#define IF4p5_PRACH_BR_CE0 0x0021
#define IF4p5_PRACH_BR_CE1 0x0022
#define IF4p5_PRACH_BR_CE2 0x0023
#define IF4p5_PRACH_BR_CE3 0x0024
#define IF4p5_PULTICK 0x0025
struct IF4p5_header {
/// Type
......
......@@ -428,12 +428,14 @@ uint8_t get_prach_fmt(uint8_t prach_ConfigIndex,lte_frame_type_t frame_type)
}
}
uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapindex, uint16_t Nf)
uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms,
uint8_t prach_ConfigIndex,
uint8_t n_ra_prboffset,
uint8_t tdd_mapindex, uint16_t Nf)
{
lte_frame_type_t frame_type = frame_parms->frame_type;
uint8_t tdd_config = frame_parms->tdd_config;
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t n_ra_prboffset = frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
uint8_t n_ra_prb;
uint8_t f_ra,t1_ra;
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
......@@ -474,92 +476,90 @@ uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms, uint8_t tdd_mapind
return(n_ra_prb);
}
int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe)
int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex,uint32_t frame, uint8_t subframe)
{
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
// uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
uint8_t tdd_config = frame_parms->tdd_config;
uint8_t t0_ra;
uint8_t t1_ra;
uint8_t t2_ra;
int prach_mask = 0;
if (frame_parms->frame_type == FDD) { //FDD
//implement Table 5.7.1-2 from 36.211 (Rel-10, p.41)
if ((((frame&1) == 1) && (subframe < 9)) ||
(((frame&1) == 0) && (subframe == 9))) // This is an odd frame, ignore even-only PRACH frames
/*
if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50
((prach_ConfigIndex&0x1f)==18) || // 18,50
((prach_ConfigIndex&0xf)==15)) // 15,47
return(0);
*/
switch (prach_ConfigIndex&0x1f) {
case 0:
case 3:
return(subframe==1);
if (subframe==1) prach_mask = 1;
break;
case 1:
case 4:
return(subframe==4);
if (subframe==4) prach_mask = 1;
break;
case 2:
case 5:
return(subframe==7);
if (subframe==7) prach_mask = 1;
break;
case 6:
return((subframe==1) || (subframe==6));
if ((subframe==1) || (subframe==6)) prach_mask=1;
break;
case 7:
return((subframe==2) || (subframe==7));
if ((subframe==2) || (subframe==7)) prach_mask=1;
break;
case 8:
return((subframe==3) || (subframe==8));
if ((subframe==3) || (subframe==8)) prach_mask=1;
break;
case 9:
return((subframe==1) || (subframe==4) || (subframe==7));
if ((subframe==1) || (subframe==4) || (subframe==7)) prach_mask=1;
break;
case 10:
return((subframe==2) || (subframe==5) || (subframe==8));
if ((subframe==2) || (subframe==5) || (subframe==8)) prach_mask=1;
break;
case 11:
return((subframe==3) || (subframe==6) || (subframe==9));
if ((subframe==3) || (subframe==6) || (subframe==9)) prach_mask=1;
break;
case 12:
return((subframe&1)==0);
if ((subframe&1)==0) prach_mask=1;
break;
case 13:
return((subframe&1)==1);
if ((subframe&1)==1) prach_mask=1;
break;
case 14:
return(1==1);
prach_mask=1;
break;
case 15:
return(subframe==9);
if (subframe==9) prach_mask=1;
break;
}
} else { // TDD
if (prach_ConfigIndex>=64) {
LOG_E(PHY,"[PHY] Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
return(0);
}
if (tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach==0) {
LOG_E(PHY,"[PHY] Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
return(0);
}
AssertFatal(prach_ConfigIndex<64,
"Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
AssertFatal(tdd_preamble_map[prach_ConfigIndex][tdd_config].num_prach>0,
"Illegal prach_ConfigIndex %d for ",prach_ConfigIndex);
t0_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t0_ra;
t1_ra = tdd_preamble_map[prach_ConfigIndex][tdd_config].map[0].t1_ra;
......@@ -576,16 +576,29 @@ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t su
(t0_ra == 0)) && // PRACH is in all frames
(((subframe<5)&&(t1_ra==0)) || // PRACH is in 1st half-frame
(((subframe>4)&&(t1_ra==1))))) { // PRACH is in 2nd half-frame
if (prach_ConfigIndex<48) // PRACH only in normal UL subframe
return((((subframe%5)-2)==t2_ra));
else // PRACH can be in UpPTS
return((((subframe%5)-1)==t2_ra));
} else
return(1==2);
if ((prach_ConfigIndex<48) && // PRACH only in normal UL subframe
(((subframe%5)-2)==t2_ra)) prach_mask=1;
else if ((((subframe%5)-1)==t2_ra)) prach_mask=1; // PRACH can be in UpPTS
}
}
// shouldn't get here!
return(2==1);
return(prach_mask);
}
int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
int prach_mask = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe);
#ifdef Rel14
int i;
for (i=0;i<4;i++) {
if (frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] == 1)
prach_mask|=(is_prach_subframe0(frame_parms,frame_parms->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i],frame,subframe)<<(i+1));
}
#endif
return(prach_mask);
}
int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf )
......@@ -665,7 +678,10 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
NCS = NCS_restricted[Ncs_config];
}
n_ra_prb = get_prach_prb_offset(&(ue->frame_parms), tdd_mapindex, Nf);
n_ra_prb = get_prach_prb_offset(&(ue->frame_parms),
ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
ue->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset,
tdd_mapindex, Nf);
prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4;
/*
......@@ -1077,12 +1093,18 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
}
//__m128i mmtmpX0,mmtmpX1,mmtmpX2,mmtmpX3;
void rx_prach(PHY_VARS_eNB *eNB,
RU_t *ru,
uint16_t *preamble_energy_list,
uint16_t *preamble_delay_list,
uint16_t Nf,
uint8_t tdd_mapindex)
void rx_prach0(PHY_VARS_eNB *eNB,
RU_t *ru,
int16_t *max_preamble,
int16_t *max_preamble_energy,
int16_t *max_preamble_delay,
uint16_t Nf,
uint8_t tdd_mapindex
#ifdef Rel14
,uint8_t br_flag,
uint8_t ce_level
#endif
)
{
int i;
......@@ -1093,46 +1115,14 @@ void rx_prach(PHY_VARS_eNB *eNB,
uint8_t prach_ConfigIndex;
uint8_t Ncs_config;
uint8_t restricted_set;
uint8_t n_ra_prb;
int subframe;
int16_t *prachF=NULL;
int16_t **rxsigF=NULL;
int16_t **prach_ifft=NULL;
int nb_rx;
if (ru) {
fp = &ru->frame_parms;
nb_rx = ru->nb_rx;
}
else if (eNB) {
fp = &eNB->frame_parms;
nb_rx = fp->nb_antennas_rx;
}
else AssertFatal(1==0,"rx_prach called without valid RU or eNB descriptor\n");
frame_type = fp->frame_type;
rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
int16_t *prach[nb_rx];
if (eNB) {
subframe = eNB->proc.subframe_prach;
prachF = eNB->prach_vars.prachF;
rxsigF = eNB->prach_vars.rxsigF;
prach_ifft = eNB->prach_vars.prach_ifft;
}
else {
subframe = ru->proc.subframe_prach;
rxsigF = ru->prach_rxsigF;
LOG_D(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
}
int16_t *prach2;
uint8_t n_ra_prb;
uint8_t preamble_index;
uint16_t NCS,NCS2;
uint16_t preamble_offset=0,preamble_offset_old;
......@@ -1156,12 +1146,96 @@ void rx_prach(PHY_VARS_eNB *eNB,
int32_t lev;
int16_t levdB;
int fft_size,log2_ifft_size;
int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
int32_t *prach_ifft;
int32_t **prach_ifftp;
#ifdef Rel14
int prach_ifft_cnt=0;
#endif
#ifdef PRACH_DEBUG
int en,en0=0;
#endif
if (ru) {
fp = &ru->frame_parms;
nb_rx = ru->nb_rx;
}
else if (eNB) {
fp = &eNB->frame_parms;
nb_rx = fp->nb_antennas_rx;
}
else AssertFatal(1==0,"rx_prach called without valid RU or eNB descriptor\n");
frame_type = fp->frame_type;
#ifdef Rel14
if (br_flag == 1) {
AssertFatal(fp->prach_emtc_config_common.prach_Config_enabled==1,
"emtc prach_Config is not enabled\n");
AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[ce_level]==1,
"ce_level %d is not active\n",ce_level);
rootSequenceIndex = fp->prach_emtc_config_common.rootSequenceIndex;
prach_ConfigIndex = fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[ce_level];
Ncs_config = fp->prach_emtc_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
restricted_set = fp->prach_emtc_config_common.prach_ConfigInfo.highSpeedFlag;
n_ra_prb = get_prach_prb_offset(fp,prach_ConfigIndex,
fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],
tdd_mapindex,Nf);
// update pointers to results for ce_level
max_preamble += ce_level;
max_preamble_energy += ce_level;
max_preamble_delay += ce_level;
}
else
#endif
{
rootSequenceIndex = fp->prach_config_common.rootSequenceIndex;
prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig;
restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag;
n_ra_prb = get_prach_prb_offset(fp,prach_ConfigIndex,
fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
tdd_mapindex,Nf);
}
int16_t *prach[nb_rx];
if (eNB) {
#ifdef Rel14
if (br_flag == 1) {
prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level];
subframe = eNB->proc.subframe_prach_br;
prachF = eNB->prach_vars_br.prachF;
rxsigF = eNB->prach_vars_br.rxsigF;
}
else
#endif
{
prach_ifftp = eNB->prach_vars.prach_ifft[0];
subframe = eNB->proc.subframe_prach;
prachF = eNB->prach_vars.prachF;
rxsigF = eNB->prach_vars.rxsigF;
}
}
else {
#ifdef Rel14
if (br_flag == 1) {
subframe = ru->proc.subframe_prach_br;
rxsigF = ru->prach_rxsigF_br[ce_level];
LOG_D(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
}
else
#endif
{
subframe = ru->proc.subframe_prach;
rxsigF = ru->prach_rxsigF;
LOG_D(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex);
}
}
AssertFatal(ru!=NULL,"ru is null\n");
for (aa=0; aa<nb_rx; aa++) {
......@@ -1186,7 +1260,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
if (eNB) start_meas(&eNB->rx_prach);
n_ra_prb = get_prach_prb_offset(fp,tdd_mapindex,Nf);
prach_root_sequence_map = (prach_fmt < 4) ? prach_root_sequence_map0_3 : prach_root_sequence_map4;
// PDP is oversampled, e.g. 1024 sample instead of 839
......@@ -1371,8 +1445,13 @@ void rx_prach(PHY_VARS_eNB *eNB,
if ((eNB==NULL) && (ru!=NULL) && ru->function == NGFI_RRU_IF4p5) {
/// **** send_IF4 of rxsigF to RAU **** ///
send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH);
/// **** send_IF4 of rxsigF to RAU **** ///
#ifdef Rel14
if (br_flag == 1) send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level);
else
#endif
send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH);
#if 0
if (dB_fixed(en0)>30) {
......@@ -1402,6 +1481,30 @@ void rx_prach(PHY_VARS_eNB *eNB,
preamble_offset_old = 99;
uint8_t update_TA = 4;
uint8_t update_TA2 = 1;
switch (eNB->frame_parms.N_RB_DL) {
case 6:
update_TA = 16;
break;
case 25:
update_TA = 4;
break;
case 50:
update_TA = 2;
break;
case 75:
update_TA = 3;
update_TA2 = 2;
case 100:
update_TA = 1;
break;
}
*max_preamble_energy=0;
for (preamble_index=0 ; preamble_index<64 ; preamble_index++) {
if (restricted_set == 0) {
// This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
......@@ -1494,10 +1597,20 @@ void rx_prach(PHY_VARS_eNB *eNB,
if (new_dft == 1) {
new_dft = 0;
Xu=(int16_t*)eNB->X_u[preamble_offset-first_nonzero_root_idx];
#ifdef Rel14
if (br_flag == 1) {
prach_ifft = prach_ifftp[prach_ifft_cnt++];
if (eNB->prach_vars_br.repetition_number[ce_level]==1) memset(prach_ifft,0,((N_ZC==839)?2048:256)*sizeof(int32_t));
}
else
#endif
{
prach_ifft = prach_ifftp[0];
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
}
memset( prachF, 0, sizeof(int16_t)*2*1024 );
memset(prachF, 0, sizeof(int16_t)*2*1024 );
#ifdef PRACH_DEBUG
if (prach[0]!= NULL) write_output("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1);
#endif
......@@ -1506,7 +1619,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
// write_output("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1);
for (aa=0;aa<nb_rx; aa++) {
// Do componentwise product with Xu*
// Do componentwise product with Xu* on each antenna
k=0;
for (offset=0; offset<(N_ZC<<1); offset+=2) {
......@@ -1520,11 +1633,18 @@ void rx_prach(PHY_VARS_eNB *eNB,
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
if (N_ZC == 839) {
log2_ifft_size = 10;
idft1024(prachF,prach_ifft[aa],1);
idft1024(prachF,prach_ifft_tmp,1);
// compute energy and accumulate over receive antennas and repetitions for BR
for (i=0;i<2048;i++)
prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>15;
} else {
idft256(prachF,prach_ifft[aa],1);
idft256(prachF,prach_ifft_tmp,1);
log2_ifft_size = 8;
// compute energy and accumulate over receive antennas and repetitions for BR
for (i=0;i<256;i++)
prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[(i<<1)] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>15;
}
#ifdef PRACH_DEBUG
if (aa==0) write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
#endif
......@@ -1545,42 +1665,85 @@ void rx_prach(PHY_VARS_eNB *eNB,
write_output("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1);
write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
write_output("Xu.m","xu",Xu,N_ZC,1,1);
write_output("prach_ifft0.m","prach_t0",prach_ifft[0],1024,1,1);
write_output("prach_ifft0.m","prach_t0",prach_ifft[0][0],1024,1,1);
exit(-1);
}