// ============================================================================
// life_core.v - Conway生命游戏核心
// Moore邻域邻居计数 + B3/S23规则
// 参数化设计：支持任意网格大小
// ============================================================================
module life_core #(
    parameter WIDTH  = 64,
    parameter HEIGHT = 64
)(
    input  wire                     clk,
    input  wire                     rst_n,
    input  wire                     enable,
    input  wire                     init,
    input  wire [WIDTH*HEIGHT-1:0]  seed,
    output wire [WIDTH*HEIGHT-1:0]  state,
    output wire [31:0]              generation,
    output wire [31:0]              population
);

    reg [WIDTH*HEIGHT-1:0] curr;
    wire [WIDTH*HEIGHT-1:0] nxt;

    // 每个元胞的邻居计数与规则应用
    genvar gx, gy;
    generate
        for (gy = 0; gy < HEIGHT; gy = gy + 1) begin : gen_row
            for (gx = 0; gx < WIDTH; gx = gx + 1) begin : gen_col
                localparam integer idx = gy * WIDTH + gx;
                // 环形边界坐标
                localparam integer xm = (gx == 0) ? WIDTH-1 : gx-1;
                localparam integer xp = (gx == WIDTH-1) ? 0 : gx+1;
                localparam integer ym = (gy == 0) ? HEIGHT-1 : gy-1;
                localparam integer yp = (gy == HEIGHT-1) ? 0 : gy+1;

                // 8个Moore邻居
                wire [7:0] neighbors;
                assign neighbors[0] = curr[ym*WIDTH+xm]; // 左上
                assign neighbors[1] = curr[ym*WIDTH+gx]; // 上
                assign neighbors[2] = curr[ym*WIDTH+xp]; // 右上
                assign neighbors[3] = curr[gy*WIDTH+xm]; // 左
                assign neighbors[4] = curr[gy*WIDTH+xp]; // 右
                assign neighbors[5] = curr[yp*WIDTH+xm]; // 左下
                assign neighbors[6] = curr[yp*WIDTH+gx]; // 下
                assign neighbors[7] = curr[yp*WIDTH+xp]; // 右下

                // 邻居计数（4位）
                wire [3:0] ncount = neighbors[0] + neighbors[1] +
                                    neighbors[2] + neighbors[3] +
                                    neighbors[4] + neighbors[5] +
                                    neighbors[6] + neighbors[7];

                // B3/S23规则
                wire self = curr[idx];
                assign nxt[idx] = self ? (ncount == 4'd2 || ncount == 4'd3) :
                                       (ncount == 4'd3);
            end
        end
    endgenerate

    // 状态更新
    reg [31:0] gen_reg;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            curr    <= {WIDTH*HEIGHT{1'b0}};
            gen_reg <= 32'd0;
        end else if (init) begin
            curr    <= seed;
            gen_reg <= 32'd0;
        end else if (enable) begin
            curr    <= nxt;
            gen_reg <= gen_reg + 32'd1;
        end
    end

    assign state = curr;
    assign generation = gen_reg;

    // 种群计数（加法器树）
    integer p;
    reg [31:0] pop_reg;
    always @(*) begin
        pop_reg = 32'd0;
        for (p = 0; p < WIDTH*HEIGHT; p = p + 1)
            pop_reg = pop_reg + curr[p];
    end
    assign population = pop_reg;

endmodule