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