data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v
1: b'%Warning-IMPLICIT: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:153: Signal definition not found, creating implicitly: \'data_sum_rdy\'\nassign data_sum_rdy = 1; \n       ^~~~~~~~~~~~\n                   ... Use "/* verilator lint_off IMPLICIT */" and lint_on around source to disable this message.\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:170: Cannot find file containing module: \'bfp_process_elemnt\'\n    bfp_process_elemnt #(\n    ^~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/213397499/verilog,data/full_repos/permissive/213397499/bfp_process_elemnt\n             data/full_repos/permissive/213397499/verilog,data/full_repos/permissive/213397499/bfp_process_elemnt.v\n             data/full_repos/permissive/213397499/verilog,data/full_repos/permissive/213397499/bfp_process_elemnt.sv\n             bfp_process_elemnt\n             bfp_process_elemnt.v\n             bfp_process_elemnt.sv\n             obj_dir/bfp_process_elemnt\n             obj_dir/bfp_process_elemnt.v\n             obj_dir/bfp_process_elemnt.sv\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:265: Cannot find file containing module: \'sif_add\'\n    sif_add #(\n    ^~~~~~~\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:316: Cannot find file containing module: \'sif_add\'\n        sif_add #(\n        ^~~~~~~\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:366: Cannot find file containing module: \'sif_add\'\n        sif_add #(\n        ^~~~~~~\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:579: Cannot find file containing module: \'sif_add\'\n    sif_add #(\n    ^~~~~~~\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:735: Cannot find file containing module: \'sif_add\'\nsif_add #(\n^~~~~~~\n%Error: data/full_repos/permissive/213397499/verilog/bfp_compute_engine.v:758: Cannot find file containing module: \'barrel_shifter\'\nbarrel_shifter #(\n^~~~~~~~~~~~~~\n%Error: Exiting due to 7 error(s), 1 warning(s)\n'
module bfp_compute_engine
# (

  parameter pc = 32,

  parameter pe = 4,

  parameter in_data_width=8,

  parameter out_data_width=24,

  parameter latency_add=1,

  parameter latency_mul=4,

  parameter bias_data_width=32
)
(
  input  wire                        clk,
  input  wire                        rst_n,


  input  wire  [pc*in_data_width-1:0]  coef,
  input  wire                          coef_vld,

  input  wire                           up_vld,
  input  wire  [pc*in_data_width-1:0]  up_dat,
  output wire                           up_rdy,


  input wire    [4:0]               shift_bits,

  input  wire                        filter_finish_data,


  output wire                        filter_finish_cal,

  input  wire  [bias_data_width-1:0]      bias_dat,
  input  wire                        bias_vld,

  input  wire                           acc_result_vld,


  output wire                        dn_vld,
  output wire  [in_data_width-1:0]    dn_dat,
  input  wire                        dn_rdy

);


localparam NUM_PE = pc / pe;

localparam LATENCY_CU = ((latency_mul + 1) + ($clog2(pe) + 1) * (latency_add + 1)) +
    $clog2(NUM_PE) * (latency_add + 1);


localparam LATENCY_CU_BIAS = LATENCY_CU + (latency_add);


genvar i;

wire [pe*in_data_width-1:0]           pixel_in[NUM_PE-1:0];
wire [pe*in_data_width-1:0]           coeff_in[NUM_PE-1:0];


wire [out_data_width-1:0]           mult_result[NUM_PE-1:0];
reg  [2*in_data_width+$clog2(pe)-1:0]           mult_result_r[NUM_PE-1:0];

wire                            mult_result_vld[NUM_PE-1:0];
reg                             mult_result_vld_r[NUM_PE-1:0];

reg  [2*in_data_width+$clog2(pe)-1:0]           mult_result_l1[NUM_PE-1:0];
reg                             mult_result_vld_l1[NUM_PE-1:0];
reg  [2*in_data_width+$clog2(pe)-1:0]           mult_result_l2[NUM_PE-1:0];
reg                             mult_result_vld_l2[NUM_PE-1:0];


wire [2*in_data_width+$clog2(pe):0]           accu_l1[(NUM_PE>>1)-1:0];
reg  [2*in_data_width+$clog2(pe):0]           accu_l1_r[(NUM_PE>>1)-1:0];

wire                            accu_l1_vld[(NUM_PE>>1)-1:0];
reg                             accu_l1_vld_r[(NUM_PE>>1)-1:0];


wire [2*in_data_width+$clog2(pe)+1:0]           accu_l2[(NUM_PE>>2)-1:0];
reg  [2*in_data_width+$clog2(pe)+1:0]           accu_l2_r[(NUM_PE>>2)-1:0];

wire                            accu_l2_vld[(NUM_PE>>2)-1:0];
reg                             accu_l2_vld_r[(NUM_PE>>2)-1:0];


wire [2*in_data_width+$clog2(pe)+2:0]           accu_l3[(NUM_PE>>3)-1:0];
reg  [2*in_data_width+$clog2(pe)+2:0]           accu_l3_r[(NUM_PE>>3)-1:0];

