* No longer keep a global variable with the current stage number, but pass it
authorunknown <s0042331@.dynamic.ewi.utwente.nl>
Tue, 1 Apr 2008 12:19:30 +0000 (14:19 +0200)
committerunknown <s0042331@.dynamic.ewi.utwente.nl>
Tue, 1 Apr 2008 12:19:30 +0000 (14:19 +0200)
   as an argument to the functions that need it. This also replaces the
   stage_odd parameter.
 * No longer loop through the needed stages, since the Montium sequencer can't
   change the twiddle memory mask dynamically. Instead, call the (new)
   do_regular_stage() function four times manually, with constant stage
   numbers that the optimizer can roll out.

FFT.mc

diff --git a/FFT.mc b/FFT.mc
index 5969315c8a174d1cadc4b8e49e60bee63f813f1c..4a80cfa8cc6241cc3f28a5c7d6b1e6a79c823215 100644 (file)
--- a/FFT.mc
+++ b/FFT.mc
@@ -6,7 +6,6 @@
 \r
 #include "FFT.h"\r
 \r
-int stage = 1;\r
 /**\r
  * Executes a single butterfly on ALU 0-3. The inputs are the words taken from\r
  * in, which will be read on various inputs of ALU 0-3. Outputs will be\r
@@ -76,7 +75,7 @@ INLINE void write_output_regular(struct mems m, struct bf_out res, bool second_h
  *                     read input a from memory b and v.v. If not, \r
  *                     simply read a from memory a and b from memory b.\r
  */\r
