Commit ec858d17 authored by Roberto Louro Magueta's avatar Roberto Louro Magueta

Compute TPMI based on SRS for 2 layers

parent 65bd9372
...@@ -386,6 +386,39 @@ const char table_38211_6_3_1_5_3[28][4][1] = { ...@@ -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]; ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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; 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); 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); 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_re[index_gI_pI] += h_times_w.r;
precoded_channel_matrix_im[index_gI_pI] += h_times_w.i; 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, ...@@ -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, ...@@ -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, ...@@ -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) { ...@@ -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,
...@@ -1690,7 +1700,7 @@ void pf_ul(module_id_t module_id, ...@@ -1690,7 +1700,7 @@ void pf_ul(module_id_t module_id,
qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator); qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
UEsched_t *iterator=UE_sched; UEsched_t *iterator=UE_sched;
/* Loop UE_sched to find max coeff and allocate transmission */ /* Loop UE_sched to find max coeff and allocate transmission */
while (remainUEs> 0 && n_rb_sched >= min_rb && iterator->UE != NULL) { while (remainUEs> 0 && n_rb_sched >= min_rb && iterator->UE != NULL) {
......
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