wire                            accu_l3_vld[(NUM_PE>>3)-1:0];
reg                             accu_l3_vld_r[(NUM_PE>>3)-1:0];


wire [2*in_data_width+$clog2(pe)+3:0]           accu_l4[(NUM_PE>>4)-1:0];
reg  [2*in_data_width+$clog2(pe)+3:0]           accu_l4_r[(NUM_PE>>4)-1:0];

wire                            accu_l4_vld[(NUM_PE>>4)-1:0];
reg                             accu_l4_vld_r[(NUM_PE>>4)-1:0];


wire [2*in_data_width+$clog2(pe)+4:0]           accu_l5[(NUM_PE>>5)-1:0];
reg  [2*in_data_width+$clog2(pe)+4:0]           accu_l5_r[(NUM_PE>>5)-1:0];

wire                            accu_l5_vld[(NUM_PE>>5)-1:0];
reg                             accu_l5_vld_r[(NUM_PE>>5)-1:0];



wire [out_data_width-1:0]           accu_chnl;
reg  [out_data_width-1:0]           accu_chnl_r;

wire                            accu_chnl_vld;
reg                             accu_chnl_vld_r;


wire [out_data_width-1:0]           partial_result;
wire                            partial_result_vld;


wire [out_data_width-1:0]           bias_result_dat;
wire                            bias_result_vld;



reg  [LATENCY_CU-1:0]          acc_result_vld_r;
reg  [LATENCY_CU_BIAS-1:0]      filter_finish_data_r;
reg                            filter_finish_cal_r;

wire                            fifo_up_rdy;


reg first_dat_point;



wire  [bias_data_width-1:0]                    shifted_dat; 


assign up_rdy = dn_rdy;
assign data_sum_rdy = 1; 





generate
for (i=0 ; i<NUM_PE; i=i+1)
begin : GENERATE_PIXEL_IN
    assign pixel_in[i] = up_dat[( pe*in_data_width*i + pe*in_data_width-1) : (pe*in_data_width*i)];
    assign coeff_in[i] = coef[( pe*in_data_width*i + pe*in_data_width-1) : (pe*in_data_width*i)];
end
endgenerate

generate
for(i=0; i<NUM_PE ; i=i+1)
begin : GENERATE_PE_DATA
    bfp_process_elemnt #(
        .pe(pe),
        .in_data_width(in_data_width),
        .out_data_width(out_data_width)
    ) u_process_elemnt_result
    (
        .rst_n(rst_n),
        .clk(clk),
        .coef(coeff_in[i]),
        .coef_vld(coef_vld),
        .up_vld(up_vld),
        .up_dat(pixel_in[i]),
        .up_rdy(),
        .dn_vld(mult_result_vld[i]),
        .dn_dat(mult_result[i]),
        .dn_rdy(1'b1)
    );
end
endgenerate






generate
for(i=0; i<NUM_PE; i=i+1)
begin : GENERATE_PE_REG_L1
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        mult_result_l1[i] <= 0;
        mult_result_vld_l1[i] <= 0; 
    end
    else if(mult_result_vld[i]) begin
        mult_result_l1[i] <= mult_result[i][2*in_data_width+$clog2(pe)-1:0];
        mult_result_vld_l1[i] <= mult_result_vld[i];
    end
    else begin
        mult_result_l1[i] <= 0;
        mult_result_vld_l1[i] <= 0; 
    end
end
endgenerate


generate
for(i=0; i<NUM_PE; i=i+1)
begin : GENERATE_PE_REG_L2
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        mult_result_l2[i] <= 0;
        mult_result_vld_l2[i] <= 0; 
    end
    else if(mult_result_vld_l1[i]) begin
        mult_result_l2[i] <= mult_result_l1[i];
        mult_result_vld_l2[i] <= mult_result_vld_l1[i];
    end
    else begin
        mult_result_l2[i] <= 0;
        mult_result_vld_l2[i] <= 0; 
    end
end
endgenerate






generate
for(i=0; i<NUM_PE; i=i+1)
begin : GENERATE_PE_REG
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        mult_result_r[i] <= 0;
        mult_result_vld_r[i] <= 0; 
    end
    else if(mult_result_vld_l2[i]) begin
        mult_result_r[i] <= mult_result_l2[i];
        mult_result_vld_r[i] <= mult_result_vld_l2[i];
    end
    else begin
        mult_result_r[i] <= 0;
        mult_result_vld_r[i] <= 0; 
    end
end
endgenerate





generate
for(i=0; i<(NUM_PE>>1) ; i=i+1)
begin : FIRST_LEVEL_ADDER
    sif_add #(
        .WIDTH_A(2*in_data_width+$clog2(pe)),
        .WIDTH_B(2*in_data_width+$clog2(pe)),
        .WIDTH_S(2*in_data_width+$clog2(pe)+1),
        .TYPE_SIGNAL(0),
        .TYPE_OP(0)
    ) u_sif_add_result_1st
    (
        .rst_n(rst_n),
        .clk(clk),
        .A_vld(mult_result_vld_r[i]),
        .A_dat(mult_result_r[i]),
        .A_rdy(),
        .B_vld(mult_result_vld_r[NUM_PE-1-i]),
        .B_dat(mult_result_r[NUM_PE-1-i]),
        .B_rdy(),
        .S_vld(accu_l1_vld[i]),
        .S_dat(accu_l1[i]),
        .S_rdy(1'b1),
        .overflow()
    );
end
endgenerate

generate
for(i=0; i<(NUM_PE>>1); i=i+1)
begin : GENERATE_ACCU_REG_FIRST_LEVEL
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        accu_l1_r[i] <= 0;
        accu_l1_vld_r[i] <= 0; 
    end
    else if(accu_l1_vld[i]) begin
        accu_l1_r[i] <= accu_l1[i];
        accu_l1_vld_r[i] <= accu_l1_vld[i];
    end
    else begin
        accu_l1_r[i] <= 0;
        accu_l1_vld_r[i] <= 0; 
    end
end
endgenerate





generate
if (pc>8) begin : SELECT_SECOND_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>2) ; i=i+1)
    begin : SECOND_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+1),
            .WIDTH_B(2*in_data_width+$clog2(pe)+1),
            .WIDTH_S(2*in_data_width+$clog2(pe)+2),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_2nd
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l1_vld_r[i]),
            .A_dat(accu_l1_r[i]),
            .A_rdy(),
            .B_vld(accu_l1_vld_r[(NUM_PE>>1)-1-i]),
            .B_dat(accu_l1_r[(NUM_PE>>1)-1-i]),
            .B_rdy(),
            .S_vld(accu_l2_vld[i]),
            .S_dat(accu_l2[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>2); i=i+1)
    begin : GENERATE_ACCU_REG_SECOND_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l2_r[i] <= 0;
            accu_l2_vld_r[i] <= 0; 
        end
        else if(accu_l2_vld[i]) begin
            accu_l2_r[i] <= accu_l2[i];
            accu_l2_vld_r[i] <= accu_l2_vld[i];
        end
        else begin
            accu_l2_r[i] <= 0;
            accu_l2_vld_r[i] <= 0; 
        end
    end
