* Actually make the output addressing different in the second half, it was
authorunknown <s0042331@.dynamic.ewi.utwente.nl>
Thu, 27 Mar 2008 15:45:56 +0000 (16:45 +0100)
committerunknown <s0042331@.dynamic.ewi.utwente.nl>
Thu, 27 Mar 2008 15:47:46 +0000 (16:47 +0100)
   still the same as the first half.
 * Actually do half a stage in do_half_regular_stage() instead of a full
   stage.
 * Let run do n_t stages instead of just two.
 * Call init_libmontiumc() in our main(), so libmontiumc actually works.

FFT.mc
FFT_support.cpp
main.cpp

diff --git a/FFT.mc b/FFT.mc
index 330b7f5be67632df7d362477e7651dc8492ac31c..3ad081668c51b058cece7d041f772a5c415ad94c 100644 (file)
--- a/FFT.mc
+++ b/FFT.mc
@@ -16,8 +16,10 @@ INLINE struct bf_out butterfly(struct bf_in in) {
        /* ALU 0 & 1 */\r
                /* im(W) * im(b) */\r
                aluexp Wixbi = west(fmul(rd1(in.W_im), rb1(in.b_im)));\r
+       \r
                /* re(W * b) = re(W) * re(b) - im(W) * im(b) */\r
                aluexp Wxbr  = ssub_acc(fmul(rc1(in.W_re), ra1(in.b_re)), Wixbi);\r
+\r
                \r
                /* re(out_a) = re(a) + re(W * b) */\r
                out.a_re =   p0o0(sadd_bf(rb1(in.a_re), Wxbr));\r
@@ -147,10 +149,10 @@ INLINE void init_output_addresses_regular(struct mems m, bool stage_odd, bool se
                set_offset(m.output_b_re, 0-2);\r
                set_offset(m.output_b_im, 0-2);\r
        } else {\r
-               set_offset(m.output_a_re, 1-2);\r
-               set_offset(m.output_a_im, 1-2);\r
-               set_offset(m.output_b_re, 0-2);\r
-               set_offset(m.output_b_im, 0-2);\r
+               set_offset(m.output_a_re, 0-2);\r
+               set_offset(m.output_a_im, 0-2);\r
+               set_offset(m.output_b_re, 1-2);\r
+               set_offset(m.output_b_im, 1-2);\r
        }\r
 }\r
 \r
