data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v
1: b'%Warning-LITENDIAN: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:19: Little bit endian vector: MSB < LSB of bit range: 0:127\n        output [0 : 16*8-1] aouts,\n               ^\n                    ... Use "/* verilator lint_off LITENDIAN */" and lint_on around source to disable this message.\n%Warning-LITENDIAN: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:20: Little bit endian vector: MSB < LSB of bit range: 0:127\n        output [0 : 16*8-1] wouts, \n               ^\n%Error: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:40: Cannot find file containing module: \'CLKDIV\'\n    CLKDIV #(.DIV_CNT(9), .BITS(4)) clkdiv (.clk(clk), .rstn(rstn), .enable(clkdiven), .clkout(clkdivo));\n    ^~~~~~\n        ... Looked in:\n             data/full_repos/permissive/467394306/verilog/ctrl,data/full_repos/permissive/467394306/CLKDIV\n             data/full_repos/permissive/467394306/verilog/ctrl,data/full_repos/permissive/467394306/CLKDIV.v\n             data/full_repos/permissive/467394306/verilog/ctrl,data/full_repos/permissive/467394306/CLKDIV.sv\n             CLKDIV\n             CLKDIV.v\n             CLKDIV.sv\n             obj_dir/CLKDIV\n             obj_dir/CLKDIV.v\n             obj_dir/CLKDIV.sv\n%Error: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:52: Cannot find file containing module: \'INPMEM\'\n    INPMEM #(.sub_mems(256), .addr_len(8)) amem(.Q(amemQ), .clk(clk), .CEN(1\'b0), .WEN(aWEN), .A(a_addr), .D(Dbuf));\n    ^~~~~~\n%Error: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:53: Cannot find file containing module: \'INPMEM\'\n    INPMEM #(.sub_mems(256), .addr_len(8)) wmem(.Q(wmemQ), .clk(clk), .CEN(1\'b0), .WEN(wWEN), .A(w_addr), .D(Dbuf));\n    ^~~~~~\n%Error: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:73: Cannot find file containing module: \'RBUF\'\n            RBUF #(.WORDLEN(8), .BUFSIZE(gi+1)) abuf_gen (\n            ^~~~\n%Error: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:82: Cannot find file containing module: \'RBUF\'\n            RBUF #(.WORDLEN(8), .BUFSIZE(gi+1)) wbuf_gen (\n            ^~~~\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:115: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n    assign chconvs = (configs[2]-2) * (configs[3]-2);\n                                ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:115: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n    assign chconvs = (configs[2]-2) * (configs[3]-2);\n                                                 ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:116: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n    assign rowconvs = (configs[2]-2);\n                                 ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:198: Bit extraction of array[3:0] requires 2 bit index, not 4 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            configs[cur_conf] <= data_in;\n                                   ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:197: Operator LTE expects 4 bits on the RHS, but RHS\'s CONST \'2\'h3\' generates 2 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                        if (cur_conf <= 2\'b11 && data_load) begin\n                                     ^~\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:299: Operator ADD expects 32 or 16 bits on the RHS, but RHS\'s VARREF \'peitcnt\' generates 4 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                    a_addr <= base_addr + peitcnt + 2 + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;\n                                                        ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:299: Operator ADD expects 32 or 16 bits on the RHS, but RHS\'s VARREF \'lcolcnt\' generates 3 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                    a_addr <= base_addr + peitcnt + 2 + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;\n                                                                                                                            ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:306: Operator ADD expects 16 bits on the RHS, but RHS\'s VARREF \'peitcnt\' generates 4 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                    a_addr <= base_addr + peitcnt + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;\n                                                        ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:306: Operator ADD expects 16 bits on the RHS, but RHS\'s VARREF \'lcolcnt\' generates 3 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                    a_addr <= base_addr + peitcnt + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;\n                                                                                                                        ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:296: Operator GTE expects 5 bits on the LHS, but LHS\'s VARREF \'peitcnt\' generates 4 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                end else if (peitcnt >= rowendcnt) begin\n                                                     ^~\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:292: Operator ADD expects 32 or 16 bits on the RHS, but RHS\'s VARREF \'peitcnt\' generates 4 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                if (convcnt + peitcnt > (configs[2] - 2) * (configs[3] - 2)) begin\n                                            ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:292: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                if (convcnt + peitcnt > (configs[2] - 2) * (configs[3] - 2)) begin\n                                                                    ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:292: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                if (convcnt + peitcnt > (configs[2] - 2) * (configs[3] - 2)) begin\n                                                                                       ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:348: Operator ADD expects 32 or 16 bits on the RHS, but RHS\'s VARREF \'lcolcnt\' generates 3 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            w_addr <= peitcnt*(9*configs[1]) + (lchcnt * 9) + (lrowcnt * 3) + lcolcnt;\n                                                                                            ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:384: Operator ADD expects 8 bits on the RHS, but RHS\'s VARREF \'baserowinc\' generates 1 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                baserow <= baserow + baserowinc;\n                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:395: Operator ASSIGNDLY expects 5 bits on the Assign RHS, but Assign RHS\'s SUB generates 32 or 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                    rowendcnt <= configs[2] - (2 + basecolnext);\n                                              ^~\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:401: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            if (convcnt > (configs[2]-2)*(configs[3]-2)) begin\n                                                     ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:401: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            if (convcnt > (configs[2]-2)*(configs[3]-2)) begin\n                                                                    ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:430: Operator ADD expects 32 or 16 bits on the RHS, but RHS\'s VARREF \'peitcnt\' generates 4 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            abufdin <= (convcnt + peitcnt < (configs[2]-2)*(configs[3]-2)) ? amemQ : 0;\n                                                ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:430: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            abufdin <= (convcnt + peitcnt < (configs[2]-2)*(configs[3]-2)) ? amemQ : 0;\n                                                                       ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:430: Operator SUB expects 32 or 16 bits on the LHS, but LHS\'s ARRAYSEL generates 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                            abufdin <= (convcnt + peitcnt < (configs[2]-2)*(configs[3]-2)) ? amemQ : 0;\n                                                                                      ^\n%Warning-WIDTH: data/full_repos/permissive/467394306/verilog/ctrl/arr_controller.v:447: Operator ASSIGNDLY expects 5 bits on the Assign RHS, but Assign RHS\'s SUB generates 32 or 8 bits.\n                                                                                      : ... In instance ARR_CTRL_16x16\n                                    rowendcnt <= configs[2] - (2 + basecolnext);\n                                              ^~\n%Error: Exiting due to 5 error(s), 24 warning(s)\n'
module ARR_CTRL_16x16
    (
        input clk,
        input rstn,
        input enable,

        input [1:0] mode,






        input data_load,
        input [7:0] data_in,

        output [0 : 16*8-1] aouts,
        output [0 : 16*8-1] wouts, 
        output saclk,
        output reg fire,
        output done);



    genvar gi;
    integer i;
    integer j;

    reg computedone;
    reg [1:0] computestart;





    wire clkdivo;
    reg clkdiven;
    CLKDIV #(.DIV_CNT(9), .BITS(4)) clkdiv (.clk(clk), .rstn(rstn), .enable(clkdiven), .clkout(clkdivo));
    assign saclk = clkdivo;





    reg aWEN, wWEN;
    reg [7:0] Dbuf;
    wire [7:0] amemQ, wmemQ;
    reg [15:0] a_addr, w_addr;

    INPMEM #(.sub_mems(256), .addr_len(8)) amem(.Q(amemQ), .clk(clk), .CEN(1'b0), .WEN(aWEN), .A(a_addr), .D(Dbuf));
    INPMEM #(.sub_mems(256), .addr_len(8)) wmem(.Q(wmemQ), .clk(clk), .CEN(1'b0), .WEN(wWEN), .A(w_addr), .D(Dbuf));





    reg [15:0] abufreads, wbufreads;
    reg [15:0] abufwrites, wbufwrites;
    wire [7:0] abufdout [0:15];
    wire [7:0] wbufdout [0:15];
    reg [7:0] abufdin, wbufdin;
    reg [3:0] prefillcnt;

    for (gi=0; gi<16; gi=gi+1) begin
        assign aouts[gi*8 : (gi+1) * 8 - 1 ] = abufdout[gi];
        assign wouts[gi*8 : (gi+1) * 8 - 1] = wbufdout[gi];
    end

    generate
        for (gi=0; gi<16; gi=gi+1) begin
            RBUF #(.WORDLEN(8), .BUFSIZE(gi+1)) abuf_gen (
                .clk(clk),
                .rstn(rstn),
                .read(abufreads[gi]),
                .write(abufwrites[gi]),
                .din(abufdin),
                .dout(abufdout[gi]));
        end
        for (gi=0; gi<16; gi=gi+1) begin
            RBUF #(.WORDLEN(8), .BUFSIZE(gi+1)) wbuf_gen (
                .clk(clk),
                .rstn(rstn),
                .read(wbufreads[gi]),
                .write(wbufwrites[gi]),
                .din(wbufdin),
                .dout(wbufdout[gi]));
        end
    endgenerate





    reg [3:0] cur_conf;
    reg [7:0] configs [0:3];















    wire [15:0] chconvs;
    wire [15:0] rowconvs;
    assign chconvs = (configs[2]-2) * (configs[3]-2);
    assign rowconvs = (configs[2]-2);

    reg [15:0] base_addr;
    reg [15:0] convcnt;
    reg [15:0] inpscnt;
    reg [7:0] basecol;
    reg [7:0] baserow;
    reg [7:0] basecolnext;
    reg baserowinc;

    reg [3:0] peitcnt;
    reg [7:0] lchcnt;
    reg [2:0] lcolcnt;
    reg [2:0] lrowcnt;
    reg [4:0] rowendcnt;

    reg [3:0] edgecnt;
    reg windowendwait;
    reg iterationwait;




    always @ (posedge clk) begin
        if(!rstn) begin





            computedone <= 0;
            computestart <= 0;
            clkdiven <= 0;


            aWEN <= 1;
            wWEN <= 1;
            Dbuf <= 0;
            abufwrites <= 0;
            wbufwrites <= 0;
            abufreads <= 0;
            wbufreads <= 0;
            abufdin <= 0;
            wbufdin <= 0;
            prefillcnt <= 0;

            cur_conf <= 0;
            for(i=0; i<4; i=i+1) begin
               configs[i] <= 0; 
            end
            a_addr <= 16'hFFFF;
            w_addr <= 16'hFFFF;

            base_addr <= 0;
            convcnt <= 0;
            inpscnt <= 0;
            basecol <= 0;
            baserow <= 0;
            basecolnext <= 0;
            baserowinc <= 0;

            peitcnt <= 0;
            lchcnt <= 0;
            lcolcnt <= 0;
            lrowcnt <= 0;
            rowendcnt <= 0;

            windowendwait <= 0;
            iterationwait <= 0;
            fire <= 0;

            edgecnt <= 0;

        end else begin
            if(enable) begin
                case (mode)

                    2'b00: begin
                        aWEN <= 1;
                        wWEN <= 1;

                        if (cur_conf <= 2'b11 && data_load) begin
                            configs[cur_conf] <= data_in;
                            cur_conf <= cur_conf + 1;
                        end
                    end

                    2'b01: begin
                        aWEN <= 1;
                        Dbuf <= data_in;

                        wWEN <= ~data_load;
                        w_addr <= w_addr + 1;
                    end

                    2'b10: begin
                        wWEN <= 1;
                        Dbuf <= data_in;

                        aWEN <= ~data_load;
                        a_addr <= a_addr + 1;



                        if(prefillcnt == 4'hF) begin
                            abufwrites <= 0;
			                wbufwrites <= 0;
                        end else begin
                            for (i=0; i<16; i=i+1) begin

                                abufwrites[i] <= (i > prefillcnt);
                                wbufwrites[i] <= (i > prefillcnt);
                                abufdin <= 0;
                                wbufdin <= 0; 
                            end
			                    prefillcnt <= prefillcnt + 1;
                        end
                    end

                    2'b11: begin

                        aWEN <= 1;
                        wWEN <= 1;

                        if(!computedone && computestart >= 2'b01 && !windowendwait && !iterationwait) begin
                            fire <= 1;
                            clkdiven <= 1;





































                                if (convcnt + peitcnt > (configs[2] - 2) * (configs[3] - 2)) begin


                                    a_addr <= 16'hdedb;
                                end else if (peitcnt >= rowendcnt) begin


                                    a_addr <= base_addr + peitcnt + 2 + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;

                                    basecolnext <= 0;
                                    baserowinc <= 1;
                                end else begin


                                    a_addr <= base_addr + peitcnt + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;

                                    basecolnext <= basecolnext + 1;
                                end

                            peitcnt <= peitcnt + 1;




































                            w_addr <= peitcnt*(9*configs[1]) + (lchcnt * 9) + (lrowcnt * 3) + lcolcnt;

                            





                            if (peitcnt == 4'hF) begin
                                iterationwait <= 1;
                                peitcnt <= 0;
                                if (lcolcnt == 2) begin

                                    lcolcnt <= 0;
                                    if(lrowcnt == 2) begin

                                        lrowcnt <= 0;
                                        lchcnt <= lchcnt + 1;
                                    end else begin
                                        lrowcnt <= lrowcnt + 1;
                                    end
                                end else begin

                                    lcolcnt <= lcolcnt + 1;
                                end
                                inpscnt <= inpscnt + 1;
                            end


                            if (inpscnt == (9 * configs[1]) - 1) begin

                                fire <= 0;
                                windowendwait <= 1;
                                inpscnt <= 0;
                                basecol <= basecolnext;
                                convcnt <= convcnt + 16;
                                baserow <= baserow + baserowinc;


                                if (base_addr+16 < rowendcnt) begin
                                    base_addr <= base_addr + 16;
                                end else begin
                                    base_addr <= base_addr + 16 + 2;
                                end


                                if(configs[2] - (2 + basecolnext) < 5'd16) begin
                                    rowendcnt <= configs[2] - (2 + basecolnext);
                                end else begin
                                    rowendcnt <= 5'd20;
                                end
                            end

                            if (convcnt > (configs[2]-2)*(configs[3]-2)) begin
                                computedone <= 1;
                                fire <= 0;
                            end





 


                            if (abufwrites == 0) begin
                                if (computestart < 2'b11) begin
                                    computestart <= computestart + 1;
                                end else begin
                                    abufwrites <= 1;
                                    wbufwrites <= 1;
                                end
                            end else begin
                                abufwrites <= abufwrites << 1;
                                wbufwrites <= wbufwrites << 1;
                            end
                                
                            edgecnt <= edgecnt + 1;
                            abufreads <= 16'h0000;
                            wbufreads <= 16'h0000;


                            abufdin <= (convcnt + peitcnt < (configs[2]-2)*(configs[3]-2)) ? amemQ : 0;
                            wbufdin <= wmemQ;
                        end else begin
                            if (!windowendwait && !iterationwait) begin
                                computestart <= computestart + 1;

                                base_addr <= 0;
                                a_addr <= 0;
                                w_addr <= 0;
                                basecol <= 0;
                                baserow <= 0;
                                basecolnext <= 0;
                                baserowinc <= 0;
                                if(computestart > 2'b00) begin
                                    clkdiven <= 1;
                                end
				if(configs[2] - (2 + basecolnext) < 5'd16) begin
                                    rowendcnt <= configs[2] - (2 + basecolnext);
                                end else begin
                                    rowendcnt <= 5'd20;
                                end
                            end else begin
                                if (windowendwait) begin
                                    $display("in window end wait.");

                                    fire <= 0;
                                    edgecnt <= edgecnt + 1;
                                    if (edgecnt == 15) begin
					$display("Window End Wait Over.");
                                        fire <= 1;
                                        windowendwait <= 0;
                                        peitcnt <= 0;
                                        abufwrites <= 16'h0000;
                                        wbufwrites <= 16'h0000;
                                        abufreads <= 16'h0000;
                                        wbufreads <= 16'h0000;
                                    end
                                end
                                if (iterationwait) begin

				    abufwrites <= 16'h0000;
                                    wbufwrites <= 16'h0000;
                                    abufreads <= 16'hFFFF;
                                    wbufreads <= 16'hFFFF;
                                    iterationwait <= 0;
                                end
                            end
                        end
                    end
                endcase
            end
        end
    end

    assign done = computedone;


endmodule
module ARR_CTRL_16x16
    (
        input clk,
        input rstn,
        input enable,

        input [1:0] mode,






        input data_load,
        input [7:0] data_in,

        output [0 : 16*8-1] aouts,
        output [0 : 16*8-1] wouts, 
        output saclk,
        output reg fire,
        output done);




    genvar gi;
    integer i;
    integer j;

    reg computedone;
    reg [1:0] computestart;





    wire clkdivo;
    reg clkdiven;
    CLKDIV #(.DIV_CNT(9), .BITS(4)) clkdiv (.clk(clk), .rstn(rstn), .enable(clkdiven), .clkout(clkdivo));
    assign saclk = clkdivo;





    reg aWEN, wWEN;
    reg [7:0] Dbuf;
    wire [7:0] amemQ, wmemQ;
    reg [15:0] a_addr, w_addr;

    INPMEM #(.sub_mems(256), .addr_len(8)) amem(.Q(amemQ), .clk(clk), .CEN(1'b0), .WEN(aWEN), .A(a_addr), .D(Dbuf));
    INPMEM #(.sub_mems(256), .addr_len(8)) wmem(.Q(wmemQ), .clk(clk), .CEN(1'b0), .WEN(wWEN), .A(w_addr), .D(Dbuf));





    reg [15:0] abufreads, wbufreads;
    reg [15:0] abufwrites, wbufwrites;
    wire [7:0] abufdout [0:15];
    wire [7:0] wbufdout [0:15];
    reg [7:0] abufdin, wbufdin;
    reg [3:0] prefillcnt;

    for (gi=0; gi<16; gi=gi+1) begin
        assign aouts[gi*8 : (gi+1) * 8 - 1 ] = abufdout[gi];
        assign wouts[gi*8 : (gi+1) * 8 - 1] = wbufdout[gi];
    end

    generate
        for (gi=0; gi<16; gi=gi+1) begin
            RBUF #(.WORDLEN(8), .BUFSIZE(gi+1)) abuf_gen (
                .clk(clk),
                .rstn(rstn),
                .read(abufreads[gi]),
                .write(abufwrites[gi]),
                .din(abufdin),
                .dout(abufdout[gi]));
        end
        for (gi=0; gi<16; gi=gi+1) begin
            RBUF #(.WORDLEN(8), .BUFSIZE(gi+1)) wbuf_gen (
                .clk(clk),
                .rstn(rstn),
                .read(wbufreads[gi]),
                .write(wbufwrites[gi]),
                .din(wbufdin),
                .dout(wbufdout[gi]));
        end
    endgenerate





    reg [3:0] cur_conf;
    reg [7:0] configs [0:3];















    wire [15:0] chconvs;
    wire [15:0] rowconvs;
    assign chconvs = (configs[2]-2) * (configs[3]-2);
    assign rowconvs = (configs[2]-2);

    reg [15:0] base_addr;
    reg [15:0] convcnt;
    reg [15:0] inpscnt;
    reg [7:0] basecol;
    reg [7:0] baserow;
    reg [7:0] basecolnext;
    reg baserowinc;

    reg [3:0] peitcnt;
    reg [7:0] lchcnt;
    reg [2:0] lcolcnt;
    reg [2:0] lrowcnt;
    reg [4:0] rowendcnt;

    reg [3:0] edgecnt;
    reg windowendwait;
    reg iterationwait;




    always @ (posedge clk) begin
        if(!rstn) begin





            computedone <= 0;
            computestart <= 0;
            clkdiven <= 0;


            aWEN <= 1;
            wWEN <= 1;
            Dbuf <= 0;
            abufwrites <= 0;
            wbufwrites <= 0;
            abufreads <= 0;
            wbufreads <= 0;
            abufdin <= 0;
            wbufdin <= 0;
            prefillcnt <= 0;

            cur_conf <= 0;
            for(i=0; i<4; i=i+1) begin
               configs[i] <= 0; 
            end
            a_addr <= 16'hFFFF;
            w_addr <= 16'hFFFF;

            base_addr <= 0;
            convcnt <= 0;
            inpscnt <= 0;
            basecol <= 0;
            baserow <= 0;
            basecolnext <= 0;
            baserowinc <= 0;

            peitcnt <= 0;
            lchcnt <= 0;
            lcolcnt <= 0;
            lrowcnt <= 0;
            rowendcnt <= 0;

            windowendwait <= 0;
            iterationwait <= 0;
            fire <= 0;

            edgecnt <= 0;

        end else begin
            if(enable) begin
                case (mode)

                    2'b00: begin
                        aWEN <= 1;
                        wWEN <= 1;

                        if (cur_conf <= 2'b11 && data_load) begin
                            configs[cur_conf] <= data_in;
                            cur_conf <= cur_conf + 1;
                        end
                    end

                    2'b01: begin
                        aWEN <= 1;
                        Dbuf <= data_in;

                        wWEN <= ~data_load;
                        w_addr <= w_addr + 1;
                    end

                    2'b10: begin
                        wWEN <= 1;
                        Dbuf <= data_in;

                        aWEN <= ~data_load;
                        a_addr <= a_addr + 1;



                        if(prefillcnt == 4'hF) begin
                            abufwrites <= 0;
			                wbufwrites <= 0;
                        end else begin
                            for (i=0; i<16; i=i+1) begin

                                abufwrites[i] <= (i > prefillcnt);
                                wbufwrites[i] <= (i > prefillcnt);
                                abufdin <= 0;
                                wbufdin <= 0; 
                            end
			                    prefillcnt <= prefillcnt + 1;
                        end
                    end

                    2'b11: begin

                        aWEN <= 1;
                        wWEN <= 1;

                        if(!computedone && computestart >= 2'b01 && !windowendwait && !iterationwait) begin
                            fire <= 1;
                            clkdiven <= 1;





































                                if (convcnt + peitcnt > (configs[2] - 2) * (configs[3] - 2)) begin


                                    a_addr <= 16'hdedb;
                                end else if (peitcnt >= rowendcnt) begin


                                    a_addr <= base_addr + peitcnt + 2 + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;

                                    basecolnext <= 0;
                                    baserowinc <= 1;
                                end else begin


                                    a_addr <= base_addr + peitcnt + (configs[2]*configs[3])*lchcnt + configs[2]*lrowcnt + lcolcnt;

                                    basecolnext <= basecolnext + 1;
                                end

                            peitcnt <= peitcnt + 1;




































                            w_addr <= peitcnt*(9*configs[1]) + (lchcnt * 9) + (lrowcnt * 3) + lcolcnt;

                            





                            if (peitcnt == 4'hF) begin
                                iterationwait <= 1;
                                peitcnt <= 0;
                                if (lcolcnt == 2) begin

                                    lcolcnt <= 0;
                                    if(lrowcnt == 2) begin

                                        lrowcnt <= 0;
                                        lchcnt <= lchcnt + 1;
                                    end else begin
                                        lrowcnt <= lrowcnt + 1;
                                    end
                                end else begin

                                    lcolcnt <= lcolcnt + 1;
                                end
                                inpscnt <= inpscnt + 1;
                            end


                            if (inpscnt == (9 * configs[1]) - 1) begin

                                fire <= 0;
                                windowendwait <= 1;
                                inpscnt <= 0;
                                basecol <= basecolnext;
                                convcnt <= convcnt + 16;
                                baserow <= baserow + baserowinc;


                                if (base_addr+16 < rowendcnt) begin
                                    base_addr <= base_addr + 16;
                                end else begin
                                    base_addr <= base_addr + 16 + 2;
                                end


                                if(configs[2] - (2 + basecolnext) < 5'd16) begin
                                    rowendcnt <= configs[2] - (2 + basecolnext);
                                end else begin
                                    rowendcnt <= 5'd20;
                                end
                            end

                            if (convcnt > (configs[2]-2)*(configs[3]-2)) begin
                                computedone <= 1;
                                fire <= 0;
                            end





 


                            if (abufwrites == 0) begin
                                if (computestart < 2'b11) begin
                                    computestart <= computestart + 1;
                                end else begin
                                    abufwrites <= 1;
                                    wbufwrites <= 1;
                                end
                            end else begin
                                abufwrites <= abufwrites << 1;
                                wbufwrites <= wbufwrites << 1;
                            end
                                
                            edgecnt <= edgecnt + 1;
                            abufreads <= 16'h0000;
                            wbufreads <= 16'h0000;


                            abufdin <= (convcnt + peitcnt < (configs[2]-2)*(configs[3]-2)) ? amemQ : 0;
                            wbufdin <= wmemQ;
                        end else begin
                            if (!windowendwait && !iterationwait) begin
                                computestart <= computestart + 1;

                                base_addr <= 0;
                                a_addr <= 0;
                                w_addr <= 0;
                                basecol <= 0;
                                baserow <= 0;
                                basecolnext <= 0;
                                baserowinc <= 0;
                                if(computestart > 2'b00) begin
                                    clkdiven <= 1;
                                end
				if(configs[2] - (2 + basecolnext) < 5'd16) begin
                                    rowendcnt <= configs[2] - (2 + basecolnext);
                                end else begin
                                    rowendcnt <= 5'd20;
                                end
                            end else begin
                                if (windowendwait) begin
                                    $display("in window end wait.");

                                    fire <= 0;
                                    edgecnt <= edgecnt + 1;
                                    if (edgecnt == 15) begin
					$display("Window End Wait Over.");
                                        fire <= 1;
                                        windowendwait <= 0;
                                        peitcnt <= 0;
                                        abufwrites <= 16'h0000;
                                        wbufwrites <= 16'h0000;
                                        abufreads <= 16'h0000;
                                        wbufreads <= 16'h0000;
                                    end
                                end
                                if (iterationwait) begin

				    abufwrites <= 16'h0000;
                                    wbufwrites <= 16'h0000;
                                    abufreads <= 16'hFFFF;
                                    wbufreads <= 16'hFFFF;
                                    iterationwait <= 0;
                                end
                            end
                        end
                    end
                endcase
            end
        end
    end

    assign done = computedone;


endmodule