end
endgenerate





generate
if (pc>16) begin : SELECT_THIRD_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>3) ; i=i+1)
    begin : THIRD_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+2),
            .WIDTH_B(2*in_data_width+$clog2(pe)+2),
            .WIDTH_S(2*in_data_width+$clog2(pe)+3),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_3rd
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l2_vld_r[i]),
            .A_dat(accu_l2_r[i]),
            .A_rdy(),
            .B_vld(accu_l2_vld_r[(NUM_PE>>2)-1-i]),
            .B_dat(accu_l2_r[(NUM_PE>>2)-1-i]),
            .B_rdy(),
            .S_vld(accu_l3_vld[i]),
            .S_dat(accu_l3[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>3); i=i+1)
    begin : GENERATE_ACCU_REG_THIRD_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l3_r[i] <= 0;
            accu_l3_vld_r[i] <= 0; 
        end
        else if(accu_l3_vld[i]) begin
            accu_l3_r[i] <= accu_l3[i];
            accu_l3_vld_r[i] <= accu_l3_vld[i];
        end
        else begin
            accu_l3_r[i] <= 0;
            accu_l3_vld_r[i] <= 0; 
        end
    end   
end
endgenerate




generate
if (pc>32) begin : SELECT_FOURTH_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>4) ; i=i+1)
    begin : FOURTH_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+3),
            .WIDTH_B(2*in_data_width+$clog2(pe)+3),
            .WIDTH_S(2*in_data_width+$clog2(pe)+4),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_4th
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l3_vld_r[i]),
            .A_dat(accu_l3_r[i]),
            .A_rdy(),
            .B_vld(accu_l3_vld_r[(NUM_PE>>3)-1-i]),
            .B_dat(accu_l3_r[(NUM_PE>>3)-1-i]),
            .B_rdy(),
            .S_vld(accu_l4_vld[i]),
            .S_dat(accu_l4[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>4); i=i+1)
    begin : GENERATE_ACCU_REG_FORTH_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l4_r[i] <= 0;
            accu_l4_vld_r[i] <= 0; 
        end
        else if(accu_l4_vld[i]) begin
            accu_l4_r[i] <= accu_l4[i];
            accu_l4_vld_r[i] <= accu_l4_vld[i];
        end
        else begin
            accu_l4_r[i] <= 0;
            accu_l4_vld_r[i] <= 0; 
        end
    end
end
endgenerate




generate
if (pc>64) begin : SELECT_FIFTH_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>5) ; i=i+1)
    begin : FIFTH_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+4),
            .WIDTH_B(2*in_data_width+$clog2(pe)+4),
            .WIDTH_S(2*in_data_width+$clog2(pe)+5),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_4th
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l4_vld_r[i]),
            .A_dat(accu_l4_r[i]),
            .A_rdy(),
            .B_vld(accu_l4_vld_r[(NUM_PE>>4)-1-i]),
            .B_dat(accu_l4_r[(NUM_PE>>4)-1-i]),
            .B_rdy(),
            .S_vld(accu_l5_vld[i]),
            .S_dat(accu_l5[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>5); i=i+1)
    begin : GENERATE_ACCU_REG_FIFTH_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l5_r[i] <= 0;
            accu_l5_vld_r[i] <= 0; 
        end
        else if(accu_l5_vld[i]) begin
            accu_l5_r[i] <= accu_l5[i];
            accu_l5_vld_r[i] <= accu_l5_vld[i];
        end
        else begin
            accu_l5_r[i] <= 0;
            accu_l5_vld_r[i] <= 0; 
        end
    end
