summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorCyril Jourdan2013-05-22 15:46:04 +0200
committerCyril Jourdan2013-05-24 08:54:42 +0200
commit712e7ad8ed4aeed7d3a5c5ab71239c362ed307f5 (patch)
tree55d887e2856c9f1d329de5d7b6dc3dd3d1ad565c /cesar
parent13aeb5d4c60cb779a08bbed7f44cbc9e310f59e1 (diff)
cesar/ce/rx/bl: compute a worst case tonemap when needed, closes #3880
This tonemap will be used as default tonemap when intervals are activated.
Diffstat (limited to 'cesar')
-rw-r--r--cesar/ce/rx/bitloading/inc/bitloading.h14
-rw-r--r--cesar/ce/rx/bitloading/src/bitloading.c132
-rw-r--r--cesar/ce/rx/bitloading/src/intervals.c8
-rw-r--r--cesar/ce/rx/bitloading/test/fsm/src/scenario_events.c6
-rw-r--r--cesar/ce/rx/bitloading/test/intervals/src/scenario_intervals_events.c6
-rw-r--r--cesar/ce/rx/bitloading/test/src/test_intervals.c145
6 files changed, 294 insertions, 17 deletions
diff --git a/cesar/ce/rx/bitloading/inc/bitloading.h b/cesar/ce/rx/bitloading/inc/bitloading.h
index 42e970cd93..5fd08f5138 100644
--- a/cesar/ce/rx/bitloading/inc/bitloading.h
+++ b/cesar/ce/rx/bitloading/inc/bitloading.h
@@ -170,6 +170,20 @@ ce_rx_bl_compute_tone_map_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
tonemask_info_t *reducedtm,
ce_rx_bitloading_t *bl);
+/**
+ * Compute the worst case tonemap from a given set of tonemap. The worst case
+ * tonemap is defined as the tonemap using the worst modulation of the
+ * tonemaps in the set for each tone.
+ * \param ce_rx CE RX context.
+ * \param tms set of tonemap in which are the tonemap to use.
+ * \param tm_list set of tonemap to use represented as a bitfield of the
+ * corresponding tonemap indexes.
+ * \return tonemap index of the created tonemap. ROBO if the new tonemap is
+ * worse than ROBO or if ROBO is in the set of tonemap to use.
+ */
+uint
+ce_rx_bl_compute_worst_case_tm (ce_rx_t *ce_rx, tonemaps_t *tms, u32 tm_list);
+
END_DECLS
#endif /* ce_rx_bitloading_inc_bitloading_h */
diff --git a/cesar/ce/rx/bitloading/src/bitloading.c b/cesar/ce/rx/bitloading/src/bitloading.c
index 9c5da4523a..6d721f674c 100644
--- a/cesar/ce/rx/bitloading/src/bitloading.c
+++ b/cesar/ce/rx/bitloading/src/bitloading.c
@@ -16,7 +16,9 @@
#include "ce_rx_bl_fsm_defs.h"
#include "ce/rx/bitloading/inc/ber.h"
#include "ce/rx/bitloading/inc/bitloading.h"
+#include "ce/rx/bitloading/inc/common.h"
#include "ce/rx/bitloading/ber_margin_update.h"
+#include "ce/rx/inc/rx.h"
#include "ce/rx/ce_rx_param.h"
#include "mac/common/tonemap.h"
#include "mac/common/defs.h"
@@ -404,3 +406,133 @@ ce_rx_bl_compute_tone_map_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
/* Return best tone map. */
return tm[good];
}
+
+uint
+ce_rx_bl_compute_worst_case_tm (ce_rx_t *ce_rx, tonemaps_t *tms, u32 tm_list)
+{
+ dbg_assert (ce_rx);
+ dbg_assert (ce_rx->mac_config);
+ dbg_assert (tms);
+
+ tonemask_info_t *ti = &ce_rx->mac_config->tonemask_info;
+
+ uint new_tmi;
+ tonemap_t *new_tm;
+ uint parsing_tmi = 0;
+ phy_fecrate_t new_tm_fecrate = PHY_FEC_RATE_16_21;
+ phy_gil_t new_tm_gil = PHY_GIL_417;
+ blk_t *tms_blk[TONEMAP_MAX];
+ u32 *tms_data[TONEMAP_MAX];
+ uint tms_nb = 0;
+
+ /* Parse the set of tonemap to determine FEC rate and guard interval
+ * that we will use for the new one. */
+ while (tm_list)
+ {
+ if (tm_list & 0x1)
+ {
+ if (parsing_tmi < TONEMAP_INDEX_NEGOTIATED_FIRST)
+ break;
+ else
+ {
+ if (tms->tm[parsing_tmi]->fecrate < new_tm_fecrate)
+ new_tm_fecrate = tms->tm[parsing_tmi]->fecrate;
+ if (tms->tm[parsing_tmi]->gil > new_tm_gil)
+ new_tm_gil = tms->tm[parsing_tmi]->gil;
+ tms_blk[tms_nb] = tms->tm[parsing_tmi]->tmdma_desc_head;
+ tms_data[tms_nb] = (u32 *)tms_blk[tms_nb]->data;
+ tms_nb++;
+ }
+ }
+ tm_list >>= 1;
+ parsing_tmi++;
+ }
+
+ dbg_assert (tms_nb <= TONEMAP_MAX);
+
+ if (parsing_tmi < TONEMAP_INDEX_NEGOTIATED_FIRST)
+ {
+ /* If ROBO mode is used as default tonemap or on an interval,
+ * use it directy for new tonemap. */
+ new_tmi = parsing_tmi;
+ }
+ else
+ {
+ new_tm = tonemap_alloc ();
+
+ uint i, j, k;
+ u32 *new_tm_data = (u32 *)new_tm->tmdma_desc_head->data;
+ u32 new_tm_cur_word;
+ uint cur_word_mod[8];
+ u32 tm_word_to_parse;
+ uint new_tm_bps = 0;
+ bool second_blk = false;
+
+ /* Compute new tonemap. */
+ for (i = 0; i < PHY_TONEMAP_WORDS; i++)
+ {
+ new_tm_cur_word = -1;
+ for (j = 0; j < 8; j++)
+ cur_word_mod[j] = CE_MOD_COUNT - 1;
+ if (i >= (BLK_SIZE / 4) && !second_blk)
+ {
+ new_tm_data = (u32 *)new_tm->tmdma_desc_head->next->data
+ - BLK_SIZE / 4;
+ for (j = 0; j < tms_nb; j++)
+ tms_data[j] = (u32 *)tms_blk[j]->next->data
+ - BLK_SIZE / 4;
+ second_blk = true;
+ }
+ for (j = 0; j < tms_nb; j++)
+ {
+ tm_word_to_parse = *((u32 *)tms_data[j] + i);
+ if (!tm_word_to_parse)
+ {
+ new_tm_cur_word = 0;
+ break;
+ }
+ else
+ {
+ for (k = 0; k < 8; k++)
+ {
+ if ((tm_word_to_parse & 0xF) < cur_word_mod[k])
+ cur_word_mod[k] = tm_word_to_parse & 0xF;
+ tm_word_to_parse >>= 4;
+ }
+ }
+ }
+ if (new_tm_cur_word)
+ {
+ new_tm_cur_word = 0;
+ for (k = 0; k < 8; k++)
+ {
+ new_tm_cur_word += cur_word_mod[k] << (k * 4);
+ new_tm_bps += CE_BIT_PER_MOD[cur_word_mod[k]];
+ }
+ }
+ *(new_tm_data + i) = new_tm_cur_word;
+ }
+
+ /* Update remaining fields of the tonemap structure.
+ * Be careful that, due to the way this tonemap is created, this
+ * function can not fill ber_target and ber_target_reached fields
+ * with relevant values. That is why they are ommited here.
+ * For the same reason, optimization table in the bitloading
+ * context of the corresponding FSM is not updated here. */
+ new_tm->fecrate = new_tm_fecrate;
+ new_tm->gil = new_tm_gil;
+ new_tm->bits_per_symbol = new_tm_bps;
+ tonemap_update (new_tm, TONEMAP_P_PBERROR_DEFAULT_UF32);
+ new_tm->cpf = true;
+
+ if (ce_rx_bl_tonemap_better_than_robo (new_tm, ti))
+ new_tmi = tonemaps_set_first_free_tmi (tms, new_tm);
+ else
+ {
+ new_tmi = PHY_MOD_ROBO;
+ tonemap_free (new_tm);
+ }
+ }
+
+ return new_tmi;
+}
diff --git a/cesar/ce/rx/bitloading/src/intervals.c b/cesar/ce/rx/bitloading/src/intervals.c
index 39b67865bf..598748b82b 100644
--- a/cesar/ce/rx/bitloading/src/intervals.c
+++ b/cesar/ce/rx/bitloading/src/intervals.c
@@ -204,14 +204,14 @@ ce_rx_bl_intervals_update_default_tm (ce_rx_t *ce_rx, sta_t *sta)
tm_list >>= 1;
new_default_tmi++;
}
- tms->default_tmi = new_default_tmi;
}
else
{
- /* TODO: if needed, include default tmi in tm_used_list. Then
- * compute new tonemap from the ones included in tm_used_list
- * (see #3880). */
+ new_default_tmi = ce_rx_bl_compute_worst_case_tm (ce_rx, tms,
+ tm_list);
}
+
+ tms->default_tmi = new_default_tmi;
}
/* Remove old default tonemap if it is unused. */
diff --git a/cesar/ce/rx/bitloading/test/fsm/src/scenario_events.c b/cesar/ce/rx/bitloading/test/fsm/src/scenario_events.c
index 659cf4adbd..9d9b7716c1 100644
--- a/cesar/ce/rx/bitloading/test/fsm/src/scenario_events.c
+++ b/cesar/ce/rx/bitloading/test/fsm/src/scenario_events.c
@@ -48,6 +48,12 @@ ce_rx_bl_pber_reset (ce_rx_bl_pber_t *ctx)
}
}
+uint
+ce_rx_bl_compute_worst_case_tm (ce_rx_t *ce_rx, tonemaps_t *tms, u32 tm_list)
+{
+ return 0;
+}
+
void
tonemaps_reset (tonemaps_t *tms, tonemap_release_list_t *tm_release_list)
{
diff --git a/cesar/ce/rx/bitloading/test/intervals/src/scenario_intervals_events.c b/cesar/ce/rx/bitloading/test/intervals/src/scenario_intervals_events.c
index 251d130650..c914c60662 100644
--- a/cesar/ce/rx/bitloading/test/intervals/src/scenario_intervals_events.c
+++ b/cesar/ce/rx/bitloading/test/intervals/src/scenario_intervals_events.c
@@ -65,6 +65,12 @@ void ce_rx_bl_ber_sliding_mean_update (ce_rx_bitloading_t *bl, u64 ber)
test_fail_unless (bl == params->bl);
}
+uint
+ce_rx_bl_compute_worst_case_tm (ce_rx_t *ce_rx, tonemaps_t *tms, u32 tm_list)
+{
+ return 0;
+}
+
u8
tonemaps_set_first_free_tmi (tonemaps_t *tms, tonemap_t *tm)
{
diff --git a/cesar/ce/rx/bitloading/test/src/test_intervals.c b/cesar/ce/rx/bitloading/test/src/test_intervals.c
index d159ab444f..3e59cb2331 100644
--- a/cesar/ce/rx/bitloading/test/src/test_intervals.c
+++ b/cesar/ce/rx/bitloading/test/src/test_intervals.c
@@ -570,13 +570,79 @@ test_suite_ce_rx_bl_intervals_update_default_tm (test_t t)
uint old_repetition_nb = ce_rx_bl_intervals_repetition_count_;
ce_rx_t ce_rx;
+ mac_config_t mac_config;
sta_t sta;
- tonemap_t tm;
- int i;
-
+ tonemask_info_t ti;
+ tonemap_t *tm_4;
+ tonemap_t *tm_5;
+ tonemap_t *tm_6;
+ tonemap_t *tm_7;
+ uint mod;
+ uint i;
+
+ const uint tone_en = tonemask_default (ti.tonemask);
+ mac_config.tonemask_info.tonemap_robo[PHY_MOD_ROBO].bits_per_symbol = 458;
+ ce_rx.mac_config = &mac_config;
+
+ tm_4 = tonemap_alloc ();
+ tm_4->fecrate = PHY_FEC_RATE_16_21;
+ tm_4->gil = PHY_GIL_567;
+ TONEMAP_WRITE_BEGIN (tm_4, ti.tonemask)
+ {
+ TONEMAP_WRITE_MOD (4);
+ }
+ TONEMAP_WRITE_END;
+ tm_5 = tonemap_alloc ();
+ tm_5->fecrate = PHY_FEC_RATE_1_2;
+ tm_5->gil = PHY_GIL_417;
+ i = 0;
+ TONEMAP_WRITE_BEGIN (tm_5, ti.tonemask)
+ {
+ if (i < tone_en / 2)
+ mod = 3;
+ else
+ mod = 5;
+ TONEMAP_WRITE_MOD (mod);
+ i++;
+ }
+ TONEMAP_WRITE_END;
+ tm_6 = tonemap_alloc ();
+ tm_6->fecrate = PHY_FEC_RATE_16_21;
+ tm_6->gil = PHY_GIL_417;
+ i = 0;
+ TONEMAP_WRITE_BEGIN (tm_6, ti.tonemask)
+ {
+ if (i < tone_en / 2)
+ mod = 2;
+ else
+ mod = 6;
+ TONEMAP_WRITE_MOD (mod);
+ i++;
+ }
+ TONEMAP_WRITE_END;
+ tm_7 = tonemap_alloc ();
+ tm_7->fecrate = PHY_FEC_RATE_1_2;
+ tm_7->gil = PHY_GIL_567;
+ i = 0;
+ TONEMAP_WRITE_BEGIN (tm_7, ti.tonemask)
+ {
+ if (i < tone_en / 3)
+ mod = 1;
+ else
+ mod = 0;
+ TONEMAP_WRITE_MOD (mod);
+ i++;
+ }
+ TONEMAP_WRITE_END;
sta.rx_tonemaps = tonemaps_alloc ();
- sta.rx_tonemaps->tm[4] = &tm;
+ sta.rx_tonemaps->tm[4] = tm_4;
sta.rx_tonemaps->tm[4]->released = 0;
+ sta.rx_tonemaps->tm[5] = tm_5;
+ sta.rx_tonemaps->tm[5]->released = 0;
+ sta.rx_tonemaps->tm[6] = tm_6;
+ sta.rx_tonemaps->tm[6]->released = 0;
+ sta.rx_tonemaps->tm[7] = tm_7;
+ sta.rx_tonemaps->tm[7]->released = 0;
/* This tests only works if the number of intervals is known, so I prefer
* to manage this locally. */
@@ -652,25 +718,79 @@ test_suite_ce_rx_bl_intervals_update_default_tm (test_t t)
test_fail_if (sta.rx_tonemaps->tm[4]->released
!= TONEMAP_RELEASE_TIMER_S);
- /* TODO: add cases of new tonemap calculation (see #3880). */
+ sta.rx_tonemaps->default_tmi = 4;
+ sta.rx_tonemaps->tm[4]->released = 0;
+
+ sta.intervals->tmi[0] = 0;
+ ce_rx_bl_intervals_update_default_tm (&ce_rx, &sta);
+ test_fail_if (sta.rx_tonemaps->default_tmi != 0);
+ test_fail_if (sta.rx_tonemaps->tm[4]->released
+ != TONEMAP_RELEASE_TIMER_S);
+
+ sta.rx_tonemaps->default_tmi = 4;
+ sta.rx_tonemaps->tm[4]->released = 0;
+
+ sta.intervals->tmi[0] = 6;
+ ce_rx_bl_intervals_update_default_tm (&ce_rx, &sta);
+ test_fail_if (sta.rx_tonemaps->default_tmi != 8);
+ test_fail_if (sta.rx_tonemaps->tm[4]->released
+ != TONEMAP_RELEASE_TIMER_S);
+ test_fail_if (sta.rx_tonemaps->tm[8]->fecrate != PHY_FEC_RATE_1_2);
+ test_fail_if (sta.rx_tonemaps->tm[8]->gil != PHY_GIL_417);
+ i = 0;
+ TONEMAP_READ_BEGIN (sta.rx_tonemaps->tm[8], ti.tonemask, mod)
+ {
+ if (i < tone_en / 2)
+ test_fail_if (mod != 2);
+ else
+ test_fail_if (mod != 5);
+ i++;
+ }
+ TONEMAP_READ_END;
+
+ sta.rx_tonemaps->default_tmi = 4;
+ sta.rx_tonemaps->tm[4]->released = 0;
+
+ sta.intervals->tmi[0] = 7;
+ ce_rx_bl_intervals_update_default_tm (&ce_rx, &sta);
+ test_fail_if (sta.rx_tonemaps->default_tmi != 0);
+ test_fail_if (sta.rx_tonemaps->tm[4]->released
+ != TONEMAP_RELEASE_TIMER_S);
} test_end;
sta.rx_tonemaps->default_tmi = 4;
sta.rx_tonemaps->tm[4]->released = 0;
+ sta.intervals->tmi[0] = 6;
test_begin (t, "Several intervals, one restarting for a better tonemap.")
{
- /* TODO: This will change with new tonemap calculation (see #3880). */
- sta.intervals->tmi[0] = TONEMAP_SRC_INTERVAL_UNAVAILABLE;
- sta.intervals->intervals[0]->default_robo = false;
+ sta.intervals->tmi[1] = TONEMAP_SRC_INTERVAL_UNAVAILABLE;
+ sta.intervals->intervals[1]->default_robo = false;
ce_rx_bl_intervals_update_default_tm (&ce_rx, &sta);
- test_fail_if (sta.rx_tonemaps->default_tmi != 4);
- test_fail_if (sta.rx_tonemaps->tm[4]->released != 0);
+ test_fail_if (sta.rx_tonemaps->default_tmi != 9);
+ test_fail_if (sta.rx_tonemaps->tm[4]->released
+ != TONEMAP_RELEASE_TIMER_S);
+ test_fail_if (sta.rx_tonemaps->tm[9]->fecrate != PHY_FEC_RATE_1_2);
+ test_fail_if (sta.rx_tonemaps->tm[9]->gil != PHY_GIL_567);
+ i = 0;
+ TONEMAP_READ_BEGIN (sta.rx_tonemaps->tm[9], ti.tonemask, mod)
+ {
+ if (i < tone_en / 2)
+ test_fail_if (mod != 2);
+ else
+ test_fail_if (mod != 4);
+ i++;
+ }
+ TONEMAP_READ_END;
} test_end;
+
+ sta.rx_tonemaps->default_tmi = 4;
+ sta.rx_tonemaps->tm[4]->released = 0;
+
test_begin (t, "Several intervals, one restarting for a worst tonemap.")
{
- sta.intervals->tmi[1] = TONEMAP_SRC_INTERVAL_UNAVAILABLE;
- sta.intervals->intervals[1]->default_robo = true;
+ sta.intervals->tmi[2] = TONEMAP_SRC_INTERVAL_UNAVAILABLE;
+ sta.intervals->intervals[2]->default_robo = true;
ce_rx_bl_intervals_update_default_tm (&ce_rx, &sta);
test_fail_if (sta.rx_tonemaps->default_tmi != 0);
test_fail_if (sta.rx_tonemaps->tm[4]->released
@@ -678,7 +798,6 @@ test_suite_ce_rx_bl_intervals_update_default_tm (test_t t)
} test_end;
/* Clean. */
- sta.rx_tonemaps->tm[4] = NULL;
tonemaps_release (sta.rx_tonemaps);
ce_rx_bl_intervals_free (sta.intervals);
ce_rx_bl_intervals_fsm_count_ = old_fsm_nb;