/* 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
add_offset(m.output_b_re, 2);\r
add_offset(m.output_b_im, 2);\r
\r
- if (second_half) {\r
+ if (!second_half) {\r
write_mem(m.output_a_re, res.a_re);\r
write_mem(m.output_a_im, res.a_im);\r
write_mem(m.output_b_re, res.b_re);\r
* 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
add_offset(m.input_a_im, 1);\r
add_offset(m.input_b_re, 1);\r
add_offset(m.input_b_im, 1);\r
- /* TODO: Update twiddle offsets */\r
+ \r
+ /* TODO: Is this true? */\r
+ add_offset(m.twiddle_re, (PARAM_N_t>>stage));\r
+ add_offset(m.twiddle_im, (PARAM_N_t>>stage));\r
+ use_mask(m.twiddle_re, (PARAM_N_t/2)-1);\r
+ use_mask(m.twiddle_im, (PARAM_N_t/2)-1);\r
+\r
return in;\r
}\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
* 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
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
-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
*/\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 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. We add an extra - 1 because this is a do while loop... */\r
+ init_loop(LC2, (PARAM_N_t / 8) - 1 - 1);\r
do {\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
+ in = read_input_regular(m, ODD_CYCLE, stage);\r
out = butterfly(in);\r
next_cycle();\r
\r
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
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
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
\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
+ do_regular_stage(1);\r
+ do_regular_stage(2);\r
+ do_regular_stage(3);\r
+ do_regular_stage(4);\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
+ set_gpo(0);\r
next_cycle();\r
- init_input_addresses_regular(m, ODD_STAGE);\r
- m = init_mem_mapping(ODD_STAGE);\r
+ freeze();\r
+ clear_gpo(0);\r
next_cycle();\r
- do_half_regular_stage(m, ODD_STAGE, FIRST_HALF);\r
- do_half_regular_stage(m, ODD_STAGE, SECOND_HALF);\r
+ freeze();\r
}\r