end
endgenerate







always @(posedge clk or negedge rst_n)
if(!rst_n) 
    first_dat_point <= 1'b0; 
else if(acc_result_vld_r[LATENCY_CU-2]) begin
    first_dat_point <= 1'b1;
end
else begin
    if (partial_result_vld)
        first_dat_point <= 1'b0;
    else
        first_dat_point <= first_dat_point;
end

generate
if (pc==8) begin
    assign partial_result_vld = accu_l1_vld_r[0];
    assign partial_result = (accu_l1_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+1),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l1_vld_r[0]),
        .B_dat(accu_l1_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
else if (pc==16) begin
    assign partial_result_vld = accu_l2_vld_r[0];
    assign partial_result = (accu_l2_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+2),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l2_vld_r[0]),
        .B_dat(accu_l2_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
else if (pc==32) begin
    assign partial_result_vld = accu_l3_vld_r[0];
    assign partial_result = (accu_l3_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+3),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l3_vld_r[0]),
        .B_dat(accu_l3_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end 
else if (pc==64) begin
    assign partial_result_vld = accu_l4_vld_r[0];
    assign partial_result = (accu_l4_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+4),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l4_vld_r[0]),
        .B_dat(accu_l4_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
else if (pc==128) begin
    assign partial_result_vld = accu_l5_vld_r[0];
    assign partial_result = (accu_l5_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+5),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l5_vld_r[0]),
        .B_dat(accu_l5_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
endgenerate






always @(posedge clk or negedge rst_n)
if(!rst_n) 
    acc_result_vld_r[0] <= 0; 
  else if(acc_result_vld&up_vld&coef_vld)
    acc_result_vld_r[0] <= acc_result_vld;
else 
    acc_result_vld_r[0] <= 0;

generate
for(i=1; i<LATENCY_CU; i=i+1)
begin : GENERATE_ACC_VALID
    always @(posedge clk or negedge rst_n)
    if(!rst_n) 
        acc_result_vld_r[i] <= 0; 
    else if(acc_result_vld_r[i-1])
        acc_result_vld_r[i] <= acc_result_vld_r[i-1];
    else 
        acc_result_vld_r[i] <= 0;
end
endgenerate





always @(posedge clk or negedge rst_n)
if(!rst_n) 
    filter_finish_data_r[0] <= 0; 
else if(filter_finish_data & dn_rdy & coef_vld)
    filter_finish_data_r[0] <= filter_finish_data;
else 
    filter_finish_data_r[0] <= 0;

generate
for(i=1; i<LATENCY_CU_BIAS; i=i+1)
begin : GENERATE_FILTER_VALID
    always @(posedge clk or negedge rst_n)
    if(!rst_n) 
        filter_finish_data_r[i] <= 0; 
    else if(filter_finish_data_r[i-1])
        filter_finish_data_r[i] <= filter_finish_data_r[i-1];
    else 
        filter_finish_data_r[i] <= 0;
end
endgenerate

always @(posedge clk or negedge rst_n)
if(!rst_n) 
    filter_finish_cal_r <= 0; 
else if(filter_finish_data_r[LATENCY_CU_BIAS-2])
    filter_finish_cal_r <= 1;
else 
    filter_finish_cal_r <= 0;

assign filter_finish_cal = filter_finish_cal_r;




always @(posedge clk or negedge rst_n)
if(!rst_n) begin
    accu_chnl_r <= 0;
    accu_chnl_vld_r <= 0; 
end
else if(accu_chnl_vld & acc_result_vld_r[LATENCY_CU-1]) begin
    accu_chnl_r <= accu_chnl;
    accu_chnl_vld_r <= accu_chnl_vld;
end
else begin
    accu_chnl_r <= 0;
    accu_chnl_vld_r <= 0; 
end





sif_add #(
    .WIDTH_A(out_data_width),
    .WIDTH_B(bias_data_width),
    .WIDTH_S(out_data_width),
    .TYPE_SIGNAL(1),
    .TYPE_OP(0)
) u_sif_bias_add_pos
(
    .rst_n(rst_n),
    .clk(clk),
    .A_vld(accu_chnl_vld_r),
    .A_dat(accu_chnl_r),
    .A_rdy(),
    .B_vld(bias_vld),
    .B_dat(bias_dat),
    .B_rdy(),
    .S_vld(bias_result_vld),
    .S_dat(bias_result_dat),
    .S_rdy(1'b1),
    .overflow()
);


barrel_shifter #(
    .w(bias_data_width)
)
u_barrel_shifter (
    .rst_n(rst_n),
    .clk(clk),  
    .up_dat(bias_result_dat),
    .dn_dat(shifted_dat),
    .ctrl(shift_bits)  
);

