// Direct Convolution Engine — 3x3 kernel, output-stationary
module direct_conv #(parameter DW=16, OW=32, KH=3, OCH=16, ICH=16)(
    input clk, rst_n, input en, input start,
    // Feature map input (one pixel at a time, row-major)
    input signed [DW-1:0] fm_in, input fm_valid, input [9:0] fm_x, fm_y,
    // Weight ROM
    input signed [DW-1:0] wt_rom [0:OCH*ICH*KH*KH-1],
    // Output
    output reg signed [DW-1:0] fm_out, output reg fm_out_valid,
    output reg [9:0] out_x, out_y, output reg [7:0] out_ch,
    output reg done
);
    reg [7:0] och_cnt, ich_cnt, kr_cnt, kc_cnt;
    reg signed [DW*2-1:0] psum;
    reg [9:0] ox, oy;
    reg [3:0] state; // 0=idle, 1=compute, 2=next, 3=done
    wire signed [DW-1:0] weight = wt_rom[och_cnt*ICH*KH*KH + ich_cnt*KH*KH + kr_cnt*KH + kc_cnt];
    always_ff @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin state<=0; psum<='0; fm_out<='0; fm_out_valid<=0; done<=0;
            och_cnt<=0; ich_cnt<=0; kr_cnt<=0; kc_cnt<=0; ox<=0; oy<=0; end
        else case(state)
          0: if(start) begin state<=1; psum<='0; och_cnt<=0; ich_cnt<=0; kr_cnt<=0; kc_cnt<=0; ox<=0; oy<=0; end
          1: if(fm_valid) begin
                psum<=psum+fm_in*weight;
                kc_cnt<=kc_cnt+1;
                if(kc_cnt>=KH-1) begin kc_cnt<=0; kr_cnt<=kr_cnt+1;
                    if(kr_cnt>=KH-1) begin kr_cnt<=0; ich_cnt<=ich_cnt+1;
                        if(ich_cnt>=ICH-1) begin ich_cnt<=0;
                            fm_out<=psum[DW*2-1:DW]; fm_out_valid<=1;
                            out_x<=ox; out_y<=oy; out_ch<=och_cnt;
                            och_cnt<=och_cnt+1; psum<='0;
                            if(och_cnt>=OCH-1) begin och_cnt<=0; ox<=ox+1;
                                if(ox>=OW-1) begin ox<=0; oy<=oy+1;
                                    if(oy>=OW-1) state<=3;
                                end
                            end
                        end
                    end
                end
            end
          3: done<=1;
        endcase
    end
endmodule