summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authordufour2010-01-26 14:01:07 +0000
committerdufour2010-01-26 14:01:07 +0000
commitf98f4150523e924d89deb4b39cbb1cda190c4028 (patch)
tree75539f67888f97244e7efc3965f600f5eadc5f31 /cesar
parent69f8884a256d1a9c6fba6bed4eb4cc7cda71bb0e (diff)
cesar/ce/rx/bitloading: rename bit loading function to remove initial
Most of bit loading functions can be used for initial or iterative bit loading algorithm. Update documentation. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@6653 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar')
-rw-r--r--cesar/ce/rx/bitloading/inc/bitloading.h165
-rw-r--r--cesar/ce/rx/bitloading/inc/initial.h134
-rw-r--r--cesar/ce/rx/bitloading/src/bitloading.c239
-rw-r--r--cesar/ce/rx/bitloading/src/initial.c238
-rw-r--r--cesar/ce/rx/bitloading/test/src/test_bl.c10
-rw-r--r--cesar/ce/rx/inc/rx.h1
6 files changed, 415 insertions, 372 deletions
diff --git a/cesar/ce/rx/bitloading/inc/bitloading.h b/cesar/ce/rx/bitloading/inc/bitloading.h
new file mode 100644
index 0000000000..77626faf6e
--- /dev/null
+++ b/cesar/ce/rx/bitloading/inc/bitloading.h
@@ -0,0 +1,165 @@
+#ifndef ce_rx_bitloading_inc_bitloading_h
+#define ce_rx_bitloading_inc_bitloading_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file ce/rx/bitloading/inc/bitloading.h
+ * \brief Functions to compute tone map using TNS algorithms.
+ * \ingroup ce_rx_bl
+ *
+ * This header declares functions used to compute and optimize tone maps using
+ * the TNS algorithms. Those functions are used by the bit loading initial and
+ * iterative.
+ */
+
+#include "ce/rx/bitloading/bitloading.h"
+
+#include "mac/common/tonemap.h"
+#include "mac/common/tonemask.h"
+
+/**
+ * Structure for the table to sort carriers with lowest BER impact.
+ * This table will contains all the theoretical BER that respect the BER
+ * consign and the impact when increasing of one modulation on theoretical
+ * BER.
+ */
+typedef struct ce_rx_bl_ber_impact_t
+{
+ /**
+ * Index of the carrier.
+ */
+ u16 carrier_index;
+ /**
+ * BER theoretical of the modulation that respect BER consign.
+ */
+ u64 ber_lower;
+ /**
+ * Impact on BER when increasing modulation to the next upper one.
+ */
+ u32 ber_diff;
+} ce_rx_bl_ber_impact_t;
+
+BEGIN_DECLS
+
+/**
+ * Compare two values.
+ * \param table optimization table.
+ * \param p1 first position to compare.
+ * \param p2 second position to compare.
+ * \return true if p1 < p2.
+ */
+static inline bool
+ce_rx_bl_ber_impact_compare (ce_rx_bl_ber_impact_t *table, uint p1, uint p2)
+{
+ /* Check parameter. */
+ dbg_assert (table);
+
+ if (table[p1].ber_diff < table[p2].ber_diff)
+ return true;
+ return false;
+}
+
+/**
+ * Swap two values.
+ * \param table optimization table.
+ * \param p1 first index to swap.
+ * \param p2 second index to swap.
+ */
+static inline void
+ce_rx_bl_ber_impact_swap (ce_rx_bl_ber_impact_t *table, uint p1, uint p2)
+{
+ /* Check parameter. */
+ dbg_assert (table);
+
+ XCH (table[p1], table[p2]);
+}
+
+/**
+ * Sort optimization table to increase carrier with lowest BER impact.
+ * \param opti_table the optimization table to sort.
+ * \param size the size of the opti_table.
+ */
+void
+ce_rx_bl_sort_optimization (ce_rx_bl_ber_impact_t *opti_table, uint size);
+
+/**
+ * Set a tone map under a BER consign.
+ * \param ber_pt BER consign to respect.
+ * \param tonemask the tone mask context.
+ * \param fec_rate the FEC rate to use (for the polynomial).
+ * \param bl the bit loading context.
+ * \param tm tone map initial generated (non-optimized version).
+ * \param opti_table the optimization table (required to optimize the tone
+ * \param tone_en tone enabled count (active but not 0).
+ * map).
+ * \return the sum of theoretical BER for the generated tone map (based on
+ * the ber_lower) pondered by the modulation.
+ *
+ * For each tone, this function will find the modulation which respect the BER
+ * consign. In consequence, the tone map will always be under the BER consign.
+ * In contrast, \sa ce_rx_bl_update_tone_map_at_ber_consign
+ * will update the tone map at BER consign.
+ * It also generates an non-sorted optimization table (for next step, to
+ * improve BER to reach BER consign).
+ */
+u64
+ce_rx_bl_update_tone_map_under_ber_consign (u64 ber_pt,
+ tonemask_info_t *tonemask,
+ phy_fecrate_t fec_rate,
+ ce_rx_bitloading_t *bl,
+ tonemap_t *tm,
+ ce_rx_bl_ber_impact_t *opti_table,
+ uint *tone_en);
+
+/**
+ * Update a tone map to reach a BER consign.
+ * \param ber_pt BER consign to respect.
+ * \param tonemask the tone mask context.
+ * \param fec_rate the FEC rate to use (for the polynomial).
+ * \param bl the bit loading context.
+ * \param tm tone map initial generated (non-iterative version).
+ * \param opti the optimization table.
+ * \return the total count of tone enabled (active but not 0).
+ *
+ * This function updates a tone map to make it perfectly respect the BER
+ * consign (or just under).
+ */
+uint
+ce_rx_bl_update_tone_map_at_ber_consign (u64 ber_pt,
+ tonemask_info_t *tonemask,
+ phy_fecrate_t fec_rate,
+ ce_rx_bitloading_t *bl,
+ tonemap_t *tm,
+ ce_rx_bl_ber_impact_t *opti);
+
+/**
+ * Compute a tone map which iterates on the BER consign.
+ * \param bpt_initial initial bits per tone (to compute initial BER
+ * consign).
+ * \param iteration_max maximum number of iteration.
+ * \param tonemask the tone mask context.
+ * \param bl the bit loading context.
+ * \return the computed tone map.
+ *
+ * This function generates a tone map which respect the BER consign, based on
+ * the bit per tone initial. It re-does this process with a new BER consign,
+ * based on the bit per tone of the newly generated tone map. Those iterations
+ * are repeated until no evolution of the BER consign or the maximum number of
+ * iterations is reached.
+ * This whole algorithm is done twice, for each FEC rate and only keep the
+ * best tone map pondered by the FEC rate.
+ */
+tonemap_t *
+ce_rx_bl_compute_tone_map_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
+ uint iteration_max,
+ tonemask_info_t *tonemask,
+ ce_rx_bitloading_t *bl);
+
+END_DECLS
+
+#endif /* ce_rx_bitloading_inc_bitloading_h */
diff --git a/cesar/ce/rx/bitloading/inc/initial.h b/cesar/ce/rx/bitloading/inc/initial.h
index 5f3e8f6b0c..5497f95fc2 100644
--- a/cesar/ce/rx/bitloading/inc/initial.h
+++ b/cesar/ce/rx/bitloading/inc/initial.h
@@ -17,145 +17,11 @@
*/
#include "ce/rx/bitloading/bitloading.h"
-#include "mac/common/tonemap.h"
#include "mac/common/tonemask.h"
-/**
- * Structure for the table to sort carriers with lowest BER impact.
- * This table will contains all the theoretical BER that respect the BER
- * consign and the impact when increasing of one modulation on theoretical
- * BER.
- */
-typedef struct ce_rx_bl_ber_impact_t
-{
- /**
- * Index of the carrier.
- */
- u16 carrier_index;
- /**
- * BER theoretical of the modulation that respect BER consign.
- */
- u64 ber_lower;
- /**
- * Impact on BER when increasing modulation to the next upper one.
- */
- u32 ber_diff;
-} ce_rx_bl_ber_impact_t;
-
BEGIN_DECLS
/**
- * Generate optimization table of BER impact and initial (non-optimized) tone
- * map.
- * \param ber_pt BER consign to respect.
- * \param tonemask the tone mask context.
- * \param fec_rate the FEC rate to use (for the polynomial).
- * \param bl the bit loading context.
- * \param tm tone map initial generated (non-optimized version).
- * \param opti_table the optimization table (required to optimize the tone
- * \param tone_en tone enabled count (active but not 0).
- * map).
- * \return the sum of theoretical BER for the generated tone map (based on
- * the ber_lower) pondered by the modulation.
- *
- * For each carrier, this function will select the modulation with the
- * theoretical BER that is just under the BER consign.
- * It will also fill the optimization table with the impact of increasing the
- * modulation by one on the theoretical BER.
- * This function will return the sum of the theoretical BER of each carrier
- * pondered with the number of bits of the modulation of this carrier.
- */
-u64
-ce_rx_bl_initial_non_optimized (u64 ber_pt, tonemask_info_t *tonemask,
- phy_fecrate_t fec_rate,
- ce_rx_bitloading_t *bl, tonemap_t *tm,
- ce_rx_bl_ber_impact_t *opti_table,
- uint *tone_en);
-
-/**
- * Compare two values.
- * \param table optimization table.
- * \param p1 first position to compare.
- * \param p2 second position to compare.
- * \return true if p1 < p2.
- */
-static inline bool
-ce_rx_bl_ber_impact_compare (ce_rx_bl_ber_impact_t *table, uint p1, uint p2)
-{
- /* Check parameter. */
- dbg_assert (table);
-
- if (table[p1].ber_diff < table[p2].ber_diff)
- return true;
- return false;
-}
-
-/**
- * Swap two values.
- * \param table optimization table.
- * \param p1 first index to swap.
- * \param p2 second index to swap.
- */
-static inline void
-ce_rx_bl_ber_impact_swap (ce_rx_bl_ber_impact_t *table, uint p1, uint p2)
-{
- /* Check parameter. */
- dbg_assert (table);
-
- XCH (table[p1], table[p2]);
-}
-
-/**
- * Sort optimization table to increase carrier with lowest BER impact.
- * \param opti_table the optimization table to sort.
- * \param size the size of the opti_table.
- */
-void
-ce_rx_bl_initial_sort_optimization (ce_rx_bl_ber_impact_t *opti_table,
- uint size);
-
-/**
- * Generate a initial tone map that respect the BER consign.
- * \param ber_pt BER consign to respect.
- * \param tonemask the tone mask context.
- * \param fec_rate the FEC rate to use (for the polynomial).
- * \param bl the bit loading context.
- * \param tm tone map initial generated (non-iterative version).
- * \param opti the optimization table.
- * \return the total count of tone enabled (active but not 0).
- *
- * This function generate a tone map that perfectly respect the BER consign
- * (or is just under).
- */
-uint
-ce_rx_bl_initial_optimized (u64 ber_pt, tonemask_info_t *tonemask,
- phy_fecrate_t fec_rate, ce_rx_bitloading_t *bl,
- tonemap_t *tm, ce_rx_bl_ber_impact_t *opti);
-
-/**
- * Compute a tone map which iterates on the BER consign.
- * \param bpt_initial initial bits per tone (to compute initial BER
- * consign).
- * \param iteration_max maximum number of iteration.
- * \param tonemask the tone mask context.
- * \param bl the bit loading context.
- * \return the computed tone map.
- *
- * This function generates a tone map which respect the BER consign, based on
- * the bit per tone initial. It re-does this process with a new BER consign,
- * based on the bit per tone of the newly generated tone map. Those iterations
- * are repeated until no evolution of the BER consign or the maximum number of
- * iterations is reached.
- * This whole algorithm is done twice, for each FEC rate and only keep the
- * best tone map pondered by the FEC rate.
- */
-tonemap_t *
-ce_rx_bl_initial_optimized_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
- uint iteration_max,
- tonemask_info_t *tonemask,
- ce_rx_bitloading_t *bl);
-
-/**
* Generate an initial tone map.
* \param tonemask the tone mask context.
* \param bl the bit loading context.
diff --git a/cesar/ce/rx/bitloading/src/bitloading.c b/cesar/ce/rx/bitloading/src/bitloading.c
index 2d60e4e4f6..b9700d3be0 100644
--- a/cesar/ce/rx/bitloading/src/bitloading.c
+++ b/cesar/ce/rx/bitloading/src/bitloading.c
@@ -12,6 +12,14 @@
*/
#include "common/std.h"
#include "ce_rx_bl_fsm_defs.h"
+#include "ce/rx/bitloading/inc/ber.h"
+#include "ce/rx/bitloading/inc/bitloading.h"
+
+#define LIB_HEAPSORT_USER_TYPE ce_rx_bl_ber_impact_t
+#define LIB_HEAPSORT_USER_COMP_LESSER ce_rx_bl_ber_impact_compare
+#define LIB_HEAPSORT_USER_SWAP ce_rx_bl_ber_impact_swap
+#define LIB_HEAPSORT_USER_PREFIX ce_rx_bl_ber_impact
+#include "lib/heapsort.h"
blk_t *
ce_rx_bl_get_nsr (ce_rx_bitloading_t *bl)
@@ -28,3 +36,234 @@ ce_rx_bl_get_nsr (ce_rx_bitloading_t *bl)
break;
}
}
+
+void
+ce_rx_bl_sort_optimization (ce_rx_bl_ber_impact_t *opti_table,
+ uint size)
+{
+ /* Check parameter. */
+ dbg_assert (opti_table);
+
+ lib_heapsort (opti_table, size);
+}
+
+u64
+ce_rx_bl_update_tone_map_under_ber_consign (u64 ber_pt,
+ tonemask_info_t *tonemask,
+ phy_fecrate_t fec_rate,
+ ce_rx_bitloading_t *bl,
+ tonemap_t *tm,
+ ce_rx_bl_ber_impact_t *opti_table,
+ uint *tone_en)
+{
+ /* Check parameters. */
+ dbg_assert (ber_pt > 0 && ber_pt < CE_RX_BL_BER_DEFAULT_OVER);
+ dbg_assert (tonemask);
+ dbg_assert (tm);
+ dbg_assert (opti_table);
+ dbg_assert (tone_en);
+
+ u8 modulation;
+ u64 ber_weighted_sum = 0;
+ u64 ber_upper;
+ uint i = 0, carrier_index = 0;
+ blk_t *cur_blk = bl->noise_nrj;
+ u32 *nsr_data = (u32 *) cur_blk->data;
+
+ tm->bits_per_symbol = 0;
+ *tone_en = 0;
+
+ /* Go through the tone map. */
+ TONEMAP_ACCESS_BEGIN (tm, tonemask->tonemask)
+ {
+ /* Index of a tone in a word of tones. */
+ uint tm_tone_index_;
+ /* The 8 tones of the word. */
+ u32 tm_word_tone_ = 0;
+ for (tm_tone_index_ = 0;
+ tm_tone_index_ < 8;
+ tm_tone_index_++)
+ {
+ /* If tone enable. */
+ if (!(tk_cur_ & 0x1))
+ {
+ /* Compute BER. */
+ ce_rx_bl_ber_vs_nsr (ce_rx_bl_ber_poly_coef[fec_rate],
+ nsr_data[carrier_index % (BLK_SIZE / 4)], ber_pt,
+ &modulation, &opti_table[i].ber_lower, &ber_upper);
+ /* Fill temporary table. */
+ if (modulation)
+ (*tone_en)++;
+ if (modulation == CE_MOD_COUNT - 1)
+ opti_table[i].ber_diff = -1;
+ else
+ opti_table[i].ber_diff = (ber_upper - opti_table[i].ber_lower) >> 32;
+ opti_table[i].carrier_index = carrier_index;
+ ber_weighted_sum += opti_table[i].ber_lower * CE_BIT_PER_MOD[modulation];
+ tm->bits_per_symbol += CE_BIT_PER_MOD[modulation];
+ i++;
+ }
+ else
+ modulation = 0;
+ /* Write tone. */
+ tm_word_tone_ |= modulation << (4 * tm_tone_index_);
+ /* Next tone mask bit. */
+ tk_cur_ >>= 1;
+ carrier_index++;
+ }
+ *tm_ = tm_word_tone_;
+ /* Next group of tone (grouped by word). */
+ tm_++;
+ }
+ TONEMAP_ACCESS_MIDDLE;
+ /* Get next block of NSR. */
+ /* Dirty? You mean? FIXME */
+ if (!(carrier_index % (BLK_SIZE / 4)))
+ {
+ cur_blk = cur_blk->next;
+ dbg_assert (cur_blk);
+ nsr_data = (u32 *) cur_blk->data;
+ }
+ TONEMAP_ACCESS_END;
+
+ return ber_weighted_sum;
+}
+
+uint
+ce_rx_bl_update_tone_map_at_ber_consign (u64 ber_pt,
+ tonemask_info_t *tonemask,
+ phy_fecrate_t fec_rate,
+ ce_rx_bitloading_t *bl,
+ tonemap_t *tm,
+ ce_rx_bl_ber_impact_t *opti)
+{
+ /* Check parameters. */
+ dbg_assert (ber_pt > 0 && ber_pt < CE_RX_BL_BER_DEFAULT_OVER);
+ dbg_assert (tonemask);
+ dbg_assert (tm);
+ dbg_assert (bl);
+ dbg_assert (opti);
+
+ uint tone_en;
+
+ /* Generate a non optimized version of the initial tone map. */
+ u64 ber_weighted_sum =
+ ce_rx_bl_update_tone_map_under_ber_consign (ber_pt, tonemask,
+ fec_rate, bl, tm, opti,
+ &tone_en);
+
+ /* Sort optimization table. */
+ ce_rx_bl_sort_optimization (opti, tonemask->carrier_nb);
+
+ /* Until we reach the limit. */
+ uint pos = 0;
+ u32 *tone_word;
+ s8 mod = -1;
+ while (ber_pt * tm->bits_per_symbol >= ber_weighted_sum)
+ {
+ /* Get the modulation of the lowest BER impact. */
+ mod = tonemap_get_tone (tm, opti[pos].carrier_index, &tone_word);
+ if (mod == 0)
+ tone_en++;
+ /* If the tone we would like to increase is already at its maximum,
+ * all the remaining tone that can be increase are already at the
+ * maximum too. So basically, we should stop the algorithm here. */
+ if (mod == CE_MOD_COUNT - 1)
+ return tone_en;
+ /* Remove from number of bits of the tone map the current value. */
+ tm->bits_per_symbol -= CE_BIT_PER_MOD[mod];
+ /* Remove from the summed BER of the tone map the current value. */
+ ber_weighted_sum -= opti[pos].ber_lower * CE_BIT_PER_MOD[mod];
+ /* Increase modulation of this tone index. */
+ tonemap_write_tone_to_word (tone_word, opti[pos].carrier_index,
+ ++mod);
+ /* Update number of bits of the tone map. */
+ tm->bits_per_symbol += CE_BIT_PER_MOD[mod];
+ /* Update summed BER of the tone map. */
+ ber_weighted_sum += (opti[pos].ber_lower + ((u64) opti[pos].ber_diff << 32))
+ * CE_BIT_PER_MOD[mod];
+ /* Next one. */
+ pos++;
+ }
+ dbg_assert (mod != -1);
+ /* Remove last one. */
+ tm->bits_per_symbol -= CE_BIT_PER_MOD[mod];
+ tonemap_write_tone_to_word (tone_word, opti[pos - 1].carrier_index,
+ --mod);
+ tm->bits_per_symbol += CE_BIT_PER_MOD[mod];
+ if (mod == 0)
+ tone_en--;
+ return tone_en;
+}
+
+tonemap_t *
+ce_rx_bl_compute_tone_map_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
+ uint iteration_max,
+ tonemask_info_t *tonemask,
+ ce_rx_bitloading_t *bl)
+{
+ /* Check parameters. */
+ dbg_assert (bpt_initial);
+ dbg_assert (iteration_max);
+ dbg_assert (tonemask);
+ dbg_assert (bl);
+
+ u64 ber_prev, ber_cur;
+ uint it_count;
+ ce_rx_bl_ber_impact_t opti[PHY_CARRIER_NB];
+ u32 sort[PHY_FEC_RATE_NB];
+ tonemap_t *tm[PHY_FEC_RATE_NB];
+ uint tone_en;
+
+ phy_fecrate_t fec_rate;
+ /* For each FEC rate. */
+ for (fec_rate = PHY_FEC_RATE_1_2; fec_rate < PHY_FEC_RATE_NB; fec_rate++)
+ {
+ it_count = 0;
+ tm[fec_rate] = tonemap_alloc ();
+ /* Start with the lowest BER consign possible (it depends on the FEC
+ * rate). */
+ ber_cur = ce_rx_bl_ber_pt_bpt (fec_rate, bpt_initial[fec_rate]);
+ do
+ {
+ /* Generate a optimized version of the tone map. */
+ tone_en = ce_rx_bl_update_tone_map_at_ber_consign
+ (ber_cur, tonemask, fec_rate, bl, tm[fec_rate], opti);
+ /* Store previous BER consign. */
+ ber_prev = ber_cur;
+ /* Get new BER consign. */
+ ber_cur = ce_rx_bl_ber_pt_bpt
+ (fec_rate, (tm[fec_rate]->bits_per_symbol *
+ CE_RX_BL_BPT_QUANT_FACTOR) / tone_en);
+ }
+ /* Repeat until no modification of the BER consign (or 6 times). */
+ while (++it_count < iteration_max && ber_prev != ber_cur);
+ /* Store tone map generated. */
+ sort[fec_rate] = tm[fec_rate]->bits_per_symbol;
+ }
+
+ /* Choose best fec_rate. */
+ /* 1/2 * 42 -> 21.
+ * 16/21 * 42 -> 32. */
+ phy_fecrate_t good, bad;
+ if ((sort[PHY_FEC_RATE_1_2] * 21)
+ > sort[PHY_FEC_RATE_16_21] * 32)
+ {
+ good = PHY_FEC_RATE_1_2;
+ bad = PHY_FEC_RATE_16_21;
+ }
+ else
+ {
+ good = PHY_FEC_RATE_16_21;
+ bad = PHY_FEC_RATE_1_2;
+ }
+ /* Remove worst tone map. */
+ tonemap_free (tm[bad]);
+ /* Configure generated tone map. */
+ tm[good]->fecrate = good;
+ /* Update pre-computed parameters. */
+ tonemap_update (tm[good], TONEMAP_P_PBERROR_DEFAULT_UF32);
+ /* Return best tone map. */
+ return tm[good];
+}
+
diff --git a/cesar/ce/rx/bitloading/src/initial.c b/cesar/ce/rx/bitloading/src/initial.c
index 5541e0ad54..82818370d2 100644
--- a/cesar/ce/rx/bitloading/src/initial.c
+++ b/cesar/ce/rx/bitloading/src/initial.c
@@ -15,244 +15,14 @@
*/
#include "common/std.h"
-#include "mac/common/tonemap.h"
-#include "ce/rx/bitloading/inc/initial.h"
+#include "ce/rx/bitloading/inc/bitloading.h"
#include "ce/rx/bitloading/inc/ber.h"
-
-#define LIB_HEAPSORT_USER_TYPE ce_rx_bl_ber_impact_t
-#define LIB_HEAPSORT_USER_COMP_LESSER ce_rx_bl_ber_impact_compare
-#define LIB_HEAPSORT_USER_SWAP ce_rx_bl_ber_impact_swap
-#define LIB_HEAPSORT_USER_PREFIX ce_rx_bl_ber_impact
-#include "lib/heapsort.h"
-
-u64
-ce_rx_bl_initial_non_optimized (u64 ber_pt, tonemask_info_t *tonemask,
- phy_fecrate_t fec_rate,
- ce_rx_bitloading_t *bl, tonemap_t *tm,
- ce_rx_bl_ber_impact_t *opti_table,
- uint *tone_en)
-{
- /* Check parameters. */
- dbg_assert (ber_pt > 0 && ber_pt < CE_RX_BL_BER_DEFAULT_OVER);
- dbg_assert (tonemask);
- dbg_assert (tm);
- dbg_assert (opti_table);
- dbg_assert (tone_en);
-
- u8 modulation;
- u64 ber_weighted_sum = 0;
- u64 ber_upper;
- uint i = 0, carrier_index = 0;
- blk_t *cur_blk = bl->noise_nrj;
- u32 *nsr_data = (u32 *) cur_blk->data;
-
- tm->bits_per_symbol = 0;
- *tone_en = 0;
-
- /* Go through the tone map. */
- TONEMAP_ACCESS_BEGIN (tm, tonemask->tonemask)
- {
- /* Index of a tone in a word of tones. */
- uint tm_tone_index_;
- /* The 8 tones of the word. */
- u32 tm_word_tone_ = 0;
- for (tm_tone_index_ = 0;
- tm_tone_index_ < 8;
- tm_tone_index_++)
- {
- /* If tone enable. */
- if (!(tk_cur_ & 0x1))
- {
- /* Compute BER. */
- ce_rx_bl_ber_vs_nsr (ce_rx_bl_ber_poly_coef[fec_rate],
- nsr_data[carrier_index % (BLK_SIZE / 4)], ber_pt,
- &modulation, &opti_table[i].ber_lower, &ber_upper);
- /* Fill temporary table. */
- if (modulation)
- (*tone_en)++;
- if (modulation == CE_MOD_COUNT - 1)
- opti_table[i].ber_diff = -1;
- else
- opti_table[i].ber_diff = (ber_upper - opti_table[i].ber_lower) >> 32;
- opti_table[i].carrier_index = carrier_index;
- ber_weighted_sum += opti_table[i].ber_lower * CE_BIT_PER_MOD[modulation];
- tm->bits_per_symbol += CE_BIT_PER_MOD[modulation];
- i++;
- }
- else
- modulation = 0;
- /* Write tone. */
- tm_word_tone_ |= modulation << (4 * tm_tone_index_);
- /* Next tone mask bit. */
- tk_cur_ >>= 1;
- carrier_index++;
- }
- *tm_ = tm_word_tone_;
- /* Next group of tone (grouped by word). */
- tm_++;
- }
- TONEMAP_ACCESS_MIDDLE;
- /* Get next block of NSR. */
- /* Dirty? You mean? FIXME */
- if (!(carrier_index % (BLK_SIZE / 4)))
- {
- cur_blk = cur_blk->next;
- dbg_assert (cur_blk);
- nsr_data = (u32 *) cur_blk->data;
- }
- TONEMAP_ACCESS_END;
-
- return ber_weighted_sum;
-}
-
-void
-ce_rx_bl_initial_sort_optimization (ce_rx_bl_ber_impact_t *opti_table,
- uint size)
-{
- /* Check parameter. */
- dbg_assert (opti_table);
-
- lib_heapsort (opti_table, size);
-}
-
-uint
-ce_rx_bl_initial_optimized (u64 ber_pt, tonemask_info_t *tonemask,
- phy_fecrate_t fec_rate, ce_rx_bitloading_t *bl,
- tonemap_t *tm, ce_rx_bl_ber_impact_t *opti)
-{
- /* Check parameters. */
- dbg_assert (ber_pt > 0 && ber_pt < CE_RX_BL_BER_DEFAULT_OVER);
- dbg_assert (tonemask);
- dbg_assert (tm);
- dbg_assert (bl);
- dbg_assert (opti);
-
- uint tone_en;
-
- /* Generate a non optimized version of the initial tone map. */
- u64 ber_weighted_sum =
- ce_rx_bl_initial_non_optimized (ber_pt, tonemask, fec_rate, bl, tm,
- opti, &tone_en);
-
- /* Sort optimization table. */
- ce_rx_bl_initial_sort_optimization (opti, tonemask->carrier_nb);
-
- /* Until we reach the limit. */
- uint pos = 0;
- u32 *tone_word;
- s8 mod = -1;
- while (ber_pt * tm->bits_per_symbol >= ber_weighted_sum)
- {
- /* Get the modulation of the lowest BER impact. */
- mod = tonemap_get_tone (tm, opti[pos].carrier_index, &tone_word);
- if (mod == 0)
- tone_en++;
- /* If the tone we would like to increase is already at its maximum,
- * all the remaining tone that can be increase are already at the
- * maximum too. So basically, we should stop the algorithm here. */
- if (mod == CE_MOD_COUNT - 1)
- return tone_en;
- /* Remove from number of bits of the tone map the current value. */
- tm->bits_per_symbol -= CE_BIT_PER_MOD[mod];
- /* Remove from the summed BER of the tone map the current value. */
- ber_weighted_sum -= opti[pos].ber_lower * CE_BIT_PER_MOD[mod];
- /* Increase modulation of this tone index. */
- tonemap_write_tone_to_word (tone_word, opti[pos].carrier_index,
- ++mod);
- /* Update number of bits of the tone map. */
- tm->bits_per_symbol += CE_BIT_PER_MOD[mod];
- /* Update summed BER of the tone map. */
- ber_weighted_sum += (opti[pos].ber_lower + ((u64) opti[pos].ber_diff << 32))
- * CE_BIT_PER_MOD[mod];
- /* Next one. */
- pos++;
- }
- dbg_assert (mod != -1);
- /* Remove last one. */
- tm->bits_per_symbol -= CE_BIT_PER_MOD[mod];
- tonemap_write_tone_to_word (tone_word, opti[pos - 1].carrier_index,
- --mod);
- tm->bits_per_symbol += CE_BIT_PER_MOD[mod];
- if (mod == 0)
- tone_en--;
- return tone_en;
-}
-
-tonemap_t *
-ce_rx_bl_initial_optimized_iterative (const u64 bpt_initial[PHY_FEC_RATE_NB],
- uint iteration_max,
- tonemask_info_t *tonemask,
- ce_rx_bitloading_t *bl)
-{
- /* Check parameters. */
- dbg_assert (bpt_initial);
- dbg_assert (iteration_max);
- dbg_assert (tonemask);
- dbg_assert (bl);
-
- u64 ber_prev, ber_cur;
- uint it_count;
- ce_rx_bl_ber_impact_t opti[PHY_CARRIER_NB];
- u32 sort[PHY_FEC_RATE_NB];
- tonemap_t *tm[PHY_FEC_RATE_NB];
- uint tone_en;
-
- phy_fecrate_t fec_rate;
- /* For each FEC rate. */
- for (fec_rate = PHY_FEC_RATE_1_2; fec_rate < PHY_FEC_RATE_NB; fec_rate++)
- {
- it_count = 0;
- tm[fec_rate] = tonemap_alloc ();
- /* Start with the lowest BER consign possible (it depends on the FEC
- * rate). */
- ber_cur = ce_rx_bl_ber_pt_bpt (fec_rate, bpt_initial[fec_rate]);
- do
- {
- /* Generate a optimized version of the tone map. */
- tone_en = ce_rx_bl_initial_optimized (ber_cur, tonemask, fec_rate,
- bl, tm[fec_rate], opti);
- /* Store previous BER consign. */
- ber_prev = ber_cur;
- /* Get new BER consign. */
- ber_cur = ce_rx_bl_ber_pt_bpt
- (fec_rate, (tm[fec_rate]->bits_per_symbol *
- CE_RX_BL_BPT_QUANT_FACTOR) / tone_en);
- }
- /* Repeat until no modification of the BER consign (or 6 times). */
- while (++it_count < iteration_max && ber_prev != ber_cur);
- /* Store tone map generated. */
- sort[fec_rate] = tm[fec_rate]->bits_per_symbol;
- }
-
- /* Choose best fec_rate. */
- /* 1/2 * 42 -> 21.
- * 16/21 * 42 -> 32. */
- phy_fecrate_t good, bad;
- if ((sort[PHY_FEC_RATE_1_2] * 21)
- > sort[PHY_FEC_RATE_16_21] * 32)
- {
- good = PHY_FEC_RATE_1_2;
- bad = PHY_FEC_RATE_16_21;
- }
- else
- {
- good = PHY_FEC_RATE_16_21;
- bad = PHY_FEC_RATE_1_2;
- }
- /* Remove worst tone map. */
- tonemap_free (tm[bad]);
- /* Configure generated tone map. */
- tm[good]->fecrate = good;
- /* Update pre-computed parameters. */
- tonemap_update (tm[good], TONEMAP_P_PBERROR_DEFAULT_UF32);
- /* Return best tone map. */
- return tm[good];
-}
+#include "ce/rx/bitloading/inc/initial.h"
tonemap_t *
ce_rx_bl_initial (tonemask_info_t *tonemask, ce_rx_bitloading_t *bl)
{
/* Only one iteration. */
- return ce_rx_bl_initial_optimized_iterative (ce_rx_bl_initial_bpt, 1,
- tonemask, bl);
+ return ce_rx_bl_compute_tone_map_iterative (ce_rx_bl_initial_bpt, 1,
+ tonemask, bl);
}
diff --git a/cesar/ce/rx/bitloading/test/src/test_bl.c b/cesar/ce/rx/bitloading/test/src/test_bl.c
index 69e87e01ff..d20eabb102 100644
--- a/cesar/ce/rx/bitloading/test/src/test_bl.c
+++ b/cesar/ce/rx/bitloading/test/src/test_bl.c
@@ -19,6 +19,7 @@
#include "ce/rx/bitloading/inc/ber.h"
#include "ce/rx/bitloading/inc/poly.h"
#include "ce/rx/bitloading/inc/initial.h"
+#include "ce/rx/bitloading/inc/bitloading.h"
#include "ce/rx/bitloading/bitloading.h"
#include "lib/rnd.h"
@@ -212,8 +213,8 @@ test_suite_ce_rx_bl_nsr_sum (test_t t)
test_begin (t, "initial tone map (non optimized)")
{
- ce_rx_bl_initial_non_optimized (ber_pt, &ti, fec_rate, &bl, tm, opti,
- &tone_en);
+ ce_rx_bl_update_tone_map_under_ber_consign (ber_pt, &ti, fec_rate,
+ &bl, tm, opti, &tone_en);
uint tone, i = 0, j = 0;
uint tone_diff = 0;
#define TONEMAP_READ_OPEN {
@@ -243,7 +244,7 @@ test_suite_ce_rx_bl_nsr_sum (test_t t)
test_begin (t, "sort optimization table")
{
uint i;
- ce_rx_bl_initial_sort_optimization (opti, ti.carrier_nb);
+ ce_rx_bl_sort_optimization (opti, ti.carrier_nb);
for (i = 0; i < ti.carrier_nb - 1; i++)
{
test_fail_if (opti[i].ber_diff > opti[i + 1].ber_diff);
@@ -257,7 +258,8 @@ test_suite_ce_rx_bl_nsr_sum (test_t t)
{
u64 ber_pt = ce_rx_bl_ber_pt_bpt (fec_rate,
ce_rx_bl_initial_bpt[fec_rate]);
- ce_rx_bl_initial_optimized (ber_pt, &ti, fec_rate, &bl, tm, opti);
+ ce_rx_bl_update_tone_map_at_ber_consign (ber_pt, &ti, fec_rate, &bl,
+ tm, opti);
uint tone, i = 0;
uint tone_diff = 0;
#define TONEMAP_READ_OPEN {
diff --git a/cesar/ce/rx/inc/rx.h b/cesar/ce/rx/inc/rx.h
index b864cb9cf5..4b166d0948 100644
--- a/cesar/ce/rx/inc/rx.h
+++ b/cesar/ce/rx/inc/rx.h
@@ -30,6 +30,7 @@
#include "ce/rx/cp/cp.h"
#include "ce/rx/bitloading/inc/initial.h"
+#include "ce/rx/bitloading/inc/bitloading.h"
#include "common/defs/priority.h"
#include "ce/rx/inc/trace.h"