assign dn_vld = bias_result_vld;
assign dn_dat = {shifted_dat[31], shifted_dat[16:10]};

endmodule
module bfp_compute_engine
# (

  parameter pc = 32,

  parameter pe = 4,

  parameter in_data_width=8,

  parameter out_data_width=24,

  parameter latency_add=1,

  parameter latency_mul=4,

  parameter bias_data_width=32
)
(
  input  wire                        clk,
  input  wire                        rst_n,


  input  wire  [pc*in_data_width-1:0]  coef,
  input  wire                          coef_vld,

  input  wire                           up_vld,
  input  wire  [pc*in_data_width-1:0]  up_dat,
  output wire                           up_rdy,


  input wire    [4:0]               shift_bits,

  input  wire                        filter_finish_data,


  output wire                        filter_finish_cal,

  input  wire  [bias_data_width-1:0]      bias_dat,
  input  wire                        bias_vld,

  input  wire                           acc_result_vld,


  output wire                        dn_vld,
  output wire  [in_data_width-1:0]    dn_dat,
  input  wire                        dn_rdy

);



localparam NUM_PE = pc / pe;

localparam LATENCY_CU = ((latency_mul + 1) + ($clog2(pe) + 1) * (latency_add + 1)) +
    $clog2(NUM_PE) * (latency_add + 1);


localparam LATENCY_CU_BIAS = LATENCY_CU + (latency_add);


genvar i;

wire [pe*in_data_width-1:0]           pixel_in[NUM_PE-1:0];
wire [pe*in_data_width-1:0]           coeff_in[NUM_PE-1:0];


wire [out_data_width-1:0]           mult_result[NUM_PE-1:0];
reg  [2*in_data_width+$clog2(pe)-1:0]           mult_result_r[NUM_PE-1:0];

wire                            mult_result_vld[NUM_PE-1:0];
reg                             mult_result_vld_r[NUM_PE-1:0];

reg  [2*in_data_width+$clog2(pe)-1:0]           mult_result_l1[NUM_PE-1:0];
reg                             mult_result_vld_l1[NUM_PE-1:0];
reg  [2*in_data_width+$clog2(pe)-1:0]           mult_result_l2[NUM_PE-1:0];
reg                             mult_result_vld_l2[NUM_PE-1:0];


wire [2*in_data_width+$clog2(pe):0]           accu_l1[(NUM_PE>>1)-1:0];
reg  [2*in_data_width+$clog2(pe):0]           accu_l1_r[(NUM_PE>>1)-1:0];

wire                            accu_l1_vld[(NUM_PE>>1)-1:0];
reg                             accu_l1_vld_r[(NUM_PE>>1)-1:0];


wire [2*in_data_width+$clog2(pe)+1:0]           accu_l2[(NUM_PE>>2)-1:0];
reg  [2*in_data_width+$clog2(pe)+1:0]           accu_l2_r[(NUM_PE>>2)-1:0];

wire                            accu_l2_vld[(NUM_PE>>2)-1:0];
reg                             accu_l2_vld_r[(NUM_PE>>2)-1:0];


wire [2*in_data_width+$clog2(pe)+2:0]           accu_l3[(NUM_PE>>3)-1:0];
reg  [2*in_data_width+$clog2(pe)+2:0]           accu_l3_r[(NUM_PE>>3)-1:0];

wire                            accu_l3_vld[(NUM_PE>>3)-1:0];
reg                             accu_l3_vld_r[(NUM_PE>>3)-1:0];


wire [2*in_data_width+$clog2(pe)+3:0]           accu_l4[(NUM_PE>>4)-1:0];
reg  [2*in_data_width+$clog2(pe)+3:0]           accu_l4_r[(NUM_PE>>4)-1:0];

wire                            accu_l4_vld[(NUM_PE>>4)-1:0];
reg                             accu_l4_vld_r[(NUM_PE>>4)-1:0];


wire [2*in_data_width+$clog2(pe)+4:0]           accu_l5[(NUM_PE>>5)-1:0];
reg  [2*in_data_width+$clog2(pe)+4:0]           accu_l5_r[(NUM_PE>>5)-1:0];

wire                            accu_l5_vld[(NUM_PE>>5)-1:0];
reg                             accu_l5_vld_r[(NUM_PE>>5)-1:0];



wire [out_data_width-1:0]           accu_chnl;
reg  [out_data_width-1:0]           accu_chnl_r;

wire                            accu_chnl_vld;
reg                             accu_chnl_vld_r;


wire [out_data_width-1:0]           partial_result;
wire                            partial_result_vld;


wire [out_data_width-1:0]           bias_result_dat;
wire                            bias_result_vld;



reg  [LATENCY_CU-1:0]          acc_result_vld_r;
reg  [LATENCY_CU_BIAS-1:0]      filter_finish_data_r;
reg                            filter_finish_cal_r;

wire                            fifo_up_rdy;


reg first_dat_point;



wire  [bias_data_width-1:0]                    shifted_dat; 


