Commit ae44bc06 authored by laurent's avatar laurent

pbch displays in the scope

parent e9ac05d4
......@@ -266,123 +266,33 @@ void nr_pbch_channel_compensation(int **rxdataF_ext,
int **rxdataF_comp,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t symbol,
uint8_t output_shift)
{
short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
//short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
#if defined(__x86_64__) || defined(__i386__)
__m128i mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#elif defined(__arm__)
int16x8_t mmtmpP0,mmtmpP1,mmtmpP2,mmtmpP3;
#endif
uint8_t output_shift) {
uint16_t nb_re=180;
uint8_t aarx;
#if defined(__x86_64__) || defined(__i386__)
__m128i *dl_ch128,*rxdataF128,*rxdataF_comp128;
#elif defined(__arm__)
#endif
const uint16_t nb_re=symbol == 2 ? 72 : 180;
AssertFatal((symbol > 0 && symbol < 4),
"symbol %d is illegal for PBCH DM-RS\n",
symbol);
if (symbol == 2) nb_re = 72;
// printf("comp: symbol %d : nb_re %d\n",symbol,nb_re);
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
#if defined(__x86_64__) || defined(__i386__)
dl_ch128 = (__m128i *)&dl_ch_estimates_ext[aarx][symbol*20*12];
rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*20*12];
rxdataF_comp128 = (__m128i *)&rxdataF_comp[aarx][symbol*20*12];
vect128 *dl_ch128 = (vect128 *)&dl_ch_estimates_ext[aarx][symbol*20*12];
vect128 *rxdataF128 = (vect128 *)&rxdataF_ext[aarx][symbol*20*12];
vect128 *rxdataF_comp128 = (vect128 *)&rxdataF_comp[aarx][symbol*20*12];
/*
printf("ch compensation dl_ch ext addr %p \n", &dl_ch_estimates_ext[aarx][symbol*20*12]);
printf("rxdataf ext addr %p symbol %d\n", &rxdataF_ext[aarx][symbol*20*12], symbol);
printf("rxdataf_comp addr %p\n",&rxdataF_comp[aarx][symbol*20*12]);
*/
#elif defined(__arm__)
// to be filled in
#endif
for (int re=0; re<nb_re; re+=12) {
// printf("******re %d\n",re);
#if defined(__x86_64__) || defined(__i386__)
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[0],rxdataF128[0]);
// print_ints("re",&mmtmpP0);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[0],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
// print_ints("im",&mmtmpP1);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[0]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
// print_ints("re(shift)",&mmtmpP0);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
// print_ints("im(shift)",&mmtmpP1);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
// print_ints("c0",&mmtmpP2);
// print_ints("c1",&mmtmpP3);
rxdataF_comp128[0] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
/*
print_shorts("rx:",rxdataF128);
print_shorts("ch:",dl_ch128);
print_shorts("pack:",rxdataF_comp128);
*/
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[1],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[1]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
rxdataF_comp128[1] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("rx:",rxdataF128+1);
// print_shorts("ch:",dl_ch128+1);
// print_shorts("pack:",rxdataF_comp128+1);
// multiply by conjugated channel
mmtmpP0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]);
// mmtmpP0 contains real part of 4 consecutive outputs (32-bit)
mmtmpP1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_shufflehi_epi16(mmtmpP1,_MM_SHUFFLE(2,3,0,1));
mmtmpP1 = _mm_sign_epi16(mmtmpP1,*(__m128i*)&conjugate[0]);
mmtmpP1 = _mm_madd_epi16(mmtmpP1,rxdataF128[2]);
// mmtmpP1 contains imag part of 4 consecutive outputs (32-bit)
mmtmpP0 = _mm_srai_epi32(mmtmpP0,output_shift);
mmtmpP1 = _mm_srai_epi32(mmtmpP1,output_shift);
mmtmpP2 = _mm_unpacklo_epi32(mmtmpP0,mmtmpP1);
mmtmpP3 = _mm_unpackhi_epi32(mmtmpP0,mmtmpP1);
rxdataF_comp128[2] = _mm_packs_epi32(mmtmpP2,mmtmpP3);
// print_shorts("rx:",rxdataF128+2);
// print_shorts("ch:",dl_ch128+2);
// print_shorts("pack:",rxdataF_comp128+2);
dl_ch128+=3;
rxdataF128+=3;
rxdataF_comp128+=3;
#elif defined(__arm__)
// to be filled in
#endif
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
*rxdataF_comp128++ = mulByConjugate128(rxdataF128++, dl_ch128++, output_shift);
}
}
#if defined(__x86_64__) || defined(__i386__)
_mm_empty();
_m_empty();
#endif
}
void nr_pbch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms,
......
......@@ -38,9 +38,7 @@ float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
extern int64_t *pss_corr_ue[3];
static void ia_receiver_on_off( FL_OBJECT *button, long arg)
{
static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "IA Receiver ON");
// PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
......@@ -52,9 +50,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg)
}
}
static void dl_traffic_on_off( FL_OBJECT *button, long arg)
{
static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "DL Traffic ON");
otg_enabled = 1;
......@@ -66,46 +62,37 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
}
}
FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
{
FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) {
FL_OBJECT *obj;
FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui );
// Define form
fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 800 );
// This the whole UI box
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
// Received signal
fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
// Time-domain channel response
fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" );
fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
// Frequency-domain channel response
fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
fl_set_xyplot_ybounds( fdui->chest_f,30,70);
// LLR of PUSCH
fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pusch_llr,2);
// I/Q PUSCH comp
fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX );
......@@ -113,7 +100,6 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pusch_comp,2);
fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
// I/Q PUCCH comp (format 1)
fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" );
fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX );
......@@ -121,7 +107,6 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pucch_comp1,2);
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
// I/Q PUCCH comp (fromat 1a/b)
fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX );
......@@ -129,13 +114,11 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pucch_comp,2);
// fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR);
// Throughput on PUSCH
fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" );
fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE );
fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color
// Generic eNB Button
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
......@@ -144,10 +127,8 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
fl_set_object_label(fdui->button_0, "DL Traffic OFF");
fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
fl_end_form( );
fdui->lte_phy_scope_enb->fdui = fdui;
return fdui;
}
......@@ -379,39 +360,31 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
}
*/
FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
{
FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) {
FL_OBJECT *obj;
FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui );
// Define form
fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 900 );
// This the whole UI box
obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" );
fl_set_object_color( obj, FL_BLACK, FL_BLACK );
// Received signal
fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
fl_set_xyplot_ybounds(fdui->rxsig_t,10,70);
// Time-domain channel response
fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
// Frequency-domain channel response
fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
fl_set_xyplot_ybounds( fdui->chest_f,30,70);
// LLR of PBCH
fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
......@@ -420,7 +393,6 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
//fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
// I/Q PBCH comp
fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
......@@ -429,14 +401,12 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
// fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
// fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
// LLR of PDCCH
fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
// I/Q PDCCH comp
fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
......@@ -444,7 +414,6 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
// LLR of PDSCH
fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
......@@ -452,20 +421,17 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
// I/Q PDSCH comp
fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" );
fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
// Throughput on PDSCH
fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
// Generic UE Button
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
......@@ -475,10 +441,8 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
fl_hide_object(fdui->button_0);
fl_end_form( );
fdui->lte_phy_scope_ue->fdui = fdui;
return fdui;
}
......@@ -486,14 +450,10 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
PHY_VARS_NR_UE *phy_vars_ue,
int eNB_id,
int UE_id,
uint8_t subframe)
{
int i,arx,atx,ind,k;
uint8_t subframe) {
NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
int nsymb_ce = frame_parms->ofdm_symbol_size;//*frame_parms->symbols_per_tti;
int samples_per_frame = frame_parms->samples_per_frame;
uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
int16_t **rxsig_t;
float **rxsig_t_dB;
float *time;
......@@ -512,7 +472,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
float llr_pbch[1920], bit_pbch[1920];
float *llr, *bit;
float *llr_pdcch, *bit_pdcch;
float *I, *Q;
static __thread float *I, *Q;
int num_pdcch_symbols=2;
int num_re = 4500;
int Qm = 2;
......@@ -563,50 +523,49 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
}
*/
I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
if (!I) I = (float *) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
if (!Q) Q = (float *) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot*2,sizeof(float));
/*
chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
for (arx=0; arx<nb_antennas_rx; arx++) {
for (int arx=0; arx<nb_antennas_rx; arx++) {
chest_t_abs[arx] = (float*) calloc(frame_parms->ofdm_symbol_size,sizeof(float));
}
chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
*/
llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float));
llr_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
bit_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
rxsig_t = (int16_t **) phy_vars_ue->common_vars.rxdata;
rxsig_t_dB = calloc(nb_antennas_rx,sizeof(float *));
llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
rxsig_t_dB = calloc(nb_antennas_rx,sizeof(float*));
for (arx=0; arx<nb_antennas_rx; arx++) {
rxsig_t_dB[arx] = (float*) calloc(samples_per_frame,sizeof(float));
for (int arx=0; arx<nb_antennas_rx; arx++) {
rxsig_t_dB[arx] = (float *) calloc(samples_per_frame,sizeof(float));
}
time = calloc(samples_per_frame,sizeof(float));
corr = calloc(samples_per_frame,sizeof(float));
/*
chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
*/
pbch_llr = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
pdcch_llr = (int8_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
// pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
//pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
// Received signal in time domain of receive antenna 0
if (rxsig_t != NULL) {
if (rxsig_t[0] != NULL) {
for (i=0; i<samples_per_frame; i++) {
for (int i=0; i<samples_per_frame; i++) {
rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
time[i] = (float) i;
}
......@@ -628,9 +587,9 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
}
if (phy_vars_ue->is_synchronized==0) {
for (ind=0;ind<3;ind++) {
for (int ind=0; ind<3; ind++) {
if (pss_corr_ue[ind]) {
for (i=0; i<samples_per_frame; i++) {
for (int i=0; i<samples_per_frame; i++) {
corr[i] = (float) pss_corr_ue[ind][i];
time[i] = (float) i;
}
......@@ -727,7 +686,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
// PBCH LLRs
if (pbch_llr != NULL) {
for (i=0; i<864; i++) {
for (int i=0; i<864; i++) {
llr_pbch[i] = (float) pbch_llr[i];
bit_pbch[i] = (float) i;
}
......@@ -735,7 +694,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,864,"","","");
}
if (phy_vars_ue->is_synchronized==1)
if (phy_vars_ue->is_synchronized!=1)
first_symbol=5;
else
first_symbol=1;
......@@ -747,17 +706,19 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
nb_re = 72;
else
nb_re = 180;
for (i=0; i<nb_re; i++) {
for (int i=0; i<nb_re; i++) {
I[i] = pbch_comp[2*symbol*20*12+2*i];
Q[i] = pbch_comp[2*symbol*20*12+2*i+1];
}
}
fl_set_xyplot_data(form->pbch_comp,I,Q,432,"","","");
}
// PDCCH LLRs
if (pdcch_llr != NULL) {
for (i=0; i<100; i++) { //12*frame_parms->N_RB_DL*2*num_pdcch_symbols
for (int i=0; i<100; i++) { //12*frame_parms->N_RB_DL*2*num_pdcch_symbols
llr_pdcch[i] = (float) pdcch_llr[2*24*9 +i];
bit_pdcch[i] = (float) i;
}
......@@ -767,16 +728,17 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
// PDCCH I/Q of MF Output
if (pdcch_comp!=NULL) {
for (i=0; i<100; i++) {
for (int i=0; i<100; i++) {
I[i] = pdcch_comp[2*50*12+2*i];
Q[i] = pdcch_comp[2*50*12+2*i+1];
}
fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
}
// PDSCH LLRs
if (pdsch_llr != NULL) {
for (i=0; i<coded_bits_per_codeword; i++) {
for (int i=0; i<coded_bits_per_codeword; i++) {
llr[i] = (float) pdsch_llr[i];
bit[i] = (float) i;
}
......@@ -787,13 +749,14 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
// PDSCH I/Q of MF Output
if (pdsch_comp!=NULL) {
for (i=0; i<nb_rb_pdsch*12; i++) {
for (int i=0; i<nb_rb_pdsch*12; i++) {
I[i] = pdsch_comp[2*2*nb_rb_pdsch*12+2*i ];
Q[i] = pdsch_comp[2*2*nb_rb_pdsch*12+2*i+1];
}
fl_set_xyplot_data(form->pdsch_comp,I,Q,nb_rb_pdsch*12,"","","");
}
/*
// PDSCH Throughput
......@@ -811,23 +774,19 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
*/
fl_check_forms();
free(time);
free(corr);
for (arx=0; arx<nb_antennas_rx; arx++) {
for (int arx=0; arx<nb_antennas_rx; arx++) {
free(rxsig_t_dB[arx]);
}
free(rxsig_t_dB);
free(I);
free(Q);
free(rxsig_t_dB);
free(llr);
free(bit);
free(bit_pdcch);
free(llr_pdcch);
/*
free(chest_f_abs);
for (arx=0; arx<nb_antennas_rx; arx++) {
......
......@@ -78,8 +78,8 @@
#include "defs_RU.h"
#define RX_NB_TH_MAX 1
#define RX_NB_TH 1
#define RX_NB_TH_MAX 2
#define RX_NB_TH 2
#define LTE_SLOTS_PER_SUBFRAME 2
......
......@@ -26,11 +26,11 @@
* The host CPU needs to have support for SSE2 at least. SSE3 and SSE4.1 functions are emulated if the CPU lacks support for them.
* This will slow down the softmodem, but may be valuable if only offline signal processing is required.
*
* \author S. Held
* \email sebastian.held@imst.de
* \company IMST GmbH
* \date 2015
* \version 0.1
* \author S. Held, Laurent THOMAS
* \email sebastian.held@imst.de, laurent.thomas@open-cells.com
* \company IMST GmbH, Open Cells Project
* \date 2019
* \version 0.2
*/
#ifndef SSE_INTRIN_H
......@@ -40,23 +40,23 @@
#if defined(__x86_64) || defined(__i386__)
#ifndef __SSE2__
# error SSE2 processor intrinsics disabled
# error SSE2 processor intrinsics disabled
#endif
#include <emmintrin.h>
#include <xmmintrin.h>
#ifdef __SSE3__
# include <pmmintrin.h>
# include <tmmintrin.h>
#include <pmmintrin.h>
#include <tmmintrin.h>
#endif
#ifdef __SSE4_1__
# include <smmintrin.h>
#include <smmintrin.h>
#endif
#ifdef __AVX2__
# include <immintrin.h>
#include <immintrin.h>
#endif
// ------------------------------------------------
......@@ -108,8 +108,7 @@ typedef union {
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_comge_epi8_SSE2(__m128i a, __m128i b)
{
static inline __m128i ssp_comge_epi8_SSE2(__m128i a, __m128i b) {
__m128i c;
c = _mm_cmpgt_epi8( a, b );
a = _mm_cmpeq_epi8( a, b );
......@@ -126,13 +125,11 @@ static inline __m128i ssp_comge_epi8_SSE2(__m128i a, __m128i b)
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_shuffle_epi8_SSE2 (__m128i a, __m128i mask)
{
static inline __m128i ssp_shuffle_epi8_SSE2 (__m128i a, __m128i mask) {
ssp_m128 A,B, MASK, maskZero;
A.i = a;
maskZero.i = ssp_comge_epi8_SSE2( mask, _mm_setzero_si128() );
MASK.i = _mm_and_si128 ( mask, _mm_set1_epi8( (char)0x0F) );
B.s8[ 0] = A.s8[ (MASK.s8[ 0]) ];
B.s8[ 1] = A.s8[ (MASK.s8[ 1]) ];
B.s8[ 2] = A.s8[ (MASK.s8[ 2]) ];
......@@ -149,7 +146,6 @@ static inline __m128i ssp_shuffle_epi8_SSE2 (__m128i a, __m128i mask)
B.s8[13] = A.s8[ (MASK.s8[13]) ];
B.s8[14] = A.s8[ (MASK.s8[14]) ];
B.s8[15] = A.s8[ (MASK.s8[15]) ];
B.i = _mm_and_si128( B.i, maskZero.i );
return B.i;
}
......@@ -182,8 +178,7 @@ static inline __m128i ssp_shuffle_epi8_SSE2 (__m128i a, __m128i mask)
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_insert_epi8_SSE2( __m128i a, int b, const int ndx )
{
static inline __m128i ssp_insert_epi8_SSE2( __m128i a, int b, const int ndx ) {
ssp_m128 Ahi, Alo;
b = b & 0xFF; /* Convert to 8-bit integer */
Ahi.i = _mm_unpackhi_epi8( a, _mm_setzero_si128() ); /* Ahi = a_8[8:15] Simulate 8bit integers as 16-bit integers */
......@@ -256,7 +251,6 @@ static inline __m128i ssp_insert_epi8_SSE2( __m128i a, int b, const int ndx )
}
return _mm_packus_epi16( Alo.i, Ahi.i ); // Pack the 16-bit integers to 8bit again.
///* Another implementation, but slower: */
//ssp_m128 A, B, mask;
//mask.i = _mm_setzero_si128();
......@@ -277,16 +271,13 @@ static inline __m128i ssp_insert_epi8_SSE2( __m128i a, int b, const int ndx )
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_cvtepi8_epi16_SSE2 ( __m128i a)
{
static inline __m128i ssp_cvtepi8_epi16_SSE2 ( __m128i a) {
__m128i b = _mm_setzero_si128 ();
__m128i c = _mm_unpacklo_epi8(a, b);
__m128i d = _mm_set1_epi16 (128);
b = _mm_and_si128(d, c);
d = _mm_set1_epi16(0x1FE);
b = _mm_mullo_epi16(b, d);
return _mm_add_epi16(c, b);
}
......@@ -299,8 +290,7 @@ static inline __m128i ssp_cvtepi8_epi16_SSE2 ( __m128i a)
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_logical_bitwise_select_SSE2( __m128i a, __m128i b, __m128i mask ) // Bitwise (mask ? a : b)
{
static inline __m128i ssp_logical_bitwise_select_SSE2( __m128i a, __m128i b, __m128i mask ) { // Bitwise (mask ? a : b)
a = _mm_and_si128 ( a, mask ); // clear a where mask = 0
b = _mm_andnot_si128( mask, b ); // clear b where mask = 1
a = _mm_or_si128 ( a, b ); // a = a OR b
......@@ -316,8 +306,7 @@ static inline __m128i ssp_logical_bitwise_select_SSE2( __m128i a, __m128i b, __m
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_max_epi8_SSE2( __m128i a, __m128i b )
{
static inline __m128i ssp_max_epi8_SSE2( __m128i a, __m128i b ) {
__m128i mask = _mm_cmpgt_epi8( a, b ); // FFFFFFFF where a > b
a = ssp_logical_bitwise_select_SSE2( a, b, mask );
return a;
......@@ -332,15 +321,12 @@ static inline __m128i ssp_max_epi8_SSE2( __m128i a, __m128i b )
* \date 2006-2008
* \copyright Apache License 2.0
*/
static inline __m128i ssp_cvtepi16_epi32_SSE2 ( __m128i a)
{
static inline __m128i ssp_cvtepi16_epi32_SSE2 ( __m128i a) {
__m128i b = _mm_set1_epi32 (-1); //0xFFFFFFFF
__m128i c = _mm_unpacklo_epi16(a, b); //FFFFa0**FFFFa1**....
__m128i d = _mm_set1_epi32 (0x8000); //0x8000
b = _mm_andnot_si128(c, d); // 0x80 for positive, 0x00 for negative
d = _mm_slli_epi32(b, 1); // 0x100 for positive, 0x000 for negative
return _mm_add_epi32(c, d);
}
#endif // __SSE4_1__
......@@ -350,5 +336,46 @@ static inline __m128i ssp_cvtepi16_epi32_SSE2 ( __m128i a)
#endif // x86_64 || i386
#endif // SSE_INTRIN_H
#if defined(__x86_64__) || defined(__i386__)
#define vect128 __m128i
#elif defined(__arm__)
#define vect128 int16x8_t
#endif
static const short minusConjug128[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
static inline vect128 mulByConjugate128(vect128 *a, vect128 *b, int8_t output_shift) {
#if defined(__x86_64__) || defined(__i386__)
vect128 realPart = _mm_madd_epi16(*a,*b);
realPart = _mm_srai_epi32(realPart,output_shift);
vect128 imagPart = _mm_shufflelo_epi16(*b,_MM_SHUFFLE(2,3,0,1));
imagPart = _mm_shufflehi_epi16(imagPart,_MM_SHUFFLE(2,3,0,1));
imagPart = _mm_sign_epi16(imagPart,*(vect128 *)minusConjug128);
imagPart = _mm_madd_epi16(imagPart,*a);
imagPart = _mm_srai_epi32(imagPart,output_shift);
vect128 lowPart = _mm_unpacklo_epi32(realPart,imagPart);
vect128 highPart = _mm_unpackhi_epi32(realPart,imagPart);
return ( _mm_packs_epi32(lowPart,highPart));
#elif defined(__arm__)
AssertFatal(false, "not developped\n");
#endif
}
#if defined(__x86_64__) || defined(__i386__)
#define displaySamples128(vect) {\
__m128i x=vect; \
printf("vector: %s = (%hd,%hd) (%hd,%hd) (%hd,%hd) (%hd,%hd)\n", #vect, \
_mm_extract_epi16(x,0), \
_mm_extract_epi16(x,1),\
_mm_extract_epi16(x,2),\
_mm_extract_epi16(x,3),\
_mm_extract_epi16(x,4),\
_mm_extract_epi16(x,5),\
_mm_extract_epi16(x,6),\
_mm_extract_epi16(x,7));\
}
#elif defined(__arm__)
displaySamples128(vect) {}
//TBD
#endif
#endif // SSE_INTRIN_H
......@@ -5,6 +5,8 @@ It replaces a actual RF board driver.
As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
#build
## From build_oai
You can build it the same way, and together with actual RF driver
Example:
......@@ -18,10 +20,19 @@ It is also possible to build actual RF and use choose on each run:
Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem)
We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver.
#usage
## Add the rfsimulator after initial build
After any regular build, you can compile the driver
```bash
cd <the_compilation_dir_from_bouild_oai_script>/build
make rfsimulator
```
Then, you can use it freely
# Usage
Setting the env variable RFSIMULATOR enables the RF board simulator
It should the set to "enb" in the eNB
## 4G case
For the UE, it should be set to the IP address of the eNB
example:
```bash
......@@ -33,6 +44,23 @@ If you reach 'RA not active' on UE, be careful to generate a valid SIM
```bash
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
```
## 5G case
After regular build, add the simulation driver
```bash
cd ran_build/build
make rfsimulator
```
### Launch gNB in one window
```bash
sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
```
### Launch UE in another window
```bash
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
```
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
In UE, you can add "-d" to get the softscope
#Caveacts
Still issues in power control: txgain, rxgain are not used
......
......@@ -997,8 +997,9 @@ void *UE_thread(void *arg) {
UE->rx_offset < 10*UE->frame_parms.samples_per_subframe )
UE->rx_offset_diff = 1;
LOG_D(PHY,"AbsSubframe %d.%d TTI SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,subframe_nr,UE->rx_offset_diff,UE->rx_offset);
LOG_E(PHY,"AbsSubframe %d.%d TTI SET rx_off_diff to %d rx_offset %d \n",proc->frame_rx,subframe_nr,UE->rx_offset_diff,UE->rx_offset);
if ( getenv("RFSIMULATOR") != 0)
UE->rx_offset_diff=0;
readBlockSize=UE->frame_parms.samples_per_subframe -
UE->frame_parms.ofdm_symbol_size -
UE->frame_parms.nb_prefix_samples0 -
......
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