* Remove some unused code.
[matthijs/projects/montium-fft.git] / FFT.mc
diff --git a/FFT.mc b/FFT.mc
index e58d2fa771e0c644297c99d1935d66dd8b1055ba..6df71adcf9574508b3254204185c092ce8e12746 100644 (file)
--- a/FFT.mc
+++ b/FFT.mc
@@ -6,21 +6,11 @@
 \r
 #include "FFT.h"\r
 \r
-       word in_a_re, in_a_im, in_b_re, in_b_im, in_W_re, in_W_im;\r
-       //out_a_re, out_a_im, out_b_re, out_b_im;\r
-       //mem input_a_re, input_a_im, input_b_re, input_b_im, output_a_re, output_a_im, output_b_re, output_b_im, twiddle_re, twiddle_im; \r
-\r
-void init()\r
-{\r
-\r
-}\r
-\r
-\r
-\r
-/*void update_gpi() {\r
-  set_gpi(0, 1);\r
-}*/\r
-\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
+ * returned and will we be available on the output ports of ALU 0 and 2.\r
+ */\r
 INLINE struct bf_out butterfly(struct bf_in in) {\r
        struct bf_out out;\r
        /* ALU 0 & 1 */\r
@@ -48,6 +38,11 @@ INLINE struct bf_out butterfly(struct bf_in in) {
                return out;\r
 }\r
 \r
+/**\r
+ * Writes the output of a butterfly given in res to the correct memory\r
+ * locations.\r
+ * @param  second_half   Are we in the second half of the stage?\r
+ */\r
 INLINE void write_output_regular(struct mems m, struct bf_out res, bool second_half) {\r
        add_offset(m.output_a_re, 2);\r
        add_offset(m.output_a_im, 2);\r
@@ -80,7 +75,7 @@ INLINE void write_output_regular(struct mems m, struct bf_out res, bool second_h
  */\r
 INLINE struct bf_in read_input_regular(struct mems m, bool cycle_odd, bool stage_odd) {\r
        struct bf_in in;\r
-       /* TODO: Select left or right memories */\r
+        /* Swap memory a and b during the odd cycles */\r
        if (cycle_odd) {\r
                in.a_re = read_mem(m.input_a_re);\r
                in.a_im = read_mem(m.input_a_im);\r
@@ -95,7 +90,8 @@ INLINE struct bf_in read_input_regular(struct mems m, bool cycle_odd, bool stage
        in.W_re = read_mem(m.twiddle_re);\r
        in.W_im = read_mem(m.twiddle_im);\r
        \r
-\r
+       \r
+       /* Read inputs sequentially */\r
        add_offset(m.input_a_re, 1);\r
        add_offset(m.input_a_im, 1);\r
        add_offset(m.input_b_re, 1);\r
@@ -105,12 +101,12 @@ INLINE struct bf_in read_input_regular(struct mems m, bool cycle_odd, bool stage
 }\r
 \r
 /**\r
- *  Initializes the addresses for the various memories.\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
+ * @param second_half True if we are initing halfway a stage.\r
  */ \r
 INLINE void init_input_addresses_regular(struct mems m, bool stage_odd) {\r
-       /* TODO: Select left or right memories */\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
        set_base(m.input_b_im, 0);\r
@@ -124,8 +120,11 @@ INLINE void init_input_addresses_regular(struct mems m, bool stage_odd) {
        set_offset(m.twiddle_re, 0);\r
        set_offset(m.twiddle_im, 0);\r
 }\r
-       \r
-       \r
+\r
+/**\r
+ * 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
        /* \r
         * For the second half of the stage, the starting addresses are \r
@@ -156,32 +155,62 @@ INLINE void init_output_addresses_regular(struct mems m, bool stage_odd, bool se
 }\r
 \r
 INLINE void do_half_regular_stage(struct mems m, bool stage_odd, 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
+        * the optimizer to do this loop unrolling for us). Since we need to\r
+        * write outputs before reading, but don't have any outputs to write\r
+        * in the first cycle, we must put the first cycle outside of the\r
+        * loop. Since the loop does two cycles at a time, this means there\r
+        * must be two cycles outside of the loop, so we put one at the end as\r
+        * well. Additionally, we also need to write the outputs of the last\r
+        * cycle in an extra cycle at the end. We probably can't combine this\r
+        * last cycle with the first cycle of the next stage, because they\r
+        * need the same memories (input becomes output and v.v.).\r
+        */\r
+\r
+       /* Initialize output addresses, this must be done twice per stage */\r
+       init_output_addresses_regular(m, stage_odd, 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_out out = butterfly(in);\r
-       \r
+\r
        /* Now, do a single stage. That means N_t / 2 cycles. Since we do 2\r
         * cycles on every iteration, plus one before and after the loop,\r
         * we will loop N_t / 4 - 1 times. */\r
        init_loop(LC2, (N_t / 4) - 1);\r
        do {\r
-               init_output_addresses_regular(m, stage_odd, second_half);\r
+               /* Write outputs of previous cycle */\r
                write_output_regular(m, out, second_half);\r
 \r
+               /* Odd cycle */\r
                in = read_input_regular(m, ODD_CYCLE, second_half);\r
                out = butterfly(in);\r
                next_cycle();\r
+\r
+               /* Write outputs of previous cycle */\r
                write_output_regular(m, out, second_half);\r
 \r
+               /* Even cycle */\r
                in = read_input_regular(m, EVEN_CYCLE, second_half);\r
                out = butterfly(in);\r
        } while (loop_next(LC2));\r
        \r
+       /* Write outputs of previous cycle */\r
        write_output_regular(m, out, second_half);\r
+\r
+       /* Last cycle */\r
        in = read_input_regular(m, ODD_CYCLE, second_half);\r
        out = butterfly(in);\r
-       \r
        next_cycle();\r
+\r
+       /* Write outputs of last cycle */\r
        write_output_regular(m, out, second_half);\r
+       \r
+       /* Force the next cycle, because the next stage must read from\r
+        * the memory we just wrote to */\r
+       next_cycle();\r
 }\r
 \r
 INLINE struct mems init_mem_mapping(bool stage_odd){\r
@@ -212,10 +241,6 @@ INLINE struct mems init_mem_mapping(bool stage_odd){
        return res;\r
 }\r
 void run() {\r
-#ifdef __MONTIUMCC__\r
-       /* main.cpp will call init before pre_run(), so only need to call init for MontiumCC */\r
-       init();\r
-#endif\r
        do { freeze(); } while (gpi(0) == 0);\r
        struct mems m;\r
        \r