Commit 400900f4 authored by Laurent THOMAS's avatar Laurent THOMAS

set correct type on many variables, fix a lot of dangerous cast, remove global...

set correct type on many variables, fix a lot of dangerous cast, remove global vars that are likely race conditions in QPSK
parent 767f1b43
......@@ -27,7 +27,7 @@
//#define NR_CSIRS_DEBUG
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
int32_t **dataF,
c16_t **dataF,
const int16_t amp,
nr_csi_info_t *nr_csi_info,
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
......@@ -39,8 +39,8 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
uint8_t *N_ports,
uint8_t *j_cdm,
uint8_t *k_overline,
uint8_t *l_overline) {
uint8_t *l_overline)
{
#ifdef NR_CSIRS_DEBUG
LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
LOG_I(NR_PHY, "csi_params->cyclic_prefix = %i\n", csi_params->cyclic_prefix);
......
......@@ -311,7 +311,7 @@ void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
uint8_t get_nr_prach_duration(uint8_t prach_format);
void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
int32_t **dataF,
c16_t **dataF,
const int16_t amp,
nr_csi_info_t *nr_csi_info,
const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
......
......@@ -465,22 +465,22 @@ static void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
simde_m_empty();
}
static void nr_ulsch_channel_compensation(c16_t *rxFext,
c16_t *chFext,
c16_t *ul_ch_maga,
c16_t *ul_ch_magb,
c16_t *ul_ch_magc,
static void nr_ulsch_channel_compensation(int nrOfLayers,
int nb_rx_ant,
int buffer_length,
c16_t rxFext[][buffer_length],
c16_t chFext[][nb_rx_ant][buffer_length],
c16_t ul_ch_maga[][buffer_length],
c16_t ul_ch_magb[][buffer_length],
c16_t ul_ch_magc[][buffer_length],
int32_t **rxComp,
c16_t *rho,
c16_t rho[][nrOfLayers][buffer_length],
NR_DL_FRAME_PARMS *frame_parms,
nfapi_nr_pusch_pdu_t* rel15_ul,
nfapi_nr_pusch_pdu_t *rel15_ul,
uint32_t symbol,
uint32_t buffer_length,
uint32_t output_shift)
{
int mod_order = rel15_ul->qam_mod_order;
int nrOfLayers = rel15_ul->nrOfLayers;
int nb_rx_ant = frame_parms->nb_antennas_rx;
simde__m256i QAM_ampa_256 = simde_mm256_setzero_si256();
simde__m256i QAM_ampb_256 = simde_mm256_setzero_si256();
......@@ -502,32 +502,31 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext,
QAM_ampc_256 = simde_mm256_set1_epi16(QAM256_n3);
}
simde__m256i xmmp0, xmmp1, xmmp2, xmmp3, xmmp4;
simde__m256i complex_shuffle256 = simde_mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2);
simde__m256i conj256 = simde_mm256_set_epi16(1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1);
for (int aatx = 0; aatx < nrOfLayers; aatx++) {
simde__m256i *rxComp_256 = (simde__m256i*) &rxComp[aatx * nb_rx_ant][symbol * buffer_length];
simde__m256i *rxF_ch_maga_256 = (simde__m256i*)&ul_ch_maga[aatx * buffer_length];
simde__m256i *rxF_ch_magb_256 = (simde__m256i*)&ul_ch_magb[aatx * buffer_length];
simde__m256i *rxF_ch_magc_256 = (simde__m256i*)&ul_ch_magc[aatx * buffer_length];
simde__m256i *rxComp_256 = (simde__m256i *)&rxComp[aatx * nb_rx_ant][symbol * buffer_length];
simde__m256i *rxF_ch_maga_256 = (simde__m256i *)ul_ch_maga[aatx];
simde__m256i *rxF_ch_magb_256 = (simde__m256i *)ul_ch_magb[aatx];
simde__m256i *rxF_ch_magc_256 = (simde__m256i *)ul_ch_magc[aatx];
for (int aarx = 0; aarx < nb_rx_ant; aarx++) {
simde__m256i *rxF_256 = (simde__m256i*) &rxFext[aarx * buffer_length];
simde__m256i *chF_256 = (simde__m256i*) &chFext[(aatx * nb_rx_ant + aarx) * buffer_length];
simde__m256i *rxF_256 = (simde__m256i *)rxFext[aarx];
simde__m256i *chF_256 = (simde__m256i *)chFext[aatx][aarx];
for (int i = 0; i < buffer_length >> 3; i++)
{
xmmp0 = simde_mm256_madd_epi16(chF_256[i], rxF_256[i]);
simde__m256i xmmp0 = simde_mm256_madd_epi16(chF_256[i], rxF_256[i]);
// xmmp0 contains real part of 4 consecutive outputs (32-bit) of conj(H_m[i])*R_m[i]
xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256);
simde__m256i xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256);
xmmp1 = simde_mm256_sign_epi16(xmmp1, conj256);
xmmp1 = simde_mm256_madd_epi16(xmmp1, rxF_256[i]);
// xmmp1 contains imag part of 4 consecutive outputs (32-bit) of conj(H_m[i])*R_m[i]
xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift);
xmmp1 = simde_mm256_srai_epi32(xmmp1, output_shift);
xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1);
xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1);
xmmp4 = simde_mm256_packs_epi32(xmmp2, xmmp3);
simde__m256i xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1);
simde__m256i xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1);
simde__m256i xmmp4 = simde_mm256_packs_epi32(xmmp2, xmmp3);
xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF_256[i]); // |h|^2
xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift);
......@@ -549,21 +548,21 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext,
}
if (rho != NULL) {
for (int atx = 0; atx < nrOfLayers; atx++) {
simde__m256i *rho_256 = (simde__m256i * )&rho[(aatx * nrOfLayers + atx) * buffer_length];
simde__m256i *chF_256 = (simde__m256i *)&chFext[(aatx * nb_rx_ant + aarx) * buffer_length];
simde__m256i *chF2_256 = (simde__m256i *)&chFext[ (atx * nb_rx_ant + aarx) * buffer_length];
simde__m256i *rho_256 = (simde__m256i *)rho[aatx][atx];
simde__m256i *chF_256 = (simde__m256i *)chFext[aatx][aarx];
simde__m256i *chF2_256 = (simde__m256i *)chFext[atx][aarx];
for (int i = 0; i < buffer_length >> 3; i++) {
// multiply by conjugated channel
xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF2_256[i]);
simde__m256i xmmp0 = simde_mm256_madd_epi16(chF_256[i], chF2_256[i]);
// xmmp0 contains real part of 4 consecutive outputs (32-bit)
xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256);
simde__m256i xmmp1 = simde_mm256_shuffle_epi8(chF_256[i], complex_shuffle256);
xmmp1 = simde_mm256_sign_epi16(xmmp1, conj256);
xmmp1 = simde_mm256_madd_epi16(xmmp1, chF2_256[i]);
// xmmp0 contains imag part of 4 consecutive outputs (32-bit)
xmmp0 = simde_mm256_srai_epi32(xmmp0, output_shift);
xmmp1 = simde_mm256_srai_epi32(xmmp1, output_shift);
xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1);
xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1);
simde__m256i xmmp2 = simde_mm256_unpacklo_epi32(xmmp0, xmmp1);
simde__m256i xmmp3 = simde_mm256_unpackhi_epi32(xmmp0, xmmp1);
rho_256[i] = simde_mm256_adds_epi16(rho_256[i], simde_mm256_packs_epi32(xmmp2, xmmp3));
}
......@@ -571,17 +570,14 @@ static void nr_ulsch_channel_compensation(c16_t *rxFext,
}
}
}
simde_mm_empty();
simde_m_empty();
}
// Zero Forcing Rx function: nr_det_HhH()
static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a
int32_t *after_mf_01,//b
int32_t *after_mf_10,//c
int32_t *after_mf_11,//d
int32_t *det_fin,//1/ad-bc
static void nr_ulsch_det_HhH(c16_t *after_mf_00, // a
c16_t *after_mf_01, // b
c16_t *after_mf_10, // c
c16_t *after_mf_11, // d
c16_t *det_fin, // 1/ad-bc
unsigned short nb_rb,
unsigned char symbol,
int32_t shift)
......@@ -643,35 +639,28 @@ static void nr_ulsch_det_HhH (int32_t *after_mf_00,//a
*
*
* */
static void nr_ulsch_conjch0_mult_ch1(int *ch0,
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0)
static void nr_ulsch_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0)
{
//This function is used to compute multiplications in H_hermitian * H matrix
short nr_conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
unsigned short rb;
simde__m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
dl_ch0_128 = (simde__m128i *)ch0;
dl_ch1_128 = (simde__m128i *)ch1;
simde__m128i *dl_ch0_128 = (simde__m128i *)ch0;
simde__m128i *dl_ch1_128 = (simde__m128i *)ch1;
ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1;
simde__m128i *ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1;
for (rb=0; rb<3*nb_rb; rb++) {
mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[0], SIMDE_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1, SIMDE_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)&nr_conjugate[0]);
mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,dl_ch1_128[0]);
mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0);
mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0);
mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
ch0conj_ch1_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3);
simde__m128i D0 = simde_mm_madd_epi16(dl_ch0_128[0], dl_ch1_128[0]);
simde__m128i D1 = simde_mm_shufflelo_epi16(dl_ch0_128[0], SIMDE_MM_SHUFFLE(2, 3, 0, 1));
D1 = simde_mm_shufflehi_epi16(D1, SIMDE_MM_SHUFFLE(2, 3, 0, 1));
D1 = simde_mm_sign_epi16(D1, *(simde__m128i *)nr_conjugate);
D1 = simde_mm_madd_epi16(D1, dl_ch1_128[0]);
D0 = simde_mm_srai_epi32(D0, output_shift0);
D1 = simde_mm_srai_epi32(D1, output_shift0);
simde__m128i D2 = simde_mm_unpacklo_epi32(D0, D1);
simde__m128i D3 = simde_mm_unpackhi_epi32(D0, D1);
ch0conj_ch1_128[0] = simde_mm_packs_epi32(D2, D3);
/*printf("\n Computing conjugates \n");
print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]);
......@@ -682,8 +671,6 @@ static void nr_ulsch_conjch0_mult_ch1(int *ch0,
dl_ch1_128+=1;
ch0conj_ch1_128+=1;
}
simde_mm_empty();
simde_m_empty();
}
static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x,
......@@ -742,10 +729,7 @@ static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x,
//print_ints("unpack lo:",&tmp_z0[0]);
tmp_z1 = simde_mm_unpackhi_epi32(xy_re_128,xy_im_128);
//print_ints("unpack hi:",&tmp_z1[0]);
output = simde_mm_packs_epi32(tmp_z0,tmp_z1);
simde_mm_empty();
simde_m_empty();
output = simde_mm_packs_epi32(tmp_z0, tmp_z1);
return(output);
}
......@@ -753,61 +737,55 @@ static simde__m128i nr_ulsch_comp_muli_sum(simde__m128i input_x,
*
*
* */
static void nr_ulsch_construct_HhH_elements(int *conjch00_ch00,
int *conjch01_ch01,
int *conjch11_ch11,
int *conjch10_ch10,//
int *conjch20_ch20,
int *conjch21_ch21,
int *conjch30_ch30,
int *conjch31_ch31,
int *conjch00_ch01,//00_01
int *conjch01_ch00,//01_00
int *conjch10_ch11,//10_11
int *conjch11_ch10,//11_10
int *conjch20_ch21,
int *conjch21_ch20,
int *conjch30_ch31,
int *conjch31_ch30,
int32_t *after_mf_00,
int32_t *after_mf_01,
int32_t *after_mf_10,
int32_t *after_mf_11,
static void nr_ulsch_construct_HhH_elements(c16_t *conjch00_ch00,
c16_t *conjch01_ch01,
c16_t *conjch11_ch11,
c16_t *conjch10_ch10, //
c16_t *conjch20_ch20,
c16_t *conjch21_ch21,
c16_t *conjch30_ch30,
c16_t *conjch31_ch31,
c16_t *conjch00_ch01, // 00_01
c16_t *conjch01_ch00, // 01_00
c16_t *conjch10_ch11, // 10_11
c16_t *conjch11_ch10, // 11_10
c16_t *conjch20_ch21,
c16_t *conjch21_ch20,
c16_t *conjch30_ch31,
c16_t *conjch31_ch30,
c16_t *after_mf_00,
c16_t *after_mf_01,
c16_t *after_mf_10,
c16_t *after_mf_11,
unsigned short nb_rb,
unsigned char symbol)
{
//This function is used to construct the (H_hermitian * H matrix) matrix elements
unsigned short rb;
simde__m128i *conjch00_ch00_128, *conjch01_ch01_128, *conjch11_ch11_128, *conjch10_ch10_128;
simde__m128i *conjch20_ch20_128, *conjch21_ch21_128, *conjch30_ch30_128, *conjch31_ch31_128;
simde__m128i *conjch00_ch01_128, *conjch01_ch00_128, *conjch10_ch11_128, *conjch11_ch10_128;
simde__m128i *conjch20_ch21_128, *conjch21_ch20_128, *conjch30_ch31_128, *conjch31_ch30_128;
simde__m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128;
conjch00_ch00_128 = (simde__m128i *)conjch00_ch00;
conjch01_ch01_128 = (simde__m128i *)conjch01_ch01;
conjch11_ch11_128 = (simde__m128i *)conjch11_ch11;
conjch10_ch10_128 = (simde__m128i *)conjch10_ch10;
conjch20_ch20_128 = (simde__m128i *)conjch20_ch20;
conjch21_ch21_128 = (simde__m128i *)conjch21_ch21;
conjch30_ch30_128 = (simde__m128i *)conjch30_ch30;
conjch31_ch31_128 = (simde__m128i *)conjch31_ch31;
conjch00_ch01_128 = (simde__m128i *)conjch00_ch01;
conjch01_ch00_128 = (simde__m128i *)conjch01_ch00;
conjch10_ch11_128 = (simde__m128i *)conjch10_ch11;
conjch11_ch10_128 = (simde__m128i *)conjch11_ch10;
conjch20_ch21_128 = (simde__m128i *)conjch20_ch21;
conjch21_ch20_128 = (simde__m128i *)conjch21_ch20;
conjch30_ch31_128 = (simde__m128i *)conjch30_ch31;
conjch31_ch30_128 = (simde__m128i *)conjch31_ch30;
after_mf_00_128 = (simde__m128i *)after_mf_00;
after_mf_01_128 = (simde__m128i *)after_mf_01;
after_mf_10_128 = (simde__m128i *)after_mf_10;
after_mf_11_128 = (simde__m128i *)after_mf_11;
simde__m128i *conjch00_ch00_128 = (simde__m128i *)conjch00_ch00;
simde__m128i *conjch01_ch01_128 = (simde__m128i *)conjch01_ch01;
simde__m128i *conjch11_ch11_128 = (simde__m128i *)conjch11_ch11;
simde__m128i *conjch10_ch10_128 = (simde__m128i *)conjch10_ch10;
simde__m128i *conjch20_ch20_128 = (simde__m128i *)conjch20_ch20;
simde__m128i *conjch21_ch21_128 = (simde__m128i *)conjch21_ch21;
simde__m128i *conjch30_ch30_128 = (simde__m128i *)conjch30_ch30;
simde__m128i *conjch31_ch31_128 = (simde__m128i *)conjch31_ch31;
simde__m128i *conjch00_ch01_128 = (simde__m128i *)conjch00_ch01;
simde__m128i *conjch01_ch00_128 = (simde__m128i *)conjch01_ch00;
simde__m128i *conjch10_ch11_128 = (simde__m128i *)conjch10_ch11;
simde__m128i *conjch11_ch10_128 = (simde__m128i *)conjch11_ch10;
simde__m128i *conjch20_ch21_128 = (simde__m128i *)conjch20_ch21;
simde__m128i *conjch21_ch20_128 = (simde__m128i *)conjch21_ch20;
simde__m128i *conjch30_ch31_128 = (simde__m128i *)conjch30_ch31;
simde__m128i *conjch31_ch30_128 = (simde__m128i *)conjch31_ch30;
simde__m128i *after_mf_00_128 = (simde__m128i *)after_mf_00;
simde__m128i *after_mf_01_128 = (simde__m128i *)after_mf_01;
simde__m128i *after_mf_10_128 = (simde__m128i *)after_mf_10;
simde__m128i *after_mf_11_128 = (simde__m128i *)after_mf_11;
for (rb=0; rb<3*nb_rb; rb++) {
......@@ -862,83 +840,52 @@ static void nr_ulsch_construct_HhH_elements(int *conjch00_ch00,
after_mf_10_128 += 1;
after_mf_11_128 += 1;
}
simde_mm_empty();
simde_m_empty();
}
// MMSE Rx function: nr_ulsch_mmse_2layers()
static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
int buffer_length,
int nb_rx_ant,
int **rxdataF_comp,
int **ul_ch_mag,
int **ul_ch_magb,
int **ul_ch_magc,
int **ul_ch_estimates_ext,
c16_t ul_ch_mag[][buffer_length],
c16_t ul_ch_magb[][buffer_length],
c16_t ul_ch_magc[][buffer_length],
c16_t ul_ch_estimates_ext[][nb_rx_ant][buffer_length],
unsigned short nb_rb,
unsigned char n_rx,
unsigned char mod_order,
int shift,
unsigned char symbol,
int length,
uint32_t noise_var,
uint32_t buffer_length)
uint32_t noise_var)
{
int *ch00, *ch01, *ch10, *ch11;
int *ch20, *ch30, *ch21, *ch31;
uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
/* we need at least alignment to 16 bytes, let's put 32 to be sure
* (maybe not necessary but doesn't hurt)
*/
int32_t conjch00_ch01[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch01_ch00[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch10_ch11[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch11_ch10[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch00_ch00[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch01_ch01[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch10_ch10[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch11_ch11[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch20_ch20[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch21_ch21[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch30_ch30[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch31_ch31[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch20_ch21[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch30_ch31[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch21_ch20[12*nb_rb] __attribute__((aligned(32)));
int32_t conjch31_ch30[12*nb_rb] __attribute__((aligned(32)));
int32_t af_mf_00[12*nb_rb] __attribute__((aligned(32)));
int32_t af_mf_01[12*nb_rb] __attribute__((aligned(32)));
int32_t af_mf_10[12*nb_rb] __attribute__((aligned(32)));
int32_t af_mf_11[12*nb_rb] __attribute__((aligned(32)));
int32_t determ_fin[12*nb_rb] __attribute__((aligned(32)));
switch (n_rx) {
case 2://
ch00 = &((int *)ul_ch_estimates_ext)[0 * buffer_length];
ch01 = &((int *)ul_ch_estimates_ext)[2 * buffer_length];
ch10 = &((int *)ul_ch_estimates_ext)[1 * buffer_length];
ch11 = &((int *)ul_ch_estimates_ext)[3 * buffer_length];
ch20 = NULL;
ch21 = NULL;
ch30 = NULL;
ch31 = NULL;
break;
case 4://
ch00 = &((int *)ul_ch_estimates_ext)[0 * buffer_length];
ch01 = &((int *)ul_ch_estimates_ext)[4 * buffer_length];
ch10 = &((int *)ul_ch_estimates_ext)[1 * buffer_length];
ch11 = &((int *)ul_ch_estimates_ext)[5 * buffer_length];
ch20 = &((int *)ul_ch_estimates_ext)[2 * buffer_length];
ch21 = &((int *)ul_ch_estimates_ext)[6 * buffer_length];
ch30 = &((int *)ul_ch_estimates_ext)[3 * buffer_length];
ch31 = &((int *)ul_ch_estimates_ext)[7 * buffer_length];
break;
default:
return -1;
break;
}
c16_t conjch00_ch01[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch01_ch00[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch10_ch11[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch11_ch10[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch00_ch00[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch01_ch01[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch10_ch10[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch11_ch11[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch20_ch20[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch21_ch21[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch30_ch30[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch31_ch31[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch20_ch21[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch30_ch31[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch21_ch20[12 * nb_rb] __attribute__((aligned(32)));
c16_t conjch31_ch30[12 * nb_rb] __attribute__((aligned(32)));
c16_t af_mf_00[12 * nb_rb] __attribute__((aligned(32)));
c16_t af_mf_01[12 * nb_rb] __attribute__((aligned(32)));
c16_t af_mf_10[12 * nb_rb] __attribute__((aligned(32)));
c16_t af_mf_11[12 * nb_rb] __attribute__((aligned(32)));
c16_t determ_fin[12 * nb_rb] __attribute__((aligned(32)));
/* 1- Compute the rx channel matrix after compensation: (1/2^log2_max)x(H_herm x H)
* for n_rx = 2
......@@ -950,106 +897,46 @@ static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
if (n_rx>=2){
// (1/2^log2_maxh)*conj_H_00xH_00: (1/(64*2))conjH_00*H_00*2^15
nr_ulsch_conjch0_mult_ch1(ch00,
ch00,
conjch00_ch00,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[0][0], ul_ch_estimates_ext[0][0], conjch00_ch00, nb_rb_0, shift);
// (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15
nr_ulsch_conjch0_mult_ch1(ch10,
ch10,
conjch10_ch10,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[1][0], ul_ch_estimates_ext[1][0], conjch10_ch10, nb_rb_0, shift);
// conj_H_00xH_01
nr_ulsch_conjch0_mult_ch1(ch00,
ch01,
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[0][0],
ul_ch_estimates_ext[0][1],
conjch00_ch01,
nb_rb_0,
shift); // this shift is equal to the channel level log2_maxh
// conj_H_10xH_11
nr_ulsch_conjch0_mult_ch1(ch10,
ch11,
conjch10_ch11,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[1][0], ul_ch_estimates_ext[1][1], conjch10_ch11, nb_rb_0, shift);
// conj_H_01xH_01
nr_ulsch_conjch0_mult_ch1(ch01,
ch01,
conjch01_ch01,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[0][1], ul_ch_estimates_ext[0][1], conjch01_ch01, nb_rb_0, shift);
// conj_H_11xH_11
nr_ulsch_conjch0_mult_ch1(ch11,
ch11,
conjch11_ch11,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[1][1], ul_ch_estimates_ext[1][1], conjch11_ch11, nb_rb_0, shift);
// conj_H_01xH_00
nr_ulsch_conjch0_mult_ch1(ch01,
ch00,
conjch01_ch00,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[0][1], ul_ch_estimates_ext[0][0], conjch01_ch00, nb_rb_0, shift);
// conj_H_11xH_10
nr_ulsch_conjch0_mult_ch1(ch11,
ch10,
conjch11_ch10,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[1][1], ul_ch_estimates_ext[1][0], conjch11_ch10, nb_rb_0, shift);
}
if (n_rx==4){
// (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2*16))conjH_20*H_20*2^15
nr_ulsch_conjch0_mult_ch1(ch20,
ch20,
conjch20_ch20,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[2][0], ul_ch_estimates_ext[2][0], conjch20_ch20, nb_rb_0, shift);
// (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15
nr_ulsch_conjch0_mult_ch1(ch30,
ch30,
conjch30_ch30,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[3][0], ul_ch_estimates_ext[3][0], conjch30_ch30, nb_rb_0, shift);
// (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
nr_ulsch_conjch0_mult_ch1(ch20,
ch21,
conjch20_ch21,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[2][0], ul_ch_estimates_ext[2][1], conjch20_ch21, nb_rb_0, shift);
nr_ulsch_conjch0_mult_ch1(ch30,
ch31,
conjch30_ch31,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[3][0], ul_ch_estimates_ext[3][1], conjch30_ch31, nb_rb_0, shift);
nr_ulsch_conjch0_mult_ch1(ch21,
ch21,
conjch21_ch21,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[2][1], ul_ch_estimates_ext[2][1], conjch21_ch21, nb_rb_0, shift);
nr_ulsch_conjch0_mult_ch1(ch31,
ch31,
conjch31_ch31,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[3][1], ul_ch_estimates_ext[3][1], conjch31_ch31, nb_rb_0, shift);
// (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15
nr_ulsch_conjch0_mult_ch1(ch21,
ch20,
conjch21_ch20,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[2][1], ul_ch_estimates_ext[2][0], conjch21_ch20, nb_rb_0, shift);
nr_ulsch_conjch0_mult_ch1(ch31,
ch30,
conjch31_ch30,
nb_rb_0,
shift);
nr_ulsch_conjch0_mult_ch1(ul_ch_estimates_ext[3][1], ul_ch_estimates_ext[3][0], conjch31_ch30, nb_rb_0, shift);
nr_ulsch_construct_HhH_elements(conjch00_ch00,
conjch01_ch01,
......@@ -1254,8 +1141,6 @@ static uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
after_mf_c_128 += 1;
after_mf_d_128 += 1;
}
simde_mm_empty();
simde_m_empty();
return(0);
}
......@@ -1280,9 +1165,8 @@ static void inner_rx(PHY_VARS_gNB *gNB,
int buffer_length = (rel15_ul->rb_size * NR_NB_SC_PER_RB + 15) & ~15;
c16_t rxFext[nb_rx_ant][buffer_length] __attribute__((aligned(32)));
c16_t chFext[nb_layer][nb_rx_ant][buffer_length] __attribute__((aligned(32)));
memset(rxFext, 0, sizeof(c16_t) * nb_rx_ant * buffer_length);
memset(chFext, 0, sizeof(c16_t) * nb_layer * nb_rx_ant* buffer_length);
memset(rxFext, 0, sizeof(rxFext));
memset(chFext, 0, sizeof(chFext));
for (int aarx = 0; aarx < nb_rx_ant; aarx++) {
for (int aatx = 0; aatx < nb_layer; aatx++) {
......@@ -1303,24 +1187,26 @@ static void inner_rx(PHY_VARS_gNB *gNB,
c16_t rxF_ch_magb [nb_layer][buffer_length] __attribute__((aligned(32)));
c16_t rxF_ch_magc [nb_layer][buffer_length] __attribute__((aligned(32)));
memset(rho, 0, sizeof(c16_t) * nb_layer * nb_layer* buffer_length);
memset(rxF_ch_maga, 0, sizeof(c16_t) * nb_layer * buffer_length);
memset(rxF_ch_magb, 0, sizeof(c16_t) * nb_layer * buffer_length);
memset(rxF_ch_magc, 0, sizeof(c16_t) * nb_layer * buffer_length);
memset(rho, 0, sizeof(rho));
memset(rxF_ch_maga, 0, sizeof(rxF_ch_maga));
memset(rxF_ch_magb, 0, sizeof(rxF_ch_magb));
memset(rxF_ch_magc, 0, sizeof(rxF_ch_magc));
for (int i = 0; i < nb_layer; i++)
memset(&pusch_vars->rxdataF_comp[i*nb_rx_ant][symbol * buffer_length], 0, sizeof(int32_t) * buffer_length);
memset(&pusch_vars->rxdataF_comp[i * nb_rx_ant][symbol * buffer_length], 0, sizeof(c16_t) * buffer_length);
nr_ulsch_channel_compensation((c16_t*)rxFext,
(c16_t*)chFext,
(c16_t*)rxF_ch_maga,
(c16_t*)rxF_ch_magb,
(c16_t*)rxF_ch_magc,
nr_ulsch_channel_compensation(nb_layer,
nb_rx_ant,
buffer_length,
rxFext,
chFext,
rxF_ch_maga,
rxF_ch_magb,
rxF_ch_magc,
pusch_vars->rxdataF_comp,
(nb_layer == 1) ? NULL : (c16_t*)rho,
(nb_layer == 1) ? NULL : rho,
frame_parms,
rel15_ul,
symbol,
buffer_length,
output_shift);
if (nb_layer == 1 && rel15_ul->transform_precoding == transformPrecoder_enabled && rel15_ul->qam_mod_order <= 6) {
......@@ -1362,27 +1248,28 @@ static void inner_rx(PHY_VARS_gNB *gNB,
}
else {
nr_ulsch_mmse_2layers(frame_parms,
(int32_t **)pusch_vars->rxdataF_comp,
(int **)rxF_ch_maga,
(int **)rxF_ch_magb,
(int **)rxF_ch_magc,
(int **)chFext,
buffer_length,
nb_rx_ant,
pusch_vars->rxdataF_comp,
rxF_ch_maga,
rxF_ch_magb,
rxF_ch_magc,
chFext,
rel15_ul->rb_size,
frame_parms->nb_antennas_rx,
rel15_ul->qam_mod_order,
pusch_vars->log2_maxh,
symbol,
pusch_vars->ul_valid_re_per_slot[symbol],
nvar,
buffer_length);
nvar);
}
}
if (nb_layer != 2 || rel15_ul->qam_mod_order >= 6)
for (int aatx = 0; aatx < nb_layer; aatx++)
nr_ulsch_compute_llr((int32_t*)&pusch_vars->rxdataF_comp[aatx * nb_rx_ant][symbol * buffer_length],
(int32_t*)rxF_ch_maga[aatx],
(int32_t*)rxF_ch_magb[aatx],
(int32_t*)rxF_ch_magc[aatx],
nr_ulsch_compute_llr((int32_t *)&pusch_vars->rxdataF_comp[aatx * nb_rx_ant][symbol * buffer_length],
(int32_t *)rxF_ch_maga[aatx],
(int32_t *)rxF_ch_magb[aatx],
(int32_t *)rxF_ch_magc[aatx],
&llr[aatx][pusch_vars->llr_offset[symbol]],
pusch_vars->ul_valid_re_per_slot[symbol],
symbol,
......@@ -1415,10 +1302,9 @@ static void nr_pusch_symbol_processing(void *arg)
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id];
for (int symbol = rdata->startSymbol; symbol < rdata->startSymbol+rdata->numSymbols; symbol++) {
int dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
if (dmrs_symbol_flag == 1)
{
if (dmrs_symbol_flag == 1) {
if ((rel15_ul->ul_dmrs_symb_pos >> ((symbol + 1) % frame_parms->symbols_per_slot)) & 0x01)
AssertFatal(1==0,"Double DMRS configuration is not yet supported\n");
AssertFatal(1 == 0, "Double DMRS configuration is not yet supported\n");
gNB->pusch_vars[ulsch_id].dmrs_symbol = symbol;
}
......
......@@ -233,14 +233,34 @@ static const short filt16_middle4[16] = {4096, 8192, 8192, 8192, 8192, 8192, 819
static const short filt16_end[16] = {4096, 8192, 8192, 8192, 12288, 16384, 16384, 16384, 0, 0, 0, 0, 0, 0, 0, 0};
// CSI-RS
static const short filt24_start[24] = {12288, 11605, 10923, 10240, 9557, 8875, 8192, 7509, 6827, 6144, 5461, 4779,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const short filt24_end[24] = {4096, 4779, 5461, 6144, 6827, 7509, 8192, 8875, 9557, 10240, 10923, 11605,
16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384};
static const short filt24_middle[24] = {4096, 4779, 5461, 6144, 6827, 7509, 8192, 8875, 9557, 10240, 10923, 11605,
12288, 11605, 10923, 10240, 9557, 8875, 8192, 7509, 6827, 6144, 5461, 4779};
static const c16_t filt24_start[12] =
{{12288, 11605}, {10923, 10240}, {9557, 8875}, {8192, 7509}, {6827, 6144}, {5461, 4779}, {0}, {0}, {0}, {0}, {0}, {0}};
static const c16_t filt24_end[12] = {{4096, 4779},
{5461, 6144},
{6827, 7509},
{8192, 8875},
{9557, 10240},
{10923, 11605},
{16384, 16384},
{16384, 16384},
{16384, 16384},
{16384, 16384},
{16384, 16384},
{16384, 16384}};
static const c16_t filt24_middle[12] = {{4096, 4779},
{5461, 6144},
{6827, 7509},
{8192, 8875},
{9557, 10240},
{10923, 11605},
{12288, 11605},
{10923, 10240},
{9557, 8875},
{8192, 7509},
{6827, 6144},
{5461, 4779}};
// UL
static const short filt16_ul_p0[16] = {4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 0, 0, 0, 0, 0, 0, 0, 0};
......
......@@ -39,23 +39,28 @@ extern openair0_config_t openair0_cfg[];
// #define DEBUG_PDSCH
// #define DEBUG_PDCCH
#define DEBUG_PDCCH_IQ(idx)
// #define DEBUG_PDCCH(idx) printf("pilot %d : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",idx,
// rxF->r,rxF->i,ch.r,ch.i,pil->r,pil->i);
// #define DEBUG_PBCH(a...) printf(a)
#define DEBUG_PBCH(a...)
//#define DEBUG_PRS_CHEST // To enable PRS Matlab dumps
//#define DEBUG_PRS_PRINTS // To enable PRS channel estimation debug logs
#define PRS_PRINTS
// #define PRS_PRINTS printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt,
// 0, snr, rxF->r,rxF->i,ch.r,ch.i,pil->r,pil->i)
#define CH_INTERP 0
#define NO_INTERP 1
/* Generic function to find the peak of channel estimation buffer */
void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val)
static int32_t peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t mean_val)
{
int32_t max_val = 0, max_idx = 0, abs_val = 0;
for(int k = 0; k < buf_len; k++)
{
abs_val = squaredMod(((c16_t*)buffer)[k]);
if(abs_val > max_val)
{
for (int k = 0; k < buf_len; k++) {
abs_val = squaredMod(((c16_t *)buffer)[k]);
if (abs_val > max_val) {
max_val = abs_val;
max_idx = k;
}
......@@ -64,11 +69,11 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t
// Check for detection threshold
LOG_D(PHY, "PRS ToA estimator: max_val %d, mean_val %d, max_idx %d\n", max_val, mean_val, max_idx);
if ((mean_val != 0) && (max_val / mean_val > 10)) {
*peak_val = max_val;
*peak_idx = max_idx;
return max_val;
} else {
*peak_val = 0;
*peak_idx = 0;
return 0;
}
}
......@@ -80,12 +85,12 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
NR_DL_FRAME_PARMS *frame_params,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
uint8_t rxAnt = 0, idx = 0;
prs_config_t *prs_cfg = &ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg;
prs_meas_t **prs_meas = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas;
c16_t ch_tmp_buf[ ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32)));
int32_t chF_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR*ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32)));
int32_t chT_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR*ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32)));
const int symbolSz = ue->frame_parms.ofdm_symbol_size;
c16_t ch_tmp_buf[symbolSz] __attribute__((aligned(32)));
int32_t chF_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR * symbolSz] __attribute__((aligned(32)));
int32_t chT_interpol[frame_params->nb_antennas_rx][NR_PRS_IDFT_OVERSAMP_FACTOR * symbolSz] __attribute__((aligned(32)));
memset(ch_tmp_buf,0,sizeof(ch_tmp_buf));
memset(chF_interpol,0,sizeof(chF_interpol));
memset(chT_interpol,0,sizeof(chF_interpol));
......@@ -93,16 +98,11 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
int slot_prs =
(proc->nr_slot_rx - rep_num * prs_cfg->PRSResourceTimeGap + frame_params->slots_per_frame) % frame_params->slots_per_frame;
int16_t *rxF, *pil, mod_prs[NR_MAX_PRS_LENGTH << 1];
const int16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
int16_t ch[2] = {0}, noiseFig[2] = {0};
int16_t k_prime = 0, k = 0;
int32_t ch_pwr = 0, snr = 0, rsrp = 0, mean_val = 0, prs_toa = 0;
double ch_pwr_dbm = 0.0f;
#ifdef DEBUG_PRS_CHEST
char filename[64] = {0}, varname[64] = {0};
#endif
int16_t *ch_tmp = (int16_t *)ch_tmp_buf;
c16_t *ch_tmp = ch_tmp_buf;
int16_t scale_factor = (1.0f/(float)(prs_cfg->NumPRSSymbols))*(1<<15);
int16_t num_pilots = (12/prs_cfg->CombSize)*prs_cfg->NumRB;
int16_t first_half = frame_params->ofdm_symbol_size - frame_params->first_carrier_offset;
......@@ -111,389 +111,328 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
LOG_D(PHY, "start_offset %d, first_half %d, second_half %d\n", start_offset, first_half, second_half);
int16_t k_prime_table[K_PRIME_TABLE_ROW_SIZE][K_PRIME_TABLE_COL_SIZE] = PRS_K_PRIME_TABLE;
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++)
{
for(int l = prs_cfg->SymbolStart; l < prs_cfg->SymbolStart+prs_cfg->NumPRSSymbols; l++) {
uint32_t *gold_prs = nr_gold_prs(ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg.NPRSID, slot_prs, l);
int symInd = l-prs_cfg->SymbolStart;
if (prs_cfg->CombSize == 2) {
int symInd = l - prs_cfg->SymbolStart;
int k_prime;
switch (prs_cfg->CombSize) {
case 2:
k_prime = k_prime_table[0][symInd];
}
else if (prs_cfg->CombSize == 4){
break;
case 4:
k_prime = k_prime_table[1][symInd];
}
else if (prs_cfg->CombSize == 6){
break;
case 6:
k_prime = k_prime_table[2][symInd];
}
else if (prs_cfg->CombSize == 12){
break;
case 12:
k_prime = k_prime_table[3][symInd];
break;
default:
LOG_E(PHY, "impossible prs_cfg->CombSize %d\n", prs_cfg->CombSize);
return -1;
}
#ifdef DEBUG_PRS_PRINTS
printf("[gNB %d][rsc %d] PRS config l %d k_prime %d:\nprs_cfg->SymbolStart %d\nprs_cfg->NumPRSSymbols %d\nprs_cfg->NumRB %d\nprs_cfg->CombSize %d\n", gNB_id, rsc_id, l, k_prime, prs_cfg->SymbolStart, prs_cfg->NumPRSSymbols, prs_cfg->NumRB, prs_cfg->CombSize);
printf(
"[gNB %d][rsc %d] PRS config l %d k_prime %d:\nprs_cfg->SymbolStart %d\nprs_cfg->NumPRSSymbols %d\nprs_cfg->NumRB "
"%d\nprs_cfg->CombSize %d\n",
gNB_id,
rsc_id,
l,
k_prime,
prs_cfg->SymbolStart,
prs_cfg->NumPRSSymbols,
prs_cfg->NumRB,
prs_cfg->CombSize);
#endif
// Pilots generation and modulation
c16_t mod_prs[NR_MAX_PRS_LENGTH];
AssertFatal(num_pilots > 0, "num_pilots needs to be gt 0 or mod_prs[0] UB");
for (int m = 0; m < num_pilots; m++)
{
idx = (((gold_prs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
mod_prs[m<<1] = nr_qpsk_mod_table[idx<<1];
mod_prs[(m<<1)+1] = nr_qpsk_mod_table[(idx<<1) + 1];
for (int m = 0; m < num_pilots; m++) {
int idx = (((gold_prs[(m << 1) >> 5]) >> ((m << 1) & 0x1f)) & 3);
mod_prs[m].r = nr_qpsk_mod_table[idx << 1];
mod_prs[m].i = nr_qpsk_mod_table[(idx << 1) + 1];
}
for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++)
{
for (int rxAnt = 0; rxAnt < frame_params->nb_antennas_rx; rxAnt++) {
// reset variables
snr = 0;
rsrp = 0;
int snr = 0;
int rsrp = 0;
// calculate RE offset
k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset;
int k = (prs_cfg->REOffset + k_prime) % prs_cfg->CombSize + prs_cfg->RBOffset * 12 + frame_params->first_carrier_offset;
// Channel estimation and interpolation
pil = (int16_t *)&mod_prs[0];
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
if(prs_cfg->CombSize == 2)
{
c16_t *pil = (c16_t *)&mod_prs[0];
c16_t *rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
const c16_t *fl, *fm, *fmm, *fml, *fmr, *fr;
if (prs_cfg->CombSize == 2) {
// Choose the interpolation filters
switch (k_prime) {
case 0:
fl = filt8_l0;
fml = filt8_m0;
fmm = filt8_mm0;
fmr = filt8_mr0;
fm = filt8_m0;
fr = filt8_r0;
fl = (c16_t *)filt8_l0;
fml = (c16_t *)filt8_m0;
fmm = (c16_t *)filt8_mm0;
fmr = (c16_t *)filt8_mr0;
fm = (c16_t *)filt8_m0;
fr = (c16_t *)filt8_r0;
break;
case 1:
fl = filt8_l1;
fmm = filt8_mm1;
fml = filt8_ml1;
fmr = fmm;
fm = filt8_m1;
fr = filt8_r1;
fl = (c16_t *)filt8_l1;
fmm = (c16_t *)filt8_mm1;
fml = (c16_t *)filt8_ml1;
fmr = (c16_t *)fmm;
fm = (c16_t *)filt8_m1;
fr = (c16_t *)filt8_r1;
break;
default:
LOG_I(PHY, "%s: ERROR!! Invalid k_prime=%d for PRS comb_size %d, symbol %d\n",__FUNCTION__, k_prime, prs_cfg->CombSize, l);
return(-1);
LOG_I(PHY,
"%s: ERROR!! Invalid k_prime=%d for PRS comb_size %d, symbol %d\n",
__FUNCTION__,
k_prime,
prs_cfg->CombSize,
l);
return (-1);
break;
}
//Start pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fl,
ch,
ch_tmp,
8);
c16_t ch = c16mulShift(*rxF, *pil, 15);
// Start pilot
multaddRealVectorComplexScalar(fl, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, 0, snr, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
//Middle pilots
for(int pIdx = 1; pIdx < num_pilots-1; pIdx+=2)
{
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
if(pIdx == 1) // 2nd pilot
{
multadd_real_vector_complex_scalar(fml,
ch,
ch_tmp,
8);
}
else
{
multadd_real_vector_complex_scalar(fm,
ch,
ch_tmp,
8);
}
rsrp += squaredMod(*rxF);
c16_t noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
// Middle pilots
for (int pIdx = 1; pIdx < num_pilots - 1; pIdx += 2) {
c16_t ch = c16mulShift(*rxF, *pil, 15);
const c16_t *tmp = pIdx == 1 /*2nd pilot*/ ? fml : fm;
multaddRealVectorComplexScalar(tmp, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*(c16_t*)rxF) - squaredMod(*(c16_t*)noiseFig)) - 10*log10(squaredMod(*(c16_t*)noiseFig));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, pIdx, snr/(pIdx+1), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
if(pIdx == (num_pilots-3)) // 2nd last pilot
{
multadd_real_vector_complex_scalar(fmr,
ch,
ch_tmp,
8);
}
else
{
multadd_real_vector_complex_scalar(fmm,
ch,
ch_tmp,
8);
}
rsrp += squaredMod(*rxF);
c16_t noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
ch = c16mulShift(*rxF, *pil, 15);
const c16_t *tmp2 = pIdx == num_pilots - 3 /*2nd pilot*/ ? fmr : fmm;
multaddRealVectorComplexScalar(tmp2, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, pIdx+1, snr/(pIdx+2), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
ch_tmp +=8;
rsrp += squaredMod(*rxF);
noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
ch_tmp += 4;
}
//End pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fr,
ch,
ch_tmp,
8);
// End pilot
ch = c16mulShift(*rxF, *pil, 15);
multaddRealVectorComplexScalar(fr, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0] * pil[0] - (int32_t)ch[1] * pil[1]) >> 15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1] * pil[0] + (int32_t)ch[0] * pil[1]) >> 15);
snr += 10 * log10(squaredMod(*((c16_t *)rxF)) - squaredMod(*((c16_t *)noiseFig))) - 10 * log10(squaredMod(*((c16_t *)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n",
rxAnt,
num_pilots - 1,
snr / num_pilots,
rxF[0],
rxF[1],
&rxF[0],
ch[0],
ch[1],
pil[0],
pil[1]);
#endif
}
else if(prs_cfg->CombSize == 4)
{
rsrp += squaredMod(*rxF);
noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
} else if (prs_cfg->CombSize == 4) {
// Choose the interpolation filters
switch (k_prime) {
case 0:
fl = (short int *)filt16a_l0;
fml = filt16a_mm0;
fmm = filt16a_mm0;
fmr = (short int *)filt16a_m0;
fm = (short int *)filt16a_m0;
fr = (short int *)filt16a_r0;
fl = filt16a_l0;
fml = (c16_t *)filt16a_mm0;
fmm = (c16_t *)filt16a_mm0;
fmr = filt16a_m0;
fm = filt16a_m0;
fr = filt16a_r0;
break;
case 1:
fl = (short int *)filt16a_l1;
fml = filt16a_ml1;
fmm = filt16a_mm1;
fmr = filt16a_mr1;
fm = (short int *)filt16a_m1;
fr = (short int *)filt16a_r1;
fl = filt16a_l1;
fml = (c16_t *)filt16a_ml1;
fmm = (c16_t *)filt16a_mm1;
fmr = (c16_t *)filt16a_mr1;
fm = filt16a_m1;
fr = filt16a_r1;
break;
case 2:
fl = (short int *)filt16a_l2;
fml = filt16a_ml2;
fmm = filt16a_mm2;
fmr = filt16a_mr2;
fm = (short int *)filt16a_m2;
fr = (short int *)filt16a_r2;
fl = filt16a_l2;
fml = (c16_t *)filt16a_ml2;
fmm = (c16_t *)filt16a_mm2;
fmr = (c16_t *)filt16a_mr2;
fm = filt16a_m2;
fr = filt16a_r2;
break;
case 3:
fl = (short int *)filt16a_l3;
fml = filt16a_ml3;
fmm = filt16a_mm3;
fmr = filt16a_mm3;
fm = (short int *)filt16a_m3;
fr = (short int *)filt16a_r3;
fl = filt16a_l3;
fml = (c16_t *)filt16a_ml3;
fmm = (c16_t *)filt16a_mm3;
fmr = (c16_t *)filt16a_mm3;
fm = filt16a_m3;
fr = filt16a_r3;
break;
default:
LOG_I(PHY, "%s: ERROR!! Invalid k_prime=%d for PRS comb_size %d, symbol %d\n",__FUNCTION__, k_prime, prs_cfg->CombSize, l);
return(-1);
LOG_I(PHY,
"%s: ERROR!! Invalid k_prime=%d for PRS comb_size %d, symbol %d\n",
__FUNCTION__,
k_prime,
prs_cfg->CombSize,
l);
return (-1);
break;
}
//Start pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fl,
ch,
ch_tmp,
16);
// Start pilot
c16_t ch = c16mulShift(*rxF, *pil, 15);
// Start pilot
multaddRealVectorComplexScalar(fl, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, 0, snr, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fml,
ch,
ch_tmp,
16);
rsrp += squaredMod(*rxF);
c16_t noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
ch = c16mulShift(*rxF, *pil, 15);
multaddRealVectorComplexScalar(fml, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, 1, snr/2, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
ch_tmp +=8;
rsrp += squaredMod(*rxF);
noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
ch_tmp += 4;
//Middle pilots
for(int pIdx = 2; pIdx < num_pilots-2; pIdx++)
{
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fmm,
ch,
ch_tmp,
16);
// Middle pilots
for (int pIdx = 2; pIdx < num_pilots - 2; pIdx++) {
c16_t ch = c16mulShift(*rxF, *pil, 15);
multaddRealVectorComplexScalar(fmm, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, pIdx, snr/(pIdx+1), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
ch_tmp +=8;
rsrp += squaredMod(*rxF);
c16_t noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
ch_tmp += 4;
}
//End pilot
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fmr,
ch,
ch_tmp,
16);
// End pilot
ch = c16mulShift(*rxF, *pil, 15);
multaddRealVectorComplexScalar(fmr, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, %+d) \n", rxAnt, num_pilots-2, snr/(num_pilots-1), rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
pil +=2;
k = (k+prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[rxAnt][l*frame_params->ofdm_symbol_size + k];
ch[0] = (int16_t)(((int32_t)rxF[0]*pil[0] + (int32_t)rxF[1]*pil[1])>>15);
ch[1] = (int16_t)(((int32_t)rxF[1]*pil[0] - (int32_t)rxF[0]*pil[1])>>15);
multadd_real_vector_complex_scalar(fr,
ch,
ch_tmp,
16);
rsrp += squaredMod(*rxF);
noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
pil++;
k = (k + prs_cfg->CombSize) % frame_params->ofdm_symbol_size;
rxF = &rxdataF[rxAnt][l * frame_params->ofdm_symbol_size + k];
ch = c16mulShift(*rxF, *pil, 15);
multaddRealVectorComplexScalar(fr, ch, ch_tmp, 8);
// SNR & RSRP estimation
rsrp += squaredMod(*((c16_t *)rxF));
noiseFig[0] = rxF[0] - (int16_t)(((int32_t)ch[0]*pil[0] - (int32_t)ch[1]*pil[1])>>15);
noiseFig[1] = rxF[1] - (int16_t)(((int32_t)ch[1]*pil[0] + (int32_t)ch[0]*pil[1])>>15);
snr += 10*log10(squaredMod(*((c16_t*)rxF)) - squaredMod(*((c16_t*)noiseFig))) - 10*log10(squaredMod(*((c16_t*)noiseFig)));
#ifdef DEBUG_PRS_PRINTS
printf("[Rx %d] pilot %3d, SNR %+2d dB: rxF - > (%+3d, %+3d) addr %p ch -> (%+3d, %+3d), pil -> (%+d, +%d) \n", rxAnt, num_pilots-1, snr/num_pilots, rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
}
else
{
AssertFatal((prs_cfg->CombSize == 2)||(prs_cfg->CombSize == 4), "[%s] DL PRS CombSize other than 2 and 4 are NOT supported currently. Exiting!!!", __FUNCTION__);
rsrp += squaredMod(*rxF);
noiseFig = c16mulShift(ch, *pil, 15);
snr += 10 * log10(squaredMod(*rxF) - squaredMod(noiseFig)) - 10 * log10(squaredMod(noiseFig));
PRS_PRINTS;
} else {
AssertFatal((prs_cfg->CombSize == 2) || (prs_cfg->CombSize == 4),
"[%s] DL PRS CombSize other than 2 and 4 are NOT supported currently. Exiting!!!",
__FUNCTION__);
}
// average out the SNR and RSRP computed
prs_meas[rxAnt]->snr = snr / (float)num_pilots;
prs_meas[rxAnt]->rsrp = rsrp / (float)num_pilots;
//reset channel pointer
ch_tmp = (int16_t*)ch_tmp_buf;
// reset channel pointer
ch_tmp = ch_tmp_buf;
} // for rxAnt
} //for l
} // for l
for (rxAnt=0; rxAnt < frame_params->nb_antennas_rx; rxAnt++)
{
for (int rxAnt = 0; rxAnt < frame_params->nb_antennas_rx; rxAnt++) {
// scale by averaging factor 1/NumPrsSymbols
multadd_complex_vector_real_scalar(ch_tmp,
scale_factor,
ch_tmp,
1,
frame_params->ofdm_symbol_size);
multadd_complex_vector_real_scalar((int16_t *)ch_tmp, scale_factor, (int16_t *)ch_tmp, 1, frame_params->ofdm_symbol_size);
#ifdef DEBUG_PRS_PRINTS
for (int rb = 0; rb < prs_cfg->NumRB; rb++)
{
for (int rb = 0; rb < prs_cfg->NumRB; rb++) {
printf("================================================================\n");
printf("\t\t\t[gNB %d][Rx %d][RB %d]\n", gNB_id, rxAnt, rb);
printf("================================================================\n");
idx = (12*rb)<<1;
printf("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n", ch_tmp[idx], ch_tmp[idx+1], ch_tmp[idx+2], ch_tmp[idx+3], ch_tmp[idx+4], ch_tmp[idx+5], ch_tmp[idx+6], ch_tmp[idx+7], ch_tmp[idx+8], ch_tmp[idx+9], ch_tmp[idx+10], ch_tmp[idx+11]);
printf("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n", ch_tmp[idx+12], ch_tmp[idx+13], ch_tmp[idx+14], ch_tmp[idx+15], ch_tmp[idx+16], ch_tmp[idx+17], ch_tmp[idx+18], ch_tmp[idx+19], ch_tmp[idx+20], ch_tmp[idx+21], ch_tmp[idx+22], ch_tmp[idx+23]);
idx = (12 * rb) << 1;
printf("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
ch_tmp[idx],
ch_tmp[idx + 1],
ch_tmp[idx + 2],
ch_tmp[idx + 3],
ch_tmp[idx + 4],
ch_tmp[idx + 5],
ch_tmp[idx + 6],
ch_tmp[idx + 7],
ch_tmp[idx + 8],
ch_tmp[idx + 9],
ch_tmp[idx + 10],
ch_tmp[idx + 11]);
printf("%4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d %4d\n",
ch_tmp[idx + 12],
ch_tmp[idx + 13],
ch_tmp[idx + 14],
ch_tmp[idx + 15],
ch_tmp[idx + 16],
ch_tmp[idx + 17],
ch_tmp[idx + 18],
ch_tmp[idx + 19],
ch_tmp[idx + 20],
ch_tmp[idx + 21],
ch_tmp[idx + 22],
ch_tmp[idx + 23]);
printf("\n");
}
#endif
// Place PRS channel estimates in FFT shifted format
if(first_half > 0)
memcpy((int16_t *)&chF_interpol[rxAnt][start_offset], &ch_tmp[0], first_half * sizeof(int32_t));
memcpy(&chF_interpol[rxAnt][start_offset], ch_tmp, first_half * sizeof(c16_t));
if(second_half > 0)
memcpy((int16_t *)&chF_interpol[rxAnt][0], &ch_tmp[first_half << 1], second_half * sizeof(int32_t));
memcpy(&chF_interpol[rxAnt][0], &ch_tmp[first_half], second_half * sizeof(c16_t));
// Convert to time domain
freq2time(NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size,
(int16_t *)&chF_interpol[rxAnt][0],
(int16_t *)&chT_interpol[rxAnt][0]);
(int16_t *)chF_interpol[rxAnt],
(int16_t *)chT_interpol[rxAnt]);
// peak estimator
mean_val = squaredMod(((c16_t *)ch_tmp)[(prs_cfg->NumRB * 12) >> 1]);
peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, &ch_pwr, mean_val);
int32_t mean_val = squaredMod(ch_tmp[(prs_cfg->NumRB * 12) >> 1]);
int32_t prs_toa;
int32_t ch_pwr =
peak_estimator(&chT_interpol[rxAnt][0], NR_PRS_IDFT_OVERSAMP_FACTOR * frame_params->ofdm_symbol_size, &prs_toa, mean_val);
// adjusting the rx_gains for channel peak power
ch_pwr_dbm = 10 * log10(ch_pwr) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(frame_params->ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm =
10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
prs_meas[rxAnt]->rsrp_dBm = 10 * log10(prs_meas[rxAnt]->rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB
- ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(symbolSz);
//prs measurements
prs_meas[rxAnt]->gNB_id = gNB_id;
......@@ -567,18 +506,19 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
{
AssertFatal(dmrss >= 0 && dmrss < 3, "symbol %d is illegal for PBCH DM-RS \n", dmrss);
const int symbolSz = fp->ofdm_symbol_size;
unsigned int ssb_offset = fp->first_carrier_offset + ssb_start_subcarrier;
if (ssb_offset >= fp->ofdm_symbol_size)
ssb_offset -= fp->ofdm_symbol_size;
if (ssb_offset >= symbolSz)
ssb_offset -= symbolSz;
int symbol_offset = fp->ofdm_symbol_size * symbol;
int symbol_offset = symbolSz * symbol;
unsigned int k = Nid_cell % 4;
DEBUG_PBCH("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, k=%u symbol %d\n",
proc->gNB_id,
ue->frame_parms.ofdm_symbol_size,
ue->frame_parms.Ncp,
symbolSz,
fp->Ncp,
k,
symbol);
......@@ -592,8 +532,8 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
c16_t *pil = pilot;
const c16_t *rxF = &rxdataF[aarx][symbol_offset + k];
DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", ue->frame_parms.N_RB_DL);
DEBUG_PBCH("k %u, first_carrier %d\n", k, ue->frame_parms.first_carrier_offset);
DEBUG_PBCH("pbch ch est pilot RB_DL %d\n", fp->N_RB_DL);
DEBUG_PBCH("k %u, first_carrier %d\n", k, fp->first_carrier_offset);
// Treat first 2 pilots specially (left edge)
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
......@@ -602,42 +542,42 @@ c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp,
DEBUG_PBCH("pilot 0 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
re_offset = (re_offset + 4) % symbolSz;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 1 : rxF - > (%d,%d) pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
re_offset = (re_offset + 4) % symbolSz;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot 2 : rxF - > (%d,%d), pil -> (%d,%d) \n", rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
re_offset = (re_offset + 4) % symbolSz;
for (int pilot_cnt = 3; pilot_cnt < (3 * 20); pilot_cnt += 3) {
// in 2nd symbol, skip middle REs (48 with DMRS, 144 for SSS, and another 48 with DMRS)
if (dmrss == 1 && pilot_cnt == 12) {
pilot_cnt=48;
re_offset = (re_offset + 144) % fp->ofdm_symbol_size;
re_offset = (re_offset + 144) % symbolSz;
}
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
re_offset = (re_offset + 4) % symbolSz;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 1, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
re_offset = (re_offset + 4) % symbolSz;
computed_val = c32x16maddShift(*pil, rxF[re_offset], computed_val, 15);
DEBUG_PBCH("pilot %u : rxF= (%d,%d) pil= (%d,%d) \n", pilot_cnt + 2, rxF[re_offset].r, rxF[re_offset].i, pil->r, pil->i);
pil++;
re_offset = (re_offset + 4) % fp->ofdm_symbol_size;
re_offset = (re_offset + 4) % symbolSz;
}
}
return computed_val;
......@@ -660,7 +600,6 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
{
int Ns = proc->nr_slot_rx;
c16_t pilot[200] __attribute__((aligned(16)));
//int slot_pbch;
uint8_t nushift = 0, lastsymbol = 0, num_rbs = 0;
const uint32_t *gold_seq = NULL;
......@@ -825,7 +764,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
if (dmrss == lastsymbol) // update time statistics for last PBCH symbol
{
// do ifft of channel estimate
LOG_D(PHY,"Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
LOG_D(PHY, "Channel Impulse Computation Slot %d Symbol %d ch_offset %d\n", Ns, symbol, ch_offset);
freq2time(fp->ofdm_symbol_size, (int16_t *)&dl_ch_estimates[aarx][ch_offset], (int16_t *)&dl_ch_estimates_time[aarx]);
}
}
......@@ -833,6 +772,15 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
return(0);
}
static inline c16_t *incrementK(c16_t *base, int *k, int max)
{
int tmp = *k + 4;
if (tmp >= max)
tmp -= max;
*k = tmp;
return base + *k + 1;
}
void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
unsigned char symbol,
......@@ -844,20 +792,15 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int slot = proc->nr_slot_rx;
unsigned char aarx;
unsigned short k;
unsigned int pilot_cnt;
int16_t ch[2],*pil,*rxF,*dl_ch;
int ch_offset,symbol_offset;
ch_offset = ue->frame_parms.ofdm_symbol_size*symbol;
symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
const int symbolSz = ue->frame_parms.ofdm_symbol_size;
const int ch_offset = symbolSz * symbol;
const int symbol_offset = symbolSz * symbol;
int nb_rb_coreset=0;
int coreset_start_rb=0;
get_coreset_rballoc(coreset->frequency_domain_resource,&nb_rb_coreset,&coreset_start_rb);
if(nb_rb_coreset==0) return;
if (nb_rb_coreset == 0)
return;
#ifdef DEBUG_PDCCH
printf("pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d, coreset_nb_rb %d\n",
......@@ -867,10 +810,10 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12;
#ifdef DEBUG_PDCCH
printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n",
printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, symbol %d\n",
gNB_id,
ch_offset,
ue->frame_parms.ofdm_symbol_size,
symbolSz,
ue->frame_parms.Ncp,
slot,
symbol);
......@@ -887,7 +830,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
if (coreset->CoreSetType == NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG)
dmrs_ref = BWPStart;
// generate pilot
int pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
c16_t pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16)));
// Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS
nr_pdcch_dmrs_rx(ue,
slot,
......@@ -896,14 +839,13 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
2000,
(nb_rb_coreset + dmrs_ref));
for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
k = coreset_start_subcarrier;
pil = (int16_t *)&pilot[dmrs_ref*3];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
dl_ch = (int16_t *)&pdcch_dl_ch_estimates[aarx][ch_offset];
memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size));
for (uint aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
int k = coreset_start_subcarrier;
c16_t *pil = pilot + dmrs_ref * 3;
c16_t *base = rxdataF[aarx] + symbol_offset;
c16_t *rxF = base + k + 1;
c16_t *dl_ch = pdcch_dl_ch_estimates[aarx] + ch_offset;
memset(dl_ch, 0, sizeof(*dl_ch) * symbolSz);
#ifdef DEBUG_PDCCH
printf("pdcch ch est pilot addr %p RB_DL %d\n",&pilot[dmrs_ref*3], ue->frame_parms.N_RB_DL);
......@@ -912,170 +854,76 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
printf("dl_ch addr %p\n",dl_ch);
#endif
#if CH_INTERP
#if CH_INTERP
// if ((ue->frame_parms.N_RB_DL&1)==0) {
// Treat first 2 pilots specially (left edge)
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PDCCH
printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
printf("pilot 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
pil += 2;
rxF += 8;
k += 4;
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PDCCH
printf("pilot 1 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil += 2;
rxF += 8;
k += 4;
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
c16_t ch = c16mulShift(*rxF, *pil, 15);
DEBUG_PDCCH_IQ(0);
multaddRealVectorComplexScalar(fl, ch, dl_ch, 16);
pil++;
rxF = incrementK(base, &k, symbolSz);
#ifdef DEBUG_PDCCH
printf("pilot 2 : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
ch = c16mulShift(*rxF, *pil, 15);
DEBUG_PDCCH_IQ(1);
multaddRealVectorComplexScalar(fm, ch, dl_ch, 16);
pil++;
rxF = incrementK(base, &k, symbolSz);
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
ch = c16mulShift(*rxF, *pil, 15);
DEBUG_PDCCH_IQ(2);
multaddRealVectorComplexScalar(fr, ch, dl_ch, 16);
#ifdef DEBUG_PDCCH
for (int m =0; m<12; m++)
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
#endif
dl_ch += 24;
pil += 2;
rxF += 8;
k += 4;
for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt += 3) {
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PDCCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fl,
ch,
dl_ch,
16);
//for (int i= 0; i<8; i++)
// printf("pilot_cnt %d dl_ch %d %d\n", pilot_cnt, dl_ch+i, *(dl_ch+i));
pil += 2;
rxF += 8;
k += 4;
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
}
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PDCCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
multadd_real_vector_complex_scalar(fm,
ch,
dl_ch,
16);
pil += 2;
rxF += 8;
k += 4;
dl_ch += 12;
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
}
pil++;
rxF = incrementK(base, &k, symbolSz);
ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
for (uint pilot_cnt = 3; pilot_cnt < (3 * nb_rb_coreset); pilot_cnt += 3) {
ch = c16mulShift(*rxF, *pil, 15);
DEBUG_PDCCH_IQ(pilot_cnt);
multaddRealVectorComplexScalar(fl, ch, dl_ch, 16);
pil++;
rxF = incrementK(base, &k, symbolSz);
#ifdef DEBUG_PDCCH
printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+2,rxF[0],rxF[1],ch[0],ch[1],pil[0],pil[1]);
#endif
ch = c16mulShift(*rxF, *pil, 15);
DEBUG_PDCCH_IQ(pilot_cnt + 1);
multaddRealVectorComplexScalar(fm, ch, dl_ch, 16);
pil++;
rxF = incrementK(base, &k, symbolSz);
multadd_real_vector_complex_scalar(fr,
ch,
dl_ch,
16);
ch = c16mulShift(*rxF, *pil, 15);
DEBUG_PDCCH_IQ(pilot_cnt + 2);
multaddRealVectorComplexScalar(fr, ch, dl_ch, 16);
#ifdef DEBUG_PDCCH
for (int m =0; m<12; m++)
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
for (int m = 0; m < 12; m++)
printf("data : dl_ch -> (%d,%d)\n", dl_ch[0 + 2 * m], dl_ch[1 + 2 * m]);
#endif
dl_ch += 24;
pil += 2;
rxF += 8;
k += 4;
}
#else //ELSE CH_INTERP
int ch_sum[2] = {0, 0};
for (pilot_cnt = 0; pilot_cnt < 3*nb_rb_coreset; pilot_cnt++) {
if (k >= ue->frame_parms.ofdm_symbol_size) {
k -= ue->frame_parms.ofdm_symbol_size;
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)];
dl_ch += 12;
pil++;
rxF = incrementK(base, &k, symbolSz);
}
#ifdef DEBUG_PDCCH
printf("pilot[%u] = (%d, %d)\trxF[%d] = (%d, %d)\n", pilot_cnt, pil[0], pil[1], k+1, rxF[0], rxF[1]);
#endif
ch_sum[0] += (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15);
ch_sum[1] += (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
pil += 2;
rxF += 8;
k += 4;
#else // ELSE CH_INTERP
c32_t ch_sum = {0};
for (uint pilot_cnt = 0; pilot_cnt < 3 * nb_rb_coreset; pilot_cnt++) {
DEBUG_PDCCH_IQ(pilot_cnt);
ch_sum = c32x16maddShift(*rxF, *pil, ch_sum, 15);
pil++;
rxF = incrementK(base, &k, symbolSz);
if (pilot_cnt % 3 == 2) {
ch[0] = ch_sum[0] / 3;
ch[1] = ch_sum[1] / 3;
multadd_real_vector_complex_scalar(filt16a_1, ch, dl_ch, 16);
c16_t ch = {ch_sum.r / 3, ch_sum.i / 3};
multaddRealVectorComplexScalar((c16_t *)filt16a_1, ch, dl_ch, 16);
#ifdef DEBUG_PDCCH
for (int m =0; m<12; m++)
printf("data : dl_ch -> (%d,%d)\n",dl_ch[0+2*m],dl_ch[1+2*m]);
#endif
dl_ch += 24;
ch_sum[0] = 0;
ch_sum[1] = 0;
dl_ch += 12;
ch_sum = (c32_t){0};
}
}
#endif //END CH_INTERP
//}
#endif // END CH_INTERP
}
}
......@@ -1419,16 +1267,16 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
c16_t dl_ch_estimates[][pdsch_est_size],
int rxdataFsize,
c16_t rxdataF[][rxdataFsize],
uint32_t *nvar)
{
// int gNB_id = proc->gNB_id;
int slot = proc->nr_slot_rx;
NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
const int ch_offset = fp->ofdm_symbol_size * symbol;
const int symbol_offset = fp->ofdm_symbol_size * symbol;
NR_DL_FRAME_PARMS * fp=&ue->frame_parms;
const int symbolSz = fp->ofdm_symbol_size;
const int ch_offset = symbolSz * symbol;
const int symbol_offset = symbolSz * symbol;
#ifdef DEBUG_PDSCH
printf(
......@@ -1437,7 +1285,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
gNB_id,
ch_offset,
symbol_offset,
fp->ofdm_symbol_size,
symbolSz,
fp->Ncp,
slot,
bwp_start_subcarrier,
......@@ -1468,11 +1316,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
#endif
c16_t *rxF = &rxdataF[aarx][symbol_offset + delta];
c16_t *dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
memset(dl_ch, 0, sizeof(*dl_ch) * fp->ofdm_symbol_size);
c16_t *dl_ch = &dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
memset(dl_ch, 0, sizeof(*dl_ch) * symbolSz);
if (config_type == NFAPI_NR_DMRS_TYPE1 && ue->chest_freq == 0) {
NFAPI_NR_DMRS_TYPE1_linear_interp(&ue->frame_parms,
NFAPI_NR_DMRS_TYPE1_linear_interp(fp,
rxF,
&pilot[6 * rb_offset],
dl_ch,
......@@ -1502,7 +1350,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
}
#ifdef DEBUG_PDSCH
dl_ch = (c16_t *)&dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
dl_ch = &dl_ch_estimates[nl * fp->nb_antennas_rx + aarx][ch_offset];
for (uint16_t idxP = 0; idxP < ceil((float)nb_rb_pdsch * 12 / 8); idxP++) {
for (uint8_t idxI = 0; idxI < 8; idxI++) {
printf("%4d\t%4d\t", dl_ch[idxP * 8 + idxI].r, dl_ch[idxP * 8 + idxI].i);
......@@ -1545,7 +1393,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
c16_t ptrs_phase_per_slot[][14],
int32_t ptrs_re_per_slot[][14],
uint32_t rx_size_symbol,
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
......@@ -1674,9 +1522,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
#ifdef DEBUG_DL_PTRS
printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i);
#endif
rotate_cpx_vector((c16_t *)&rxdataF_comp[0][aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
rotate_cpx_vector(&rxdataF_comp[0][aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
&phase_per_symbol[i],
(c16_t *)&rxdataF_comp[0][aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
&rxdataF_comp[0][aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
((*nb_rb) * NR_NB_SC_PER_RB),
15);
}// if not DMRS Symbol
......
......@@ -41,9 +41,6 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
NR_DL_FRAME_PARMS *frame_params,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
/* Generic function to find the peak of channel estimation buffer */
void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val, int32_t mean_val);
/*!
\brief This function performs channel estimation including frequency and temporal interpolation
*/
......@@ -94,7 +91,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
unsigned short bwp_start_subcarrier,
unsigned short nb_rb_pdsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
c16_t dl_ch_estimates[][pdsch_est_size],
int rxdataFsize,
c16_t rxdataF[][rxdataFsize],
uint32_t *nvar);
......@@ -112,7 +109,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size]);
c16_t dl_ch_estimates[][pdsch_est_size]);
void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
uint8_t gNB_index,
......@@ -132,7 +129,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
c16_t ptrs_phase_per_slot[][14],
int32_t ptrs_re_per_slot[][14],
uint32_t rx_size_symbol,
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
NR_DL_FRAME_PARMS *frame_parms,
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
......
......@@ -78,7 +78,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size])
c16_t dl_ch_estimates[][pdsch_est_size])
{
int slot = proc->nr_slot_rx;
int aarx, aatx, gNB_id = 0;
......@@ -113,7 +113,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
ue->measurements.rx_power[gNB_id][aarx] = 0;
for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){
const int z=signal_energy_nodc(&dl_ch_estimates[gNB_id][ch_offset], N_RB_DL * NR_NB_SC_PER_RB);
const int z = signal_energy_nodc((int32_t *)&dl_ch_estimates[gNB_id][ch_offset], N_RB_DL * NR_NB_SC_PER_RB);
rx_spatial_power[gNB_id][aatx][aarx] = z;
if (rx_spatial_power[gNB_id][aatx][aarx] < 0)
......
......@@ -46,13 +46,13 @@
//#define NR_CSIRS_DEBUG
//#define NR_CSIIM_DEBUG
void nr_det_A_MF_2x2(int32_t *a_mf_00,
int32_t *a_mf_01,
int32_t *a_mf_10,
int32_t *a_mf_11,
static void nr_det_A_MF_2x2(c16_t *a_mf_00,
c16_t *a_mf_01,
c16_t *a_mf_10,
c16_t *a_mf_11,
int32_t *det_fin,
const unsigned short nb_rb) {
const unsigned short nb_rb)
{
int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
simde__m128i ad_re_128, bc_re_128, det_re_128;
......@@ -86,13 +86,10 @@ void nr_det_A_MF_2x2(int32_t *a_mf_00,
a_mf_10_128+=1;
a_mf_11_128+=1;
}
simde_mm_empty();
simde_m_empty();
}
void nr_squared_matrix_element(int32_t *a,
int32_t *a_sq,
const unsigned short nb_rb) {
static void nr_squared_matrix_element(c16_t *a, c16_t *a_sq, const unsigned short nb_rb)
{
simde__m128i *a_128 = (simde__m128i *)a;
simde__m128i *a_sq_128 = (simde__m128i *)a_sq;
for (int rb=0; rb<3*nb_rb; rb++) {
......@@ -100,16 +97,15 @@ void nr_squared_matrix_element(int32_t *a,
a_sq_128+=1;
a_128+=1;
}
simde_mm_empty();
simde_m_empty();
}
void nr_numer_2x2(int32_t *a_00_sq,
int32_t *a_01_sq,
int32_t *a_10_sq,
int32_t *a_11_sq,
static void nr_numer_2x2(c16_t *a_00_sq,
c16_t *a_01_sq,
c16_t *a_10_sq,
c16_t *a_11_sq,
int32_t *num_fin,
const unsigned short nb_rb) {
const unsigned short nb_rb)
{
simde__m128i *a_00_sq_128 = (simde__m128i *)a_00_sq;
simde__m128i *a_01_sq_128 = (simde__m128i *)a_01_sq;
simde__m128i *a_10_sq_128 = (simde__m128i *)a_10_sq;
......@@ -125,8 +121,6 @@ void nr_numer_2x2(int32_t *a_00_sq,
a_10_sq_128+=1;
a_11_sq_128+=1;
}
simde_mm_empty();
simde_m_empty();
}
bool is_csi_rs_in_symbol(const fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, const int symbol) {
......@@ -188,11 +182,11 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
const uint8_t *j_cdm,
const uint8_t *k_overline,
const uint8_t *l_overline,
int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
c16_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
uint32_t *rsrp,
int *rsrp_dBm,
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
uint16_t meas_count = 0;
uint32_t rsrp_sum = 0;
......@@ -219,19 +213,17 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
uint16_t symb = lp + l_overline[cdm_id];
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset];
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
rx_csi_rs_signal[k].r = rx_signal[k].r;
rx_csi_rs_signal[k].i = rx_signal[k].i;
c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset];
rx_csi_rs_signal[k] = rx_signal[k];
rsrp_sum += (((int32_t)(rx_csi_rs_signal[k].r)*rx_csi_rs_signal[k].r) +
((int32_t)(rx_csi_rs_signal[k].i)*rx_csi_rs_signal[k].i));
rsrp_sum += squaredMod(rx_csi_rs_signal[k]);
meas_count++;
#ifdef NR_CSIRS_DEBUG
int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size;
c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
c16_t *tx_csi_rs_signal = &nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset + dataF_offset];
LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
symb,
k,
......@@ -277,12 +269,13 @@ uint32_t calc_power_csirs(const uint16_t *x, const fapi_nr_dl_config_csirs_pdu_r
return sum_x2 / size - (sum_x / size) * (sum_x / size);
}
int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
static int nr_csi_rs_channel_estimation(
const PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const nr_csi_info_t *nr_csi_info,
const int32_t **csi_rs_generated_signal,
const int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
c16_t **csi_rs_generated_signal,
const c16_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
const uint8_t N_cdm_groups,
const uint8_t CDM_group_size,
const uint8_t k_prime,
......@@ -292,12 +285,12 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
const uint8_t *k_overline,
const uint8_t *l_overline,
uint8_t mem_offset,
int32_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size],
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
c16_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size],
c16_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
int16_t *log2_re,
int16_t *log2_maxh,
uint32_t *noise_power) {
uint32_t *noise_power)
{
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
const int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
*noise_power = 0;
......@@ -305,15 +298,12 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
int count = 0;
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
/// LS channel estimation
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
for (uint port_tx = 0; port_tx < N_ports; port_tx++) {
memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size * sizeof(c16_t));
}
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb + csirs_config_pdu->nr_of_rbs); rb++) {
// for freq density 0.5 checks if even or odd RB
if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
continue;
......@@ -334,17 +324,10 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
for (int lp = 0; lp <= l_prime; lp++) {
uint16_t symb = lp + l_overline[cdm_id];
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].r + (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].i)>>nr_csi_info->csi_rs_generated_signal_bits);
int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].i - (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].r)>>nr_csi_info->csi_rs_generated_signal_bits);
// This is not just the LS estimation for each (k,l), but also the sum of the different contributions
// for the sake of optimizing the memory used.
csi_rs_ls_estimated_channel16[kinit].r += csi_rs_ls_estimated_channel_re;
csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im;
const c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset + dataF_offset];
const c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset];
csi_rs_ls_estimated_channel[ant_rx][port_tx][kinit] =
c16MulConjShift(tx_csi_rs_signal[k], rx_csi_rs_signal[k], nr_csi_info->csi_rs_generated_signal_bits);
}
}
}
......@@ -360,9 +343,9 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k);
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
c16_t *tx_csi_rs_signal = &csi_rs_generated_signal[port_tx][symbol_offset + dataF_offset];
c16_t *rx_csi_rs_signal = &csi_rs_received_signal[ant_rx][symbol_offset];
c16_t *csi_rs_ls_estimated_channel16 = csi_rs_ls_estimated_channel[ant_rx][port_tx];
printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ",
port_tx+3000, ant_rx,
tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i,
......@@ -389,18 +372,20 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
count++;
uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
uint16_t k_offset = k + mem_offset;
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
int16_t *csi_rs_ls_estimated_channel16 = (int16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset];
if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16, 24);
} else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) ||
(rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case
multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
const uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
const uint16_t k_offset = k + mem_offset;
for (uint port_tx = 0; port_tx < N_ports; port_tx++) {
c16_t val = csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
c16_t *csi_rs_estimated_channel = &csi_rs_estimated_channel_freq[ant_rx][port_tx][k_offset];
if (k == 0 || k == frame_parms->first_carrier_offset) { // Start of OFDM symbol case or first occupied subcarrier case
multaddRealVectorComplexScalar(filt24_start, val, csi_rs_estimated_channel, 24);
} else if ((k + NR_NB_SC_PER_RB >= frame_parms->ofdm_symbol_size)
|| (rb
== csirs_config_pdu->start_rb + csirs_config_pdu->nr_of_rbs
- 1)) { // End of OFDM symbol case or Last occupied subcarrier case
multaddRealVectorComplexScalar(filt24_end, val, csi_rs_estimated_channel - 3 * sizeof(c16_t), 24);
} else { // Middle case
multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
multaddRealVectorComplexScalar(filt24_middle, val, csi_rs_estimated_channel - 3 * sizeof(c16_t), 24);
}
}
}
......@@ -434,8 +419,8 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
(k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB;
LOG_I(NR_PHY, "(k = %4d) |\t", k);
for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) {
c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][mem_offset];
c16_t *csi_rs_ls_estimated_channel16 = csi_rs_ls_estimated_channel[ant_rx][port_tx];
c16_t *csi_rs_estimated_channel16 = &csi_rs_estimated_channel_freq[ant_rx][port_tx][mem_offset];
printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
port_tx+3000, ant_rx,
csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i,
......@@ -446,7 +431,6 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
printf("\n");
}
#endif
}
*noise_power /= (frame_parms->nb_antennas_rx*N_ports);
......@@ -460,15 +444,15 @@ int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue,
return 0;
}
int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
static int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
const nr_csi_info_t *nr_csi_info,
const uint8_t N_ports,
uint8_t mem_offset,
int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
c16_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
const int16_t log2_maxh,
uint8_t *rank_indicator) {
uint8_t *rank_indicator)
{
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
const int16_t cond_dB_threshold = 5;
int count = 0;
......@@ -486,13 +470,14 @@ int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue,
* | conjch00 conjch10 | x | ch00 ch01 | = | conjch00*ch00+conjch10*ch10 conjch00*ch01+conjch10*ch11 |
* | conjch01 conjch11 | | ch10 ch11 | | conjch01*ch00+conjch11*ch10 conjch01*ch01+conjch11*ch11 |
*/
int32_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
int32_t csi_rs_estimated_determ_fin[frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
int32_t csi_rs_estimated_numer_fin[frame_parms->ofdm_symbol_size + FILTER_MARGIN] __attribute__((aligned(32)));
const uint8_t sum_shift = 1; // log2(2x2) = 2, which is a shift of 1 bit
const int sZ = frame_parms->ofdm_symbol_size + FILTER_MARGIN;
c16_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][sZ]
__attribute__((aligned(32)));
c16_t csi_rs_estimated_A_MF[N_ports][N_ports][sZ] __attribute__((aligned(32)));
c16_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][sZ] __attribute__((aligned(32)));
int32_t csi_rs_estimated_determ_fin[sZ] __attribute__((aligned(32)));
int32_t csi_rs_estimated_numer_fin[sZ] __attribute__((aligned(32)));
const uint sum_shift = 1; // log2(2x2) = 2, which is a shift of 1 bit
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
......@@ -597,14 +582,14 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue,
const nr_csi_info_t *nr_csi_info,
const uint8_t N_ports,
uint8_t mem_offset,
const int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
const c16_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size + FILTER_MARGIN],
const uint32_t interference_plus_noise_power,
const uint8_t rank_indicator,
const int16_t log2_re,
uint8_t *i1,
uint8_t *i2,
uint32_t *precoded_sinr_dB) {
uint32_t *precoded_sinr_dB)
{
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
// i1 is a three-element vector in the form of [i11 i12 i13], when CodebookType is specified as 'Type1SinglePanel'.
......@@ -621,11 +606,8 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue,
}
if(rank_indicator == 0 || rank_indicator == 1) {
int32_t sum_re[4] = {0};
int32_t sum_im[4] = {0};
int32_t sum2_re[4] = {0};
int32_t sum2_im[4] = {0};
c32_t sum[4] = {0};
c32_t sum2[4] = {0};
int32_t tested_precoded_sinr[4] = {0};
for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
......@@ -636,41 +618,45 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue,
uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
uint16_t k_offset = k + mem_offset;
for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
c16_t *csi_rs_estimated_channel_p0 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][0][k_offset];
c16_t *csi_rs_estimated_channel_p1 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][1][k_offset];
const c16_t csi_rs_estimated_channel_p0 = csi_rs_estimated_channel_freq[ant_rx][0][k_offset];
const c16_t csi_rs_estimated_channel_p1 = csi_rs_estimated_channel_freq[ant_rx][1][k_offset];
// H_p0 + 1*H_p1 = (H_p0_re + H_p1_re) + 1j*(H_p0_im + H_p1_im)
sum_re[0] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r);
sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i);
sum2_re[0] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r))>>log2_re;
sum2_im[0] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i))>>log2_re;
c32_t tmp, tmp2;
csum(tmp, csi_rs_estimated_channel_p0, csi_rs_estimated_channel_p1);
csum(sum[0], sum[0], tmp);
tmp2 = (c32_t){(tmp.r * tmp.r) >> log2_re, (tmp.i * tmp.i) >> log2_re};
csum(sum2[0], sum2[0], tmp2);
// H_p0 + 1j*H_p1 = (H_p0_re - H_p1_im) + 1j*(H_p0_im + H_p1_re)
sum_re[1] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i);
sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r);
sum2_re[1] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i))>>log2_re;
sum2_im[1] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r))>>log2_re;
tmp = (c32_t){csi_rs_estimated_channel_p0.r - csi_rs_estimated_channel_p1.i,
csi_rs_estimated_channel_p0.i + csi_rs_estimated_channel_p1.r};
csum(sum[1], sum[1], tmp);
tmp2 = (c32_t){(tmp.r * tmp.r) >> log2_re, (tmp.i * tmp.i) >> log2_re};
csum(sum2[1], sum2[1], tmp2);
// H_p0 - 1*H_p1 = (H_p0_re - H_p1_re) + 1j*(H_p0_im - H_p1_im)
sum_re[2] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r);
sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i);
sum2_re[2] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r))>>log2_re;
sum2_im[2] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i))>>log2_re;
tmp = (c32_t){csi_rs_estimated_channel_p0.r - csi_rs_estimated_channel_p1.r,
csi_rs_estimated_channel_p0.i - csi_rs_estimated_channel_p1.i};
csum(sum[2], sum[2], tmp);
tmp2 = (c32_t){(tmp.r * tmp.r) >> log2_re, (tmp.i * tmp.i) >> log2_re};
csum(sum2[1], sum2[1], tmp2);
// H_p0 - 1j*H_p1 = (H_p0_re + H_p1_im) + 1j*(H_p0_im - H_p1_re)
sum_re[3] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i);
sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r);
sum2_re[3] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i))>>log2_re;
sum2_im[3] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r))>>log2_re;
tmp = (c32_t){csi_rs_estimated_channel_p0.r + csi_rs_estimated_channel_p1.i,
csi_rs_estimated_channel_p0.i - csi_rs_estimated_channel_p1.r};
csum(sum[2], sum[2], tmp);
tmp2 = (c32_t){(tmp.r * tmp.r) >> log2_re, (tmp.i * tmp.i) >> log2_re};
csum(sum2[2], sum2[2], tmp2);
}
}
// We should perform >>nr_csi_info->log2_re here for all terms, but since sum2_re and sum2_im can be high values,
// we performed this above.
for(int p = 0; p<4; p++) {
int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re);
int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>log2_re);
tested_precoded_sinr[p] = (power_re+power_im)/(int32_t)interference_plus_noise_power;
c32_t power = {sum2[p].r - (sum[p].r >> log2_re) * (sum[p].r >> log2_re),
sum2[p].i - (sum[p].i >> log2_re) * (sum[p].i >> log2_re)};
tested_precoded_sinr[p] = (power.r + power.i) / (int32_t)interference_plus_noise_power;
}
if(rank_indicator == 0) {
......@@ -887,7 +873,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
}
const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
c16_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP];
uint8_t N_cdm_groups = 0;
uint8_t CDM_group_size = 0;
uint8_t k_prime = 0;
......@@ -922,8 +908,8 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
k_overline,
l_overline);
int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN];
c16_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size];
c16_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size + FILTER_MARGIN];
// (long)&csi_rs_estimated_channel_freq[0][0][frame_parms->first_carrier_offset] & 0x1F gives us the remainder of the integer division by 32 of the memory address
// By subtracting the previous value of 32, we know how much is left to have a multiple of 32.
......@@ -953,7 +939,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
proc,
csirs_config_pdu,
ue->nr_csi_info,
(const int32_t **) ue->nr_csi_info->csi_rs_generated_signal,
ue->nr_csi_info->csi_rs_generated_signal,
csi_rs_received_signal,
N_cdm_groups,
CDM_group_size,
......
......@@ -86,11 +86,11 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
static void nr_dlsch_mmse(uint32_t rx_size_symbol,
unsigned char n_rx,
unsigned char n_tx, // number of layer
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int32_t dl_ch_mag[][n_rx][rx_size_symbol],
int32_t dl_ch_magb[][n_rx][rx_size_symbol],
int32_t dl_ch_magr[][n_rx][rx_size_symbol],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_mag[][n_rx][rx_size_symbol],
c16_t dl_ch_magb[][n_rx][rx_size_symbol],
c16_t dl_ch_magr[][n_rx][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
unsigned short nb_rb,
unsigned char mod_order,
int shift,
......@@ -114,10 +114,10 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol,
uint sz,
int16_t layer_llr[][sz],
NR_DL_FRAME_PARMS *frame_parms,
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int32_t dl_ch_mag[rx_size_symbol],
int32_t dl_ch_magb[rx_size_symbol],
int32_t dl_ch_magr[rx_size_symbol],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_mag[rx_size_symbol],
c16_t dl_ch_magb[rx_size_symbol],
c16_t dl_ch_magr[rx_size_symbol],
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
unsigned char harq_pid,
......@@ -147,9 +147,9 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
c16_t rxdataF[][rxdataF_sz],
uint32_t rx_size_symbol,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
c16_t dl_ch_estimates[][pdsch_est_size],
c16_t rxdataF_ext[][rx_size_symbol],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
unsigned char symbol,
uint8_t pilots,
uint8_t config_type,
......@@ -162,7 +162,7 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
int chest_time_type);
static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
int32_t median[MAX_ANT][MAX_ANT],
int n_tx,
int n_rx,
......@@ -188,11 +188,11 @@ static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol,
static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
int nbRx,
c16_t rxdataF_ext[][rx_size_symbol],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
int32_t dl_ch_mag[][nbRx][rx_size_symbol],
int32_t dl_ch_magb[][nbRx][rx_size_symbol],
int32_t dl_ch_magr[][nbRx][rx_size_symbol],
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_mag[][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][nbRx][rx_size_symbol],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int ***rho,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_layers,
......@@ -212,14 +212,14 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
@param nb_rb Number of allocated RBs
*/
static void nr_dlsch_channel_level(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
uint8_t n_rx,
uint8_t n_tx,
int32_t avg[MAX_ANT][MAX_ANT],
uint32_t len);
void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
static void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
c16_t dl_ch_estimates_ext[][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
uint8_t n_rx,
......@@ -227,14 +227,14 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
uint8_t pilots,
uint32_t len,
unsigned short nb_rb);
void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
short n_tx,
short n_rx,
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int ***rho,
int32_t dl_ch_mag[][n_rx][rx_size_symbol],
int32_t dl_ch_magb[][n_rx][rx_size_symbol],
int32_t dl_ch_magr[][n_rx][rx_size_symbol],
c16_t dl_ch_mag[][n_rx][rx_size_symbol],
c16_t dl_ch_magb[][n_rx][rx_size_symbol],
c16_t dl_ch_magr[][n_rx][rx_size_symbol],
unsigned char symbol,
unsigned short nb_rb,
int length);
......@@ -247,7 +247,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
bool first_symbol_flag,
unsigned char harq_pid,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
c16_t dl_ch_estimates[][pdsch_est_size],
int16_t *llr[2],
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
......@@ -255,7 +255,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int32_t *log2_maxh,
int rx_size_symbol,
int nbRx,
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G,
......@@ -263,17 +263,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
{
const int nl = dlsch[0].Nl;
const int matrixSz = ue->frame_parms.nb_antennas_rx * nl;
__attribute__((aligned(32))) int32_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
__attribute__((aligned(32))) c16_t dl_ch_estimates_ext[matrixSz][rx_size_symbol];
memset(dl_ch_estimates_ext, 0, sizeof(dl_ch_estimates_ext));
__attribute__((aligned(32))) int32_t dl_ch_mag[nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol];
__attribute__((aligned(32))) c16_t dl_ch_mag[nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol];
memset(dl_ch_mag, 0, sizeof(dl_ch_mag));
__attribute__((aligned(32))) int32_t dl_ch_magb[nl][nbRx][rx_size_symbol];
__attribute__((aligned(32))) c16_t dl_ch_magb[nl][nbRx][rx_size_symbol];
memset(dl_ch_magb, 0, sizeof(dl_ch_magb));
__attribute__((aligned(32))) int32_t dl_ch_magr[nl][nbRx][rx_size_symbol];
__attribute__((aligned(32))) c16_t dl_ch_magr[nl][nbRx][rx_size_symbol];
memset(dl_ch_magr, 0, sizeof(dl_ch_magr));
NR_UE_COMMON *common_vars = &ue->common_vars;
NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
......@@ -637,20 +638,26 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
write_output(filename, "rxdataF0", &rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
snprintf(filename, 50, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
write_output(filename, "dl_ch_estimates", &dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
write_output(filename, "dl_ch_estimates", dl_ch_estimates[aa], NR_SYMBOLS_PER_SLOT * frame_parms->ofdm_symbol_size, 1, 1);
snprintf(filename, 50, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
write_output(filename, "rxdataF_ext", &rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
write_output(filename, "rxdataF_ext", rxdataF_ext[aa], NR_SYMBOLS_PER_SLOT * frame_parms->N_RB_DL * NR_NB_SC_PER_RB, 1, 1);
snprintf(filename, 50, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
write_output(filename, "dl_ch_estimates_ext00", &dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
write_output(filename,
"dl_ch_estimates_ext00",
dl_ch_estimates_ext[aa],
NR_SYMBOLS_PER_SLOT * frame_parms->N_RB_DL * NR_NB_SC_PER_RB,
1,
1);
snprintf(filename, 50, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
write_output(filename, "rxdataF_comp00", &rxdataF_comp[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
write_output(filename, "rxdataF_comp00", rxdataF_comp[aa], NR_SYMBOLS_PER_SLOT * frame_parms->N_RB_DL * NR_NB_SC_PER_RB, 1, 1);
/*
for (int i=0; i < 2; i++){
snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) -
4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
}
*/
#endif
......@@ -759,11 +766,11 @@ simde__m128i nr_dlsch_a_mult_conjb(simde__m128i a, simde__m128i b, unsigned char
static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
int nbRx,
c16_t rxdataF_ext[][rx_size_symbol],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
int32_t dl_ch_mag[][nbRx][rx_size_symbol],
int32_t dl_ch_magb[][nbRx][rx_size_symbol],
int32_t dl_ch_magr[][nbRx][rx_size_symbol],
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_mag[][nbRx][rx_size_symbol],
c16_t dl_ch_magb[][nbRx][rx_size_symbol],
c16_t dl_ch_magr[][nbRx][rx_size_symbol],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int ***rho,
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_layers,
......@@ -951,8 +958,8 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol,
}
}
void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
static void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
c16_t dl_ch_estimates_ext[][rx_size_symbol],
NR_DL_FRAME_PARMS *frame_parms,
uint8_t n_tx,
uint8_t n_rx,
......@@ -1012,7 +1019,7 @@ void nr_dlsch_scale_channel(uint32_t rx_size_symbol,
@param len Number of allocated PDSCH REs
*/
void nr_dlsch_channel_level(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
uint8_t n_rx,
uint8_t n_tx,
int32_t avg[MAX_ANT][MAX_ANT],
......@@ -1046,7 +1053,7 @@ void nr_dlsch_channel_level(uint32_t rx_size_symbol,
}
static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol,
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
int32_t median[MAX_ANT][MAX_ANT],
int n_tx,
int n_rx,
......@@ -1087,9 +1094,9 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
c16_t rxdataF[][rxdataF_sz],
uint32_t rx_size_symbol,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
c16_t dl_ch_estimates[][pdsch_est_size],
c16_t rxdataF_ext[][rx_size_symbol],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
unsigned char symbol,
uint8_t pilots,
uint8_t config_type,
......@@ -1122,9 +1129,8 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
c16_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
for (unsigned char l = 0; l < Nl; l++) {
int32_t *dl_ch0 = &dl_ch_estimates[(l * frame_parms->nb_antennas_rx) + aarx][validDmrsEst * frame_parms->ofdm_symbol_size];
int32_t *dl_ch0_ext = dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx];
c16_t *dl_ch0 = &dl_ch_estimates[(l * frame_parms->nb_antennas_rx) + aarx][validDmrsEst * frame_parms->ofdm_symbol_size];
c16_t *dl_ch0_ext = dl_ch_estimates_ext[(l * frame_parms->nb_antennas_rx) + aarx];
if (pilots == 0) { //data symbol only
if (l == 0) {
......@@ -1204,37 +1210,34 @@ static void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
}
}
void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
static void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
short n_tx,
short n_rx,
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int ***rho,
int32_t dl_ch_mag[][n_rx][rx_size_symbol],
int32_t dl_ch_magb[][n_rx][rx_size_symbol],
int32_t dl_ch_magr[][n_rx][rx_size_symbol],
c16_t dl_ch_mag[][n_rx][rx_size_symbol],
c16_t dl_ch_magb[][n_rx][rx_size_symbol],
c16_t dl_ch_magr[][n_rx][rx_size_symbol],
unsigned char symbol,
unsigned short nb_rb,
int length) {
unsigned char aatx, aarx;
int i;
simde__m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r;
int length)
{
uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
if (n_rx>1) {
for (aatx=0; aatx<n_tx; aatx++) {
rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[aatx][0] + symbol * nb_rb * 12);
dl_ch_mag128_0 = (simde__m128i *)dl_ch_mag[aatx][0];
dl_ch_mag128_0b = (simde__m128i *)dl_ch_magb[aatx][0];
dl_ch_mag128_0r = (simde__m128i *)dl_ch_magr[aatx][0];
for (aarx=1; aarx<n_rx; aarx++) {
rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[aatx][aarx] + symbol * nb_rb * 12);
dl_ch_mag128_1 = (simde__m128i *)dl_ch_mag[aatx][aarx];
dl_ch_mag128_1b = (simde__m128i *)dl_ch_magb[aatx][aarx];
dl_ch_mag128_1r = (simde__m128i *)dl_ch_magr[aatx][aarx];
for (int aatx = 0; aatx < n_tx; aatx++) {
simde__m128i *rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[aatx][0] + symbol * nb_rb * 12);
simde__m128i *dl_ch_mag128_0 = (simde__m128i *)dl_ch_mag[aatx][0];
simde__m128i *dl_ch_mag128_0b = (simde__m128i *)dl_ch_magb[aatx][0];
simde__m128i *dl_ch_mag128_0r = (simde__m128i *)dl_ch_magr[aatx][0];
for (int aarx = 1; aarx < n_rx; aarx++) {
simde__m128i *rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[aatx][aarx] + symbol * nb_rb * 12);
simde__m128i *dl_ch_mag128_1 = (simde__m128i *)dl_ch_mag[aatx][aarx];
simde__m128i *dl_ch_mag128_1b = (simde__m128i *)dl_ch_magb[aatx][aarx];
simde__m128i *dl_ch_mag128_1r = (simde__m128i *)dl_ch_magr[aatx][aarx];
// MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM/256 llr computation)
for (i=0; i<nb_rb_0*3; i++) {
for (int i = 0; i < nb_rb_0 * 3; i++) {
rxdataF_comp128_0[i] = simde_mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]);
dl_ch_mag128_0[i] = simde_mm_adds_epi16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]);
dl_ch_mag128_0b[i] = simde_mm_adds_epi16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]);
......@@ -1243,27 +1246,25 @@ void nr_dlsch_detection_mrc(uint32_t rx_size_symbol,
}
}
#ifdef DEBUG_DLSCH_DEMOD
for (i=0; i<nb_rb_0*3; i++) {
printf("symbol%d RB %d\n",symbol,i/3);
rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[0][0] + symbol * nb_rb * 12);
rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[0][n_rx] + symbol * nb_rb * 12);
print_shorts("tx 1 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_0[i]);
print_shorts("tx 2 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_1[i]);
for (int i = 0; i < nb_rb_0 * 3; i++) {
printf("symbol%d RB %d\n", symbol, i / 3);
simde__m128i *rxdataF_comp128_0 = (simde__m128i *)(rxdataF_comp[0][0] + symbol * nb_rb * 12);
simde__m128i *rxdataF_comp128_1 = (simde__m128i *)(rxdataF_comp[0][n_rx] + symbol * nb_rb * 12);
print_shorts("tx 1 mrc_re/mrc_Im:", (int16_t *)&rxdataF_comp128_0[i]);
print_shorts("tx 2 mrc_re/mrc_Im:", (int16_t *)&rxdataF_comp128_1[i]);
// printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]);
// printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]);
}
#endif
if (rho) {
/*rho128_0 = (simde__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12];
rho128_1 = (simde__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
simde__m128i *rho128_1 = (simde__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12];
for (i=0; i<nb_rb_0*3; i++) {
// print_shorts("mrc rho0:",&rho128_0[i]);
// print_shorts("mrc rho1:",&rho128_1[i]);
rho128_0[i] = simde_mm_adds_epi16(simde_mm_srai_epi16(rho128_0[i],1),simde_mm_srai_epi16(rho128_1[i],1));
}*/
}
simde_mm_empty();
simde_m_empty();
}
}
......@@ -1580,35 +1581,28 @@ uint8_t nr_matrix_inverse(int32_t size,
*
*
* */
void nr_conjch0_mult_ch1(int *ch0,
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0)
void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0)
{
//This function is used to compute multiplications in H_hermitian * H matrix
short nr_conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
unsigned short rb;
simde__m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
dl_ch0_128 = (simde__m128i *)ch0;
dl_ch1_128 = (simde__m128i *)ch1;
simde__m128i *dl_ch0_128 = (simde__m128i *)ch0;
simde__m128i *dl_ch1_128 = (simde__m128i *)ch1;
ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1;
simde__m128i *ch0conj_ch1_128 = (simde__m128i *)ch0conj_ch1;
for (rb=0; rb<3*nb_rb; rb++) {
mmtmpD0 = simde_mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
mmtmpD1 = simde_mm_shufflelo_epi16(dl_ch0_128[0],SIMDE_MM_SHUFFLE(2,3,0,1));
simde__m128i mmtmpD0 = simde_mm_madd_epi16(*dl_ch0_128, *dl_ch1_128);
simde__m128i mmtmpD1 = simde_mm_shufflelo_epi16(*dl_ch0_128, SIMDE_MM_SHUFFLE(2, 3, 0, 1));
mmtmpD1 = simde_mm_shufflehi_epi16(mmtmpD1,SIMDE_MM_SHUFFLE(2,3,0,1));
mmtmpD1 = simde_mm_sign_epi16(mmtmpD1,*(simde__m128i*)&nr_conjugate[0]);
mmtmpD1 = simde_mm_madd_epi16(mmtmpD1,dl_ch1_128[0]);
mmtmpD1 = simde_mm_sign_epi16(mmtmpD1, *(simde__m128i *)nr_conjugate);
mmtmpD1 = simde_mm_madd_epi16(mmtmpD1, *dl_ch1_128);
mmtmpD0 = simde_mm_srai_epi32(mmtmpD0,output_shift0);
mmtmpD1 = simde_mm_srai_epi32(mmtmpD1,output_shift0);
mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
simde__m128i mmtmpD2 = simde_mm_unpacklo_epi32(mmtmpD0, mmtmpD1);
simde__m128i mmtmpD3 = simde_mm_unpackhi_epi32(mmtmpD0, mmtmpD1);
ch0conj_ch1_128[0] = simde_mm_packs_epi32(mmtmpD2,mmtmpD3);
*ch0conj_ch1_128 = simde_mm_packs_epi32(mmtmpD2, mmtmpD3);
/*printf("\n Computing conjugates \n");
print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]);
......@@ -1619,8 +1613,6 @@ void nr_conjch0_mult_ch1(int *ch0,
dl_ch1_128+=1;
ch0conj_ch1_128+=1;
}
simde_mm_empty();
simde_m_empty();
}
/*
......@@ -1629,11 +1621,11 @@ void nr_conjch0_mult_ch1(int *ch0,
static void nr_dlsch_mmse(uint32_t rx_size_symbol,
unsigned char n_rx,
unsigned char n_tx, // number of layer
int32_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int32_t dl_ch_mag[][n_rx][rx_size_symbol],
int32_t dl_ch_magb[][n_rx][rx_size_symbol],
int32_t dl_ch_magr[][n_rx][rx_size_symbol],
int32_t dl_ch_estimates_ext[][rx_size_symbol],
c16_t rxdataF_comp[][n_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_mag[][n_rx][rx_size_symbol],
c16_t dl_ch_magb[][n_rx][rx_size_symbol],
c16_t dl_ch_magr[][n_rx][rx_size_symbol],
c16_t dl_ch_estimates_ext[][rx_size_symbol],
unsigned short nb_rb,
unsigned char mod_order,
int shift,
......@@ -1641,7 +1633,6 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
int length,
uint32_t noise_var)
{
int *ch0r, *ch0c;
uint32_t nb_rb_0 = length/12 + ((length%12)?1:0);
c16_t determ_fin[12 * nb_rb_0] __attribute__((aligned(32)));
......@@ -1658,11 +1649,11 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
for (int rtx=0;rtx<n_tx;rtx++) {//row
for (int ctx=0;ctx<n_tx;ctx++) {//column
for (int aarx=0;aarx<n_rx;aarx++) {
ch0r = (int *)dl_ch_estimates_ext[rtx*n_rx+aarx];
ch0c = (int *)dl_ch_estimates_ext[ctx*n_rx+aarx];
c16_t *ch0r = dl_ch_estimates_ext[rtx * n_rx + aarx];
c16_t *ch0c = dl_ch_estimates_ext[ctx * n_rx + aarx];
nr_conjch0_mult_ch1(ch0r,
ch0c,
(int32_t *)conjH_H_elements[aarx][ctx][rtx], // sic
conjH_H_elements[aarx][ctx][rtx], // sic
nb_rb_0,
shift);
if (aarx != 0)
......@@ -1713,7 +1704,11 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol,
// printf("Computing r_%d c_%d\n",rtx,ctx);
// print_shorts(" H_h_H=",(int16_t*)&conjH_H_elements[ctx*n_tx+rtx][0][0]);
// print_shorts(" Inv_H_h_H=",(int16_t*)&inv_H_h_H[ctx*n_tx+rtx][0]);
nr_a_mult_b(inv_H_h_H[ctx][rtx], (c16_t *)(rxdataF_comp[ctx][0] + symbol * nb_rb * 12), outtemp, nb_rb_0, shift - (fp_flag == 1 ? 2 : 0));
nr_a_mult_b(inv_H_h_H[ctx][rtx],
rxdataF_comp[ctx][0] + symbol * nb_rb * 12,
outtemp,
nb_rb_0,
shift - (fp_flag == 1 ? 2 : 0));
nr_a_sum_b(rxdataF_zforcing[rtx], outtemp,
nb_rb_0); // a =a + b
}
......@@ -1826,10 +1821,10 @@ static int nr_dlsch_llr(uint32_t rx_size_symbol,
uint sz,
int16_t layer_llr[][sz],
NR_DL_FRAME_PARMS *frame_parms,
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
int32_t dl_ch_mag[rx_size_symbol],
int32_t dl_ch_magb[rx_size_symbol],
int32_t dl_ch_magr[rx_size_symbol],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t dl_ch_mag[rx_size_symbol],
c16_t dl_ch_magb[rx_size_symbol],
c16_t dl_ch_magr[rx_size_symbol],
NR_DL_UE_HARQ_t *dlsch0_harq,
NR_DL_UE_HARQ_t *dlsch1_harq,
unsigned char harq_pid,
......
......@@ -49,15 +49,14 @@ int16_t nr_zeros[8] __attribute__((aligned(16))) = {0, 0, 0, 0, 0, 0, 0, 0};
//----------------------------------------------------------------------------------------------
int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
uint16_t nb_rb)
{
c16_t *rxF = (c16_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)];
c16_t *rxF = rxdataF_comp + symbol * nb_rb * 12;
c16_t *llr32 = (c16_t *)dlsch_llr;
int i;
......@@ -90,28 +89,20 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
//----------------------------------------------------------------------------------------------
void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
int32_t *dl_ch_mag,
c16_t *dl_ch_mag,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
uint16_t nb_rb)
{
simde__m128i *rxF = (simde__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
simde__m128i *ch_mag;
simde__m128i *rxF = (simde__m128i *)&rxdataF_comp[(symbol * nb_rb * 12)];
simde__m128i llr128[2];
uint32_t *llr32;
int i;
unsigned char len_mod4=0;
llr32 = (uint32_t*)dlsch_llr;
ch_mag = (simde__m128i *)dl_ch_mag;
unsigned char len_mod4 = 0;
llr32 = (uint32_t *)dlsch_llr;
simde__m128i *ch_mag = (simde__m128i *)dl_ch_mag;
// printf("len=%d\n", len);
len_mod4 = len&3;
......@@ -120,8 +111,7 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
// printf("len>>=2=%d\n", len);
len+=(len_mod4==0 ? 0 : 1);
// printf("len+=%d\n", len);
for (i=0; i<len; i++) {
for (int i = 0; i < len; i++) {
simde__m128i xmm0 =simde_mm_abs_epi16(rxF[i]);
xmm0 =simde_mm_subs_epi16(ch_mag[i],xmm0);
......@@ -136,12 +126,8 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
llr32[5] =simde_mm_extract_epi32(llr128[1],1); //((uint32_t *)&llr128[1])[1];
llr32[6] =simde_mm_extract_epi32(llr128[1],2); //((uint32_t *)&llr128[1])[2];
llr32[7] =simde_mm_extract_epi32(llr128[1],3); //((uint32_t *)&llr128[1])[3];
llr32+=8;
llr32 += 8;
}
simde_mm_empty();
simde_m_empty();
}
//----------------------------------------------------------------------------------------------
......@@ -149,22 +135,19 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
//----------------------------------------------------------------------------------------------
void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
int32_t *dl_ch_mag,
int32_t *dl_ch_magb,
c16_t *dl_ch_mag,
c16_t *dl_ch_magb,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
uint16_t nb_rb)
{
simde__m128i *rxF = (simde__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
simde__m128i *ch_mag,*ch_magb;
int i,len2;
simde__m128i *ch_mag, *ch_magb;
unsigned char len_mod4;
int16_t *llr2;
llr2 = dlsch_llr;
int16_t *llr2 = dlsch_llr;
ch_mag = (simde__m128i *)dl_ch_mag;
ch_magb = (simde__m128i *)dl_ch_magb;
......@@ -179,10 +162,10 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
pllr_symbol);*/
len_mod4 =len&3;
len2=len>>2; // length in quad words (4 REs)
int len2 = len >> 2; // length in quad words (4 REs)
len2+=((len_mod4==0)?0:1);
for (i=0; i<len2; i++) {
for (int i = 0; i < len2; i++) {
simde__m128i xmm1, xmm2;
xmm1 =simde_mm_abs_epi16(rxF[i]);
xmm1 =simde_mm_subs_epi16(ch_mag[i],xmm1);
......@@ -231,12 +214,8 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
llr2[3] =simde_mm_extract_epi16(xmm1,7);//((short *)&xmm1)[j+1];
llr2[4] =simde_mm_extract_epi16(xmm2,6);//((short *)&xmm2)[j];
llr2[5] =simde_mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1];
llr2+=6;
llr2 += 6;
}
simde_mm_empty();
simde_m_empty();
}
//----------------------------------------------------------------------------------------------
......@@ -244,11 +223,11 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
//----------------------------------------------------------------------------------------------
void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
int32_t *dl_ch_mag,
int32_t *dl_ch_magb,
int32_t *dl_ch_magr,
c16_t *dl_ch_mag,
c16_t *dl_ch_magb,
c16_t *dl_ch_magr,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
......@@ -257,7 +236,6 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
simde__m128i *rxF = (simde__m128i*)&rxdataF_comp[(symbol*nb_rb*12)];
simde__m128i *ch_mag,*ch_magb,*ch_magr;
int i,len2;
unsigned char len_mod4;
int16_t *llr2;
......@@ -268,10 +246,10 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
ch_magr = (simde__m128i *)dl_ch_magr;
len_mod4 =len&3;
len2=len>>2; // length in quad words (4 REs)
int len2 = len >> 2; // length in quad words (4 REs)
len2+=((len_mod4==0)?0:1);
for (i=0; i<len2; i++) {
for (int i = 0; i < len2; i++) {
simde__m128i xmm1 = simde_mm_abs_epi16(rxF[i]);
xmm1 = simde_mm_subs_epi16(ch_mag[i],xmm1);
simde__m128i xmm2 = simde_mm_abs_epi16(xmm1);
......@@ -317,12 +295,8 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
llr2[5] = simde_mm_extract_epi16(xmm2,7);//((short *)&xmm2)[j+1];
llr2[6] = simde_mm_extract_epi16(xmm3,6);
llr2[7] = simde_mm_extract_epi16(xmm3,7);
llr2+=8;
llr2 += 8;
}
simde_mm_empty();
simde_m_empty();
}
//==============================================================================================
......@@ -332,23 +306,6 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
//----------------------------------------------------------------------------------------------
// QPSK
//----------------------------------------------------------------------------------------------
simde__m128i y0r_over2 __attribute__ ((aligned(16)));
simde__m128i y0i_over2 __attribute__ ((aligned(16)));
simde__m128i y1r_over2 __attribute__ ((aligned(16)));
simde__m128i y1i_over2 __attribute__ ((aligned(16)));
simde__m128i A __attribute__ ((aligned(16)));
simde__m128i B __attribute__ ((aligned(16)));
simde__m128i C __attribute__ ((aligned(16)));
simde__m128i D __attribute__ ((aligned(16)));
simde__m128i E __attribute__ ((aligned(16)));
simde__m128i F __attribute__ ((aligned(16)));
simde__m128i G __attribute__ ((aligned(16)));
simde__m128i H __attribute__ ((aligned(16)));
void nr_qpsk_qpsk(short *stream0_in,
short *stream1_in,
short *stream0_out,
......@@ -373,11 +330,7 @@ void nr_qpsk_qpsk(short *stream0_in,
simde__m128i *stream1_128i_in = (simde__m128i *)stream1_in;
simde__m128i *stream0_128i_out = (simde__m128i *)stream0_out;
simde__m128i ONE_OVER_SQRT_8 =simde_mm_set1_epi16(23170); //round(2^16/sqrt(8))
int i;
for (i=0; i<length>>2; i+=2) {
for (int i = 0; i < length >> 2; i += 2) {
// in each iteration, we take 8 complex samples
simde__m128i xmm0 = rho01_128i[i]; // 4 symbols
simde__m128i xmm1 = rho01_128i[i+1];
......@@ -444,35 +397,35 @@ void nr_qpsk_qpsk(short *stream0_in,
// 1 term for numerator of LLR
xmm3 =simde_mm_subs_epi16(y1r_over2,rho_rpi);
A =simde_mm_abs_epi16(xmm3); // A = |y1r/2 - rho/sqrt(8)|
simde__m128i A = simde_mm_abs_epi16(xmm3); // A = |y1r/2 - rho/sqrt(8)|
xmm2 =simde_mm_adds_epi16(A,y0i_over2); // = |y1r/2 - rho/sqrt(8)| + y0i/2
xmm3 =simde_mm_subs_epi16(y1i_over2,rho_rmi);
B =simde_mm_abs_epi16(xmm3); // B = |y1i/2 - rho*/sqrt(8)|
simde__m128i B = simde_mm_abs_epi16(xmm3); // B = |y1i/2 - rho*/sqrt(8)|
simde__m128i logmax_num_re0 =simde_mm_adds_epi16(B,xmm2); // = |y1r/2 - rho/sqrt(8)|+|y1i/2 - rho*/sqrt(8)| + y0i/2
// 2 term for numerator of LLR
xmm3 =simde_mm_subs_epi16(y1r_over2,rho_rmi);
C =simde_mm_abs_epi16(xmm3); // C = |y1r/2 - rho*/4|
simde__m128i C = simde_mm_abs_epi16(xmm3); // C = |y1r/2 - rho*/4|
xmm2 =simde_mm_subs_epi16(C,y0i_over2); // = |y1r/2 - rho*/4| - y0i/2
xmm3 =simde_mm_adds_epi16(y1i_over2,rho_rpi);
D =simde_mm_abs_epi16(xmm3); // D = |y1i/2 + rho/4|
simde__m128i D = simde_mm_abs_epi16(xmm3); // D = |y1i/2 + rho/4|
xmm2 =simde_mm_adds_epi16(xmm2,D); // |y1r/2 - rho*/4| + |y1i/2 + rho/4| - y0i/2
logmax_num_re0 =simde_mm_max_epi16(logmax_num_re0,xmm2); // max, numerator done
// 1 term for denominator of LLR
xmm3 =simde_mm_adds_epi16(y1r_over2,rho_rmi);
E =simde_mm_abs_epi16(xmm3); // E = |y1r/2 + rho*/4|
simde__m128i E = simde_mm_abs_epi16(xmm3); // E = |y1r/2 + rho*/4|
xmm2 =simde_mm_adds_epi16(E,y0i_over2); // = |y1r/2 + rho*/4| + y0i/2
xmm3 =simde_mm_subs_epi16(y1i_over2,rho_rpi);
F =simde_mm_abs_epi16(xmm3); // F = |y1i/2 - rho/4|
simde__m128i F = simde_mm_abs_epi16(xmm3); // F = |y1i/2 - rho/4|
simde__m128i logmax_den_re0 =simde_mm_adds_epi16(F,xmm2); // = |y1r/2 + rho*/4| + |y1i/2 - rho/4| + y0i/2
// 2 term for denominator of LLR
xmm3 =simde_mm_adds_epi16(y1r_over2,rho_rpi);
G =simde_mm_abs_epi16(xmm3); // G = |y1r/2 + rho/4|
simde__m128i G = simde_mm_abs_epi16(xmm3); // G = |y1r/2 + rho/4|
xmm2 =simde_mm_subs_epi16(G,y0i_over2); // = |y1r/2 + rho/4| - y0i/2
xmm3 =simde_mm_adds_epi16(y1i_over2,rho_rmi);
H =simde_mm_abs_epi16(xmm3); // H = |y1i/2 + rho*/4|
simde__m128i H = simde_mm_abs_epi16(xmm3); // H = |y1i/2 + rho*/4|
xmm2 =simde_mm_adds_epi16(xmm2,H); // = |y1r/2 + rho/4| + |y1i/2 + rho*/4| - y0i/2
logmax_den_re0 =simde_mm_max_epi16(logmax_den_re0,xmm2); // max, denominator done
......@@ -508,8 +461,6 @@ void nr_qpsk_qpsk(short *stream0_in,
simde_mm_storeu_si128(&stream0_128i_out[i],simde_mm_unpacklo_epi16(y0r,y0i)); // = [L1(1), L2(1), L1(2), L2(2)]
if (i<((length>>1) - 1)) // false if only 2 REs remain
simde_mm_storeu_si128(&stream0_128i_out[i+1],simde_mm_unpackhi_epi16(y0r,y0i));
simde_mm_storeu_si128(&stream0_128i_out[i + 1], simde_mm_unpackhi_epi16(y0r, y0i));
}
}
......@@ -98,7 +98,7 @@ int32_t nr_dlsch_qpsk_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
@param nb_rb number of RBs for this allocation
*/
int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
uint8_t symbol,
uint32_t len,
......@@ -119,9 +119,9 @@ int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms,
*/
void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
int32_t *dl_ch_mag,
c16_t *dl_ch_mag,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
......@@ -142,21 +142,21 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms,
*/
void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
int32_t *dl_ch_mag,
int32_t *dl_ch_magb,
c16_t *dl_ch_mag,
c16_t *dl_ch_magb,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
uint16_t nb_rb);
void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF_comp,
c16_t *rxdataF_comp,
int16_t *dlsch_llr,
int32_t *dl_ch_mag,
int32_t *dl_ch_magb,
int32_t *dl_ch_magr,
c16_t *dl_ch_mag,
c16_t *dl_ch_magb,
c16_t *dl_ch_magr,
uint8_t symbol,
uint32_t len,
uint8_t first_symbol_flag,
......@@ -169,11 +169,7 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
uint16_t *llr_deint,
uint16_t nb_rb_pdsch);
void nr_conjch0_mult_ch1(int *ch0,
int *ch1,
int32_t *ch0conj_ch1,
unsigned short nb_rb,
unsigned char output_shift0);
void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0);
/** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several
threads (on multi-core machines) corresponding to different HARQ processes. The routine first
......@@ -409,7 +405,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
bool first_symbol_flag,
unsigned char harq_pid,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size],
c16_t dl_ch_estimates[][pdsch_est_size],
int16_t *llr[2],
uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
......@@ -417,7 +413,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
int32_t *log2_maxh,
int rx_size_symbol,
int nbRx,
int32_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t rxdataF_comp[][nbRx][rx_size_symbol * NR_SYMBOLS_PER_SLOT],
c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
int G,
......
......@@ -123,7 +123,7 @@ typedef struct {
typedef struct {
uint8_t csi_rs_generated_signal_bits;
int32_t **csi_rs_generated_signal;
c16_t **csi_rs_generated_signal;
bool csi_im_meas_computed;
uint32_t interference_plus_noise_power;
} nr_csi_info_t;
......
......@@ -220,7 +220,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
nr_generate_csi_rs(&gNB->frame_parms,
(int32_t **)gNB->common_vars.txdataF,
gNB->common_vars.txdataF,
gNB->TX_AMP,
gNB->nr_csi_info,
csi_params,
......
......@@ -303,7 +303,7 @@ void nr_ue_measurement_procedures(uint16_t l,
const UE_nr_rxtx_proc_t *proc,
NR_UE_DLSCH_t *dlsch,
uint32_t pdsch_est_size,
int32_t dl_ch_estimates[][pdsch_est_size])
c16_t dl_ch_estimates[][pdsch_est_size])
{
NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
int nr_slot_rx = proc->nr_slot_rx;
......@@ -357,7 +357,7 @@ void nr_ue_measurement_procedures(uint16_t l,
static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc,
int estimateSz,
struct complex16 dl_ch_estimates[][estimateSz],
c16_t dl_ch_estimates[][estimateSz],
c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
{
int ret = 0;
......@@ -507,8 +507,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
dlsch0->Nl);
const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot * ue->frame_parms.ofdm_symbol_size + 15) / 16) * 16;
__attribute__((aligned(32))) int32_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx * dlsch0->Nl][pdsch_est_size];
memset(pdsch_dl_ch_estimates, 0, sizeof(int32_t) * ue->frame_parms.nb_antennas_rx * dlsch0->Nl * pdsch_est_size);
__attribute__((aligned(32))) c16_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx * dlsch0->Nl][pdsch_est_size];
memset(pdsch_dl_ch_estimates, 0, sizeof(pdsch_dl_ch_estimates));
c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT];
memset(ptrs_phase_per_slot, 0, sizeof(ptrs_phase_per_slot));
......@@ -517,7 +517,8 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
memset(ptrs_re_per_slot, 0, sizeof(ptrs_re_per_slot));
const uint32_t rx_size_symbol = dlsch[0].dlsch_config.number_rbs * NR_NB_SC_PER_RB;
__attribute__((aligned(32))) int32_t rxdataF_comp[dlsch[0].Nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT];
__attribute__((
aligned(32))) c16_t rxdataF_comp[dlsch[0].Nl][ue->frame_parms.nb_antennas_rx][rx_size_symbol * NR_SYMBOLS_PER_SLOT];
memset(rxdataF_comp, 0, sizeof(rxdataF_comp));
uint32_t nvar = 0;
......
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