Commit 6c590b90 authored by Roberto Louro Magueta's avatar Roberto Louro Magueta

Compute noise variance to be used in MMSE

parent 4b263c3f
...@@ -120,7 +120,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -120,7 +120,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int ul_id, int ul_id,
unsigned short bwp_start_subcarrier, unsigned short bwp_start_subcarrier,
nfapi_nr_pusch_pdu_t *pusch_pdu, nfapi_nr_pusch_pdu_t *pusch_pdu,
int *max_ch) { int *max_ch,
uint32_t *nvar) {
c16_t pilot[3280] __attribute__((aligned(32))); c16_t pilot[3280] __attribute__((aligned(32)));
const int chest_freq = gNB->chest_freq; const int chest_freq = gNB->chest_freq;
...@@ -186,6 +187,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -186,6 +187,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#endif #endif
int nest_count = 0;
uint64_t noise_amp2 = 0;
c16_t ul_ls_est[symbolSize] __attribute__((aligned(32))); c16_t ul_ls_est[symbolSize] __attribute__((aligned(32)));
memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize); memset(ul_ls_est, 0, sizeof(c16_t) * symbolSize);
NR_ULSCH_delay_t *delay = &gNB->ulsch[ul_id].delay; NR_ULSCH_delay_t *delay = &gNB->ulsch[ul_id].delay;
...@@ -284,12 +287,16 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -284,12 +287,16 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int k = pilot_cnt << 1; int k = pilot_cnt << 1;
ul_ch[k] = c16mulShift(ul_ch[k], ul_inv_delay_table[k], 8); ul_ch[k] = c16mulShift(ul_ch[k], ul_inv_delay_table[k], 8);
ul_ch[k + 1] = c16mulShift(ul_ch[k + 1], ul_inv_delay_table[k + 1], 8); ul_ch[k + 1] = c16mulShift(ul_ch[k + 1], ul_inv_delay_table[k + 1], 8);
noise_amp2 += c16amp2(c16sub(ul_ls_est[k], ul_ch[k]));
noise_amp2 += c16amp2(c16sub(ul_ls_est[k + 1], ul_ch[k + 1]));
#ifdef DEBUG_PUSCH #ifdef DEBUG_PUSCH
re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize; re_offset = (k0 + (n << 2) + (k_line << 1)) % symbolSize;
c16_t *rxF = &rxdataF[soffset + re_offset]; c16_t *rxF = &rxdataF[soffset + re_offset];
printf("ch -> (%4d,%4d), ch_inter -> (%4d,%4d)\n", ul_ls_est[k].r, ul_ls_est[k].i, ul_ch[k].r, ul_ch[k].i); printf("ch -> (%4d,%4d), ch_inter -> (%4d,%4d)\n", ul_ls_est[k].r, ul_ls_est[k].i, ul_ch[k].r, ul_ch[k].i);
#endif #endif
pilot_cnt++; pilot_cnt++;
nest_count += 2;
} }
} }
...@@ -307,6 +314,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -307,6 +314,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
multadd_real_four_symbols_vector_complex_scalar(filt8_rep4, &ch, &ul_ls_est[n]); multadd_real_four_symbols_vector_complex_scalar(filt8_rep4, &ch, &ul_ls_est[n]);
ul_ls_est[n + 4] = ch; ul_ls_est[n + 4] = ch;
ul_ls_est[n + 5] = ch; ul_ls_est[n + 5] = ch;
noise_amp2 += c16amp2(c16sub(ch0, ch));
nest_count++;
} }
// Delay compensation // Delay compensation
...@@ -501,7 +510,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -501,7 +510,12 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
#ifdef DEBUG_CH #ifdef DEBUG_CH
fclose(debug_ch_est); fclose(debug_ch_est);
#endif #endif
return(0);
if (nvar && nest_count > 0) {
*nvar = (uint32_t)(noise_amp2 / nest_count);
}
return 0;
} }
......
...@@ -47,7 +47,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, ...@@ -47,7 +47,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int ul_id, int ul_id,
unsigned short bwp_start_subcarrier, unsigned short bwp_start_subcarrier,
nfapi_nr_pusch_pdu_t *pusch_pdu, nfapi_nr_pusch_pdu_t *pusch_pdu,
int *max_ch); int *max_ch,
uint32_t *nvar);
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
......
...@@ -1482,7 +1482,7 @@ uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms, ...@@ -1482,7 +1482,7 @@ uint8_t nr_ulsch_mmse_2layers(NR_DL_FRAME_PARMS *frame_parms,
int shift, int shift,
unsigned char symbol, unsigned char symbol,
int length, int length,
int noise_var) uint32_t noise_var)
{ {
int *ch00, *ch01, *ch10, *ch11; int *ch00, *ch01, *ch10, *ch11;
int *ch20, *ch30, *ch21, *ch31; int *ch20, *ch30, *ch21, *ch31;
...@@ -1881,6 +1881,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -1881,6 +1881,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
//---------------------------------------------------------- //----------------------------------------------------------
start_meas(&gNB->ulsch_channel_estimation_stats); start_meas(&gNB->ulsch_channel_estimation_stats);
int max_ch = 0; int max_ch = 0;
uint32_t nvar = 0;
for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) { for(uint8_t symbol = rel15_ul->start_symbol_index; symbol < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); symbol++) {
uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01; uint8_t dmrs_symbol_flag = (rel15_ul->ul_dmrs_symb_pos >> symbol) & 0x01;
LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag); LOG_D(PHY, "symbol %d, dmrs_symbol_flag :%d\n", symbol, dmrs_symbol_flag);
...@@ -1890,7 +1891,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -1890,7 +1891,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
pusch_vars->dmrs_symbol = symbol; pusch_vars->dmrs_symbol = symbol;
for (int nl=0; nl<rel15_ul->nrOfLayers; nl++) { for (int nl=0; nl<rel15_ul->nrOfLayers; nl++) {
uint32_t nvar_tmp = 0;
nr_pusch_channel_estimation(gNB, nr_pusch_channel_estimation(gNB,
slot, slot,
get_dmrs_port(nl,rel15_ul->dmrs_ports), get_dmrs_port(nl,rel15_ul->dmrs_ports),
...@@ -1898,7 +1899,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -1898,7 +1899,9 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
ulsch_id, ulsch_id,
bwp_start_subcarrier, bwp_start_subcarrier,
rel15_ul, rel15_ul,
&max_ch); &max_ch,
&nvar_tmp);
nvar += nvar_tmp;
} }
nr_gnb_measurements(gNB, ulsch, pusch_vars, symbol, rel15_ul->nrOfLayers); nr_gnb_measurements(gNB, ulsch, pusch_vars, symbol, rel15_ul->nrOfLayers);
...@@ -1929,6 +1932,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -1929,6 +1932,8 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
} }
} }
nvar /= (rel15_ul->nr_of_symbols * rel15_ul->nrOfLayers * frame_parms->nb_antennas_rx);
if (gNB->chest_time == 1) { // averaging time domain channel estimates if (gNB->chest_time == 1) { // averaging time domain channel estimates
nr_chest_time_domain_avg(frame_parms, nr_chest_time_domain_avg(frame_parms,
pusch_vars->ul_ch_estimates, pusch_vars->ul_ch_estimates,
...@@ -2055,7 +2060,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -2055,7 +2060,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
// Apply MMSE for 2 Tx layers // Apply MMSE for 2 Tx layers
if (rel15_ul->nrOfLayers == 2) { if (rel15_ul->nrOfLayers == 2) {
int noise_var = 100; // TODO: Get noise variance
nr_ulsch_mmse_2layers(frame_parms, nr_ulsch_mmse_2layers(frame_parms,
pusch_vars->rxdataF_comp, pusch_vars->rxdataF_comp,
pusch_vars->ul_ch_mag0, pusch_vars->ul_ch_mag0,
...@@ -2067,7 +2071,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, ...@@ -2067,7 +2071,7 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB,
pusch_vars->log2_maxh, pusch_vars->log2_maxh,
symbol, symbol,
nb_re_pusch, nb_re_pusch,
noise_var); nvar);
} }
stop_meas(&gNB->ulsch_mrc_stats); stop_meas(&gNB->ulsch_mrc_stats);
......
...@@ -97,6 +97,17 @@ extern "C" { ...@@ -97,6 +97,17 @@ extern "C" {
#define squaredMod(a) ((a).r*(a).r + (a).i*(a).i) #define squaredMod(a) ((a).r*(a).r + (a).i*(a).i)
#define csum(res, i1, i2) (res).r = (i1).r + (i2).r ; (res).i = (i1).i + (i2).i #define csum(res, i1, i2) (res).r = (i1).r + (i2).r ; (res).i = (i1).i + (i2).i
__attribute__((always_inline)) inline uint32_t c16amp2(const c16_t a) {
return a.r * a.r + a.i * a.i;
}
__attribute__((always_inline)) inline c16_t c16sub(const c16_t a, const c16_t b) {
return (c16_t) {
.r = (int16_t) (a.r - b.r),
.i = (int16_t) (a.i - b.i)
};
}
__attribute__((always_inline)) inline c16_t c16Shift(const c16_t a, const int Shift) { __attribute__((always_inline)) inline c16_t c16Shift(const c16_t a, const int Shift) {
return (c16_t) { return (c16_t) {
.r = (int16_t)(a.r >> Shift), .r = (int16_t)(a.r >> Shift),
......
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