Compute TPMI based on SRS for 2 layers
This commit is contained in:
@@ -386,6 +386,39 @@ const char table_38211_6_3_1_5_3[28][4][1] = {
|
|||||||
{{'1'}, {'o'}, {'o'}, {'n'}} // tpmi 27
|
{{'1'}, {'o'}, {'o'}, {'n'}} // tpmi 27
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TS 38.211 - Table 6.3.1.5-4: Precoding matrix W for two-layer transmission using two antenna ports, 'n' = -1 and 'o' = -j
|
||||||
|
const char table_38211_6_3_1_5_4[3][2][2] = {
|
||||||
|
{{'1', '0'}, {'0', '1'}}, // tpmi 0
|
||||||
|
{{'1', '1'}, {'1', 'n'}}, // tpmi 1
|
||||||
|
{{'1', '1'}, {'j', 'o'}} // tpmi 2
|
||||||
|
};
|
||||||
|
|
||||||
|
// TS 38.211 - Table 6.3.1.5-5: Precoding matrix W for two-layer transmission using four antenna ports, 'n' = -1 and 'o' = -j
|
||||||
|
const char table_38211_6_3_1_5_5[22][4][2] = {
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'0', '0'}, {'0', '0'}}, // tpmi 0
|
||||||
|
{{'1', '0'}, {'0', '0'}, {'0', '1'}, {'0', '0'}}, // tpmi 1
|
||||||
|
{{'1', '0'}, {'0', '0'}, {'0', '0'}, {'0', '1'}}, // tpmi 2
|
||||||
|
{{'0', '0'}, {'1', '0'}, {'0', '1'}, {'0', '0'}}, // tpmi 3
|
||||||
|
{{'0', '0'}, {'1', '0'}, {'0', '0'}, {'0', '1'}}, // tpmi 4
|
||||||
|
{{'0', '0'}, {'0', '0'}, {'1', '0'}, {'0', '1'}}, // tpmi 5
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'o'}}, // tpmi 6
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'1', '0'}, {'0', 'j'}}, // tpmi 7
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', '1'}}, // tpmi 8
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'o', '0'}, {'0', 'n'}}, // tpmi 9
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'o'}}, // tpmi 10
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'n', '0'}, {'0', 'j'}}, // tpmi 11
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', '1'}}, // tpmi 12
|
||||||
|
{{'1', '0'}, {'0', '1'}, {'j', '0'}, {'0', 'n'}}, // tpmi 13
|
||||||
|
{{'1', '1'}, {'1', '1'}, {'1', 'n'}, {'1', 'n'}}, // tpmi 14
|
||||||
|
{{'1', '1'}, {'1', '1'}, {'j', 'o'}, {'j', 'o'}}, // tpmi 15
|
||||||
|
{{'1', '1'}, {'j', 'j'}, {'1', 'n'}, {'j', 'o'}}, // tpmi 16
|
||||||
|
{{'1', '1'}, {'j', 'j'}, {'j', 'o'}, {'n', '1'}}, // tpmi 17
|
||||||
|
{{'1', '1'}, {'n', 'n'}, {'1', 'n'}, {'n', '1'}}, // tpmi 18
|
||||||
|
{{'1', '1'}, {'n', 'n'}, {'j', 'o'}, {'o', 'j'}}, // tpmi 19
|
||||||
|
{{'1', '1'}, {'o', 'o'}, {'1', 'n'}, {'o', 'j'}}, // tpmi 20
|
||||||
|
{{'1', '1'}, {'o', 'o'}, {'j', 'o'}, {'1', 'n'}} // tpmi 21
|
||||||
|
};
|
||||||
|
|
||||||
void get_info_from_tda_tables(int default_abc,
|
void get_info_from_tda_tables(int default_abc,
|
||||||
int tda,
|
int tda,
|
||||||
int dmrs_TypeA_Position,
|
int dmrs_TypeA_Position,
|
||||||
|
|||||||
@@ -146,4 +146,6 @@ extern const int32_t table_38213_10_1_1_c2[5];
|
|||||||
extern const char table_38211_6_3_1_5_1[6][2][1];
|
extern const char table_38211_6_3_1_5_1[6][2][1];
|
||||||
extern const char table_38211_6_3_1_5_2[28][4][1];
|
extern const char table_38211_6_3_1_5_2[28][4][1];
|
||||||
extern const char table_38211_6_3_1_5_3[28][4][1];
|
extern const char table_38211_6_3_1_5_3[28][4][1];
|
||||||
|
extern const char table_38211_6_3_1_5_4[3][2][2];
|
||||||
|
extern const char table_38211_6_3_1_5_5[22][4][2];
|
||||||
#endif //DEF_H
|
#endif //DEF_H
|
||||||
|
|||||||
@@ -1033,19 +1033,27 @@ void get_precoder_matrix_coef(char *w,
|
|||||||
const uint16_t num_ue_srs_ports,
|
const uint16_t num_ue_srs_ports,
|
||||||
const uint8_t transform_precoding,
|
const uint8_t transform_precoding,
|
||||||
const uint8_t tpmi,
|
const uint8_t tpmi,
|
||||||
const uint8_t uI) {
|
const uint8_t uI,
|
||||||
|
int layer_idx)
|
||||||
|
{
|
||||||
if (ul_ri == 0) {
|
if (ul_ri == 0) {
|
||||||
if (num_ue_srs_ports == 2) {
|
if (num_ue_srs_ports == 2) {
|
||||||
*w = *table_38211_6_3_1_5_1[tpmi][uI];
|
*w = table_38211_6_3_1_5_1[tpmi][uI][layer_idx];
|
||||||
} else {
|
} else {
|
||||||
if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) {
|
if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled) {
|
||||||
*w = *table_38211_6_3_1_5_2[tpmi][uI];
|
*w = table_38211_6_3_1_5_2[tpmi][uI][layer_idx];
|
||||||
} else {
|
} else {
|
||||||
*w = *table_38211_6_3_1_5_3[tpmi][uI];
|
*w = table_38211_6_3_1_5_3[tpmi][uI][layer_idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ul_ri == 1) {
|
||||||
|
if (num_ue_srs_ports == 2) {
|
||||||
|
*w = table_38211_6_3_1_5_4[tpmi][uI][layer_idx];
|
||||||
|
} else {
|
||||||
|
*w = table_38211_6_3_1_5_5[tpmi][uI][layer_idx];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
AssertFatal(1==0,"Function get_precoder_matrix_coef() does not support %i layers yet!\n", ul_ri+1);
|
AssertFatal(1 == 0, "Function get_precoder_matrix_coef() does not support %i layers yet!\n", ul_ri + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1058,20 +1066,21 @@ int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config,
|
|||||||
const uint16_t prg_size,
|
const uint16_t prg_size,
|
||||||
const uint16_t num_prgs,
|
const uint16_t num_prgs,
|
||||||
const uint8_t ul_ri) {
|
const uint8_t ul_ri) {
|
||||||
|
if (ul_ri > 1) {
|
||||||
|
LOG_D(NR_MAC, "TPMI computation for ul_ri %i is not implemented yet!\n", ul_ri);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t tpmi_sel = 0;
|
uint8_t tpmi_sel = 0;
|
||||||
int16_t precoded_channel_matrix_re[num_prgs*num_gnb_antenna_elements];
|
const uint8_t nrOfLayers = ul_ri + 1;
|
||||||
int16_t precoded_channel_matrix_im[num_prgs*num_gnb_antenna_elements];
|
int16_t precoded_channel_matrix_re[num_prgs * num_gnb_antenna_elements];
|
||||||
c16_t *channel_matrix16 = (c16_t*)channel_matrix;
|
int16_t precoded_channel_matrix_im[num_prgs * num_gnb_antenna_elements];
|
||||||
|
c16_t *channel_matrix16 = (c16_t *)channel_matrix;
|
||||||
uint32_t max_precoded_signal_power = 0;
|
uint32_t max_precoded_signal_power = 0;
|
||||||
int additional_max_tpmi = -1;
|
int additional_max_tpmi = -1;
|
||||||
char w;
|
char w;
|
||||||
|
|
||||||
uint8_t max_tpmi = get_max_tpmi(pusch_Config,
|
uint8_t max_tpmi = get_max_tpmi(pusch_Config, num_ue_srs_ports, &nrOfLayers, &additional_max_tpmi);
|
||||||
num_ue_srs_ports,
|
|
||||||
&ul_ri,
|
|
||||||
&additional_max_tpmi);
|
|
||||||
|
|
||||||
uint8_t end_tpmi_loop = additional_max_tpmi > max_tpmi ? additional_max_tpmi : max_tpmi;
|
uint8_t end_tpmi_loop = additional_max_tpmi > max_tpmi ? additional_max_tpmi : max_tpmi;
|
||||||
|
|
||||||
// channel_matrix x precoder_matrix
|
// channel_matrix x precoder_matrix
|
||||||
@@ -1080,44 +1089,43 @@ int nr_srs_tpmi_estimation(const NR_PUSCH_Config_t *pusch_Config,
|
|||||||
// [ (gI=2,uI=0) (gI=2,uI=1) ... (gI=2,uI=num_ue_srs_ports-1) ] [uI=2]
|
// [ (gI=2,uI=0) (gI=2,uI=1) ... (gI=2,uI=num_ue_srs_ports-1) ] [uI=2]
|
||||||
// ... ...
|
// ... ...
|
||||||
|
|
||||||
for(uint8_t tpmi = 0; tpmi<=end_tpmi_loop; tpmi++) {
|
for (uint8_t tpmi = 0; tpmi <= end_tpmi_loop && end_tpmi_loop > 0; tpmi++) {
|
||||||
|
|
||||||
if (tpmi > max_tpmi) {
|
if (tpmi > max_tpmi) {
|
||||||
tpmi = end_tpmi_loop;
|
tpmi = end_tpmi_loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int pI = 0; pI <num_prgs; pI++) {
|
for (int pI = 0; pI < num_prgs; pI++) {
|
||||||
for(int gI = 0; gI < num_gnb_antenna_elements; gI++) {
|
for (int gI = 0; gI < num_gnb_antenna_elements; gI++) {
|
||||||
|
uint16_t index_gI_pI = gI * num_prgs + pI;
|
||||||
uint16_t index_gI_pI = gI*num_prgs + pI;
|
|
||||||
precoded_channel_matrix_re[index_gI_pI] = 0;
|
precoded_channel_matrix_re[index_gI_pI] = 0;
|
||||||
precoded_channel_matrix_im[index_gI_pI] = 0;
|
precoded_channel_matrix_im[index_gI_pI] = 0;
|
||||||
|
|
||||||
for(int uI = 0; uI < num_ue_srs_ports; uI++) {
|
for (int uI = 0; uI < num_ue_srs_ports; uI++) {
|
||||||
|
for (int layer_idx = 0; layer_idx < nrOfLayers; layer_idx++) {
|
||||||
|
uint16_t index = uI * num_gnb_antenna_elements * num_prgs + index_gI_pI;
|
||||||
|
get_precoder_matrix_coef(&w, ul_ri, num_ue_srs_ports, transform_precoding, tpmi, uI, layer_idx);
|
||||||
|
c16_t h_times_w = nr_h_times_w(channel_matrix16[index], w);
|
||||||
|
|
||||||
uint16_t index = uI*num_gnb_antenna_elements*num_prgs + index_gI_pI;
|
precoded_channel_matrix_re[index_gI_pI] += h_times_w.r;
|
||||||
get_precoder_matrix_coef(&w, ul_ri, num_ue_srs_ports, transform_precoding, tpmi, uI);
|
precoded_channel_matrix_im[index_gI_pI] += h_times_w.i;
|
||||||
c16_t h_times_w = nr_h_times_w(channel_matrix16[index], w);
|
|
||||||
|
|
||||||
precoded_channel_matrix_re[index_gI_pI] += h_times_w.r;
|
|
||||||
precoded_channel_matrix_im[index_gI_pI] += h_times_w.i;
|
|
||||||
|
|
||||||
#ifdef SRS_IND_DEBUG
|
#ifdef SRS_IND_DEBUG
|
||||||
LOG_I(NR_MAC, "(uI %i, gI %i, pI %i) channel_matrix --> real %i, imag %i\n",
|
LOG_I(NR_MAC, "(pI %i, gI %i, uI %i, layer_idx %i) w = %c, channel_matrix --> real %i, imag %i\n",
|
||||||
uI, gI, pI, channel_matrix16[index].r, channel_matrix16[index].i);
|
pI, gI, uI, layer_idx, w, channel_matrix16[index].r, channel_matrix16[index].i);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SRS_IND_DEBUG
|
#ifdef SRS_IND_DEBUG
|
||||||
LOG_I(NR_MAC, "(gI %i, pI %i) precoded_channel_coef --> real %i, imag %i\n",
|
LOG_I(NR_MAC, "(pI %i, gI %i) precoded_channel_coef --> real %i, imag %i\n",
|
||||||
gI, pI, precoded_channel_matrix_re[index_gI_pI], precoded_channel_matrix_im[index_gI_pI]);
|
pI, gI, precoded_channel_matrix_re[index_gI_pI], precoded_channel_matrix_im[index_gI_pI]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t precoded_signal_power = calc_power_complex(precoded_channel_matrix_re,
|
uint32_t precoded_signal_power = calc_power_complex(precoded_channel_matrix_re,
|
||||||
precoded_channel_matrix_im,
|
precoded_channel_matrix_im,
|
||||||
num_prgs*num_gnb_antenna_elements);
|
num_prgs * num_gnb_antenna_elements);
|
||||||
|
|
||||||
#ifdef SRS_IND_DEBUG
|
#ifdef SRS_IND_DEBUG
|
||||||
LOG_I(NR_MAC, "(tpmi %i) precoded_signal_power = %i\n", tpmi, precoded_signal_power);
|
LOG_I(NR_MAC, "(tpmi %i) precoded_signal_power = %i\n", tpmi, precoded_signal_power);
|
||||||
@@ -1198,7 +1206,7 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
|||||||
const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold;
|
const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold;
|
||||||
uint16_t *ulprbbl = nr_mac->ulprbbl;
|
uint16_t *ulprbbl = nr_mac->ulprbbl;
|
||||||
|
|
||||||
uint8_t num_rbs = nr_srs_beamforming_report.prg_size * nr_srs_beamforming_report.prgs[0].num_prgs;
|
uint16_t num_rbs = nr_srs_beamforming_report.prg_size * nr_srs_beamforming_report.prgs[0].num_prgs;
|
||||||
memset(ulprbbl, 0, num_rbs * sizeof(uint16_t));
|
memset(ulprbbl, 0, num_rbs * sizeof(uint16_t));
|
||||||
for (int rb = 0; rb < num_rbs; rb++) {
|
for (int rb = 0; rb < num_rbs; rb++) {
|
||||||
int snr = (nr_srs_beamforming_report.prgs[0].prg_list[rb / nr_srs_beamforming_report.prg_size].rb_snr >> 1) - 64;
|
int snr = (nr_srs_beamforming_report.prgs[0].prg_list[rb / nr_srs_beamforming_report.prg_size].rb_snr >> 1) - 64;
|
||||||
@@ -1242,11 +1250,12 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: This should be improved
|
|
||||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||||
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
|
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
|
||||||
sched_ctrl->srs_feedback.sri = NR_SRS_SRI_0;
|
sched_ctrl->srs_feedback.sri = NR_SRS_SRI_0;
|
||||||
sched_ctrl->srs_feedback.ul_ri = 0; // TODO: Compute this
|
|
||||||
|
nr_srs_ri_computation(&nr_srs_normalized_channel_iq_matrix, current_BWP, &sched_ctrl->srs_feedback.ul_ri);
|
||||||
|
|
||||||
sched_ctrl->srs_feedback.tpmi = nr_srs_tpmi_estimation(current_BWP->pusch_Config,
|
sched_ctrl->srs_feedback.tpmi = nr_srs_tpmi_estimation(current_BWP->pusch_Config,
|
||||||
current_BWP->transform_precoding,
|
current_BWP->transform_precoding,
|
||||||
nr_srs_normalized_channel_iq_matrix.channel_matrix,
|
nr_srs_normalized_channel_iq_matrix.channel_matrix,
|
||||||
@@ -1256,7 +1265,9 @@ void handle_nr_srs_measurements(const module_id_t module_id,
|
|||||||
nr_srs_normalized_channel_iq_matrix.prg_size,
|
nr_srs_normalized_channel_iq_matrix.prg_size,
|
||||||
nr_srs_normalized_channel_iq_matrix.num_prgs,
|
nr_srs_normalized_channel_iq_matrix.num_prgs,
|
||||||
sched_ctrl->srs_feedback.ul_ri);
|
sched_ctrl->srs_feedback.ul_ri);
|
||||||
|
|
||||||
sprintf(stats->srs_stats, "UL-RI %d, TPMI %d", sched_ctrl->srs_feedback.ul_ri + 1, sched_ctrl->srs_feedback.tpmi);
|
sprintf(stats->srs_stats, "UL-RI %d, TPMI %d", sched_ctrl->srs_feedback.ul_ri + 1, sched_ctrl->srs_feedback.tpmi);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1525,7 +1536,6 @@ static int comparator(const void *p, const void *q) {
|
|||||||
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
|
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pf_ul(module_id_t module_id,
|
void pf_ul(module_id_t module_id,
|
||||||
frame_t frame,
|
frame_t frame,
|
||||||
sub_frame_t slot,
|
sub_frame_t slot,
|
||||||
|
|||||||
Reference in New Issue
Block a user