module fm_3d_interp (
  clk_core,
  i_en,
  i_a,
  i_b,
  i_t,
  o_c
);

////////////////////////////
// I/O definition
////////////////////////////
    input         clk_core;
    input         i_en;
    input  [21:0] i_a;
    input  [21:0] i_b;
    input  [21:0] i_t;
    output [21:0] o_c;          // result


///////////////////////////////////////////
//  wire 
///////////////////////////////////////////
    wire [21:0]  w_b_a_3z;
    wire [21:0]  w_a_3z;
    wire [21:0]  w_t_3z;
    wire [21:0]  w_abt_6z;
    wire [21:0]  w_a_6z;

////////////////////////////
// module instance
////////////////////////////

    // stage1-3

    // ib-ia
    fm_3d_fadd fadd_b_a (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(i_b),
        .i_b(i_a),
        .i_adsb(1'b1),
        .o_c(w_b_a_3z)
    );

    fm_3d_delay #(22,3) delay_a (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_a),
        .o_data(w_a_3z)
    );

    fm_3d_delay #(22,3) delay_t (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(i_t),
        .o_data(w_t_3z)
    );

    // stage 4-6

    // (i_b-i_a)*t
    fm_3d_fmul fmul_t (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_b_a_3z),
        .i_b(w_t_3z),
        .o_c(w_abt_6z)
    );

    fm_3d_delay #(22,3) delay_a_2 (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_data(w_a_3z),
        .o_data(w_a_6z)
    );

    // stage 6-9

    // i_a + (i_b-i_a) *t
    fm_3d_fadd fadd_ab (
        .clk_core(clk_core),
        .i_en(i_en),
        .i_a(w_a_6z),
        .i_b(w_abt_6z),
        .i_adsb(1'b0),
        .o_c(o_c)
    );

endmodule