assign up_rdy = dn_rdy;
assign data_sum_rdy = 1; 





generate
for (i=0 ; i<NUM_PE; i=i+1)
begin : GENERATE_PIXEL_IN
    assign pixel_in[i] = up_dat[( pe*in_data_width*i + pe*in_data_width-1) : (pe*in_data_width*i)];
    assign coeff_in[i] = coef[( pe*in_data_width*i + pe*in_data_width-1) : (pe*in_data_width*i)];
end
endgenerate

generate
for(i=0; i<NUM_PE ; i=i+1)
begin : GENERATE_PE_DATA
    bfp_process_elemnt #(
        .pe(pe),
        .in_data_width(in_data_width),
        .out_data_width(out_data_width)
    ) u_process_elemnt_result
    (
        .rst_n(rst_n),
        .clk(clk),
        .coef(coeff_in[i]),
        .coef_vld(coef_vld),
        .up_vld(up_vld),
        .up_dat(pixel_in[i]),
        .up_rdy(),
        .dn_vld(mult_result_vld[i]),
        .dn_dat(mult_result[i]),
        .dn_rdy(1'b1)
    );
end
endgenerate






generate
for(i=0; i<NUM_PE; i=i+1)
begin : GENERATE_PE_REG_L1
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        mult_result_l1[i] <= 0;
        mult_result_vld_l1[i] <= 0; 
    end
    else if(mult_result_vld[i]) begin
        mult_result_l1[i] <= mult_result[i][2*in_data_width+$clog2(pe)-1:0];
        mult_result_vld_l1[i] <= mult_result_vld[i];
    end
    else begin
        mult_result_l1[i] <= 0;
        mult_result_vld_l1[i] <= 0; 
    end
end
endgenerate


generate
for(i=0; i<NUM_PE; i=i+1)
begin : GENERATE_PE_REG_L2
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        mult_result_l2[i] <= 0;
        mult_result_vld_l2[i] <= 0; 
    end
    else if(mult_result_vld_l1[i]) begin
        mult_result_l2[i] <= mult_result_l1[i];
        mult_result_vld_l2[i] <= mult_result_vld_l1[i];
    end
    else begin
        mult_result_l2[i] <= 0;
        mult_result_vld_l2[i] <= 0; 
    end
end
endgenerate






generate
for(i=0; i<NUM_PE; i=i+1)
begin : GENERATE_PE_REG
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        mult_result_r[i] <= 0;
        mult_result_vld_r[i] <= 0; 
    end
    else if(mult_result_vld_l2[i]) begin
        mult_result_r[i] <= mult_result_l2[i];
        mult_result_vld_r[i] <= mult_result_vld_l2[i];
    end
    else begin
        mult_result_r[i] <= 0;
        mult_result_vld_r[i] <= 0; 
    end
end
endgenerate





generate
for(i=0; i<(NUM_PE>>1) ; i=i+1)
begin : FIRST_LEVEL_ADDER
    sif_add #(
        .WIDTH_A(2*in_data_width+$clog2(pe)),
        .WIDTH_B(2*in_data_width+$clog2(pe)),
        .WIDTH_S(2*in_data_width+$clog2(pe)+1),
        .TYPE_SIGNAL(0),
        .TYPE_OP(0)
    ) u_sif_add_result_1st
    (
        .rst_n(rst_n),
        .clk(clk),
        .A_vld(mult_result_vld_r[i]),
        .A_dat(mult_result_r[i]),
        .A_rdy(),
        .B_vld(mult_result_vld_r[NUM_PE-1-i]),
        .B_dat(mult_result_r[NUM_PE-1-i]),
        .B_rdy(),
        .S_vld(accu_l1_vld[i]),
        .S_dat(accu_l1[i]),
        .S_rdy(1'b1),
        .overflow()
    );
end
endgenerate

generate
for(i=0; i<(NUM_PE>>1); i=i+1)
begin : GENERATE_ACCU_REG_FIRST_LEVEL
    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin
        accu_l1_r[i] <= 0;
        accu_l1_vld_r[i] <= 0; 
    end
    else if(accu_l1_vld[i]) begin
        accu_l1_r[i] <= accu_l1[i];
        accu_l1_vld_r[i] <= accu_l1_vld[i];
    end
    else begin
        accu_l1_r[i] <= 0;
        accu_l1_vld_r[i] <= 0; 
    end
end
endgenerate





generate
if (pc>8) begin : SELECT_SECOND_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>2) ; i=i+1)
    begin : SECOND_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+1),
            .WIDTH_B(2*in_data_width+$clog2(pe)+1),
            .WIDTH_S(2*in_data_width+$clog2(pe)+2),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_2nd
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l1_vld_r[i]),
            .A_dat(accu_l1_r[i]),
            .A_rdy(),
            .B_vld(accu_l1_vld_r[(NUM_PE>>1)-1-i]),
            .B_dat(accu_l1_r[(NUM_PE>>1)-1-i]),
            .B_rdy(),
            .S_vld(accu_l2_vld[i]),
            .S_dat(accu_l2[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>2); i=i+1)
    begin : GENERATE_ACCU_REG_SECOND_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l2_r[i] <= 0;
            accu_l2_vld_r[i] <= 0; 
        end
        else if(accu_l2_vld[i]) begin
            accu_l2_r[i] <= accu_l2[i];
            accu_l2_vld_r[i] <= accu_l2_vld[i];
        end
        else begin
            accu_l2_r[i] <= 0;
            accu_l2_vld_r[i] <= 0; 
        end
    end
