Commit e3c7e40b authored by Raymond Knopp's avatar Raymond Knopp

integration of SLBCH receiver and full synchronization procedure

parent 65a96273
......@@ -1110,6 +1110,7 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/rar_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_syncSL.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
......
......@@ -87,7 +87,7 @@ uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
#ifdef RM_DEBUG
printf("row %d, index %d, index-Nd %d index-Nd+1 %d (k,Kpi+2k,Kpi+2k+1) (%d,%d,%d) w(%d,%d,%d)\n",row,index,index-ND,((index+1)%Kpi)-ND,k,Kpi+(k<<1),Kpi+(k<<1)+1,w[k],w[Kpi+(k<<1)],w[Kpi+1+(k<<1)]);
printf("row %d (k,Kpi+2k,Kpi+2k+1) (%d,%d,%d) w(%d,%d,%d)\n",row,k,Kpi+k2,Kpi+k2+1,w[k],w[Kpi+k2],w[Kpi+1+k2]);
if (w[k]== LTE_NULL)
nulled++;
......@@ -156,7 +156,7 @@ uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
w[Kpi+k] = d[(int32_t)index3-(int32_t)ND3+1];
w[(Kpi<<1)+k] = d[(int32_t)index3-(int32_t)ND3+2];
#ifdef RM_DEBUG_CC
printf("row %d, index %d k %d w(%d,%d,%d)\n",row,index,k,w[k],w[Kpi+k],w[(Kpi<<1)+k]);
printf("row %d, index %d (k,k+Kpi,k+2Kpi) (%d,%d,%d) w(%d,%d,%d)\n",row,index,k,k+Kpi,k+Kpi<<1,w[k],w[Kpi+k],w[(Kpi<<1)+k]);
if (w[k]== LTE_NULL)
nulled++;
......@@ -375,7 +375,7 @@ uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
{
uint32_t RCC = (D>>5), ND;
uint32_t col,Kpi,index;
uint32_t row,col,Kpi,index;
int32_t k;
#ifdef RM_DEBUG_CC
uint32_t nulled=0;
......@@ -401,15 +401,16 @@ uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
printf("Col %d\n",col);
#endif
index = bitrev_cc[col];
if (index<ND) {
w[k] = LTE_NULL;
w[Kpi+k] = LTE_NULL;
w[(Kpi<<1)+k] = LTE_NULL;
for (row=0;row<RCC;row++){
if (index<ND) {
w[k] = LTE_NULL;
w[Kpi+k] = LTE_NULL;
w[(Kpi<<1)+k] = LTE_NULL;
#ifdef RM_DEBUG_CC
nulled+=3;
nulled+=3;
#endif
}
}
/*
//bits beyond 32 due to "filler" bits
......@@ -439,9 +440,11 @@ uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w)
}
*/
#ifdef RM_DEBUG_CC
printf("k %d w (%d,%d,%d), index-ND %d index+32-ND %d\n",k,w[k],w[Kpi+k],w[(Kpi<<1)+k],index-ND,index+32-ND);
printf("k %d w (%d,%d,%d), index-ND %d index+32-ND %d\n",k,w[k],w[Kpi+k],w[(Kpi<<1)+k],index-ND,index+32-ND);
#endif
k+=RCC;
index+=32;
k++;
}
}
#ifdef RM_DEBUG_CC
......@@ -649,7 +652,10 @@ uint32_t lte_rate_matching_cc(uint32_t RCC,
for (k=0; k<E; k++) {
#ifdef RM_DEBUG_CC
AssertFatal(w[ind]==0 || w[ind]==1 || w[ind]==LTE_NULL,
"w[%d] = %d is illegal\n",ind,w[ind]);
#endif
while(w[ind] == LTE_NULL) {
#ifdef RM_DEBUG_CC
......
......@@ -960,6 +960,13 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
ue->pusch_sldch->drs_ch_estimates = (int32_t **)malloc(2*sizeof(int32_t*));
ue->pusch_sldch->rxdataF_comp = (int32_t **)malloc(2*sizeof(int32_t*));
ue->pusch_sldch->ul_ch_mag = (int32_t **)malloc(2*sizeof(int32_t*));
ue->pusch_slbch = (LTE_eNB_PUSCH*)malloc(sizeof(LTE_eNB_PUSCH));
ue->pusch_slbch->rxdataF_ext = (int32_t **)malloc(2*sizeof(int32_t*));
ue->pusch_slbch->drs_ch_estimates = (int32_t **)malloc(2*sizeof(int32_t*));
ue->pusch_slbch->rxdataF_comp = (int32_t **)malloc(2*sizeof(int32_t*));
ue->pusch_slbch->ul_ch_mag = (int32_t **)malloc(2*sizeof(int32_t*));
ue->sl_rxdata_7_5kHz = (int16_t **)malloc(2*sizeof(int32_t*));
ue->sl_rxdataF = (int16_t **)malloc(2*sizeof(int32_t*));
......@@ -979,11 +986,16 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
ue->pusch_sldch->drs_ch_estimates[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
ue->pusch_sldch->rxdataF_comp[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
ue->pusch_sldch->ul_ch_mag[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
ue->pusch_slbch->rxdataF_ext[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
ue->pusch_slbch->drs_ch_estimates[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
ue->pusch_slbch->rxdataF_comp[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
ue->pusch_slbch->ul_ch_mag[aa] = (int32_t*)malloc16_clear(ue->frame_parms.N_RB_DL*12*14*sizeof(int32_t));
}
ue->slsch_dlsch_llr = (int16_t *)malloc(2*6*12*1200*sizeof(int16_t*));
ue->slsch_ulsch_llr = (int16_t *)malloc(2*6*12*1200*sizeof(int16_t*));
ue->sldch_dlsch_llr = (int16_t *)malloc(2*2*12*1200*sizeof(int16_t*));
ue->sldch_ulsch_llr = (int16_t *)malloc(2*2*12*1200*sizeof(int16_t*));
......
......@@ -122,7 +122,7 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com
} else AssertFatal(1==0,"primary_synch2_time not allocated\n");
primary_synch0SL_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
primary_synch0SL_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int16_t)*2);
if (primary_synch0SL_time) {
// bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
bzero(primary_synch0SL_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
......@@ -133,7 +133,7 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com
// primary_synch1_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
primary_synch1SL_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
primary_synch1SL_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int16_t)*2);
if (primary_synch1SL_time) {
// bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
......@@ -333,8 +333,8 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com
break;
}
for (i=0; i<frame_parms->ofdm_symbol_size; i++)
((int32_t*)primary_synch0SL_time)[i] = sync_tmp[i];
for (i=0; i<frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples; i++)
((int32_t*)primary_synch0SL_time)[i] = sync_tmp[(i+(frame_parms->ofdm_symbol_size-frame_parms->nb_prefix_samples))%frame_parms->ofdm_symbol_size];
k=frame_parms->ofdm_symbol_size-36;
......@@ -380,16 +380,17 @@ int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *com
break;
}
for (i=0; i<frame_parms->ofdm_symbol_size; i++)
((int32_t*)primary_synch1SL_time)[i] = sync_tmp[i];
for (i=0; i<frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples; i++)
((int32_t*)primary_synch1SL_time)[i] = sync_tmp[(i+(frame_parms->ofdm_symbol_size-frame_parms->nb_prefix_samples))%frame_parms->ofdm_symbol_size];
/*
write_output("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1);
write_output("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1);
write_output("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1);
write_output("primary_syncSL0.m","psyncSL0",primary_synch0SL_time,frame_parms->ofdm_symbol_size,1,1);
write_output("primary_syncSL1.m","psyncSL1",primary_synch1SL_time,frame_parms->ofdm_symbol_size,1,1);
*/
*/ write_output("primary_syncSL1.m","psyncSL1",primary_synch1SL_time,frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples,1,1);
return (1);
}
......@@ -667,12 +668,18 @@ int lte_sync_timeSL(PHY_VARS_UE *ue,
//calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
for (int ar=0; ar<frame_parms->nb_antennas_rx; ar++) {
result = dot_product((int16_t*)primary_synch0SL_time, (int16_t*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
result = dot_product((int16_t*)primary_synch0SL_time,
(int16_t*) &(rxdata[ar][n]),
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples,
11);
((int16_t*)&tmp0)[0] += ((int16_t*) &result)[0];
((int16_t*)&tmp0)[1] += ((int16_t*) &result)[1];
result = dot_product((int16_t*)primary_synch1SL_time, (int16_t*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
result = dot_product((int16_t*)primary_synch1SL_time,
(int16_t*) &(rxdata[ar][n]),
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples,
11);
((int16_t*)&tmp1)[0] += ((int16_t*) &result)[0];
((int16_t*)&tmp1)[1] += ((int16_t*) &result)[1];
......@@ -689,7 +696,7 @@ int lte_sync_timeSL(PHY_VARS_UE *ue,
if (n>(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)) {
// if (n<4096) printf("syncSL: sample %d (nprime %d) : , mag0 %d, prev0 %d, mag1 %d, prev1 %d\n",
// n,nprime,magtmp0,sync_corr0[nprime],magtmp1,sync_corr1[nprime]);
// n,nprime,magtmp0,sync_corr0[nprime],magtmp1,sync_corr1[nprime]);
lev0 = magtmp0 + sync_corr0[nprime];
lev1 = magtmp1 + sync_corr1[nprime];
......@@ -701,12 +708,13 @@ int lte_sync_timeSL(PHY_VARS_UE *ue,
}
sync_corr0[nprime]=magtmp0;
sync_corr1[nprime]=magtmp1;
if (n<FRAME_LENGTH_COMPLEX_SAMPLES) sync_corr_ue1[n] = magtmp1;
}
avg0/=length;
avg1/=length;
avg0/=(length/4);
avg1/=(length/4);
// PSS in symbol 1
int pssoffset = frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0 + frame_parms->nb_prefix_samples;
int pssoffset = frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples0;
if (maxlev0 > maxlev1) {
if ((int64_t)maxlev0 > (5*avg0)) {*lev = maxlev0; *ind=0; *avg=avg0; return((length+maxpos0-pssoffset)%length);};
......
......@@ -114,9 +114,9 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
#ifdef DEBUG_CH
if (l==pilot_pos1)
write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,1);
write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,1);
else
write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,1);
write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,1);
#endif
......@@ -152,7 +152,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
mmtmpU3 = _mm_unpackhi_epi32(mmtmpU0,mmtmpU1);
ul_ch128[0] = _mm_packs_epi32(mmtmpU2,mmtmpU3);
// printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]);
// printf("rb %d ch: %d %d\n",i,((int16_t*)ul_ch128)[0],((int16_t*)ul_ch128)[1]);
// multiply by conjugated channel
mmtmpU0 = _mm_madd_epi16(ul_ref128[1],rxdataF128[1]);
// mmtmpU0 contains real part of 4 consecutive outputs (32-bit)
......@@ -339,7 +339,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
#ifdef DEBUG_CH
LOG_D(PHY,"lte_ul_channel_estimation: k=%d, alpha = %d, beta = %d\n",k,alpha,beta);
// LOG_D(PHY,"lte_ul_channel_estimation: k=%d, alpha = %d, beta = %d\n",k,alpha,beta);
#endif
//symbol_offset_subframe = frame_parms->N_RB_UL*12*k;
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/pss.c
* \brief Top-level routines for generating primary synchronization signal (PSS) V8.6 2009-03
* \author F. Kaltenberger, O. Tonelli, R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: raymond.knopp@eurecom.fr
* \note
* \warning
*/
/* file: initial_syncSL.c
purpose: Initial synchronization procedures for Sidelink (SPSS/SSSS/PSBCH detection)
author: raymond.knopp@eurecom.fr
date: 13.05.2018
*/
//#include "defs.h"
#include "PHY/defs.h"
#include "PHY/extern.h"
int initial_syncSL(PHY_VARS_UE *ue) {
int index;
int64_t psslevel;
int64_t avglevel;
ue->rx_offsetSL = lte_sync_timeSL(ue,
&index,
&psslevel,
&avglevel);
printf("index %d, psslevel %lld dB avglevel %lld dB => %d sample offset\n",
index,dB_fixed(psslevel),dB_fixed(avglevel),ue->rx_offsetSL);
int32_t sss_metric;
int32_t phase_max;
rx_slsss(ue,&sss_metric,&phase_max,index);
generate_sl_grouphop(ue);
if (rx_psbch(ue) == -1)
ue->slbch_errors++;
else {
// send payload to RRC
}
}
......@@ -752,14 +752,15 @@ void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
}
pbch_e[i] = (pbch_e[i]&1) ^ ((s>>(i&0x1f))&1);
}
}
void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
int8_t* llr,
uint32_t length,
uint8_t frame_mod4)
uint8_t frame_mod4,
int SLflag)
{
int i;
uint8_t reset;
......@@ -767,7 +768,7 @@ void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
reset = 1;
// x1 is set in first call to lte_gold_generic
x2 = frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.6.1
x2 = SLflag==0 ? frame_parms->Nid_cell : frame_parms->Nid_SL; //this is c_init in 36.211 Sec 6.6.1
// msg("pbch_unscrambling: Nid_cell = %d\n",x2);
for (i=0; i<length; i++) {
......@@ -778,7 +779,7 @@ void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
}
// take the quarter of the PBCH that corresponds to this frame
if ((i>=(frame_mod4*(length>>2))) && (i<((1+frame_mod4)*(length>>2)))) {
if (SLflag==1 || ((i>=(frame_mod4*(length>>2))) && (i<((1+frame_mod4)*(length>>2))))) {
if (((s>>(i%32))&1)==0)
llr[i] = -llr[i];
......@@ -838,7 +839,6 @@ void pbch_quantize(int8_t *pbch_llr8,
pbch_llr8[i]=-8;
else
pbch_llr8[i] = (char)(pbch_llr[i]);
}
}
......@@ -956,7 +956,8 @@ uint16_t rx_pbch(LTE_UE_COMMON *lte_ue_common_vars,
pbch_unscrambling(frame_parms,
pbch_e_rx,
pbch_E,
frame_mod4);
frame_mod4,
0);
......
......@@ -1444,11 +1444,13 @@ void pbch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
\param frame_parms Pointer to frame descriptor
\param llr Output of the demodulator
\param length Length of the sequence
\param frame_mod4 Frame number modulo 4*/
\param frame_mod4 Frame number modulo 4
\param SL_flag Flag to indicate SLBCH instead of BCH*/
void pbch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
int8_t* llr,
uint32_t length,
uint8_t frame_mod4);
uint8_t frame_mod4,
int SL_flag);
/*! \brief DCI Encoding. This routine codes an arbitrary DCI PDU after appending the 8-bit 3GPP CRC. It then applied sub-block interleaving and rate matching.
\param a Pointer to DCI PDU (coded in bytes)
......@@ -2322,6 +2324,8 @@ int generate_slsss(int32_t **txdataF,
LTE_DL_FRAME_PARMS *frame_parms,
uint16_t symbol);
int rx_slsss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *phase_max,int Nid2);
/*! \brief Top-level generation route for Sidelink BCH,PSS and SSS
\param ue pointer to UE descriptor
\param frame_tx Frame number
......@@ -2352,5 +2356,7 @@ int generate_slbch(int32_t **txdataF,
int subframe,
uint8_t *slmib);
int rx_psbch(PHY_VARS_UE *ue);
/**@}*/
#endif
......@@ -29,10 +29,10 @@
* \note
* \warning
*/
/* file: pss.c
purpose: generate the primary synchronization signals of LTE
author: florian.kaltenberger@eurecom.fr, oscar.tonelli@yahoo.it
date: 21.10.2009
/* file: slbch.c
purpose: TX and RX procedures for Sidelink Broadcast Channel
author: raymond.knopp@eurecom.fr
date: 02.05.2018
*/
//#include "defs.h"
......@@ -42,6 +42,9 @@
#define PSBCH_A 40
#define PSBCH_E 1008 //12REs/PRB*6PRBs*7symbols*2 bits/RB
int generate_slbch(int32_t **txdataF,
short amp,
LTE_DL_FRAME_PARMS *frame_parms,
......@@ -50,8 +53,8 @@ int generate_slbch(int32_t **txdataF,
uint8_t slbch_a[PSBCH_A>>3];
uint32_t psbch_D;
uint8_t psbch_d[96+(3*(16+PBCH_A))];
uint8_t psbch_w[3*3*(16+PBCH_A)];
uint8_t psbch_d[96+(3*(16+PSBCH_A))];
uint8_t psbch_w[3*3*(16+PSBCH_A)];
uint8_t psbch_e[PSBCH_E];
uint8_t RCC;
int a;
......@@ -61,7 +64,10 @@ int generate_slbch(int32_t **txdataF,
AssertFatal(frame_parms->Ncp==NORMAL,"Only Normal Prefix supported for Sidelink\n");
AssertFatal(frame_parms->Ncp==NORMAL,"Only Normal Prefix supported for Sidelink\n");
bzero(slbch_a,PSBCH_A>>3);
bzero(psbch_e,PSBCH_E);
memset(psbch_d,LTE_NULL,96);
for (int i=0; i<(PSBCH_A>>3); i++)
slbch_a[(PSBCH_A>>3)-i-1] = slmib[i];
......@@ -69,7 +75,7 @@ int generate_slbch(int32_t **txdataF,
RCC = sub_block_interleaving_cc(psbch_D,psbch_d+96,psbch_w);
lte_rate_matching_cc(RCC,PSBCH_E,psbch_w,psbch_e);
// for (int i=0;i<PSBCH_E;i++) printf("PSBCH E[%d] %d\n",i,psbch_e[i]);
pbch_scrambling(frame_parms,
psbch_e,
PSBCH_E,
......@@ -82,26 +88,33 @@ int generate_slbch(int32_t **txdataF,
a = (amp*SQRT_18_OVER_32_Q15)>>(15-2);
int Nsymb=14;
int16_t precin[144*12];
int16_t precout[144*12];
for (int i=0;i<144*7;i++)
if (*eptr++ == 1) precin[i] =-a;
else precin[i] = a;
dft_lte((int32_t*)precout,
(int32_t*)precin,
72,
12);
int j=0;
for (symb=0;symb<10;symb++) {
k = (frame_parms->ofdm_symbol_size<<1)-72;
printf("Generating PSBCH in symbol %d offset %d\n",symb,
(subframe*Nsymb*frame_parms->ofdm_symbol_size)+(symb*frame_parms->ofdm_symbol_size));
// printf("Generating PSBCH in symbol %d offset %d\n",symb,
// (subframe*Nsymb*frame_parms->ofdm_symbol_size)+(symb*frame_parms->ofdm_symbol_size));
txptr = (int16_t*)&txdataF[0][(subframe*Nsymb*frame_parms->ofdm_symbol_size)+(symb*frame_parms->ofdm_symbol_size)];
// first half (negative frequencies)
for (int i=0;i<72;i++) {
if (*eptr++ == 1) txptr[k] =-a;
else txptr[k] = a;
k++;
}
k=0;
for (int i=0;i<72;i++,j++,k++) txptr[k] = precout[j];
// second half (positive frequencies)
for (int i=0;i<72;i++) {
if (*eptr++ == 1) txptr[k] =-a;
else txptr[k] = a;
k++;
}
for (int i=0,k=0;i<72;i++,j++,k++) txptr[k] = precout[j];
if (symb==0) symb+=3;
}
......@@ -113,3 +126,205 @@ int generate_slbch(int32_t **txdataF,
return(0);
}
int rx_psbch(PHY_VARS_UE *ue) {
int16_t **rxdataF = ue->sl_rxdataF;
int16_t **rxdataF_ext = ue->pusch_slbch->rxdataF_ext;
int16_t **drs_ch_estimates = ue->pusch_sldch->drs_ch_estimates;
int16_t **rxdataF_comp = ue->pusch_sldch->rxdataF_comp;
int16_t **ul_ch_mag = ue->pusch_sldch->ul_ch_mag;
int32_t avgs;
uint8_t log2_maxh=0;
int32_t avgU[2];
int Nsymb=7;
RU_t ru_tmp;
memset((void*)&ru_tmp,0,sizeof(RU_t));
memcpy((void*)&ru_tmp.frame_parms,(void*)&ue->frame_parms,sizeof(LTE_DL_FRAME_PARMS));
ru_tmp.N_TA_offset=0;
ru_tmp.common.rxdata_7_5kHz = (int32_t**)malloc16(ue->frame_parms.nb_antennas_rx*sizeof(int32_t*));
for (int aa=0;aa<ue->frame_parms.nb_antennas_rx;aa++)
ru_tmp.common.rxdata_7_5kHz[aa] = (int32_t*)&ue->common_vars.rxdata_syncSL[aa][ue->rx_offsetSL*2];
ru_tmp.common.rxdataF = (int32_t**)rxdataF;
ru_tmp.nb_rx = ue->frame_parms.nb_antennas_rx;
for (int l=0; l<11; l++) {
slot_fep_ul(&ru_tmp,l%7,(l>6)?1:0,0);
ulsch_extract_rbs_single((int32_t**)rxdataF,
(int32_t**)rxdataF_ext,
(ue->frame_parms.N_RB_UL/2)-3,
6,
l,
0,
&ue->frame_parms);
if (l==0) l+=2;
}
#ifdef PSBCH_DEBUG
write_output("slbch_rxF.m",
"slbchrxF",
&rxdataF[0][0],
14*ue->frame_parms.ofdm_symbol_size,1,1);
write_output("slbch_rxF_ext.m","slbchrxF_ext",rxdataF_ext[0],14*12*ue->frame_parms.N_RB_DL,1,1);
#endif
lte_ul_channel_estimation(&ue->frame_parms,
(int32_t**)drs_ch_estimates,
(int32_t**)NULL,
(int32_t**)rxdataF_ext,
6,
0,
0,
ue->gh[0][0], //u
0, //v
(ue->frame_parms.Nid_SL>>1)&7, //cyclic_shift
3,
1, // interpolation
0);
lte_ul_channel_estimation(&ue->frame_parms,
(int32_t**)drs_ch_estimates,
(int32_t**)NULL,
(int32_t**)rxdataF_ext,
6,
0,
0,
ue->gh[0][1],//u
0,//v
(ue->frame_parms.Nid_SL>>1)&7,//cyclic_shift,
10,
1, // interpolation
0);
ulsch_channel_level(drs_ch_estimates,
&ue->frame_parms,
avgU,
2);
#ifdef PSBCH_DEBUG
write_output("drsbch_ext0.m","drsbchest0",drs_ch_estimates[0],ue->frame_parms.N_RB_UL*12*14,1,1);
#endif
avgs = 0;
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
avgs = cmax(avgs,avgU[aarx]);
// log2_maxh = 4+(log2_approx(avgs)/2);
log2_maxh = (log2_approx(avgs)/2)+ log2_approx(ue->frame_parms.nb_antennas_rx-1)+4;
for (int l=0; l<10; l++) {
ulsch_channel_compensation(
rxdataF_ext,
drs_ch_estimates,
ul_ch_mag,
NULL,
rxdataF_comp,
&ue->frame_parms,
l,
2, //Qm
6, //nb_rb
log2_maxh); // log2_maxh+I0_shift
if (ue->frame_parms.nb_antennas_rx > 1)
ulsch_detection_mrc(&ue->frame_parms,
rxdataF_comp,
ul_ch_mag,
NULL,
l,
6 //nb_rb
);
freq_equalization(&ue->frame_parms,
rxdataF_comp,
ul_ch_mag,
NULL,
l,
72,
2);
if (l==0) l=3;
}
lte_idft(&ue->frame_parms,
rxdataF_comp[0],
72);
#ifdef PSBCH_DEBUG
write_output("slbch_rxF_comp.m","slbchrxF_comp",rxdataF_comp[0],ue->frame_parms.N_RB_UL*12*14,1,1);
#endif
int8_t llr[PSBCH_E];
int8_t *llrp = llr;
for (int l=0; l<10; l++) {
pbch_quantize(llrp,
&rxdataF_comp[0][l*ue->frame_parms.N_RB_UL*12*2],
72*2);
llrp += 72*2;
if (l==0) l=3;
}
pbch_unscrambling(&ue->frame_parms,
llr,
PSBCH_E,
0,
1);
#ifdef PSBCH_DEBUG
write_output("slbch_llr.m","slbch_llr",llr,PSBCH_E,1,4);
#endif
uint8_t slbch_a[2+(PSBCH_A>>3)];
uint32_t psbch_D;
uint8_t psbch_d_rx[96+(3*(16+PSBCH_A))];
uint8_t dummy_w_rx[3*3*(16+PSBCH_A)];
uint8_t psbch_w_rx[3*3*(16+PSBCH_A)];
uint8_t *psbch_e_rx=llr;
uint8_t RCC;
int a;
uint8_t *decoded_output = ue->slss_rx.slmib;
psbch_D = 16+PSBCH_A;
memset(dummy_w_rx,0,3*3*(psbch_D));
RCC = generate_dummy_w_cc(psbch_D,
dummy_w_rx);
lte_rate_matching_cc_rx(RCC,PSBCH_E,psbch_w_rx,dummy_w_rx,psbch_e_rx);
sub_block_deinterleaving_cc(psbch_D,
&psbch_d_rx[96],
&psbch_w_rx[0]);
memset(slbch_a,0,((16+PSBCH_A)>>3));
phy_viterbi_lte_sse2(psbch_d_rx+96,slbch_a,16+PSBCH_A);
// Fix byte endian of PSBCH (bit 39 goes in first)
for (int i=0; i<(PSBCH_A>>3); i++)
decoded_output[(PSBCH_A>>3)-i-1] = slbch_a[i];
// for (int i=0; i<(PSBCH_A>>3); i++) printf("SLBCH %d : %x\n",i,decoded_output[i]);
#ifdef DEBUG_PSBCH
LOG_I(PHY,"PSBCH CRC %x : %x\n",
crc16(slbch_a,PSBCH_A),
((uint16_t)slbch_a[PSBCH_A>>3]<<8)+slbch_a[(PSBCH_A>>3)+1]);
#endif
uint16_t crc = (crc16(slbch_a,PSBCH_A)>>16) ^
(((uint16_t)slbch_a[PSBCH_A>>3]<<8)+slbch_a[(PSBCH_A>>3)+1]);
if (crc>0) return(-1);
else return(0);
}
......@@ -150,6 +150,97 @@ void sldch_decoding(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,int frame_rx,int subfra
log2_maxh = (log2_approx(avgs)/2)+ log2_approx(ue->frame_parms.nb_antennas_rx-1)+4;
for (int l=0; l<(Nsymb<<1)-1; l++) {
if (((ue->frame_parms.Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
((ue->frame_parms.Ncp == 1) && ((l==2) || (l==8)))) {
l++;
}
ulsch_channel_compensation(
rxdataF_ext,
drs_ch_estimates,
ul_ch_mag,
NULL,
rxdataF_comp,
&ue->frame_parms,
l,
2, //Qm
2, //nb_rb
log2_maxh); // log2_maxh+I0_shift
if (ue->frame_parms.nb_antennas_rx > 1)
ulsch_detection_mrc(&ue->frame_parms,
rxdataF_comp,
ul_ch_mag,
NULL,
l,
2 //nb_rb
);
freq_equalization(&ue->frame_parms,
rxdataF_comp,
ul_ch_mag,
NULL,
l,
24,
2);
}
lte_idft(&ue->frame_parms,
rxdataF_comp[0],
24);
#ifdef PSDCH_DEBUG
write_output("sldch_rxF_comp.m","sldchrxF_comp",rxdataF_comp[0],ue->frame_parms.N_RB_UL*12*14,1,1);
#endif
lte_ul_channel_estimation(&ue->frame_parms,
(int32_t**)drs_ch_estimates,
(int32_t**)NULL,
(int32_t**)rxdataF_ext,
2,
frame_rx,
subframe_rx,
0, //u
0, //v
0, //cyclic_shift
3,
1, // interpolation
0);
lte_ul_channel_estimation(&ue->frame_parms,
(int32_t**)drs_ch_estimates,
(int32_t**)NULL,
(int32_t**)rxdataF_ext,
2,
frame_rx,
subframe_rx,
0,//u
0,//v
0,//cyclic_shift,
10,
1, // interpolation
0);
ulsch_channel_level(drs_ch_estimates,
&ue->frame_parms,
avgU,
2);
#ifdef PSDCH_DEBUG
write_output("drs_ext0.m","drsest0",drs_ch_estimates[0],ue->frame_parms.N_RB_UL*12*14,1,1);
#endif
avgs = 0;
for (int aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
avgs = cmax(avgs,avgU[aarx]);
// log2_maxh = 4+(log2_approx(avgs)/2);
log2_maxh = (log2_approx(avgs)/2)+ log2_approx(ue->frame_parms.nb_antennas_rx-1)+4;
for (int l=0; l<(Nsymb<<1)-1; l++) {
if (((ue->frame_parms.Ncp == 0) && ((l==3) || (l==10)))|| // skip pilots
......
......@@ -56,7 +56,7 @@ void check_and_generate_slss(PHY_VARS_UE *ue,int frame_tx,int subframe_tx) {
ue->frame_parms.Nid_SL = slss->slss_id;
// 6 PRBs => ceil(10*log10(6)) = 8
ue->tx_power_dBm[subframe_tx] = -6;
ue->tx_power_dBm[subframe_tx] = 8;
ue->tx_total_RE[subframe_tx] = 72;
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
......@@ -79,34 +79,34 @@ void check_and_generate_slss(PHY_VARS_UE *ue,int frame_tx,int subframe_tx) {
// PSS
generate_slpss(ue->common_vars.txdataF,
tx_amp,
tx_amp<<1,
&ue->frame_parms,
1,
subframe_tx
);
generate_slpss(ue->common_vars.txdataF,
tx_amp,
tx_amp<<1,
&ue->frame_parms,
2,
subframe_tx
);
/*
generate_slbch(ue->common_vars.txdataF,
tx_amp,
&ue->frame_parms,
subframe_tx,
ue->slss->slmib);
*/
generate_slsss(ue->common_vars.txdataF,
subframe_tx,
tx_amp,
tx_amp<<2,
&ue->frame_parms,
11);
generate_slsss(ue->common_vars.txdataF,
subframe_tx,
tx_amp,
tx_amp<<2,
&ue->frame_parms,
12);
......@@ -116,9 +116,9 @@ void check_and_generate_slss(PHY_VARS_UE *ue,int frame_tx,int subframe_tx) {
generate_drs_pusch(ue,
NULL,
0,
tx_amp,
tx_amp<<2,
subframe_tx,
(1+(ue->frame_parms.N_RB_UL/2))-3,
(ue->frame_parms.N_RB_UL/2)-3,
6,
0,
NULL,
......@@ -130,7 +130,5 @@ void check_and_generate_slss(PHY_VARS_UE *ue,int frame_tx,int subframe_tx) {
LOG_D(PHY,"ULSCH (after slss) : signal F energy %d dB (txdataF %p)\n",dB_fixed(signal_energy(&ue->common_vars.txdataF[0][subframe_tx*14*ue->frame_parms.ofdm_symbol_size],14*ue->frame_parms.ofdm_symbol_size)),&ue->common_vars.txdataF[0][subframe_tx*14*ue->frame_parms.ofdm_symbol_size]);
// write_output("txdataF_pre.m","txF_pre",&ue->common_vars.txdataF[0][subframe_tx*14*ue->frame_parms.ofdm_symbol_size],14*ue->frame_parms.ofdm_symbol_size,1,1);
}
#endif
......@@ -283,7 +283,7 @@ int16_t phaseSL_re[7] = {16383, 25101, 30791, 32767, 30791, 25101, 16383};
int16_t phaseSL_im[7] = {-28378, -21063, -11208, 0, 11207, 21062, 28377};
int rx_slsss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *phase_max,int Nid2,int subframe_rx)
int rx_slsss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *phase_max,int Nid2)
{
uint8_t i;
......@@ -322,8 +322,6 @@ int rx_slsss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *phase_max,int Nid2,int
ru_tmp.nb_rx = ue->frame_parms.nb_antennas_rx;
// remove_7_5_kHz(&ru_tmp,(subframe_rx<<1));
// remove_7_5_kHz(&ru_tmp,(subframe_rx<<1)+1);
// PSS
slot_fep_ul(&ru_tmp,1,0,0);
slot_fep_ul(&ru_tmp,2,0,0);
......@@ -395,7 +393,6 @@ int rx_slsss(PHY_VARS_UE *ue,int32_t *tot_metric,uint8_t *phase_max,int Nid2,int
}
}
}
exit(-1);
return(0);
}
......
......@@ -1307,6 +1307,7 @@ typedef struct {
LTE_eNB_DLSCH_t *dlsch_sldch;
LTE_UE_ULSCH_t *ulsch_sldch;
LTE_eNB_PUSCH *pusch_sldch;
LTE_eNB_PUSCH *pusch_slbch;
LTE_eNB_PUSCH *pusch_slcch;
LTE_UE_DLSCH_t *dlsch_rx_slsch;
LTE_UE_DLSCH_t *dlsch_rx_sldch[MAX_SLDCH];
......@@ -1317,7 +1318,7 @@ typedef struct {
int16_t *sldch_dlsch_llr;
int16_t *sldch_ulsch_llr;
SLSS_t *slss;
SLSCH_t slss_rx;
SLSS_t slss_rx;
SLSCH_t *slsch;
SLSCH_t slsch_rx;
int slsch_active;
......@@ -1334,7 +1335,7 @@ typedef struct {
pthread_mutex_t slss_mutex;
pthread_mutex_t sldch_mutex;
pthread_mutex_t slsch_mutex;
int slbch_errors;
//Paging parameters
uint32_t IMSImod1024;
uint32_t PF;
......
......@@ -46,10 +46,14 @@
#include "unitary_defs.h"
//#define PSBCH_DEBUG 1
int nfapi_mode=0;
double cpuf;
extern int32_t* sync_corr_ue1;
#define PSBCH_A 40
#define PSBCH_E 1008 //12REs/PRB*6PRBs*7symbols*2 bits/RB
int main(int argc, char **argv) {
......@@ -78,15 +82,13 @@ int main(int argc, char **argv) {
int pscch_errors=0;
int do_SLSS=0;
int index;
int64_t psslevel;
int64_t avglevel;
AssertFatal(load_configmodule(argc,argv) != NULL,
"cannot load configuration module, exiting\n");
logInit();
// enable these lines if you need debug info
set_comp_log(PHY,LOG_INFO,LOG_HIGH,1);
set_comp_log(OCM,LOG_INFO,LOG_HIGH,1);
set_glog(log_level,LOG_HIGH);
......@@ -314,6 +316,7 @@ int main(int argc, char **argv) {
if (do_SLSS == 1) {
slss.SL_OffsetIndicator = 0;
slss.slss_id = 170;
UE->frame_parms.Nid_SL = slss.slss_id;
slss.slmib_length = 5;
slss.slmib[0] = 0;
slss.slmib[1] = 1;
......@@ -329,6 +332,8 @@ int main(int argc, char **argv) {
// 0dBm transmit power for PSCCH = 0dBm - 10*log10(12) dBm/RE
generate_sl_grouphop(UE);
for (double snr=snr0;snr<snr+snr_int;snr+=snr_step) {
printf("*****************SNR %f\n",snr);
UE2UE[0][0][0]->path_loss_dB = -132.24 + snr + 10*log10(12);
......@@ -338,7 +343,8 @@ int main(int argc, char **argv) {
UE->slsch_rxcnt[0] = 0; UE->slsch_rxcnt[1] = 0; UE->slsch_rxcnt[2] = 0; UE->slsch_rxcnt[3] = 0;
pscch_errors=0;
UE->sl_fep_done = 0;
UE->slbch_errors=0;
for (trials = 0;trials<n_trials;trials++) {
UE->pscch_coded=0;
UE->pscch_generated=0;
......@@ -362,7 +368,9 @@ int main(int argc, char **argv) {
ulsch_common_procedures(UE,&proc,0);
// write_output("txsig0SL.m","txs0",&UE->common_vars.txdata[0][UE->frame_parms.samples_per_tti*subframe],UE->frame_parms.samples_per_tti,1,1);
// printf("Running do_SL_sig for frame %d subframe %d (%d,%d,%d,%d)\n",frame,subframe,UE->slss_generated,UE->pscch_generated,UE->psdch_generated,UE->pssch_generated);
do_SL_sig(0,UE2UE,subframe,UE->pscch_generated,&UE->frame_parms,frame,0);
do_SL_sig(0,UE2UE,subframe,UE->pscch_generated,
3*(UE->frame_parms.ofdm_symbol_size)+2*(UE->frame_parms.nb_prefix_samples)+UE->frame_parms.nb_prefix_samples0,
&UE->frame_parms,frame,0);
// write_output("rxsig0.m","rxs0",&UE->common_vars.rxdata[0][UE->frame_parms.samples_per_tti*subframe],UE->frame_parms.samples_per_tti,1,1);
if (do_SLSS==1)
memcpy((void*)&UE->common_vars.rxdata_syncSL[0][(((frame&3)*10)+subframe)*2*UE->frame_parms.samples_per_tti],
......@@ -377,24 +385,12 @@ int main(int argc, char **argv) {
}
rx_slcch(UE,frame,subframe);
rx_slsch(UE,&proc,frame,subframe);
if ((absSF % 40) == 3 && do_SLSS==1) {
printf("Running Initial synchronization for SL\n");
// initial synch for SL
initial_syncSL(UE);
// write_output("rxsyncb.m","rxsyncb",(void*)UE->common_vars.rxdata_syncSL[0],(UE->frame_parms.samples_per_tti),1,1);
UE->rx_offsetSL = lte_sync_timeSL(UE,
&index,
&psslevel,
&avglevel);
printf("absSF %d: Frame %d, index %d, psslevel %lld dB avglevel %lld dB => %d sample offset\n",
absSF,frame,index,dB_fixed(psslevel),dB_fixed(avglevel),UE->rx_offsetSL);
int32_t sss_metric;
int32_t phase_max;
rx_slsss(UE,&sss_metric,&phase_max,index,subframe);
// write_output("rxsynca.m","rxsynca",(void*)UE->common_vars.rxdata_syncSL[0],(UE->frame_parms.samples_per_tti),1,1);
// exit(-1);
}
UE->sl_fep_done = 0;
......
......@@ -549,7 +549,7 @@ void do_UL_sig(channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM
}
void do_SL_sig(int UE_id,channel_desc_t *UE2UE[NUMBER_OF_UE_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs],
uint16_t subframe,uint16_t slot, LTE_DL_FRAME_PARMS *frame_parms,
uint16_t subframe,uint16_t slot, int symbol_offset, LTE_DL_FRAME_PARMS *frame_parms,
uint32_t frame,uint8_t CC_id)
{
......@@ -605,11 +605,11 @@ void do_SL_sig(int UE_id,channel_desc_t *UE2UE[NUMBER_OF_UE_MAX][NUMBER_OF_UE_MA
if (((double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe] +
UE2UE[UE_id][0][CC_id]->path_loss_dB) <= -125.0) {
// don't simulate a UE that is too weak
LOG_D(OCM,"[SIM][SL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d,slot_ind %d)\n",
LOG_I(OCM,"[SIM][SL] UE %d tx_pwr %d dBm (num_RE %d) for subframe %d (sf_offset %d,slot_ind %d,symbol_offset %d)\n",
UE_id,
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,slot,sf_offset);
subframe,sf_offset,slot,symbol_offset);
} else {
tx_pwr = dac_fixed_gain((double**)s_re,
(double**)s_im,
......@@ -617,20 +617,21 @@ void do_SL_sig(int UE_id,channel_desc_t *UE2UE[NUMBER_OF_UE_MAX][NUMBER_OF_UE_MA
sf_offset,
nb_antennas_tx,
frame_parms->samples_per_tti,
(slot == 2)? sf_offset+(frame_parms->samples_per_tti>>1) : sf_offset,
((slot == 2)? sf_offset+(frame_parms->samples_per_tti>>1) : sf_offset)+symbol_offset,
frame_parms->ofdm_symbol_size,
14,
(double)PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe]-10*log10((double)PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
1,
NULL,
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]); // This make the previous argument the total power
LOG_I(OCM,"[SIM][SL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d/%d)\n",
LOG_I(OCM,"[SIM][SL] UE %d tx_pwr %f dBm (target %d dBm, num_RE %d) for subframe %d (sf_offset %d/%d/%d)\n",
UE_id,
10*log10(tx_pwr*PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe]),
PHY_vars_UE_g[UE_id][CC_id]->tx_power_dBm[subframe],
PHY_vars_UE_g[UE_id][CC_id]->tx_total_RE[subframe],
subframe,sf_offset,
(slot == 2)? sf_offset+(frame_parms->samples_per_tti>>1) : sf_offset);
(slot == 2)? sf_offset+(frame_parms->samples_per_tti>>1) : sf_offset,
symbol_offset);
multipath_channel(UE2UE[UE_id][0][CC_id],s_re,s_im,r_re0,r_im0,
......
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