Compute noise variance to be used in MMSE
This commit is contained in:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user