-INLINE struct bf_in read_input_regular(struct mems m, bool cycle_odd, bool stage_odd) {\r
+INLINE struct bf_in read_input_regular(struct mems m, bool cycle_odd, int stage) {\r
        struct bf_in in;\r
         /* Swap memory a and b during the odd cycles */\r
        if (cycle_odd) {\r
@@ -110,11 +109,10 @@ INLINE struct bf_in read_input_regular(struct mems m, bool cycle_odd, bool stage
 }\r
 \r
 /**\r
- * Initializes the addresses for writing the outputs.\r
- * @param stage_odd   True if this is an odd stage.\r
- * @param second_half True if we are initing halfway a stage.\r
+ * Initializes the addresses for reading the inputs and twiddel factors.\r
+ * Should be called once at the start of each stage.\r
  */ \r
-INLINE void init_input_addresses_regular(struct mems m, bool stage_odd) {\r
+INLINE void init_input_addresses_regular(struct mems m) {\r
        /* We simply start reading at address 0 incrementally */\r
        set_base(m.input_a_im, 0);\r
        set_base(m.input_b_re, 0);\r
@@ -134,7 +132,7 @@ INLINE void init_input_addresses_regular(struct mems m, bool stage_odd) {
  * Initializes the addresses for reading the inputs. This function must be\r
  * called twice per stage, since halfway the stage the addressing changes.\r
  */\r
-INLINE void init_output_addresses_regular(struct mems m, bool stage_odd, bool second_half) {\r
+INLINE void init_output_addresses_regular(struct mems m, bool second_half) {\r
        /* \r
         * For the second half of the stage, the starting addresses are \r
         * reversed. write_output_regular above will also swap the output\r
@@ -163,7 +161,7 @@ INLINE void init_output_addresses_regular(struct mems m, bool stage_odd, bool se
        }\r
 }\r
 \r
-INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_half){\r
+INLINE void do_half_regular_stage(struct mems m, int stage, bool second_half){\r
         /*\r
         * We are doing two cycles in each iteration, so we can alternate the\r
         * cycle_odd argument (which only works with constants, I don't expect\r
@@ -179,10 +177,10 @@ INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_hal
         */\r
 \r
        /* Initialize output addresses, this must be done twice per stage */\r
-       init_output_addresses_regular(m, stage_odd, second_half);\r
+       init_output_addresses_regular(m, second_half);\r
 \r
        /* First cycle (no previous output to write) */\r
-       struct bf_in in = read_input_regular(m, EVEN_CYCLE, stage_odd);\r
+       struct bf_in in = read_input_regular(m, EVEN_CYCLE, stage);\r
        struct bf_out out = butterfly(in);\r
 \r
        /* Now, do half a single stage. That means N_t / 4 cycles. Since we do 2\r
@@ -194,7 +192,7 @@ INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_hal
                write_output_regular(m, out, second_half);\r
 \r
                /* Odd cycle */\r
-               in = read_input_regular(m, ODD_CYCLE, second_half);\r
+               in = read_input_regular(m, ODD_CYCLE, stage);\r
                out = butterfly(in);\r
                next_cycle();\r
 \r
@@ -202,7 +200,7 @@ INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_hal
                write_output_regular(m, out, second_half);\r
 \r
                /* Even cycle */\r
-               in = read_input_regular(m, EVEN_CYCLE, second_half);\r
+               in = read_input_regular(m, EVEN_CYCLE, stage);\r
                out = butterfly(in);\r
        } while (loop_next(LC2));\r
        \r
@@ -210,7 +208,7 @@ INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_hal
        write_output_regular(m, out, second_half);\r
 \r
        /* Last cycle */\r
-       in = read_input_regular(m, ODD_CYCLE, second_half);\r
+       in = read_input_regular(m, ODD_CYCLE, stage);\r
        out = butterfly(in);\r
        next_cycle();\r
 \r
@@ -222,9 +220,15 @@ INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_hal
        next_cycle();\r
 }\r
 \r
-INLINE struct mems init_mem_mapping(bool stage_odd){\r
+/**\r
+ * Assign the input and output memories, based on the current stage. Also \r
+ * assigns the twiddle memories, but those are fixed.\r
+ */\r
+INLINE struct mems init_mem_mapping(int stage){\r
        struct mems res;\r
-       if (stage_odd) {\r
+       /* Use left memories for input on odd (ie, first) \r
+        * stages and right memories on even stages. */\r
+       if ((stage % 2) == 0) {\r
                res.input_a_re   = alloc_mem(P0M1);\r
                res.input_a_im   = alloc_mem(P1M1);\r
                res.input_b_re   = alloc_mem(P2M1);\r
@@ -249,27 +253,21 @@ INLINE struct mems init_mem_mapping(bool stage_odd){
        \r
        return res;\r
 }\r
+\r
+INLINE void do_regular_stage(int stage)\r
+{\r
+       struct mems m = init_mem_mapping(stage);\r
+       init_input_addresses_regular(m);\r
+       /* do_half_regular_stage will init output addresses */\r
+       next_cycle();\r
+       do_half_regular_stage(m, stage, FIRST_HALF);\r
+       do_half_regular_stage(m, stage, SECOND_HALF);\r
+}\r
 void run() {\r
        do { freeze(); } while (gpi(0) == 0);\r
-       struct mems m;\r
 \r
-       /* We need to do n_t regular stages. Since we do two stages each\r
-        * iteration, we'll do n_t / 2 iterations (and a -1 because we check after looping) */\r
-       init_loop(LC1, (PARAM_n_t / 2) - 1);\r
-       do {\r
-               m = init_mem_mapping(EVEN_STAGE);\r
-               init_input_addresses_regular(m, EVEN_STAGE);\r
-               /* do_half_regular_stage will init output addresses */\r
-               next_cycle();\r
-               do_half_regular_stage(m, EVEN_STAGE, FIRST_HALF);\r
-               do_half_regular_stage(m, EVEN_STAGE, SECOND_HALF);\r
-               stage++;\r
-               next_cycle();\r
-               init_input_addresses_regular(m, ODD_STAGE);\r
-               m = init_mem_mapping(ODD_STAGE);\r
-               next_cycle();\r
-               do_half_regular_stage(m, ODD_STAGE, FIRST_HALF);\r
-               do_half_regular_stage(m, ODD_STAGE, SECOND_HALF);\r
-               stage++;\r
-       } while (loop_next(LC1));\r
+       do_regular_stage(1);\r
+       do_regular_stage(2);\r
+       do_regular_stage(3);\r
+       do_regular_stage(4);\r
 }\r