@@ -176,10 +178,10 @@ INLINE void do_half_regular_stage(struct mems m, bool stage_odd, bool second_hal
        struct bf_in in = read_input_regular(m, EVEN_CYCLE, stage_odd);\r
        struct bf_out out = butterfly(in);\r
 \r
-       /* Now, do a single stage. That means N_t / 2 cycles. Since we do 2\r
+       /* Now, do half a single stage. That means N_t / 4 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, (PARAM_N_t / 4) - 1);\r
+        * we will loop N_t / 8 - 1 times. */\r
+       init_loop(LC2, (PARAM_N_t / 8) - 1);\r
        do {\r
                /* Write outputs of previous cycle */\r
                write_output_regular(m, out, second_half);\r
@@ -243,17 +245,22 @@ INLINE struct mems init_mem_mapping(bool stage_odd){
 void run() {\r
        do { freeze(); } while (gpi(0) == 0);\r
        struct mems m;\r
-       \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
-       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
+\r
+       /* We need to do n_t regular stages. Since we do two stages each\r
+        * iteration, we'll do n_t / 2 iterations. */\r
+       init_loop(LC1, (PARAM_n_t / 2));\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
+               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
+       } while (loop_next(LC1));\r
 }\r
index 6f21e5a24afa1e9cca6fe74a37bfa4965ff6d2ea..23d07f08ca102e114e7428807701f364fcdcc566 100644 (file)
@@ -4,7 +4,7 @@
 \r
 \r
 /* Didn't the Montium use Q15 instead of Q14? */\r
-#define FIXED_POINT 14\r
+#define FIXED_POINT 15\r
 #define WORD_SIZE   16\r
 \r
 #define WORDS_PER_LINE 4\r
@@ -55,46 +55,73 @@ void pre_run()
        input_a_im   = alloc_mem(P1M0);\r
        input_b_re   = alloc_mem(P2M0);\r
        input_b_im   = alloc_mem(P3M0);\r
-       output_a_re  = alloc_mem(P0M1);\r
-       output_a_im  = alloc_mem(P1M1);\r
-       output_b_re  = alloc_mem(P2M1);\r
-       output_b_im  = alloc_mem(P3M1);\r
+       \r
+       twiddle_re   = alloc_mem(P4M0);\r
+       twiddle_im   = alloc_mem(P4M1);\r
        \r
        /* TODO: Init memory and twiddles */\r
-       for (i=0;i<SIZE/2;i++)\r
+       for (i=0;i<PARAM_N_t/2;i++)\r
        {\r
-               set_mem(twiddle_re->id, i, to_fixed(cos(2*M_PI/SIZE*i)));\r
-               set_mem(twiddle_im->id, i, to_fixed(sin(2*M_PI/SIZE*i)));\r
+               set_mem(twiddle_re->id, i, to_fixed(cos(i*2*M_PI/PARAM_N_t)));\r
+               set_mem(twiddle_im->id, i, to_fixed(sin(i*2*M_PI/PARAM_N_t)));\r
        }\r
        \r
-       for (i=0;i<SIZE;i++)\r
+       for (i=0;i<PARAM_N_t;i++)\r
        {\r
-               int value = to_fixed(sin((float)i/SIZE*2*2*M_PI));\r
-               if (i<SIZE/2)\r
+               int value = to_fixed(sin((float)i*2*M_PI/PARAM_N_t));\r
+\r
+               if (i<PARAM_N_t/2)\r
                {\r
-                       set_mem(input_a_re->id, i, value);\r
-                       set_mem(input_a_im->id, i, 0);\r
+                       if (i % 2 == 0) {\r
+                               set_mem(input_a_re->id, i, value);\r
+                               set_mem(input_a_im->id, i, 0);\r
+                       } else {\r
+                               set_mem(input_b_re->id, i, value);\r
+                               set_mem(input_b_im->id, i, 0);\r
+                       }\r
                }\r
                else\r
                {\r
-                       set_mem(input_a_re->id, i - SIZE / 2, value);\r
-                       set_mem(input_a_im->id, i - SIZE / 2, 0);\r
+                       if (i % 2 == 0) {\r
+                               set_mem(input_b_re->id, i - PARAM_N_t/2, value);\r
+                               set_mem(input_b_im->id, i - PARAM_N_t/2, 0);\r
+                       } else {\r
+                               set_mem(input_a_re->id, i - PARAM_N_t/2, value);\r
+                               set_mem(input_a_im->id, i - PARAM_N_t/2, 0);\r
+                       }\r
                }\r
        }\r
-}\r
-\r
-void post_run()\r
-{\r
+       \r
        printf("re(W)\n");\r
-       print_mem(twiddle_re, 0, SIZE, true);\r
+       print_mem(twiddle_re, 0, PARAM_N_t/2, true);\r
        printf("im(W)\n");\r
-       print_mem(twiddle_im, 0, SIZE, true);\r
+       print_mem(twiddle_im, 0, PARAM_N_t/2, true);\r
        printf("re(in_a)\n");\r
-       print_mem(input_a_re, 0, SIZE, true);\r
+       print_mem(input_a_re, 0, PARAM_N_t/2, true);\r
        printf("re(in_b)\n");\r
-       print_mem(input_b_re, 0, SIZE, true);\r
+       print_mem(input_b_re, 0, PARAM_N_t/2, true);\r
+}\r
+\r
+void post_run()\r
+{\r
+       if (PARAM_n_t % 2 == 0) {\r
+               /* When the number of stages is odd, the \r
+                * outputs end up at the left memories again */\r
+               output_a_re  = alloc_mem(P0M0);\r
+               output_a_im  = alloc_mem(P1M0);\r
+               output_b_re  = alloc_mem(P2M0);\r
+               output_b_im  = alloc_mem(P3M0);\r
+       } else {\r
+               output_a_re  = alloc_mem(P0M1);\r
+               output_a_im  = alloc_mem(P1M1);\r
+               output_b_re  = alloc_mem(P2M1);\r
+               output_b_im  = alloc_mem(P3M1);\r
+       }\r
        printf("re(out_a)\n");\r
-       print_mem(output_a_re, 0, SIZE, true);\r
+       print_mem(output_a_re, 0, PARAM_N_t/2, true);\r
+       print_mem(output_b_re, 0, PARAM_N_t/2, true);\r
        printf("im(out_a)\n");\r
-       print_mem(output_a_im, 0, SIZE, true);\r
+       print_mem(output_a_im, 0, PARAM_N_t/2, true);\r
+       print_mem(output_b_im, 0, PARAM_N_t/2, true);\r
+\r
 }\r
index 3c2d4a6b246584d4753bc27270bcfc3e277f269b..f8cec1091da4b9a3ddd311c3dc32fdda406e6e0c 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -1,7 +1,8 @@
 #include "FFT.h"\r
 \r
 int main(int argc, char* argv[]) {\r
-\r
+       init_libmontiumc();\r
+       \r
        pre_run();\r
     set_gpi(0, 1);\r
        run();\r