From 631cd33f152bad951f751a2148e126892d0af73a Mon Sep 17 00:00:00 2001 From: sfn Date: Tue, 25 Jan 2022 11:34:57 +0100 Subject: [PATCH] Adjust ZF Rx fixed point shift --- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 66 ++++++++++--------- targets/ARCH/rfsimulator/simulator.c | 8 +-- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 2 +- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 7e95033a26..7fc1e99c31 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -474,7 +474,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0; if (cpumeas(CPUMEAS_GETSTATE)) - LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); /* Store the valid DL RE's */ @@ -2104,7 +2104,7 @@ uint8_t nr_matrix_inverse(int32_t **a44,//Input matrix//conjH_H_elements[0] nb_rb, +1, shift0); - print_shorts("nr_det_",(int16_t*)&ad_bc[0]); + //print_shorts("nr_det_",(int16_t*)&ad_bc[0]); //Compute Inversion of the H^*H matrix /* For 2x2 MIMO matrix, we compute @@ -2135,7 +2135,7 @@ uint8_t nr_matrix_inverse(int32_t **a44,//Input matrix//conjH_H_elements[0] nb_rb, ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1), shift0); - printf("H_h_H(r%d,c%d)=%d+j%d --> inv_H_h_H(%d,%d) = %d+j%d \n",rtx,ctx,((short *)a44[ctx*size+rtx])[0],((short *)a44[ctx*size+rtx])[1],ctx,rtx,((short *)inv_H_h_H[rtx*size+ctx])[0],((short *)inv_H_h_H[rtx*size+ctx])[1]); + //printf("H_h_H(r%d,c%d)=%d+j%d --> inv_H_h_H(%d,%d) = %d+j%d \n",rtx,ctx,((short *)a44[ctx*size+rtx])[0],((short *)a44[ctx*size+rtx])[1],ctx,rtx,((short *)inv_H_h_H[rtx*size+ctx])[0],((short *)inv_H_h_H[rtx*size+ctx])[1]); } } _mm_empty(); @@ -2159,15 +2159,18 @@ uint8_t nr_matrix_inverse(int32_t **a44,//Input matrix//conjH_H_elements[0] determin_cpx = nr_determin_cpx(a44_cpx,// size,//size +1); - if (i<4) printf("nr_det_cpx = %lf+j%lf \n",creal(determin_cpx)/(1<<(size-1)*shift0),cimag(determin_cpx)/(1<<(size-1)*shift0)); - //Round and convert to Q15 - if (creal(determin_cpx)>0)//determin of the symmetric matrix is real part only - ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)/(1<<(size-1)*shift0))+0.5);// - else - ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)/(1<<(size-1)*shift0))-0.5);// - ((short*) ad_bc)[(i<<1)+1] = (short) 0;//Imag=0 + //if (i<4) printf("order %d nr_det_cpx = %lf+j%lf \n",log2_approx(creal(determin_cpx)),creal(determin_cpx)/(1<<((size-1)*shift0)),cimag(determin_cpx)/(1<<((size-1)*shift0))); - //Compute Inversion of the H^*H matrix + //Round and convert to Q15 (Out in the same format as Fixed point). + if (creal(determin_cpx)>0) {//determin of the symmetric matrix is real part only + ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)/(1<<((size-1)*shift0)))+0.5);// + ((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)/(1<<((size-1)*shift0)))+0.5);// + } else { + ((short*) ad_bc)[i<<1] = (short) ((creal(determin_cpx)/(1<<((size-1)*shift0)))-0.5);// + ((short*) ad_bc)[(i<<1)+1] = (short) ((cimag(determin_cpx)/(1<<((size-1)*shift0)))-0.5);// + } + //if (i<4) printf("nr_det_FP= %d+j%d \n",((short*) ad_bc)[i<<1],((short*) ad_bc)[(i<<1)+1]); + //Compute Inversion of the H^*H matrix (normalized output divide by determinant) for (int rtx=0;rtx inv_H_h_H(%d,%d) = %lf+j%lf \n",rtx,ctx,creal(a44_cpx[ctx*size+rtx]),cimag(a44_cpx[ctx*size+rtx]),ctx,rtx,creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<15),cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<15)); + ((rtx&1)==1?-1:1)*((ctx&1)==1?-1:1))/(determin_cpx); + //if (i==0) printf("H_h_H(r%d,c%d)=%lf+j%lf --> inv_H_h_H(%d,%d) = %lf+j%lf \n",rtx,ctx,creal(a44_cpx[ctx*size+rtx]),cimag(a44_cpx[ctx*size+rtx]),ctx,rtx,creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<18),cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<18)); if (creal(inv_H_h_H_cpx[rtx*size+ctx])>0) - ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<15))+0.5);// + ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<18))+0.5);//Convert to Q 18 else - ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<15))-0.5);// + ((short *) inv_H_h_H[rtx*size+ctx])[i<<1] = (short) ((creal(inv_H_h_H_cpx[rtx*size+ctx])*(1<<18))-0.5);// if (cimag(inv_H_h_H_cpx[rtx*size+ctx])>0) - ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<15))+0.5);// + ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<18))+0.5);// else - ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<15))-0.5);// + ((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1] = (short) ((cimag(inv_H_h_H_cpx[rtx*size+ctx])*(1<<18))-0.5);// + + //if (i<4) printf("inv_H_h_H_FP(%d,%d)= %d+j%d \n",ctx,rtx, ((short *) inv_H_h_H[rtx*size+ctx])[i<<1],((short *) inv_H_h_H[rtx*size+ctx])[(i<<1)+1]); } } } @@ -2310,15 +2315,15 @@ uint8_t nr_zero_forcing_rx(int **rxdataF_comp, inv_H_h_H[ctx*n_tx+rtx] = (int32_t *)malloc16_clear( 12*nb_rb_0*sizeof(int32_t) ); } } - int fpshift = 5; - int fp_flag = 0; + int fp_flag = 1;//0: float point calc 1: Fixed point calc + int fpshift = 8; nr_matrix_inverse(conjH_H_elements[0],//Input matrix inv_H_h_H,//Inverse determ_fin,//determin n_tx,//size nb_rb_0, fp_flag,//fixed point flag - fpshift); + fpshift);//the out put is Q15 // multiply Matrix inversion pf H_h_H by the rx signal vector int32_t outtemp[12*nb_rb_0] __attribute__((aligned(32))); @@ -2339,17 +2344,17 @@ uint8_t nr_zero_forcing_rx(int **rxdataF_comp, (int *)&rxdataF_comp[ctx*n_rx][symbol*nb_rb*12], outtemp, nb_rb_0, - fpshift);//9 + fpshift + (fp_flag? 0: 2));//out in 15-fpshift nr_a_sum_b((__m128i *)rxdataF_zforcing[rtx], - (__m128i *)outtemp, - nb_rb_0);//a =a + b + (__m128i *)outtemp, + nb_rb_0);//a =a + b } -//#ifdef DEBUG_DLSCH_DEMOD +#ifdef DEBUG_DLSCH_DEMOD printf("Computing layer_%d \n",rtx);; print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][0]); print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][4]); print_shorts(" Rx signal:=",(int16_t*)&rxdataF_zforcing[rtx][8]); -//#endif +#endif } //Copy zero_forcing out to output array @@ -2387,9 +2392,8 @@ uint8_t nr_zero_forcing_rx(int **rxdataF_comp, for (int rb=0; rb<3*nb_rb_0; rb++) { //for symmetric H_h_H matrix, the determinant is only real values if (fp_flag) { - mmtmpD2 = _mm_sign_epi16(determ_fin_128[0],*(__m128i*)&nr_realpart[0]); - mmtmpD3 = mmtmpD2; - mmtmpD3 = _mm_shufflelo_epi16(mmtmpD3,_MM_SHUFFLE(2,3,0,1)); + mmtmpD2 = _mm_sign_epi16(determ_fin_128[0],*(__m128i*)&nr_realpart[0]);//set imag part to 0 + mmtmpD3 = _mm_shufflelo_epi16(mmtmpD2,_MM_SHUFFLE(2,3,0,1)); mmtmpD3 = _mm_shufflehi_epi16(mmtmpD3,_MM_SHUFFLE(2,3,0,1)); mmtmpD2 = _mm_add_epi16(mmtmpD2,mmtmpD3); @@ -2406,11 +2410,11 @@ uint8_t nr_zero_forcing_rx(int **rxdataF_comp, dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1); } else{ dl_ch_mag128_0[0] = QAM_amp128; - dl_ch_mag128_0[0] = _mm_srai_epi16(dl_ch_mag128_0[0],fpshift); + dl_ch_mag128_0[0] = _mm_srai_epi16(dl_ch_mag128_0[0],fpshift-1); dl_ch_mag128b_0[0] = QAM_amp128b; - dl_ch_mag128b_0[0] = _mm_srai_epi16(dl_ch_mag128b_0[0],fpshift); + dl_ch_mag128b_0[0] = _mm_srai_epi16(dl_ch_mag128b_0[0],fpshift-1); dl_ch_mag128r_0[0] = QAM_amp128r; - dl_ch_mag128r_0[0] = _mm_srai_epi16(dl_ch_mag128r_0[0],fpshift); + dl_ch_mag128r_0[0] = _mm_srai_epi16(dl_ch_mag128r_0[0],fpshift-1); } determ_fin_128 += 1; diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index bff62e522d..24a0348d35 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -736,10 +736,10 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest CirSize ); else { // no channel modeling - double H_awgn_mimo[4][4] ={{1.0, 0.0, 0.0, 0.0},//rx 0 - {0.0, 1.0, 0.0, 0.0}, //rx 1 - {0.0, 0.0, 1.0, 0.0}, //rx 2 - {0.0, 0.0, 0.0, 1.0}};//rx 3 + double H_awgn_mimo[4][4] ={{1.0, 0.2, 0.1, 0.05}, //rx 0 + {0.2, 1.0, 0.2, 0.1}, //rx 1 + {0.1, 0.2, 1.0, 0.2}, //rx 2 + {0.05, 0.1, 0.2, 1.0}};//rx 3 sample_t *out=(sample_t *)samplesVoid[a]; int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index b682f130b1..e5348ab605 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -219,7 +219,7 @@ RUs = ( #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; ## beamforming 2x4 matrix: #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000]; - ## beamforming 4x4 matrix: + #beamforming 4x4 matrix: bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external";