// ============================================================================
// life_line_buffer.v - 行缓冲架构的生命游戏引擎
// 逐行处理，面积小，适合VGA实时显示
// ============================================================================
module life_line_buffer #(
    parameter WIDTH  = 640,
    parameter HEIGHT = 480
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             step_en,
    input  wire             init,
    output wire [WIDTH-1:0] row_out,      // 当前输出行
    output wire [8:0]       row_idx,      // 当前行号
    output wire [31:0]      generation,
    output wire             frame_done    // 一帧完成
);

    // ---- 双端口行缓冲 ----
    // row_buf_0: 存储偶数行, row_buf_1: 存储奇数行
    // 当前处理行y时，需要行y-1, y, y+1的数据
    reg [WIDTH-1:0] line_buf [0:2];  // 3行缓冲
    reg [WIDTH-1:0] new_line;        // 新计算行
    reg [WIDTH-1:0] wr_buf [0:HEIGHT-1];  // 写回缓冲

    reg [8:0]  y_cnt;
    reg [31:0] gen_cnt;
    reg        frame_done_r;

    // 移位寄存器：3×3窗口提取
    reg [2:0] sr_prev, sr_curr, sr_next;

    integer x;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            y_cnt <= 9'd0;
            gen_cnt <= 32'd0;
            frame_done_r <= 1'b0;
        end else if (step_en) begin
            frame_done_r <= 1'b0;
            new_line <= {WIDTH{1'b0}};

            for (x = 0; x < WIDTH; x = x + 1) begin
                // 更新3×3移位寄存器
                sr_prev <= {sr_prev[1:0], line_buf[0][x]};
                sr_curr <= {sr_curr[1:0], line_buf[1][x]};
                sr_next <= {sr_next[1:0], line_buf[2][x]};

                // 提取8个邻居
                wire [7:0] nb;
                assign nb = {sr_prev[2], sr_prev[1], sr_prev[0],
                             sr_curr[2],               sr_curr[0],
                             sr_next[2], sr_next[1], sr_next[0]};

                wire [3:0] nc = nb[0]+nb[1]+nb[2]+nb[3]+
                                nb[4]+nb[5]+nb[6]+nb[7];
                wire self = sr_curr[1];

                new_line[x] <= self ? (nc==2 || nc==3) : (nc==3);
            end

            // 行缓冲滚动
            line_buf[0] <= line_buf[1];
            line_buf[1] <= line_buf[2];
            line_buf[2] <= new_line;

            // 写回
            wr_buf[y_cnt] <= new_line;

            if (y_cnt == HEIGHT - 1) begin
                y_cnt <= 9'd0;
                gen_cnt <= gen_cnt + 32'd1;
                frame_done_r <= 1'b1;
            end else begin
                y_cnt <= y_cnt + 9'd1;
            end
        end
    end

    assign row_out    = line_buf[1];
    assign row_idx    = y_cnt;
    assign generation = gen_cnt;
    assign frame_done = frame_done_r;

endmodule