// Multi-Core Scheduler — Work distribution across N cores
module multicore_sched #(parameter N_CORES=4, DW=16, AW=20, MAX_TASKS=64)(
    input clk, rst_n, input start,
    // Task queue
    input [7:0] num_tasks,
    input [AW-1:0] task_addr [0:MAX_TASKS-1],
    input [7:0] task_size [0:MAX_TASKS-1],
    input [3:0] task_type [0:MAX_TASKS-1], // 0=conv, 1=fc, 2=attn
    // Per-core interface
    output reg [AW-1:0] core_task_addr [0:N_CORES-1],
    output reg [7:0] core_task_size [0:N_CORES-1],
    output reg [3:0] core_task_type [0:N_CORES-1],
    output reg [N_CORES-1:0] core_start,
    input [N_CORES-1:0] core_done,
    // Synchronization
    output reg barrier, // All cores sync at barrier
    output reg all_done
);
    reg [7:0] task_cnt;
    reg [2:0] core_assign; // Round-robin assignment counter
    reg [3:0] state; // 0=idle, 1=dispatch, 2=wait, 3=barrier, 4=done
    reg [N_CORES-1:0] core_busy;
    reg [7:0] dispatched, completed;
    integer ci;
    always_ff @(posedge clk or negedge rst_n) begin
        if(!rst_n) begin state<=0; task_cnt<=0; core_assign<=0; barrier<=0; all_done<=0;
            core_busy<=0; dispatched<=0; completed<=0; core_start<=0;
            for(ci=0;ci<N_CORES;ci++) begin core_task_addr[ci]<='0; core_task_size[ci]<='0; core_task_type[ci]<='0; end
        end else case(state)
          0: if(start) begin state<=1; task_cnt<=0; core_assign<=0; dispatched<=0; completed<=0; end
          1: begin // Dispatch tasks round-robin
                core_start <= '0;
                if(task_cnt < num_tasks) begin
                    core_task_addr[core_assign]  <= task_addr[task_cnt];
                    core_task_size[core_assign]  <= task_size[task_cnt];
                    core_task_type[core_assign]  <= task_type[task_cnt];
                    core_start[core_assign]      <= 1;
                    core_busy[core_assign]       <= 1;
                    task_cnt  <= task_cnt + 1;
                    core_assign <= core_assign + 1;
                    dispatched <= dispatched + 1;
                end else state <= 2;
            end
          2: begin // Wait for all dispatched tasks
                for(ci=0;ci<N_CORES;ci++) begin
                    if(core_done[ci] && core_busy[ci]) begin
                        core_busy[ci] <= 0;
                        completed <= completed + 1;
                    end
                end
                if(completed >= dispatched) state <= 3;
            end
          3: begin // Barrier sync
                barrier <= 1;
                if(task_cnt >= num_tasks) state <= 4;
                else begin state <= 1; dispatched <= 0; completed <= 0; end
            end
          4: all_done <= 1;
        endcase
    end
endmodule