module InnerBlend
(
    input clock,
    input  [8:0] Op,
    input  [7:0] A,
    input  [7:0] B,
    input  [7:0] C,
    output reg [7:0] O
);

    function  [10:0] mul8x3;
        input   [7:0] op1;
        input   [2:0] op2;
    begin
        mul8x3 = 11'd0;
        if(op2[0]) mul8x3 = mul8x3 + op1;
        if(op2[1]) mul8x3 = mul8x3 + {op1, 1'b0};
        if(op2[2]) mul8x3 = mul8x3 + {op1, 2'b00};
    end
    endfunction

    reg OpOnes;
    reg [10:0] Amul, Bmul, Cmul;
    reg [10:0] At, Bt, Ct;
    reg [11:0] Res;

    reg [8:0] Op_q, Op_q_q, Op_q_q_q, Op_q_q_q_q;
    reg [7:0] A_q, A_q_q, A_q_q_q, A_q_q_q_q, B_q, B_q_q, C_q, C_q_q;

    always_ff @(posedge clock) begin
        // stage 1
        { Op_q, A_q, B_q, C_q } <= { Op, A, B, C };

        // stage 2
        OpOnes <= Op_q[4];
        Amul <= mul8x3(A_q, Op_q[7:5]);
        Bmul <= mul8x3(B_q, {Op_q[3:2], 1'b0});
        Cmul <= mul8x3(C_q, {Op_q[1:0], 1'b0});
        { Op_q_q, A_q_q, B_q_q, C_q_q } <= { Op_q, A_q, B_q, C_q };

        // stage 3
        At <=  Amul;
        Bt <= (OpOnes == 0) ? Bmul : {3'b0, B_q_q};
        Ct <= (OpOnes == 0) ? Cmul : {3'b0, C_q_q};
        { Op_q_q_q, A_q_q_q } <= { Op_q_q, A_q_q };

        // stage 4
        Res <= {At, 1'b0} + Bt + Ct;
        { Op_q_q_q_q, A_q_q_q_q } <= { Op_q_q_q, A_q_q_q };

        // stage 5
        O <= Op_q_q_q_q[8] ? A_q_q_q_q : Res[11:4];
    end
endmodule