end
endgenerate





generate
if (pc>16) begin : SELECT_THIRD_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>3) ; i=i+1)
    begin : THIRD_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+2),
            .WIDTH_B(2*in_data_width+$clog2(pe)+2),
            .WIDTH_S(2*in_data_width+$clog2(pe)+3),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_3rd
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l2_vld_r[i]),
            .A_dat(accu_l2_r[i]),
            .A_rdy(),
            .B_vld(accu_l2_vld_r[(NUM_PE>>2)-1-i]),
            .B_dat(accu_l2_r[(NUM_PE>>2)-1-i]),
            .B_rdy(),
            .S_vld(accu_l3_vld[i]),
            .S_dat(accu_l3[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>3); i=i+1)
    begin : GENERATE_ACCU_REG_THIRD_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l3_r[i] <= 0;
            accu_l3_vld_r[i] <= 0; 
        end
        else if(accu_l3_vld[i]) begin
            accu_l3_r[i] <= accu_l3[i];
            accu_l3_vld_r[i] <= accu_l3_vld[i];
        end
        else begin
            accu_l3_r[i] <= 0;
            accu_l3_vld_r[i] <= 0; 
        end
    end   
end
endgenerate




generate
if (pc>32) begin : SELECT_FOURTH_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>4) ; i=i+1)
    begin : FOURTH_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+3),
            .WIDTH_B(2*in_data_width+$clog2(pe)+3),
            .WIDTH_S(2*in_data_width+$clog2(pe)+4),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_4th
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l3_vld_r[i]),
            .A_dat(accu_l3_r[i]),
            .A_rdy(),
            .B_vld(accu_l3_vld_r[(NUM_PE>>3)-1-i]),
            .B_dat(accu_l3_r[(NUM_PE>>3)-1-i]),
            .B_rdy(),
            .S_vld(accu_l4_vld[i]),
            .S_dat(accu_l4[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>4); i=i+1)
    begin : GENERATE_ACCU_REG_FORTH_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l4_r[i] <= 0;
            accu_l4_vld_r[i] <= 0; 
        end
        else if(accu_l4_vld[i]) begin
            accu_l4_r[i] <= accu_l4[i];
            accu_l4_vld_r[i] <= accu_l4_vld[i];
        end
        else begin
            accu_l4_r[i] <= 0;
            accu_l4_vld_r[i] <= 0; 
        end
    end
end
endgenerate




