@@ -153,6 +153,7 @@ static unsigned extract_layer_hop_rx_pilots(dmrs_symbol_list&
153153// / \param[out] pilot_products Helper buffer for internal computations (same size as pilots_lse).
154154// / \param[in] rx_pilots Received pilots.
155155// / \param[in] pilots Transmitted pilots.
156+ // / \param[in] dmrs_mask Boolean mask identifying the OFDM symbols carrying DM-RS within the slot.
156157// / \param[in] scs Subcarrier spacing.
157158// / \param[in] cp_cum_duration Cumulative duration of all CPs in the slot.
158159// / \param[in] first_hop_symbol Index of the first OFDM symbol of the current hop, within the slot.
@@ -174,22 +175,34 @@ static std::pair<float, optional<float>> preprocess_pilots_and_cfo(span<cf_t>
174175 unsigned i_layer);
175176
176177// / \brief Estimates the noise energy of one hop.
177- // / \param[in] pilots DM-RS pilots.
178- // / \param[in] rx_pilots Received samples corresponding to DM-RS pilots.
179- // / \param[in] estimates Estimated channel frequency response.
180- // / \param[in] beta DM-RS-to-data amplitude gain (linear scale).
181- // / \param[in] hop_symbols Number of OFDM symbols containing DM-RS pilots in the current hop.
182- // / \param[in] hop_offset Number of OFDM symbols containing DM-RS pilots in the previous hop (set to 0 if the current
183- // / hop is the first/only one).
184- // / \param[in] i_layer Index of the selected layer.
178+ // / \param[in] pilots DM-RS pilots.
179+ // / \param[in] rx_pilots Received samples corresponding to DM-RS pilots.
180+ // / \param[in] estimates Estimated channel frequency response.
181+ // / \param[in] beta DM-RS-to-data amplitude gain (linear scale).
182+ // / \param[in] dmrs_mask Boolean mask identifying the OFDM symbols carrying DM-RS within the slot.
183+ // / \param[in] scs Subcarrier spacing.
184+ // / \param[in] cfo Carrier frequency offset.
185+ // / \param[in] cp_cum_duration Cumulative duration of all CPs in the slot.
186+ // / \param[in] first_hop_symbol Index of the first OFDM symbol of the current hop, within the slot.
187+ // / \param[in] last_hop_symbol Index of the last OFDM symbol of the current hop (not included), within the slot.
188+ // / \param[in] hop_symbols Number of OFDM symbols containing DM-RS pilots in the current hop.
189+ // / \param[in] hop_offset Number of OFDM symbols containing DM-RS pilots in the previous hop (set to 0 if the
190+ // / current hop is the first/only one).
191+ // / \param[in] i_layer Index of the selected layer.
185192// / \return The noise energy for the current hop.
186- static float estimate_noise (const dmrs_symbol_list& pilots,
187- const dmrs_symbol_list& rx_pilots,
188- span<const cf_t > estimates,
189- float beta,
190- unsigned hop_symbols,
191- unsigned hop_offset,
192- unsigned i_layer);
193+ static float estimate_noise (const dmrs_symbol_list& pilots,
194+ const dmrs_symbol_list& rx_pilots,
195+ span<const cf_t > estimates,
196+ float beta,
197+ const bounded_bitset<MAX_NSYMB_PER_SLOT>& dmrs_mask,
198+ const subcarrier_spacing& scs,
199+ optional<float > cfo,
200+ span<const float > cp_cum_duration,
201+ unsigned first_hop_symbol,
202+ unsigned last_hop_symbol,
203+ unsigned hop_symbols,
204+ unsigned hop_offset,
205+ unsigned i_layer);
193206
194207// / \brief Estimates the time alignment based on one hop.
195208// /
@@ -336,13 +349,12 @@ void port_channel_estimator_average_impl::compute_layer_hop(srsran::channel_esti
336349 hop_offset,
337350 i_layer);
338351 epre += hop_results.first ;
339-
340- if (hop_results.second .has_value ()) {
341- float cfo_hop = hop_results.second .value ();
352+ optional<float > cfo_hop = hop_results.second ;
353+ if (cfo_hop.has_value ()) {
342354 if (cfo_normalized.has_value ()) {
343- cfo_normalized = (cfo_normalized.value () + cfo_hop) / 2 ;
355+ cfo_normalized = (cfo_normalized.value () + cfo_hop. value () ) / 2 ;
344356 } else {
345- cfo_normalized = cfo_hop;
357+ cfo_normalized = cfo_hop. value () ;
346358 }
347359 }
348360
@@ -373,8 +385,19 @@ void port_channel_estimator_average_impl::compute_layer_hop(srsran::channel_esti
373385 rsrp += std::real (srsvec::dot_prod (filtered_pilots_lse, filtered_pilots_lse)) * beta_scaling * beta_scaling *
374386 static_cast <float >(nof_dmrs_symbols);
375387
376- noise_var +=
377- estimate_noise (pilots, rx_pilots, filtered_pilots_lse, beta_scaling, nof_dmrs_symbols, hop_offset, i_layer);
388+ noise_var += estimate_noise (pilots,
389+ rx_pilots,
390+ filtered_pilots_lse,
391+ beta_scaling,
392+ pattern.symbols ,
393+ cfg.scs ,
394+ cfo_hop,
395+ cp_cum_duration,
396+ first_symbol,
397+ last_symbol,
398+ nof_dmrs_symbols,
399+ hop_offset,
400+ i_layer);
378401
379402 time_alignment_s += estimate_time_alignment (filtered_pilots_lse, pattern, hop, cfg.scs , *ta_estimator);
380403
@@ -502,7 +525,7 @@ static std::pair<float, optional<float>> preprocess_pilots_and_cfo(span<cf_t>
502525 pilot_products, std::polar (1 .0f , -TWOPI * (i_symbol + cp_cum_duration[i_symbol]) * cfo), pilot_products);
503526 srsvec::add (pilots_lse, pilot_products, pilots_lse);
504527 epre += std::real (srsvec::dot_prod (rx_pilots.get_symbol (i_dmrs, i_layer), rx_pilots.get_symbol (i_dmrs, i_layer)));
505- i_dmrs++ ;
528+ ++i_dmrs ;
506529 };
507530
508531 dmrs_mask.for_each (i_dmrs_1 + 1 , last_hop_symbol, combine_pilots);
@@ -511,13 +534,19 @@ static std::pair<float, optional<float>> preprocess_pilots_and_cfo(span<cf_t>
511534 return {epre, cfo};
512535}
513536
514- static float estimate_noise (const dmrs_symbol_list& pilots,
515- const dmrs_symbol_list& rx_pilots,
516- span<const cf_t > estimates,
517- float beta,
518- unsigned hop_symbols,
519- unsigned hop_offset,
520- unsigned i_layer)
537+ static float estimate_noise (const dmrs_symbol_list& pilots,
538+ const dmrs_symbol_list& rx_pilots,
539+ span<const cf_t > estimates,
540+ float beta,
541+ const bounded_bitset<MAX_NSYMB_PER_SLOT>& dmrs_mask,
542+ const subcarrier_spacing& scs,
543+ optional<float > cfo,
544+ span<const float > cp_cum_duration,
545+ unsigned first_hop_symbol,
546+ unsigned last_hop_symbol,
547+ unsigned hop_symbols,
548+ unsigned hop_offset,
549+ unsigned i_layer)
521550{
522551 std::array<cf_t , MAX_RB * NRE> avg_estimates_buffer;
523552 std::array<cf_t , MAX_RB * NRE> predicted_obs_buffer;
@@ -528,15 +557,36 @@ static float estimate_noise(const dmrs_symbol_list& pilots,
528557
529558 span<cf_t > predicted_obs = span<cf_t >(predicted_obs_buffer).first (estimates.size ());
530559 float noise_energy = 0 .0F ;
531- for (unsigned i_symbol = 0 ; i_symbol != hop_symbols; ++i_symbol) {
532- span<const cf_t > symbol_pilots = pilots.get_symbol (hop_offset + i_symbol, i_layer);
533- span<const cf_t > symbol_rx_pilots = rx_pilots.get_symbol (i_symbol, i_layer);
534560
535- srsvec::prod (scaled_estimates, symbol_pilots, predicted_obs);
536- srsvec::add (predicted_obs, symbol_rx_pilots, predicted_obs);
561+ if (cfo.has_value ()) {
562+ auto noise_cfo = [&, i_dmrs = 0 ](size_t i_symbol) mutable {
563+ span<const cf_t > symbol_pilots = pilots.get_symbol (hop_offset + i_dmrs, i_layer);
564+ span<const cf_t > symbol_rx_pilots = rx_pilots.get_symbol (i_dmrs, i_layer);
565+
566+ srsvec::prod (scaled_estimates, symbol_pilots, predicted_obs);
567+ srsvec::sc_prod (
568+ predicted_obs, std::polar (1 .0f , TWOPI * (i_symbol + cp_cum_duration[i_symbol]) * cfo.value ()), predicted_obs);
569+ srsvec::add (predicted_obs, symbol_rx_pilots, predicted_obs);
570+
571+ noise_energy += std::real (srsvec::dot_prod (predicted_obs, predicted_obs));
572+ ++i_dmrs;
573+ };
537574
538- noise_energy += std::real (srsvec::dot_prod (predicted_obs, predicted_obs));
575+ dmrs_mask.for_each (first_hop_symbol, last_hop_symbol, noise_cfo);
576+ } else {
577+ auto noise_no_cfo = [&, i_dmrs = 0 ](size_t i_symbol) mutable {
578+ span<const cf_t > symbol_pilots = pilots.get_symbol (hop_offset + i_dmrs, i_layer);
579+ span<const cf_t > symbol_rx_pilots = rx_pilots.get_symbol (i_dmrs, i_layer);
580+
581+ srsvec::prod (scaled_estimates, symbol_pilots, predicted_obs);
582+ srsvec::add (predicted_obs, symbol_rx_pilots, predicted_obs);
583+
584+ noise_energy += std::real (srsvec::dot_prod (predicted_obs, predicted_obs));
585+ ++i_dmrs;
586+ };
587+ dmrs_mask.for_each (first_hop_symbol, last_hop_symbol, noise_no_cfo);
539588 }
589+
540590 return noise_energy;
541591}
542592
0 commit comments