// Sparse Computing Engine — Skip-zero multiplication
module sparse_engine #(parameter DW=16, N=16, AW=32)(
    input clk, rst_n, input en,
    input signed [DW-1:0] act_in [0:N-1], input a_valid,
    input signed [DW-1:0] wt_in [0:N-1], input w_valid, input is_zero [0:N-1],
    output reg signed [AW-1:0] result, output reg r_valid,
    output reg [7:0] active_pes   // Number of non-zero multiplications
);
    reg signed [AW-1:0] acc;
    reg [7:0] nz_cnt;
    integer i;
    always_ff @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin acc<='0; result<='0; r_valid<=0; active_pes<=0; nz_cnt<=0; end
        else if(en && a_valid && w_valid) begin
            acc<='0; nz_cnt<=0;
            for(i=0;i<N;i++) begin
                if(!is_zero[i]) begin
                    acc<=acc+act_in[i]*wt_in[i]; nz_cnt<=nz_cnt+1;
                end
            end
            result<=acc; r_valid<=1; active_pes<=nz_cnt;
        end else r_valid<=0;
    end
endmodule

// CSC (Compressed Sparse Column) format decoder
module csc_decoder #(parameter DW=16, IDX_W=12)(
    input clk, rst_n, input en,
    input [IDX_W-1:0] col_ptr, input [IDX_W-1:0] row_idx [0:15],
    input signed [DW-1:0] nz_vals [0:15], input [3:0] nnz,
    output reg signed [DW-1:0] act_out [0:15],
    output reg [3:0] valid_mask, output reg out_valid
);
    integer j; always_ff @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin for(j=0;j<16;j++) act_out[j]<='0; valid_mask<='0; out_valid<=0; end
        else if(en) begin valid_mask<=nnz; out_valid<=1;
            for(j=0;j<16;j++) begin
                if(j<nnz) act_out[row_idx[j[3:0]]]<=nz_vals[j[3:0]]; // Simplified indexing
                else act_out[j]<='0;
            end
        end else out_valid<=0;
    end
endmodule