generate
if (pc>64) begin : SELECT_FIFTH_LEVEL_ADDER
    for(i=0; i<(NUM_PE>>5) ; i=i+1)
    begin : FIFTH_LEVEL_ADDER
        sif_add #(
            .WIDTH_A(2*in_data_width+$clog2(pe)+4),
            .WIDTH_B(2*in_data_width+$clog2(pe)+4),
            .WIDTH_S(2*in_data_width+$clog2(pe)+5),
            .TYPE_SIGNAL(0),
            .TYPE_OP(0)
        ) u_sif_add_result_4th
        (
            .rst_n(rst_n),
            .clk(clk),
            .A_vld(accu_l4_vld_r[i]),
            .A_dat(accu_l4_r[i]),
            .A_rdy(),
            .B_vld(accu_l4_vld_r[(NUM_PE>>4)-1-i]),
            .B_dat(accu_l4_r[(NUM_PE>>4)-1-i]),
            .B_rdy(),
            .S_vld(accu_l5_vld[i]),
            .S_dat(accu_l5[i]),
            .S_rdy(1'b1),
            .overflow()
        );
    end

    for(i=0; i<(NUM_PE>>5); i=i+1)
    begin : GENERATE_ACCU_REG_FIFTH_LEVEL
        always @(posedge clk or negedge rst_n)
        if(!rst_n) begin
            accu_l5_r[i] <= 0;
            accu_l5_vld_r[i] <= 0; 
        end
        else if(accu_l5_vld[i]) begin
            accu_l5_r[i] <= accu_l5[i];
            accu_l5_vld_r[i] <= accu_l5_vld[i];
        end
        else begin
            accu_l5_r[i] <= 0;
            accu_l5_vld_r[i] <= 0; 
        end
    end
end
endgenerate







always @(posedge clk or negedge rst_n)
if(!rst_n) 
    first_dat_point <= 1'b0; 
else if(acc_result_vld_r[LATENCY_CU-2]) begin
    first_dat_point <= 1'b1;
end
else begin
    if (partial_result_vld)
        first_dat_point <= 1'b0;
    else
        first_dat_point <= first_dat_point;
end

generate
if (pc==8) begin
    assign partial_result_vld = accu_l1_vld_r[0];
    assign partial_result = (accu_l1_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+1),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l1_vld_r[0]),
        .B_dat(accu_l1_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
else if (pc==16) begin
    assign partial_result_vld = accu_l2_vld_r[0];
    assign partial_result = (accu_l2_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+2),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l2_vld_r[0]),
        .B_dat(accu_l2_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
else if (pc==32) begin
    assign partial_result_vld = accu_l3_vld_r[0];
    assign partial_result = (accu_l3_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+3),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l3_vld_r[0]),
        .B_dat(accu_l3_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end 
else if (pc==64) begin
    assign partial_result_vld = accu_l4_vld_r[0];
    assign partial_result = (accu_l4_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+4),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l4_vld_r[0]),
        .B_dat(accu_l4_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
else if (pc==128) begin
    assign partial_result_vld = accu_l5_vld_r[0];
    assign partial_result = (accu_l5_vld_r[0] & ((!acc_result_vld_r[LATENCY_CU-1]) & !first_dat_point)) ? accu_chnl : {out_data_width{1'b0}};
    sif_add #(
        .WIDTH_B(2*in_data_width+$clog2(pe)+5),
        .WIDTH_A(out_data_width),
        .WIDTH_S(out_data_width),
        .TYPE_SIGNAL(1),
        .TYPE_OP(0)
    ) u_sif_acc_chnl_pos
    (
        .rst_n(rst_n),
        .clk(clk),
        .B_vld(accu_l5_vld_r[0]),
        .B_dat(accu_l5_r[0]),
        .B_rdy(),
        .A_vld(partial_result_vld),
        .A_dat(partial_result),
        .A_rdy(),
        .S_vld(accu_chnl_vld),
        .S_dat(accu_chnl),
        .S_rdy(1'b1),
        .overflow()
    );
end
endgenerate






always @(posedge clk or negedge rst_n)
if(!rst_n) 
    acc_result_vld_r[0] <= 0; 
  else if(acc_result_vld&up_vld&coef_vld)
    acc_result_vld_r[0] <= acc_result_vld;
else 
    acc_result_vld_r[0] <= 0;

generate
for(i=1; i<LATENCY_CU; i=i+1)
begin : GENERATE_ACC_VALID
    always @(posedge clk or negedge rst_n)
    if(!rst_n) 
        acc_result_vld_r[i] <= 0; 
    else if(acc_result_vld_r[i-1])
        acc_result_vld_r[i] <= acc_result_vld_r[i-1];
    else 
        acc_result_vld_r[i] <= 0;
end
endgenerate





always @(posedge clk or negedge rst_n)
if(!rst_n) 
    filter_finish_data_r[0] <= 0; 
else if(filter_finish_data & dn_rdy & coef_vld)
    filter_finish_data_r[0] <= filter_finish_data;
else 
    filter_finish_data_r[0] <= 0;

generate
for(i=1; i<LATENCY_CU_BIAS; i=i+1)
begin : GENERATE_FILTER_VALID
    always @(posedge clk or negedge rst_n)
    if(!rst_n) 
        filter_finish_data_r[i] <= 0; 
    else if(filter_finish_data_r[i-1])
        filter_finish_data_r[i] <= filter_finish_data_r[i-1];
    else 
        filter_finish_data_r[i] <= 0;
end
endgenerate

always @(posedge clk or negedge rst_n)
if(!rst_n) 
    filter_finish_cal_r <= 0; 
else if(filter_finish_data_r[LATENCY_CU_BIAS-2])
    filter_finish_cal_r <= 1;
else 
    filter_finish_cal_r <= 0;

assign filter_finish_cal = filter_finish_cal_r;




always @(posedge clk or negedge rst_n)
if(!rst_n) begin
    accu_chnl_r <= 0;
    accu_chnl_vld_r <= 0; 
end
else if(accu_chnl_vld & acc_result_vld_r[LATENCY_CU-1]) begin
    accu_chnl_r <= accu_chnl;
    accu_chnl_vld_r <= accu_chnl_vld;
end
else begin
    accu_chnl_r <= 0;
    accu_chnl_vld_r <= 0; 
end





sif_add #(
    .WIDTH_A(out_data_width),
    .WIDTH_B(bias_data_width),
    .WIDTH_S(out_data_width),
    .TYPE_SIGNAL(1),
    .TYPE_OP(0)
) u_sif_bias_add_pos
(
    .rst_n(rst_n),
    .clk(clk),
    .A_vld(accu_chnl_vld_r),
    .A_dat(accu_chnl_r),
    .A_rdy(),
    .B_vld(bias_vld),
    .B_dat(bias_dat),
    .B_rdy(),
    .S_vld(bias_result_vld),
    .S_dat(bias_result_dat),
    .S_rdy(1'b1),
    .overflow()
);


barrel_shifter #(
    .w(bias_data_width)
)
u_barrel_shifter (
    .rst_n(rst_n),
    .clk(clk),  
    .up_dat(bias_result_dat),
    .dn_dat(shifted_dat),
    .ctrl(shift_bits)  
);

assign dn_vld = bias_result_vld;
assign dn_dat = {shifted_dat[31], shifted_dat[16:10]};

endmodule