Merge remote-tracking branch 'origin/improve-nr_ul_channel_estimation' into integration_2022_wk35b
This commit is contained in:
@@ -48,6 +48,10 @@
|
|||||||
|
|
||||||
// main log variables
|
// main log variables
|
||||||
|
|
||||||
|
// Fixme: a better place to be shure it is called
|
||||||
|
void read_cpu_hardware (void) __attribute__ ((constructor));
|
||||||
|
void read_cpu_hardware (void) {__builtin_cpu_init(); }
|
||||||
|
|
||||||
log_mem_cnt_t log_mem_d[2];
|
log_mem_cnt_t log_mem_d[2];
|
||||||
int log_mem_flag=0;
|
int log_mem_flag=0;
|
||||||
int log_mem_multi=1;
|
int log_mem_multi=1;
|
||||||
|
|||||||
@@ -366,6 +366,7 @@ typedef struct {
|
|||||||
#define MATLAB_CSHORT_BRACKET3 15
|
#define MATLAB_CSHORT_BRACKET3 15
|
||||||
|
|
||||||
int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec);
|
int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec);
|
||||||
|
#define write_output(a, b, c, d, e, f) write_file_matlab(a, b, c, d, e, f, 0)
|
||||||
|
|
||||||
/*----------------macro definitions for reading log configuration from the config module */
|
/*----------------macro definitions for reading log configuration from the config module */
|
||||||
#define CONFIG_STRING_LOG_PREFIX "log_config"
|
#define CONFIG_STRING_LOG_PREFIX "log_config"
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ notifiedFIFO_t measur_fifo;
|
|||||||
double get_cpu_freq_GHz(void)
|
double get_cpu_freq_GHz(void)
|
||||||
{
|
{
|
||||||
if (cpu_freq_GHz <1 ) {
|
if (cpu_freq_GHz <1 ) {
|
||||||
time_stats_t ts = {0};
|
time_stats_t ts = {0};
|
||||||
reset_meas(&ts);
|
reset_meas(&ts);
|
||||||
ts.trials++;
|
ts.trials++;
|
||||||
ts.in = rdtsc_oai();
|
ts.in = rdtsc_oai();
|
||||||
sleep(1);
|
sleep(1);
|
||||||
ts.diff = (rdtsc_oai()-ts.in);
|
ts.diff = (rdtsc_oai()-ts.in);
|
||||||
cpu_freq_GHz = (double)ts.diff/1000000000;
|
cpu_freq_GHz = (double)ts.diff/1000000000;
|
||||||
printf("CPU Freq is %f \n", cpu_freq_GHz);
|
printf("CPU Freq is %f \n", cpu_freq_GHz);
|
||||||
}
|
}
|
||||||
return cpu_freq_GHz;
|
return cpu_freq_GHz;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,9 +475,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
|
|||||||
srs_vars[srs_id].srs = (int32_t *) malloc16_clear (2 * fp->ofdm_symbol_size * sizeof (int32_t));
|
srs_vars[srs_id].srs = (int32_t *) malloc16_clear (2 * fp->ofdm_symbol_size * sizeof (int32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(PHY,"PRACH allocation\n");
|
|
||||||
// PRACH
|
// PRACH
|
||||||
prach_vars->prachF = (int16_t *) malloc16_clear (1024 * 2 * sizeof (int16_t));
|
|
||||||
// assume maximum of 64 RX antennas for PRACH receiver
|
// assume maximum of 64 RX antennas for PRACH receiver
|
||||||
prach_vars->prach_ifft[0] = (int32_t **) malloc16_clear (64 * sizeof (int32_t *));
|
prach_vars->prach_ifft[0] = (int32_t **) malloc16_clear (64 * sizeof (int32_t *));
|
||||||
|
|
||||||
@@ -485,8 +483,6 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
|
|||||||
prach_vars->prach_ifft[0][i] = (int32_t *) malloc16_clear (1024 * 2 * sizeof (int32_t));
|
prach_vars->prach_ifft[0][i] = (int32_t *) malloc16_clear (1024 * 2 * sizeof (int32_t));
|
||||||
|
|
||||||
prach_vars->rxsigF[0] = (int16_t **) malloc16_clear (64 * sizeof (int16_t *));
|
prach_vars->rxsigF[0] = (int16_t **) malloc16_clear (64 * sizeof (int16_t *));
|
||||||
// PRACH BR
|
|
||||||
prach_vars_br->prachF = (int16_t *)malloc16_clear( 1024*2*sizeof(int32_t) );
|
|
||||||
|
|
||||||
// assume maximum of 64 RX antennas for PRACH receiver
|
// assume maximum of 64 RX antennas for PRACH receiver
|
||||||
for (int ce_level = 0; ce_level < 4; ce_level++) {
|
for (int ce_level = 0; ce_level < 4; ce_level++) {
|
||||||
@@ -576,8 +572,6 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) {
|
|||||||
|
|
||||||
for (UE_id=0; UE_id<NUMBER_OF_SRS_MAX; UE_id++) free_and_zero(srs_vars[UE_id].srs);
|
for (UE_id=0; UE_id<NUMBER_OF_SRS_MAX; UE_id++) free_and_zero(srs_vars[UE_id].srs);
|
||||||
|
|
||||||
free_and_zero(prach_vars->prachF);
|
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]);
|
for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]);
|
||||||
|
|
||||||
free_and_zero(prach_vars->prach_ifft[0]);
|
free_and_zero(prach_vars->prach_ifft[0]);
|
||||||
@@ -589,7 +583,6 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) {
|
|||||||
free_and_zero(prach_vars->rxsigF[ce_level]);
|
free_and_zero(prach_vars->rxsigF[ce_level]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_and_zero(prach_vars_br->prachF);
|
|
||||||
free_and_zero(prach_vars->rxsigF[0]);
|
free_and_zero(prach_vars->rxsigF[0]);
|
||||||
|
|
||||||
for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_ULSCH_MAX; ULSCH_id++) {
|
for (int ULSCH_id=0; ULSCH_id<NUMBER_OF_ULSCH_MAX; ULSCH_id++) {
|
||||||
|
|||||||
@@ -106,9 +106,9 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
#ifdef DEBUG_CH
|
#ifdef DEBUG_CH
|
||||||
|
|
||||||
if (Ns==0)
|
if (Ns==0)
|
||||||
LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,1);
|
LOG_M("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,0);
|
||||||
else
|
else
|
||||||
LOG_M("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,1);
|
LOG_M("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],2*Msc_RS,2,0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -311,7 +311,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
// alpha = (int16_t) (((int32_t) SCALE * (int32_t) (pilot_pos2-k))/(pilot_pos2-pilot_pos1));
|
// alpha = (int16_t) (((int32_t) SCALE * (int32_t) (pilot_pos2-k))/(pilot_pos2-pilot_pos1));
|
||||||
// beta = (int16_t) (((int32_t) SCALE * (int32_t) (k-pilot_pos1))/(pilot_pos2-pilot_pos1));
|
// beta = (int16_t) (((int32_t) SCALE * (int32_t) (k-pilot_pos1))/(pilot_pos2-pilot_pos1));
|
||||||
#ifdef DEBUG_CH
|
#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\n",k);
|
||||||
#endif
|
#endif
|
||||||
//symbol_offset_subframe = frame_parms->N_RB_UL*12*k;
|
//symbol_offset_subframe = frame_parms->N_RB_UL*12*k;
|
||||||
|
|
||||||
@@ -436,9 +436,9 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
#ifdef DEBUG_CH
|
#ifdef DEBUG_CH
|
||||||
|
|
||||||
if (l==pilot_pos1)
|
if (l==pilot_pos1)
|
||||||
write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,1);
|
write_output("drs_seq0.m","drsseq0",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,0);
|
||||||
else
|
else
|
||||||
write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,1);
|
write_output("drs_seq1.m","drsseq1",ul_ref_sigs_rx[u][v][Msc_RS_idx],Msc_RS,1,0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
symbol_offset = frame_parms->N_RB_UL*12*l;
|
symbol_offset = frame_parms->N_RB_UL*12*l;
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
uint32_t subframe_offset=((frame_parms->Ncp==0)?14:12)*frame_parms->ofdm_symbol_size*subframe;
|
uint32_t subframe_offset=((frame_parms->Ncp==0)?14:12)*frame_parms->ofdm_symbol_size*subframe;
|
||||||
|
|
||||||
memset(d,0,24*sizeof(int16_t));
|
memset(d,0,24*sizeof(int16_t));
|
||||||
|
const int nushift=frame_parms->nushift;
|
||||||
|
|
||||||
if (frame_parms->nb_antenna_ports_eNB==1)
|
if (frame_parms->nb_antenna_ports_eNB==1)
|
||||||
gain_lin_QPSK = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2_Q15)>>15);
|
gain_lin_QPSK = (int16_t)(((int32_t)amp*ONE_OVER_SQRT2_Q15)>>15);
|
||||||
else
|
else
|
||||||
@@ -245,7 +246,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y1_16[7] = -y0_16[5];
|
y1_16[7] = -y0_16[5];
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m];
|
y0[j] += y0_16[m];
|
||||||
y1[j] += y1_16[m++];
|
y1[j] += y1_16[m++];
|
||||||
y0[j+1] += y0_16[m];
|
y0[j+1] += y0_16[m];
|
||||||
@@ -287,7 +288,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y1_16[7] = -y0_16[5];
|
y1_16[7] = -y0_16[5];
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m];
|
y0[j] += y0_16[m];
|
||||||
y1[j] += y1_16[m++];
|
y1[j] += y1_16[m++];
|
||||||
y0[j+1] += y0_16[m];
|
y0[j+1] += y0_16[m];
|
||||||
@@ -329,7 +330,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y1_16[7] = -y0_16[5];
|
y1_16[7] = -y0_16[5];
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m];
|
y0[j] += y0_16[m];
|
||||||
y1[j] += y1_16[m++];
|
y1[j] += y1_16[m++];
|
||||||
y0[j+1] += y0_16[m];
|
y0[j+1] += y0_16[m];
|
||||||
@@ -360,7 +361,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y0_16[7] = d[7]*gain_lin_QPSK;
|
y0_16[7] = d[7]*gain_lin_QPSK;
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m++];
|
y0[j] += y0_16[m++];
|
||||||
y0[j+1] += y0_16[m++];
|
y0[j+1] += y0_16[m++];
|
||||||
}
|
}
|
||||||
@@ -385,7 +386,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y0_16[7] = d[15]*gain_lin_QPSK;
|
y0_16[7] = d[15]*gain_lin_QPSK;
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m++];
|
y0[j] += y0_16[m++];
|
||||||
y0[j+1] += y0_16[m++];
|
y0[j+1] += y0_16[m++];
|
||||||
}
|
}
|
||||||
@@ -410,7 +411,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y0_16[7] = d[23]*gain_lin_QPSK;
|
y0_16[7] = d[23]*gain_lin_QPSK;
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m++];
|
y0[j] += y0_16[m++];
|
||||||
y0[j+1] += y0_16[m++];
|
y0[j+1] += y0_16[m++];
|
||||||
}
|
}
|
||||||
@@ -533,7 +534,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y1_16[7] = -y0_16[5];
|
y1_16[7] = -y0_16[5];
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m];
|
y0[j] += y0_16[m];
|
||||||
y1[j] += y1_16[m++];
|
y1[j] += y1_16[m++];
|
||||||
y0[j+1] += y0_16[m];
|
y0[j+1] += y0_16[m];
|
||||||
@@ -644,7 +645,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
|
|||||||
y0_16[7] = d[7]*gain_lin_QPSK;
|
y0_16[7] = d[7]*gain_lin_QPSK;
|
||||||
|
|
||||||
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
for (i=0,j=0,m=0; i<6; i++,j+=2) {
|
||||||
if ((i!=(frame_parms->nushift))&&(i!=(frame_parms->nushift+3))) {
|
if ((i!=(nushift))&&(i!=((nushift+3)%6))) {
|
||||||
y0[j] += y0_16[m++];
|
y0[j] += y0_16[m++];
|
||||||
y0[j+1] += y0_16[m++];
|
y0[j+1] += y0_16[m++];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
uint8_t Ncs_config;
|
uint8_t Ncs_config;
|
||||||
uint8_t restricted_set;
|
uint8_t restricted_set;
|
||||||
uint8_t n_ra_prb;
|
uint8_t n_ra_prb;
|
||||||
int16_t *prachF=NULL;
|
|
||||||
int16_t **rxsigF=NULL;
|
int16_t **rxsigF=NULL;
|
||||||
int16_t *prach2;
|
|
||||||
uint8_t preamble_index;
|
uint8_t preamble_index;
|
||||||
uint16_t NCS,NCS2;
|
uint16_t NCS,NCS2;
|
||||||
uint16_t preamble_offset=0,preamble_offset_old;
|
uint16_t preamble_offset=0,preamble_offset_old;
|
||||||
@@ -77,12 +75,10 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
uint8_t not_found;
|
uint8_t not_found;
|
||||||
int k=0;
|
int k=0;
|
||||||
uint16_t u;
|
uint16_t u;
|
||||||
int16_t *Xu=0;
|
c16_t *Xu=0;
|
||||||
uint16_t offset;
|
|
||||||
int16_t Ncp;
|
int16_t Ncp;
|
||||||
uint16_t first_nonzero_root_idx=0;
|
uint16_t first_nonzero_root_idx=0;
|
||||||
uint8_t new_dft=0;
|
uint8_t new_dft=0;
|
||||||
uint8_t aa;
|
|
||||||
int32_t lev;
|
int32_t lev;
|
||||||
int16_t levdB;
|
int16_t levdB;
|
||||||
int fft_size=0,log2_ifft_size;
|
int fft_size=0,log2_ifft_size;
|
||||||
@@ -130,14 +126,11 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
tdd_mapindex,Nf);
|
tdd_mapindex,Nf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t *prach[nb_rx];
|
|
||||||
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
|
uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
|
||||||
uint16_t N_ZC = (prach_fmt <4)?839:139;
|
uint16_t N_ZC = (prach_fmt <4)?839:139;
|
||||||
|
|
||||||
if (eNB) {
|
if (eNB) {
|
||||||
if (br_flag == 1) {
|
if (br_flag == 1) {
|
||||||
prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level];
|
prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level];
|
||||||
prachF = eNB->prach_vars_br.prachF;
|
|
||||||
rxsigF = eNB->prach_vars_br.rxsigF[ce_level];
|
rxsigF = eNB->prach_vars_br.rxsigF[ce_level];
|
||||||
|
|
||||||
if (LOG_DEBUGFLAG(PRACH)) {
|
if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
@@ -151,7 +144,6 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prach_ifftp = eNB->prach_vars.prach_ifft[0];
|
prach_ifftp = eNB->prach_vars.prach_ifft[0];
|
||||||
prachF = eNB->prach_vars.prachF;
|
|
||||||
rxsigF = eNB->prach_vars.rxsigF[0];
|
rxsigF = eNB->prach_vars.rxsigF[0];
|
||||||
|
|
||||||
//if (LOG_DEBUGFLAG(PRACH)) {
|
//if (LOG_DEBUGFLAG(PRACH)) {
|
||||||
@@ -179,7 +171,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
AssertFatal(ru!=NULL,"ru is null\n");
|
AssertFatal(ru!=NULL,"ru is null\n");
|
||||||
int8_t dBEn0=0;
|
int8_t dBEn0=0;
|
||||||
for (aa=0; aa<nb_rx; aa++) {
|
int16_t *prach[nb_rx];
|
||||||
|
for (int aa=0; aa<nb_rx; aa++) {
|
||||||
if (ru->if_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node
|
if (ru->if_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node
|
||||||
// DJP - indexing below in subframe zero takes us off the beginning of the array???
|
// DJP - indexing below in subframe zero takes us off the beginning of the array???
|
||||||
prach[aa] = (int16_t *)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset];
|
prach[aa] = (int16_t *)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset];
|
||||||
@@ -291,9 +284,9 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
LOG_D(PHY,"rx_prach: Doing FFT for N_RB_UL %d nb_rx:%d Ncp:%d\n",fp->N_RB_UL, nb_rx, Ncp);
|
LOG_D(PHY,"rx_prach: Doing FFT for N_RB_UL %d nb_rx:%d Ncp:%d\n",fp->N_RB_UL, nb_rx, Ncp);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (aa=0; aa<nb_rx; aa++) {
|
for (int aa=0; aa<nb_rx; aa++) {
|
||||||
AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa);
|
AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa);
|
||||||
prach2 = prach[aa] + (Ncp<<1);
|
int16_t *prach2 = prach[aa] + (Ncp<<1); // <<1 because type int16 but input is c16
|
||||||
|
|
||||||
// do DFT
|
// do DFT
|
||||||
switch (fp->N_RB_UL) {
|
switch (fp->N_RB_UL) {
|
||||||
@@ -562,37 +555,38 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
if (new_dft == 1) {
|
if (new_dft == 1) {
|
||||||
new_dft = 0;
|
new_dft = 0;
|
||||||
|
|
||||||
if (br_flag == 1) {
|
if (br_flag == 1) {
|
||||||
Xu=(int16_t *)eNB->X_u_br[ce_level][preamble_offset-first_nonzero_root_idx];
|
Xu=(c16_t *)eNB->X_u_br[ce_level][preamble_offset-first_nonzero_root_idx];
|
||||||
prach_ifft = prach_ifftp[prach_ifft_cnt++];
|
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));
|
if (eNB->prach_vars_br.repetition_number[ce_level]==1) memset(prach_ifft,0,((N_ZC==839)?2048:256)*sizeof(int32_t));
|
||||||
} else {
|
} else {
|
||||||
Xu=(int16_t *)eNB->X_u[preamble_offset-first_nonzero_root_idx];
|
Xu=(c16_t *)eNB->X_u[preamble_offset-first_nonzero_root_idx];
|
||||||
prach_ifft = prach_ifftp[0];
|
prach_ifft = prach_ifftp[0];
|
||||||
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
|
memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t));
|
||||||
}
|
}
|
||||||
|
c16_t prachF[1024] __attribute__((aligned(32)))={0};
|
||||||
memset(prachF, 0, sizeof(int16_t)*2*1024 );
|
|
||||||
|
if (LOG_DUMPFLAG(PRACH))
|
||||||
if (LOG_DUMPFLAG(PRACH)) {
|
for (int z=0; z<nb_rx; z++)
|
||||||
if (prach[0]!= NULL) LOG_M("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1);
|
if( prach[z] ) {
|
||||||
|
char tmp[128];
|
||||||
LOG_M("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1);
|
sprintf(tmp,"prach_rx%d.m", z);
|
||||||
LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],12288,1,1);
|
LOG_M(tmp,tmp,prach[z],6144+792,1,1);
|
||||||
LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],12288,1,1);
|
sprintf(tmp,"prach_rxF%d.m", z);
|
||||||
}
|
LOG_M(tmp,tmp,rxsigF[z],12288,1,1);
|
||||||
|
}
|
||||||
for (aa=0; aa<nb_rx; aa++) {
|
|
||||||
|
for (int aa=0; aa<nb_rx; aa++) {
|
||||||
// Do componentwise product with Xu* on each antenna
|
// Do componentwise product with Xu* on each antenna
|
||||||
k=0;
|
k=0;
|
||||||
|
|
||||||
for (offset=0; offset<(N_ZC<<1); offset+=2) {
|
for (int offset=0; offset<N_ZC; offset++) {
|
||||||
prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][k] + (int32_t)Xu[offset+1]*rxsigF[aa][k+1])>>15);
|
prachF[offset].r = (int16_t)(((int32_t)Xu[offset].r*rxsigF[aa][k] + (int32_t)Xu[offset].i*rxsigF[aa][k+1])>>15);
|
||||||
prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][k+1] - (int32_t)Xu[offset+1]*rxsigF[aa][k])>>15);
|
prachF[offset].i = (int16_t)(((int32_t)Xu[offset].r*rxsigF[aa][k+1] - (int32_t)Xu[offset].i*rxsigF[aa][k])>>15);
|
||||||
k+=2;
|
k+=2;
|
||||||
|
|
||||||
if (k==(12*2*fp->ofdm_symbol_size))
|
if (k==(12*2*fp->ofdm_symbol_size))
|
||||||
k=0;
|
k=0;
|
||||||
}
|
}
|
||||||
@@ -600,13 +594,13 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
|
// Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139)
|
||||||
if (N_ZC == 839) {
|
if (N_ZC == 839) {
|
||||||
log2_ifft_size = 10;
|
log2_ifft_size = 10;
|
||||||
idft(IDFT_1024,prachF,prach_ifft_tmp,1);
|
idft(IDFT_1024,(int16_t*)prachF,prach_ifft_tmp,1);
|
||||||
|
|
||||||
// compute energy and accumulate over receive antennas and repetitions for BR
|
// compute energy and accumulate over receive antennas and repetitions for BR
|
||||||
for (i=0; i<2048; i++)
|
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)])>>9;
|
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)])>>9;
|
||||||
} else {
|
} else {
|
||||||
idft(IDFT_256,prachF,prach_ifft_tmp,1);
|
idft(IDFT_256,(int16_t*)prachF,prach_ifft_tmp,1);
|
||||||
log2_ifft_size = 8;
|
log2_ifft_size = 8;
|
||||||
|
|
||||||
// compute energy and accumulate over receive antennas and repetitions for BR
|
// compute energy and accumulate over receive antennas and repetitions for BR
|
||||||
@@ -674,14 +668,12 @@ void rx_prach0(PHY_VARS_eNB *eNB,
|
|||||||
|
|
||||||
if (br_flag == 0) {
|
if (br_flag == 0) {
|
||||||
LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1);
|
LOG_M("rxsigF.m","prach_rxF",&rxsigF[0][0],12288,1,1);
|
||||||
LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
|
|
||||||
LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
|
LOG_M("Xu.m","xu",Xu,N_ZC,1,1);
|
||||||
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
|
LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1);
|
||||||
LOG_M("SF2_3.m","sf2_3",&ru->common.rxdata[0][2*fp->samples_per_tti],2*fp->samples_per_tti,1,1);
|
LOG_M("SF2_3.m","sf2_3",&ru->common.rxdata[0][2*fp->samples_per_tti],2*fp->samples_per_tti,1,1);
|
||||||
} else {
|
} else {
|
||||||
LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb);
|
LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb);
|
||||||
LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1);
|
LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1);
|
||||||
LOG_M("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1);
|
|
||||||
LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1);
|
LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1);
|
||||||
LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1);
|
LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
|
|||||||
return max_pos - sync_pos;
|
return max_pos - sync_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
|
||||||
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) {
|
const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) {
|
||||||
int timing_advance = 0;
|
int timing_advance = 0;
|
||||||
int max_val = 0;
|
int max_val = 0;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -183,4 +183,4 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB,
|
|||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -480,45 +480,45 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
nbSymb = dlsch1_harq->nb_symbols;
|
nbSymb = dlsch1_harq->nb_symbols;
|
||||||
pduBitmap = dlsch1_harq->pduBitmap;
|
pduBitmap = dlsch1_harq->pduBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for PTRS bitmap and process it respectively */
|
/* Check for PTRS bitmap and process it respectively */
|
||||||
if((pduBitmap & 0x1) && (type == PDSCH)) {
|
if((pduBitmap & 0x1) && (type == PDSCH)) {
|
||||||
nr_pdsch_ptrs_processing(ue,
|
nr_pdsch_ptrs_processing(ue,
|
||||||
pdsch_vars,
|
pdsch_vars,
|
||||||
frame_parms,
|
frame_parms,
|
||||||
dlsch0_harq,
|
dlsch0_harq,
|
||||||
dlsch1_harq,
|
dlsch1_harq,
|
||||||
gNB_id,
|
gNB_id,
|
||||||
nr_slot_rx,
|
nr_slot_rx,
|
||||||
symbol,
|
symbol,
|
||||||
(nb_rb_pdsch*12),
|
(nb_rb_pdsch*12),
|
||||||
dlsch[0]->rnti,rx_type);
|
dlsch[0]->rnti,rx_type);
|
||||||
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
|
pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* at last symbol in a slot calculate LLR's for whole slot */
|
/* at last symbol in a slot calculate LLR's for whole slot */
|
||||||
if(symbol == (startSymbIdx + nbSymb -1)) {
|
if(symbol == (startSymbIdx + nbSymb -1)) {
|
||||||
for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
|
for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
|
||||||
/* re evaluating the first symbol flag as LLR's are done in symbol loop */
|
/* re evaluating the first symbol flag as LLR's are done in symbol loop */
|
||||||
if(i == startSymbIdx && i < 3) {
|
if(i == startSymbIdx && i < 3) {
|
||||||
first_symbol_flag =1;
|
first_symbol_flag =1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
first_symbol_flag=0;
|
first_symbol_flag=0;
|
||||||
}
|
}
|
||||||
/* Calculate LLR's for each symbol */
|
/* Calculate LLR's for each symbol */
|
||||||
nr_dlsch_llr(pdsch_vars, frame_parms,
|
nr_dlsch_llr(pdsch_vars, frame_parms,
|
||||||
rxdataF_comp_ptr, dl_ch_mag_ptr,
|
rxdataF_comp_ptr, dl_ch_mag_ptr,
|
||||||
dlsch0_harq, dlsch1_harq,
|
dlsch0_harq, dlsch1_harq,
|
||||||
rx_type, harq_pid,
|
rx_type, harq_pid,
|
||||||
gNB_id, gNB_id_i,
|
gNB_id, gNB_id_i,
|
||||||
first_symbol_flag,
|
first_symbol_flag,
|
||||||
i, nb_rb_pdsch,
|
i, nb_rb_pdsch,
|
||||||
codeword_TB0, codeword_TB1,
|
codeword_TB0, codeword_TB1,
|
||||||
pdsch_vars[gNB_id]->dl_valid_re[i-1],
|
pdsch_vars[gNB_id]->dl_valid_re[i-1],
|
||||||
nr_slot_rx, beamforming_mode);
|
nr_slot_rx, beamforming_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
|
int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType;
|
||||||
uint8_t nb_re_dmrs;
|
uint8_t nb_re_dmrs;
|
||||||
uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
|
uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos);
|
||||||
@@ -528,29 +528,29 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
|
|||||||
nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups;
|
||||||
}
|
}
|
||||||
dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
|
dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb,
|
||||||
dlsch[0]->harq_processes[harq_pid]->nb_symbols,
|
dlsch[0]->harq_processes[harq_pid]->nb_symbols,
|
||||||
nb_re_dmrs,
|
nb_re_dmrs,
|
||||||
dmrs_len,
|
dmrs_len,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Qm,
|
dlsch[0]->harq_processes[harq_pid]->Qm,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Nl);
|
dlsch[0]->harq_processes[harq_pid]->Nl);
|
||||||
nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
|
nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Nl,
|
dlsch[0]->harq_processes[harq_pid]->Nl,
|
||||||
dlsch[0]->harq_processes[harq_pid]->Qm,
|
dlsch[0]->harq_processes[harq_pid]->Qm,
|
||||||
dlsch[0]->harq_processes[harq_pid]->G,
|
dlsch[0]->harq_processes[harq_pid]->G,
|
||||||
codeword_TB0,
|
codeword_TB0,
|
||||||
codeword_TB1,
|
codeword_TB1,
|
||||||
pdsch_vars[gNB_id]->layer_llr);
|
pdsch_vars[gNB_id]->layer_llr);
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]);
|
||||||
if (cpumeas(CPUMEAS_GETSTATE))
|
if (cpumeas(CPUMEAS_GETSTATE))
|
||||||
LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %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: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0));
|
||||||
|
|
||||||
// Please keep it: useful for debugging
|
// Please keep it: useful for debugging
|
||||||
#ifdef DEBUG_PDSCH_RX
|
#ifdef DEBUG_PDSCH_RX
|
||||||
char filename[50];
|
char filename[50];
|
||||||
uint8_t aa = 0;
|
uint8_t aa = 0;
|
||||||
|
|
||||||
snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
|
snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
|
||||||
write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
|
write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PHY/types.h"
|
|
||||||
#include "PHY/defs.h"
|
|
||||||
#include "PHY/extern.h"
|
|
||||||
|
|
||||||
|
|
||||||
void bit8_rxdemux(int length,int offset)
|
|
||||||
{
|
|
||||||
|
|
||||||
int i;
|
|
||||||
short *rx1_ptr = (short *)&PHY_vars->rx_vars[1].RX_DMA_BUFFER[offset];
|
|
||||||
short *rx0_ptr = (short *)&PHY_vars->rx_vars[0].RX_DMA_BUFFER[offset];
|
|
||||||
char *rx0_ptr2 = (char *)(&PHY_vars->rx_vars[0].RX_DMA_BUFFER[offset]);
|
|
||||||
// short tmp;
|
|
||||||
short r0,i0,r1,i1;
|
|
||||||
|
|
||||||
// printf("demuxing: %d,%d\n",length,offset);
|
|
||||||
|
|
||||||
// printf("%x %x\n",PHY_vars->chsch_data[0].CHSCH_f_sync[0], PHY_vars->chsch_data[0].CHSCH_f_sync[1]);
|
|
||||||
|
|
||||||
for (i=0; i<length; i++) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
r0= (short)(rx0_ptr2[i<<2]); // Re 0
|
|
||||||
|
|
||||||
i0= (short)(rx0_ptr2[(i<<2)+1]); // Im 0
|
|
||||||
|
|
||||||
r1= (short)(rx0_ptr2[(i<<2)+2]); // Re 1
|
|
||||||
|
|
||||||
i1= (short)(rx0_ptr2[(i<<2)+3]); // Im 1
|
|
||||||
|
|
||||||
rx0_ptr[(i<<1)] = r0;
|
|
||||||
rx0_ptr[(i<<1)+1] =i0;
|
|
||||||
rx1_ptr[i<<1] =r1;
|
|
||||||
rx1_ptr[(i<<1)+1] =i1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf("%x %x\n",PHY_vars->chsch_data[0].CHSCH_f_sync[0], PHY_vars->chsch_data[0].CHSCH_f_sync[1]);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PHY/types.h"
|
|
||||||
#include "PHY/defs.h"
|
|
||||||
#include "PHY/extern.h"
|
|
||||||
|
|
||||||
|
|
||||||
void bit8_txmux(int length,int offset)
|
|
||||||
{
|
|
||||||
|
|
||||||
int i;
|
|
||||||
short *dest,*dest2;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i=0; i<length; i++) {
|
|
||||||
|
|
||||||
dest = (short *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[i+offset];
|
|
||||||
dest2 = (short *)&PHY_vars->tx_vars[1].TX_DMA_BUFFER[i+offset];
|
|
||||||
|
|
||||||
((char *)dest)[0] = (char)(dest[0]>>BIT8_TX_SHIFT);
|
|
||||||
((char *)dest)[1] = (char)(dest[1]>>BIT8_TX_SHIFT);
|
|
||||||
((char *)dest)[2] = (char)(dest2[0]>>BIT8_TX_SHIFT);
|
|
||||||
((char *)dest)[3] = (char)(dest2[1]>>BIT8_TX_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "defs.h"
|
|
||||||
|
|
||||||
static __m128i alpha_128 __attribute__ ((aligned(16)));
|
|
||||||
static __m128i shift __attribute__ ((aligned(16)));
|
|
||||||
|
|
||||||
int add_cpx_vector(short *x,
|
|
||||||
short *alpha,
|
|
||||||
short *y,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
|
|
||||||
alpha_128 = _mm_set1_epi32(*((int*)alpha));
|
|
||||||
|
|
||||||
// we compute 4 cpx multiply for each loop
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
y_128[0] = _mm_adds_epi16(alpha_128, x_128[0]);
|
|
||||||
y_128[1] = _mm_adds_epi16(alpha_128, x_128[1]);
|
|
||||||
y_128[2] = _mm_adds_epi16(alpha_128, x_128[2]);
|
|
||||||
y_128[3] = _mm_adds_epi16(alpha_128, x_128[3]);
|
|
||||||
|
|
||||||
|
|
||||||
x_128+=4;
|
|
||||||
y_128 +=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int add_vector32_scalar(short *x,
|
|
||||||
int alpha,
|
|
||||||
short *y,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
|
|
||||||
alpha_128 = _mm_setr_epi32(alpha,0,alpha,0);
|
|
||||||
|
|
||||||
// we compute 4 cpx multiply for each loop
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
y_128[0] = _mm_add_epi32(alpha_128, x_128[0]);
|
|
||||||
y_128[1] = _mm_add_epi32(alpha_128, x_128[1]);
|
|
||||||
y_128[2] = _mm_add_epi32(alpha_128, x_128[2]);
|
|
||||||
y_128[3] = _mm_add_epi32(alpha_128, x_128[3]);
|
|
||||||
|
|
||||||
|
|
||||||
x_128+=4;
|
|
||||||
y_128 +=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int add_real_vector64_scalar(short *x,
|
|
||||||
long long int a,
|
|
||||||
short *y,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
|
|
||||||
alpha_128 = _mm_set1_epi64((__m64) a);
|
|
||||||
|
|
||||||
// we compute 4 cpx multiply for each loop
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
y_128[0] = _mm_add_epi64(alpha_128, x_128[0]);
|
|
||||||
y_128[1] = _mm_add_epi64(alpha_128, x_128[1]);
|
|
||||||
y_128[2] = _mm_add_epi64(alpha_128, x_128[2]);
|
|
||||||
y_128[3] = _mm_add_epi64(alpha_128, x_128[3]);
|
|
||||||
|
|
||||||
|
|
||||||
x_128+=4;
|
|
||||||
y_128+=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MAIN
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
main ()
|
|
||||||
{
|
|
||||||
|
|
||||||
short input[256] __attribute__((aligned(16)));
|
|
||||||
short output[256] __attribute__((aligned(16)));
|
|
||||||
|
|
||||||
int i;
|
|
||||||
c16_t alpha;
|
|
||||||
|
|
||||||
Zero_Buffer(output,256*2);
|
|
||||||
|
|
||||||
input[0] = 100;
|
|
||||||
input[1] = 200;
|
|
||||||
input[2] = 100;
|
|
||||||
input[3] = 200;
|
|
||||||
input[4] = 1234;
|
|
||||||
input[5] = -1234;
|
|
||||||
input[6] = 1234;
|
|
||||||
input[7] = -1234;
|
|
||||||
input[8] = 100;
|
|
||||||
input[9] = 200;
|
|
||||||
input[10] = 100;
|
|
||||||
input[11] = 200;
|
|
||||||
input[12] = 1000;
|
|
||||||
input[13] = 2000;
|
|
||||||
input[14] = 1000;
|
|
||||||
input[15] = 2000;
|
|
||||||
|
|
||||||
alpha.r = 10;
|
|
||||||
alpha.i = -10;
|
|
||||||
|
|
||||||
add_cpx_vector(input,(short*) &alpha,input,8);
|
|
||||||
|
|
||||||
for (i=0; i<16; i+=2)
|
|
||||||
printf("output[%d] = %d + %d i\n",i,input[i],input[i+1]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //MAIN
|
|
||||||
@@ -23,153 +23,6 @@
|
|||||||
#include "tools_defs.h"
|
#include "tools_defs.h"
|
||||||
|
|
||||||
|
|
||||||
int add_vector16(short *x,
|
|
||||||
short *y,
|
|
||||||
short *z,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
__m128i *z_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
z_128 = (__m128i *)&z[0];
|
|
||||||
|
|
||||||
|
|
||||||
for(i=0; i<(N>>5); i++) {
|
|
||||||
/*
|
|
||||||
printf("i = %d\n",i);
|
|
||||||
print_shorts(x_128[0],"x[0]=");
|
|
||||||
print_shorts(y_128[0],"y[0]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
z_128[0] = _mm_adds_epi16(x_128[0],y_128[0]);
|
|
||||||
/*
|
|
||||||
print_shorts(z_128[0],"z[0]=");
|
|
||||||
|
|
||||||
print_shorts(x_128[1],"x[1]=");
|
|
||||||
print_shorts(y_128[1],"y[1]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
z_128[1] = _mm_adds_epi16(x_128[1],y_128[1]);
|
|
||||||
/*
|
|
||||||
print_shorts(z_128[1],"z[1]=");
|
|
||||||
|
|
||||||
print_shorts(x_128[2],"x[2]=");
|
|
||||||
print_shorts(y_128[2],"y[2]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
z_128[2] = _mm_adds_epi16(x_128[2],y_128[2]);
|
|
||||||
/*
|
|
||||||
print_shorts(z_128[2],"z[2]=");
|
|
||||||
|
|
||||||
print_shorts(x_128[3],"x[3]=");
|
|
||||||
print_shorts(y_128[3],"y[3]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
z_128[3] = _mm_adds_epi16(x_128[3],y_128[3]);
|
|
||||||
/*
|
|
||||||
print_shorts(z_128[3],"z[3]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
x_128 +=4;
|
|
||||||
y_128 +=4;
|
|
||||||
z_128 +=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
print_shorts64(__m64 x,char *s) {
|
|
||||||
|
|
||||||
printf("%s ",s);
|
|
||||||
printf("%d %d %d %d\n",((short *)&x)[0],((short *)&x)[1],((short *)&x)[2],((short *)&x)[3]);
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int add_vector16_64(short *x,
|
|
||||||
short *y,
|
|
||||||
short *z,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m64 *x_64;
|
|
||||||
__m64 *y_64;
|
|
||||||
__m64 *z_64;
|
|
||||||
|
|
||||||
x_64 = (__m64 *)&x[0];
|
|
||||||
y_64 = (__m64 *)&y[0];
|
|
||||||
z_64 = (__m64 *)&z[0];
|
|
||||||
|
|
||||||
|
|
||||||
for(i=0; i<(N>>2); i++) {
|
|
||||||
/*
|
|
||||||
printf("i = %d\n",i);
|
|
||||||
print_shorts64(x_64[i],"x[i]=");
|
|
||||||
print_shorts64(y_64[i],"y[i]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
z_64[i] = _mm_adds_pi16(x_64[i],y_64[i]);
|
|
||||||
/*
|
|
||||||
print_shorts64(z_64[i],"z[i]=");
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int add_cpx_vector32(short *x,
|
|
||||||
short *y,
|
|
||||||
short *z,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
__m128i *z_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
z_128 = (__m128i *)&z[0];
|
|
||||||
|
|
||||||
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
z_128[0] = _mm_add_epi32(x_128[0],y_128[0]);
|
|
||||||
z_128[1] = _mm_add_epi32(x_128[1],y_128[1]);
|
|
||||||
z_128[2] = _mm_add_epi32(x_128[2],y_128[2]);
|
|
||||||
z_128[3] = _mm_add_epi32(x_128[3],y_128[3]);
|
|
||||||
|
|
||||||
|
|
||||||
x_128+=4;
|
|
||||||
y_128 +=4;
|
|
||||||
z_128 +=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t sub_cpx_vector16(int16_t *x,
|
int32_t sub_cpx_vector16(int16_t *x,
|
||||||
int16_t *y,
|
int16_t *y,
|
||||||
int16_t *z,
|
int16_t *z,
|
||||||
@@ -201,73 +54,6 @@ int32_t sub_cpx_vector16(int16_t *x,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int add_real_vector64(short *x,
|
|
||||||
short* y,
|
|
||||||
short *z,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
__m128i *z_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
z_128 = (__m128i *)&z[0];
|
|
||||||
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
z_128[0] = _mm_add_epi64(x_128[0], y_128[0]);
|
|
||||||
z_128[1] = _mm_add_epi64(x_128[1], y_128[1]);
|
|
||||||
z_128[2] = _mm_add_epi64(x_128[2], y_128[2]);
|
|
||||||
z_128[3] = _mm_add_epi64(x_128[3], y_128[3]);
|
|
||||||
|
|
||||||
|
|
||||||
x_128+=4;
|
|
||||||
y_128+=4;
|
|
||||||
z_128+=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sub_real_vector64(short *x,
|
|
||||||
short* y,
|
|
||||||
short *z,
|
|
||||||
unsigned int N)
|
|
||||||
{
|
|
||||||
unsigned int i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
__m128i *z_128;
|
|
||||||
|
|
||||||
x_128 = (__m128i *)&x[0];
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
z_128 = (__m128i *)&z[0];
|
|
||||||
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
z_128[0] = _mm_sub_epi64(x_128[0], y_128[0]);
|
|
||||||
z_128[1] = _mm_sub_epi64(x_128[1], y_128[1]);
|
|
||||||
z_128[2] = _mm_sub_epi64(x_128[2], y_128[2]);
|
|
||||||
z_128[3] = _mm_sub_epi64(x_128[3], y_128[3]);
|
|
||||||
|
|
||||||
|
|
||||||
x_128+=4;
|
|
||||||
y_128+=4;
|
|
||||||
z_128+=4;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MAIN
|
#ifdef MAIN
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -280,7 +66,7 @@ main ()
|
|||||||
int i;
|
int i;
|
||||||
c16_t alpha;
|
c16_t alpha;
|
||||||
|
|
||||||
Zero_Buffer(output,256*2);
|
memset(output,0,256*2);
|
||||||
|
|
||||||
input[0] = 100;
|
input[0] = 100;
|
||||||
input[1] = 200;
|
input[1] = 200;
|
||||||
|
|||||||
+114
-215
@@ -22,28 +22,6 @@
|
|||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
#include "tools_defs.h"
|
#include "tools_defs.h"
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
|
||||||
#define simd_q15_t __m128i
|
|
||||||
#define simdshort_q15_t __m64
|
|
||||||
#define shiftright_int16(a,shift) _mm_srai_epi16(a,shift)
|
|
||||||
#define set1_int16(a) _mm_set1_epi16(a)
|
|
||||||
#define mulhi_int16(a,b) _mm_slli_epi16(_mm_mulhi_epi16(a,b),1)
|
|
||||||
#define mulhi_s1_int16(a,b) _mm_slli_epi16(_mm_mulhi_epi16(a,b),2)
|
|
||||||
#define adds_int16(a,b) _mm_adds_epi16(a,b)
|
|
||||||
#define mullo_int16(a,b) _mm_mullo_epi16(a,b)
|
|
||||||
#elif defined(__arm__)
|
|
||||||
#define simd_q15_t int16x8_t
|
|
||||||
#define simdshort_q15_t int16x4_t
|
|
||||||
#define shiftright_int16(a,shift) vshrq_n_s16(a,shift)
|
|
||||||
#define set1_int16(a) vdupq_n_s16(a)
|
|
||||||
#define mulhi_int16(a,b) vqdmulhq_s16(a,b)
|
|
||||||
#define mulhi_s1_int16(a,b) vshlq_n_s16(vqdmulhq_s16(a,b),1)
|
|
||||||
#define adds_int16(a,b) vqaddq_s16(a,b)
|
|
||||||
#define mullo_int16(a,b) vmulq_s16(a,b)
|
|
||||||
#define _mm_empty()
|
|
||||||
#define _m_empty()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void multadd_complex_vector_real_scalar(int16_t *x,
|
void multadd_complex_vector_real_scalar(int16_t *x,
|
||||||
int16_t alpha,
|
int16_t alpha,
|
||||||
@@ -111,216 +89,137 @@ void multadd_real_vector_complex_scalar(int16_t *x,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
|
|
||||||
int16_t *alpha,
|
|
||||||
int16_t *y)
|
|
||||||
{
|
|
||||||
|
|
||||||
// do 8 multiplications at a time
|
|
||||||
simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x;
|
|
||||||
simd_q15_t y_128;
|
|
||||||
y_128 = _mm_loadu_si128((simd_q15_t*)y);
|
|
||||||
|
|
||||||
alpha_r_128 = set1_int16(alpha[0]);
|
|
||||||
alpha_i_128 = set1_int16(alpha[1]);
|
|
||||||
|
|
||||||
|
|
||||||
yr = mulhi_s1_int16(alpha_r_128,x_128[0]);
|
|
||||||
yi = mulhi_s1_int16(alpha_i_128,x_128[0]);
|
|
||||||
y_128 = _mm_adds_epi16(y_128,_mm_unpacklo_epi16(yr,yi));
|
|
||||||
y_128 = _mm_adds_epi16(y_128,_mm_unpackhi_epi16(yr,yi));
|
|
||||||
|
|
||||||
_mm_storeu_si128((simd_q15_t*)y, y_128);
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
|
|
||||||
}
|
|
||||||
#ifdef __AVX2__
|
|
||||||
void rotate_cpx_vector(c16_t *x,
|
void rotate_cpx_vector(c16_t *x,
|
||||||
c16_t *alpha,
|
c16_t *alpha,
|
||||||
c16_t *y,
|
c16_t *y,
|
||||||
uint32_t N,
|
uint32_t N,
|
||||||
uint16_t output_shift)
|
uint16_t output_shift)
|
||||||
{
|
{
|
||||||
// Multiply elementwise two complex vectors of N elements
|
// multiply a complex vector with a complex value (alpha)
|
||||||
// x - input 1 in the format |Re0 Im0 |,......,|Re(N-1) Im(N-1)|
|
// stores result in y
|
||||||
// We assume x1 with a dynamic of 15 bit maximum
|
// N is the number of complex numbers
|
||||||
//
|
// output_shift reduces the result of the multiplication by this number of bits
|
||||||
// alpha - input 2 in the format |Re0 Im0|
|
//AssertFatal(N%8==0, "To be developped");
|
||||||
// We assume x2 with a dynamic of 15 bit maximum
|
#ifdef __AVX2__
|
||||||
//
|
if ( (intptr_t)x%32 == 0 && !(intptr_t)y%32 == 0 && __builtin_cpu_supports("avx2")) {
|
||||||
// y - output in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)|
|
// output is 32 bytes aligned, but not the input
|
||||||
//
|
|
||||||
// N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
|
const c16_t for_re={alpha->r, -alpha->i};
|
||||||
//
|
__m256i const alpha_for_real = _mm256_set1_epi32(*(uint32_t*)&for_re);
|
||||||
// log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0)
|
const c16_t for_im={alpha->i, alpha->r};
|
||||||
// WARNING: log2_amp>0 can cause overflow!!
|
__m256i const alpha_for_im= _mm256_set1_epi32(*(uint32_t*)&for_im);
|
||||||
|
__m256i const perm_mask =
|
||||||
uint32_t i; // loop counter
|
_mm256_set_epi8(31,30,23,22,29,28,21,20,27,26,19,18,25,24,17,16,
|
||||||
|
15,14,7,6,13,12,5,4,11,10,3,2,9,8,1,0);
|
||||||
|
__m256i* xd= (__m256i*)x;
|
||||||
simd_q15_t *y_128,alpha_128;
|
const __m256i *end=xd+N/8;
|
||||||
int32_t *xd=(int32_t *)x;
|
for( __m256i* yd = (__m256i *)y; xd<end ; yd++, xd++) {
|
||||||
|
const __m256i xre = _mm256_srai_epi32(_mm256_madd_epi16(*xd,alpha_for_real),
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
output_shift);
|
||||||
__m128i shift = _mm_cvtsi32_si128(output_shift);
|
const __m256i xim = _mm256_srai_epi32(_mm256_madd_epi16(*xd,alpha_for_im),
|
||||||
register simd_q15_t m0,m1,m2,m3;
|
output_shift);
|
||||||
|
// a bit faster than unpacklo+unpackhi+packs
|
||||||
((int16_t *)&alpha_128)[0] = alpha->r;
|
const __m256i tmp=_mm256_packs_epi32(xre,xim);
|
||||||
((int16_t *)&alpha_128)[1] = -alpha->i;
|
*yd=_mm256_shuffle_epi8(tmp,perm_mask);
|
||||||
((int16_t *)&alpha_128)[2] = alpha->i;
|
}
|
||||||
((int16_t *)&alpha_128)[3] = alpha->r;
|
c16_t* alpha16=(c16_t*) alpha, *yLast;
|
||||||
((int16_t *)&alpha_128)[4] = alpha->r;
|
yLast=((c16_t*)y)+(N/8)*8;
|
||||||
((int16_t *)&alpha_128)[5] = -alpha->i;
|
for (c16_t* xTail=(c16_t*) end;
|
||||||
((int16_t *)&alpha_128)[6] = alpha->i;
|
xTail<((c16_t*) x)+N;
|
||||||
((int16_t *)&alpha_128)[7] = alpha->r;
|
xTail++, yLast++) {
|
||||||
#elif defined(__arm__)
|
*yLast=c16mulShift(*xTail,*alpha16,output_shift);
|
||||||
int32x4_t shift;
|
}
|
||||||
int32x4_t ab_re0,ab_re1,ab_im0,ab_im1,re32,im32;
|
} else {
|
||||||
int16_t reflip[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
|
||||||
int32x4x2_t xtmp;
|
|
||||||
|
|
||||||
((int16_t *)&alpha_128)[0] = alpha->r;
|
|
||||||
((int16_t *)&alpha_128)[1] = alpha->i;
|
|
||||||
((int16_t *)&alpha_128)[2] = alpha->r;
|
|
||||||
((int16_t *)&alpha_128)[3] = alpha->i;
|
|
||||||
((int16_t *)&alpha_128)[4] = alpha->r;
|
|
||||||
((int16_t *)&alpha_128)[5] = alpha->i;
|
|
||||||
((int16_t *)&alpha_128)[6] = alpha->r;
|
|
||||||
((int16_t *)&alpha_128)[7] = alpha->i;
|
|
||||||
int16x8_t bflip = vrev32q_s16(alpha_128);
|
|
||||||
int16x8_t bconj = vmulq_s16(alpha_128,*(int16x8_t *)reflip);
|
|
||||||
shift = vdupq_n_s32(-output_shift);
|
|
||||||
#endif
|
#endif
|
||||||
y_128 = (simd_q15_t *) y;
|
// Multiply elementwise two complex vectors of N elements
|
||||||
|
// x - input 1 in the format |Re0 Im0 |,......,|Re(N-1) Im(N-1)|
|
||||||
|
// We assume x1 with a dynamic of 15 bit maximum
|
||||||
|
//
|
||||||
|
// alpha - input 2 in the format |Re0 Im0|
|
||||||
|
// We assume x2 with a dynamic of 15 bit maximum
|
||||||
|
//
|
||||||
|
// y - output in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)|
|
||||||
|
//
|
||||||
|
// N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
|
||||||
|
//
|
||||||
|
// log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0)
|
||||||
|
// WARNING: log2_amp>0 can cause overflow!!
|
||||||
|
|
||||||
|
uint32_t i; // loop counter
|
||||||
|
|
||||||
|
|
||||||
for(i=0; i<N>>2; i++) {
|
simd_q15_t *y_128,alpha_128;
|
||||||
|
int32_t *xd=(int32_t *)x;
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(__i386__)
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
m0 = _mm_setr_epi32(xd[0],xd[0],xd[1],xd[1]);
|
__m128i shift = _mm_cvtsi32_si128(output_shift);
|
||||||
m1 = _mm_setr_epi32(xd[2],xd[2],xd[3],xd[3]);
|
register simd_q15_t m0,m1,m2,m3;
|
||||||
m2 = _mm_madd_epi16(m0,alpha_128); //complex multiply. result is 32bit [Re Im Re Im]
|
|
||||||
m3 = _mm_madd_epi16(m1,alpha_128); //complex multiply. result is 32bit [Re Im Re Im]
|
|
||||||
m2 = _mm_sra_epi32(m2,shift); // shift right by shift in order to compensate for the input amplitude
|
|
||||||
m3 = _mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude
|
|
||||||
|
|
||||||
y_128[0] = _mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im]
|
((int16_t *)&alpha_128)[0] = alpha->r;
|
||||||
//print_ints("y_128[0]=", &y_128[0]);
|
((int16_t *)&alpha_128)[1] = -alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[2] = alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[3] = alpha->r;
|
||||||
|
((int16_t *)&alpha_128)[4] = alpha->r;
|
||||||
|
((int16_t *)&alpha_128)[5] = -alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[6] = alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[7] = alpha->r;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int32x4_t shift;
|
||||||
|
int32x4_t ab_re0,ab_re1,ab_im0,ab_im1,re32,im32;
|
||||||
|
int16_t reflip[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
||||||
|
int32x4x2_t xtmp;
|
||||||
|
|
||||||
|
((int16_t *)&alpha_128)[0] = alpha->r;
|
||||||
|
((int16_t *)&alpha_128)[1] = alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[2] = alpha->r;
|
||||||
|
((int16_t *)&alpha_128)[3] = alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[4] = alpha->r;
|
||||||
|
((int16_t *)&alpha_128)[5] = alpha->i;
|
||||||
|
((int16_t *)&alpha_128)[6] = alpha->r;
|
||||||
|
((int16_t *)&alpha_128)[7] = alpha->i;
|
||||||
|
int16x8_t bflip = vrev32q_s16(alpha_128);
|
||||||
|
int16x8_t bconj = vmulq_s16(alpha_128,*(int16x8_t *)reflip);
|
||||||
|
shift = vdupq_n_s32(-output_shift);
|
||||||
|
#endif
|
||||||
|
y_128 = (simd_q15_t *) y;
|
||||||
|
|
||||||
|
|
||||||
|
for(i=0; i<N>>2; i++) {
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
m0 = _mm_setr_epi32(xd[0],xd[0],xd[1],xd[1]);
|
||||||
|
m1 = _mm_setr_epi32(xd[2],xd[2],xd[3],xd[3]);
|
||||||
|
m2 = _mm_madd_epi16(m0,alpha_128); //complex multiply. result is 32bit [Re Im Re Im]
|
||||||
|
m3 = _mm_madd_epi16(m1,alpha_128); //complex multiply. result is 32bit [Re Im Re Im]
|
||||||
|
m2 = _mm_sra_epi32(m2,shift); // shift right by shift in order to compensate for the input amplitude
|
||||||
|
m3 = _mm_sra_epi32(m3,shift); // shift right by shift in order to compensate for the input amplitude
|
||||||
|
|
||||||
|
y_128[0] = _mm_packs_epi32(m2,m3); // pack in 16bit integers with saturation [re im re im re im re im]
|
||||||
|
//print_ints("y_128[0]=", &y_128[0]);
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
|
|
||||||
ab_re0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bconj)[0]);
|
ab_re0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bconj)[0]);
|
||||||
ab_re1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bconj)[1]);
|
ab_re1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bconj)[1]);
|
||||||
ab_im0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bflip)[0]);
|
ab_im0 = vmull_s16(((int16x4_t*)xd)[0],((int16x4_t*)&bflip)[0]);
|
||||||
ab_im1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bflip)[1]);
|
ab_im1 = vmull_s16(((int16x4_t*)xd)[1],((int16x4_t*)&bflip)[1]);
|
||||||
re32 = vshlq_s32(vcombine_s32(vpadd_s32(((int32x2_t*)&ab_re0)[0],((int32x2_t*)&ab_re0)[1]),
|
re32 = vshlq_s32(vcombine_s32(vpadd_s32(((int32x2_t*)&ab_re0)[0],((int32x2_t*)&ab_re0)[1]),
|
||||||
vpadd_s32(((int32x2_t*)&ab_re1)[0],((int32x2_t*)&ab_re1)[1])),
|
vpadd_s32(((int32x2_t*)&ab_re1)[0],((int32x2_t*)&ab_re1)[1])),
|
||||||
shift);
|
shift);
|
||||||
im32 = vshlq_s32(vcombine_s32(vpadd_s32(((int32x2_t*)&ab_im0)[0],((int32x2_t*)&ab_im0)[1]),
|
im32 = vshlq_s32(vcombine_s32(vpadd_s32(((int32x2_t*)&ab_im0)[0],((int32x2_t*)&ab_im0)[1]),
|
||||||
vpadd_s32(((int32x2_t*)&ab_im1)[0],((int32x2_t*)&ab_im1)[1])),
|
vpadd_s32(((int32x2_t*)&ab_im1)[0],((int32x2_t*)&ab_im1)[1])),
|
||||||
shift);
|
shift);
|
||||||
|
|
||||||
xtmp = vzipq_s32(re32,im32);
|
xtmp = vzipq_s32(re32,im32);
|
||||||
|
|
||||||
y_128[0] = vcombine_s16(vmovn_s32(xtmp.val[0]),vmovn_s32(xtmp.val[1]));
|
y_128[0] = vcombine_s16(vmovn_s32(xtmp.val[0]),vmovn_s32(xtmp.val[1]));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xd+=4;
|
xd+=4;
|
||||||
y_128+=1;
|
y_128+=1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
int mult_vector32_scalar(int16_t *x1,
|
|
||||||
int x2,
|
|
||||||
int16_t *y,
|
|
||||||
uint32_t N)
|
|
||||||
|
|
||||||
{
|
|
||||||
// Multiply elementwise two real vectors of N elements
|
|
||||||
// x1 - input 1 in the format |Re(0) xxx Re(1) xxx|,......,|Re(N-2) xxx Re(N-1) xxx|
|
|
||||||
// We assume x1 with a dinamic of 31 bit maximum
|
|
||||||
//
|
|
||||||
// x1 - input 2
|
|
||||||
//
|
|
||||||
// y - output in the format |Re0 (64bit) |,......,|Re(N-1) (64bit)|
|
|
||||||
//
|
|
||||||
// N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
|
|
||||||
//
|
|
||||||
|
|
||||||
uint32_t i; // loop counter
|
|
||||||
|
|
||||||
__m128i *x1_128;
|
|
||||||
__m128i x2_128;
|
|
||||||
__m128i *y_128;
|
|
||||||
|
|
||||||
|
|
||||||
x1_128 = (__m128i *)&x1[0];
|
|
||||||
x2_128 = _mm_setr_epi32(x2,0,x2,0);
|
|
||||||
y_128 = (__m128i *)&y[0];
|
|
||||||
|
|
||||||
|
|
||||||
// we compute 4 cpx multiply for each loop
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
y_128[0] = _mm_mul_epu32(x1_128[0],x2_128);
|
|
||||||
y_128[1] = _mm_mul_epu32(x1_128[1],x2_128);
|
|
||||||
y_128[2] = _mm_mul_epu32(x1_128[2],x2_128);
|
|
||||||
y_128[3] = _mm_mul_epu32(x1_128[3],x2_128);
|
|
||||||
|
|
||||||
|
|
||||||
x1_128+=4;
|
|
||||||
y_128 +=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int complex_conjugate(int16_t *x1,
|
|
||||||
int16_t *y,
|
|
||||||
uint32_t N)
|
|
||||||
|
|
||||||
{
|
|
||||||
uint32_t i; // loop counter
|
|
||||||
|
|
||||||
simd_q15_t *x1_128;
|
|
||||||
simd_q15_t *y_128;
|
|
||||||
int16_t x2[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
|
|
||||||
simd_q15_t *x2_128 = (simd_q15_t*)&x2[0];
|
|
||||||
x1_128 = (simd_q15_t *)&x1[0];
|
|
||||||
y_128 = (simd_q15_t *)&y[0];
|
|
||||||
|
|
||||||
|
|
||||||
// we compute 4 cpx multiply for each loop
|
|
||||||
for(i=0; i<(N>>3); i++) {
|
|
||||||
y_128[0] = mullo_int16(x1_128[0],*x2_128);
|
|
||||||
y_128[1] = mullo_int16(x1_128[1],*x2_128);
|
|
||||||
y_128[2] = mullo_int16(x1_128[2],*x2_128);
|
|
||||||
y_128[3] = mullo_int16(x1_128[3],*x2_128);
|
|
||||||
|
|
||||||
|
|
||||||
x1_128+=4;
|
|
||||||
y_128 +=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
_m_empty();
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MAIN
|
#ifdef MAIN
|
||||||
#define L 8
|
#define L 8
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PHY/sse_intrin.h"
|
|
||||||
|
|
||||||
void Zero_Buffer(void *buf,unsigned int length)
|
|
||||||
{
|
|
||||||
// zeroes the mmx_t buffer 'buf' starting from buf[0] to buf[length-1] in bytes
|
|
||||||
int i;
|
|
||||||
register __m64 mm0;
|
|
||||||
__m64 *mbuf = (__m64 *)buf;
|
|
||||||
|
|
||||||
// length>>=3; // put length in quadwords
|
|
||||||
mm0 = _m_pxor(mm0,mm0); // clear the register
|
|
||||||
|
|
||||||
for(i=0; i<length>>3; i++) // for each i
|
|
||||||
mbuf[i] = mm0; // put 0 in buf[i]
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mmxcopy(void *dest,void *src,int size)
|
|
||||||
{
|
|
||||||
|
|
||||||
// copy size bytes from src to dest
|
|
||||||
register int i;
|
|
||||||
register __m64 mm0;
|
|
||||||
__m64 *mmsrc = (__m64 *)src, *mmdest= (__m64 *)dest;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i=0; i<size>>3; i++) {
|
|
||||||
mm0 = mmsrc[i];
|
|
||||||
mmdest[i] = mm0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_mm_empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Zero_Buffer_nommx(void *buf,unsigned int length)
|
|
||||||
{
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<length>>2; i++)
|
|
||||||
((int *)buf)[i] = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2575,7 +2575,6 @@ const static int16_t tw64c[96] __attribute__((aligned(32))) = {
|
|||||||
#define simd_q15_t __m128i
|
#define simd_q15_t __m128i
|
||||||
#define simdshort_q15_t __m64
|
#define simdshort_q15_t __m64
|
||||||
#define shiftright_int16(a,shift) _mm_srai_epi16(a,shift)
|
#define shiftright_int16(a,shift) _mm_srai_epi16(a,shift)
|
||||||
#define set1_int16(a) _mm_set1_epi16(a);
|
|
||||||
#define mulhi_int16(a,b) _mm_mulhrs_epi16 (a,b)
|
#define mulhi_int16(a,b) _mm_mulhrs_epi16 (a,b)
|
||||||
#ifdef __AVX2__
|
#ifdef __AVX2__
|
||||||
#define simd256_q15_t __m256i
|
#define simd256_q15_t __m256i
|
||||||
|
|||||||
+206
-87
@@ -29,46 +29,199 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "PHY/sse_intrin.h"
|
#include "PHY/sse_intrin.h"
|
||||||
#include "common/utils/assertions.h"
|
#include "common/utils/assertions.h"
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
#define simd_q15_t __m128i
|
||||||
|
#define simdshort_q15_t __m64
|
||||||
|
#define shiftright_int16(a,shift) _mm_srai_epi16(a,shift)
|
||||||
|
#define set1_int16(a) _mm_set1_epi16(a)
|
||||||
|
#define mulhi_int16(a,b) _mm_mulhrs_epi16 (a,b)
|
||||||
|
#define mulhi_s1_int16(a,b) _mm_slli_epi16(_mm_mulhi_epi16(a,b),2)
|
||||||
|
#define adds_int16(a,b) _mm_adds_epi16(a,b)
|
||||||
|
#define mullo_int16(a,b) _mm_mullo_epi16(a,b)
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#define simd_q15_t int16x8_t
|
||||||
|
#define simdshort_q15_t int16x4_t
|
||||||
|
#define shiftright_int16(a,shift) vshrq_n_s16(a,shift)
|
||||||
|
#define set1_int16(a) vdupq_n_s16(a)
|
||||||
|
#define mulhi_int16(a,b) vqdmulhq_s16(a,b)
|
||||||
|
#define mulhi_s1_int16(a,b) vshlq_n_s16(vqdmulhq_s16(a,b),1)
|
||||||
|
#define adds_int16(a,b) vqaddq_s16(a,b)
|
||||||
|
#define mullo_int16(a,b) vmulq_s16(a,b)
|
||||||
|
#define _mm_empty()
|
||||||
|
#define _m_empty()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||||
|
|
||||||
typedef struct complexd {
|
typedef struct complexd {
|
||||||
double r;
|
double r;
|
||||||
double i;
|
double i;
|
||||||
} cd_t;
|
} cd_t;
|
||||||
|
|
||||||
typedef struct complexf {
|
typedef struct complexf {
|
||||||
float r;
|
float r;
|
||||||
float i;
|
float i;
|
||||||
} cf_t;
|
} cf_t;
|
||||||
|
|
||||||
typedef struct complex16 {
|
typedef struct complex16 {
|
||||||
int16_t r;
|
int16_t r;
|
||||||
int16_t i;
|
int16_t i;
|
||||||
} c16_t;
|
} c16_t;
|
||||||
|
|
||||||
typedef struct complex32 {
|
typedef struct complex32 {
|
||||||
int32_t r;
|
int32_t r;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
} c32_t;
|
} c32_t;
|
||||||
|
|
||||||
|
typedef struct complex64 {
|
||||||
|
int64_t r;
|
||||||
|
int64_t i;
|
||||||
|
} c64_t;
|
||||||
|
|
||||||
|
#define squaredMod(a) ((a).r*(a).r + (a).i*(a).i)
|
||||||
|
#define csum(res, i1, i2) (res).r = (i1).r + (i2).r ; (res).i = (i1).i + (i2).i
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline c16_t c16mulShift(const c16_t a, const c16_t b, const int Shift) {
|
||||||
|
return (c16_t) {
|
||||||
|
.r = (int16_t)((a.r * b.r - a.i * b.i) >> Shift),
|
||||||
|
.i = (int16_t)((a.r * b.i + a.i * b.r) >> Shift)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct complex64 {
|
__attribute__((always_inline)) inline c16_t c16divShift(const c16_t a, const c16_t b, const int Shift) {
|
||||||
int64_t r;
|
return (c16_t) {
|
||||||
int64_t i;
|
.r = (int16_t)((a.r * b.r + a.i * b.i) >> Shift),
|
||||||
} c64_t;
|
.i = (int16_t)((a.r * b.i - a.i * b.r) >> Shift)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline c16_t c16maddShift(const c16_t a, const c16_t b, c16_t c, const int Shift) {
|
||||||
|
return (c16_t) {
|
||||||
|
.r = (int16_t)(((a.r * b.r - a.i * b.i ) >> Shift) + c.r),
|
||||||
|
.i = (int16_t)(((a.r * b.i + a.i * b.r ) >> Shift) + c.i)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#define squaredMod(a) ((a).r*(a).r+(a).i*(a).i)
|
__attribute__((always_inline)) inline c32_t c32x16mulShift(const c16_t a, const c16_t b, const int Shift) {
|
||||||
#define csum(res, i1, i2) (res).r=(i1).r+(i2).r ; (res).i=(i1).i+(i2).i
|
return (c32_t) {
|
||||||
|
.r = (a.r * b.r - a.i * b.i) >> Shift,
|
||||||
|
.i = (a.r * b.i + a.i * b.r) >> Shift
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline c32_t c32x16maddShift(const c16_t a, const c16_t b, const c32_t c, const int Shift) {
|
||||||
|
return (c32_t) {
|
||||||
|
.r = ((a.r * b.r - a.i * b.i) >> Shift) + c.r,
|
||||||
|
.i = ((a.r * b.i + a.i * b.r) >> Shift) + c.i
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline c16_t c16x32div(const c32_t a, const int div) {
|
||||||
|
return (c16_t) {
|
||||||
|
.r = (int16_t)(a.r / div),
|
||||||
|
.i = (int16_t)(a.i / div)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// On N complex numbers
|
||||||
|
// y.r += (x * alpha.r) >> 14
|
||||||
|
// y.i += (x * alpha.i) >> 14
|
||||||
|
// See regular C implementation at the end
|
||||||
|
__attribute__((always_inline)) inline void c16multaddVectRealComplex(const int16_t *x,
|
||||||
|
const c16_t *alpha,
|
||||||
|
c16_t *y,
|
||||||
|
const int N) {
|
||||||
|
#ifdef __AVX2__
|
||||||
|
const int8_t makePairs[32] __attribute__((aligned(32)))={
|
||||||
|
0,1,0+16,1+16,
|
||||||
|
2,3,2+16,3+16,
|
||||||
|
4,5,4+16,5+16,
|
||||||
|
6,7,6+16,7+16,
|
||||||
|
8,9,8+16,9+16,
|
||||||
|
10,11,10+16,11+16,
|
||||||
|
12,13,12+16,13+16,
|
||||||
|
14,15,14+16,15+16};
|
||||||
|
|
||||||
|
__m256i alpha256= _mm256_set1_epi32(*(int32_t *)alpha);
|
||||||
|
__m128i *x128=(__m128i *)x;
|
||||||
|
__m128i *y128=(__m128i *)y;
|
||||||
|
AssertFatal(N%8==0,"Not implemented\n");
|
||||||
|
for (int i=0; i<N/8; i++) {
|
||||||
|
const __m256i xduplicate=_mm256_broadcastsi128_si256(*x128);
|
||||||
|
const __m256i x_duplicate_ordered=_mm256_shuffle_epi8(xduplicate,*(__m256i*)makePairs);
|
||||||
|
const __m256i x_mul_alpha_shift15 =_mm256_mulhrs_epi16(alpha256, x_duplicate_ordered);
|
||||||
|
// Existing multiplication normalization is weird, constant table in alpha need to be doubled
|
||||||
|
const __m256i x_mul_alpha_x2= _mm256_adds_epi16(x_mul_alpha_shift15,x_mul_alpha_shift15);
|
||||||
|
*y128= _mm_adds_epi16(_mm256_extracti128_si256(x_mul_alpha_x2,0),*y128);
|
||||||
|
y128++;
|
||||||
|
*y128= _mm_adds_epi16(_mm256_extracti128_si256(x_mul_alpha_x2,1),*y128);
|
||||||
|
y128++;
|
||||||
|
x128++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__x86_64__) || defined(__i386__) || defined(__arm__)
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
// do 8 multiplications at a time
|
||||||
|
simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x,*y_128=(simd_q15_t*)y;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
// printf("alpha = %d,%d\n",alpha[0],alpha[1]);
|
||||||
|
alpha_r_128 = set1_int16(alpha->r);
|
||||||
|
alpha_i_128 = set1_int16(alpha->i);
|
||||||
|
|
||||||
|
j=0;
|
||||||
|
|
||||||
|
for (i=0; i<N>>3; i++) {
|
||||||
|
|
||||||
|
yr = mulhi_s1_int16(alpha_r_128,x_128[i]);
|
||||||
|
yi = mulhi_s1_int16(alpha_i_128,x_128[i]);
|
||||||
|
#if defined(__x86_64__) || defined(__i386__)
|
||||||
|
y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpacklo_epi16(yr,yi));
|
||||||
|
j++;
|
||||||
|
y_128[j] = _mm_adds_epi16(y_128[j],_mm_unpackhi_epi16(yr,yi));
|
||||||
|
j++;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
int16x8x2_t yint;
|
||||||
|
yint = vzipq_s16(yr,yi);
|
||||||
|
y_128[j] = adds_int16(y_128[j],yint.val[0]);
|
||||||
|
j++;
|
||||||
|
y_128[j] = adds_int16(y_128[j],yint.val[1]);
|
||||||
|
|
||||||
|
j++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
for (int i=0; i<N; i++) {
|
||||||
|
int tmpr=y[i].r+((x[i]*alpha->r)>>14);
|
||||||
|
if (tmpr>INT16_MAX)
|
||||||
|
tmpr=INT16_MAX;
|
||||||
|
if (tmpr<INT16_MIN)
|
||||||
|
tmpr=INT16_MIN;
|
||||||
|
int tmpi=y[i].i+((x[i]*alpha->i)>>14);
|
||||||
|
if (tmpi>INT16_MAX)
|
||||||
|
tmpi=INT16_MAX;
|
||||||
|
if (tmpi<INT16_MIN)
|
||||||
|
tmpi=INT16_MIN;
|
||||||
|
y[i].r=(int16_t)tmpr;
|
||||||
|
y[i].i=(int16_t)tmpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
//cmult_sv.h
|
//cmult_sv.h
|
||||||
|
|
||||||
/*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
|
/*!\fn void multadd_real_vector_complex_scalar(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N)
|
||||||
@@ -85,10 +238,29 @@ void multadd_real_vector_complex_scalar(int16_t *x,
|
|||||||
int16_t *y,
|
int16_t *y,
|
||||||
uint32_t N);
|
uint32_t N);
|
||||||
|
|
||||||
void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
|
__attribute__((always_inline)) inline void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
|
||||||
int16_t *alpha,
|
c16_t *alpha,
|
||||||
int16_t *y);
|
c16_t *y)
|
||||||
|
{
|
||||||
|
|
||||||
|
// do 8 multiplications at a time
|
||||||
|
simd_q15_t alpha_r_128,alpha_i_128,yr,yi,*x_128=(simd_q15_t*)x;
|
||||||
|
simd_q15_t y_128;
|
||||||
|
y_128 = _mm_loadu_si128((simd_q15_t*)y);
|
||||||
|
|
||||||
|
alpha_r_128 = set1_int16(alpha->r);
|
||||||
|
alpha_i_128 = set1_int16(alpha->i);
|
||||||
|
|
||||||
|
|
||||||
|
yr = mulhi_s1_int16(alpha_r_128,x_128[0]);
|
||||||
|
yi = mulhi_s1_int16(alpha_i_128,x_128[0]);
|
||||||
|
y_128 = _mm_adds_epi16(y_128,_mm_unpacklo_epi16(yr,yi));
|
||||||
|
y_128 = _mm_adds_epi16(y_128,_mm_unpackhi_epi16(yr,yi));
|
||||||
|
|
||||||
|
_mm_storeu_si128((simd_q15_t*)y, y_128);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*!\fn void multadd_complex_vector_real_scalar(int16_t *x,int16_t alpha,int16_t *y,uint8_t zero_flag,uint32_t N)
|
/*!\fn void multadd_complex_vector_real_scalar(int16_t *x,int16_t alpha,int16_t *y,uint8_t zero_flag,uint32_t N)
|
||||||
This function performs componentwise multiplication and accumulation of a real scalar and a complex vector.
|
This function performs componentwise multiplication and accumulation of a real scalar and a complex vector.
|
||||||
@param x Vector input (Q1.15) in the format |Re0 Im0|Re1 Im 1| ...
|
@param x Vector input (Q1.15) in the format |Re0 Im0|Re1 Im 1| ...
|
||||||
@@ -114,7 +286,7 @@ void multadd_complex_vector_real_scalar(int16_t *x,
|
|||||||
|
|
||||||
//cmult_vv.c
|
//cmult_vv.c
|
||||||
/*!
|
/*!
|
||||||
Multiply elementwise the complex conjugate of x1 with x2.
|
Multiply elementwise the complex conjugate of x1 with x2.
|
||||||
@param x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
|
@param x1 - input 1 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
|
||||||
We assume x1 with a dinamic of 15 bit maximum
|
We assume x1 with a dinamic of 15 bit maximum
|
||||||
@param x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
|
@param x2 - input 2 in the format |Re0 Im0 Re1 Im1|,......,|Re(N-2) Im(N-2) Re(N-1) Im(N-1)|
|
||||||
@@ -364,8 +536,8 @@ dft_size_idx_t get_dft(int ofdm_symbol_size)
|
|||||||
printf("function get_dft : unsupported ofdm symbol size \n");
|
printf("function get_dft : unsupported ofdm symbol size \n");
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return DFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function;
|
return DFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum idft_size_idx {
|
typedef enum idft_size_idx {
|
||||||
@@ -448,8 +620,8 @@ idft_size_idx_t get_idft(int ofdm_symbol_size)
|
|||||||
printf("function get_idft : unsupported ofdm symbol size \n");
|
printf("function get_idft : unsupported ofdm symbol size \n");
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return IDFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function
|
return IDFT_SIZE_IDXTABLESIZE; // never reached and will trigger assertion in idft function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -491,58 +663,6 @@ int32_t sub_cpx_vector16(int16_t *x,
|
|||||||
int16_t *z,
|
int16_t *z,
|
||||||
uint32_t N);
|
uint32_t N);
|
||||||
|
|
||||||
int32_t add_cpx_vector32(int16_t *x,
|
|
||||||
int16_t *y,
|
|
||||||
int16_t *z,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
int32_t add_real_vector64(int16_t *x,
|
|
||||||
int16_t *y,
|
|
||||||
int16_t *z,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
int32_t sub_real_vector64(int16_t *x,
|
|
||||||
int16_t *y,
|
|
||||||
int16_t *z,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
int32_t add_real_vector64_scalar(int16_t *x,
|
|
||||||
long long int a,
|
|
||||||
int16_t *y,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
/*!\fn int32_t add_vector16(int16_t *x,int16_t *y,int16_t *z,uint32_t N)
|
|
||||||
This function performs componentwise addition of two vectors with Q1.15 components.
|
|
||||||
@param x Vector input (Q1.15)
|
|
||||||
@param y Scalar input (Q1.15)
|
|
||||||
@param z Scalar output (Q1.15)
|
|
||||||
@param N Length of x WARNING: N must be a multiple of 32
|
|
||||||
|
|
||||||
The function implemented is : \f$\mathbf{z} = \mathbf{x} + \mathbf{y}\f$
|
|
||||||
*/
|
|
||||||
int32_t add_vector16(int16_t *x,
|
|
||||||
int16_t *y,
|
|
||||||
int16_t *z,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
int32_t add_vector16_64(int16_t *x,
|
|
||||||
int16_t *y,
|
|
||||||
int16_t *z,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
int32_t complex_conjugate(int16_t *x1,
|
|
||||||
int16_t *y,
|
|
||||||
uint32_t N);
|
|
||||||
|
|
||||||
void bit8_txmux(int32_t length,int32_t offset);
|
|
||||||
|
|
||||||
void bit8_rxdemux(int32_t length,int32_t offset);
|
|
||||||
|
|
||||||
void Zero_Buffer(void *,uint32_t);
|
|
||||||
void Zero_Buffer_nommx(void *buf,uint32_t length);
|
|
||||||
|
|
||||||
void mmxcopy(void *dest,void *src,int size);
|
|
||||||
|
|
||||||
/*!\fn int32_t signal_energy(int *,uint32_t);
|
/*!\fn int32_t signal_energy(int *,uint32_t);
|
||||||
\brief Computes the signal energy per subcarrier
|
\brief Computes the signal energy per subcarrier
|
||||||
*/
|
*/
|
||||||
@@ -631,7 +751,6 @@ int64_t dot_product64(int16_t *x,
|
|||||||
|
|
||||||
double interp(double x, double *xs, double *ys, int count);
|
double interp(double x, double *xs, double *ys, int count);
|
||||||
|
|
||||||
int write_output(const char *fname,const char *vname,void *data,int length,int dec,char format);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,9 +181,6 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/// \brief ?.
|
|
||||||
/// first index: ? [0..1023] (hard coded)
|
|
||||||
int16_t *prachF;
|
|
||||||
/// \brief ?.
|
/// \brief ?.
|
||||||
/// first index: ce_level [0..3]
|
/// first index: ce_level [0..3]
|
||||||
/// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
|
/// second index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx.
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
|
|||||||
|
|
||||||
void prach_procedures(PHY_VARS_eNB *eNB,
|
void prach_procedures(PHY_VARS_eNB *eNB,
|
||||||
int br_flag ) {
|
int br_flag ) {
|
||||||
uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4],avg_preamble_energy[4];
|
uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0},avg_preamble_energy[4]={0};
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
int frame,subframe;
|
int frame,subframe;
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class gtpEndPoints {
|
|||||||
|
|
||||||
~gtpEndPoints() {
|
~gtpEndPoints() {
|
||||||
// automatically close all sockets on quit
|
// automatically close all sockets on quit
|
||||||
for (const auto p : instances)
|
for (const auto &p : instances)
|
||||||
close(p.first);
|
close(p.first);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user