// ============================================================================
// ca_pipeline.v - 4级流水线CA引擎
// Stage 1: 地址生成+读请求
// Stage 2: 数据返回+邻居提取
// Stage 3: 规则计算
// Stage 4: 写回+缓冲交换
// ============================================================================
module ca_pipeline #(
    parameter WIDTH  = 256,
    parameter HEIGHT = 256,
    parameter RULE   = 8'd30
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             start,
    output wire             done,
    output wire             pipeline_busy,
    output wire [1:0]       pipeline_stage,  // 当前活跃阶段
    output wire [31:0]      throughput        // 已完成步数
);

    // ---- 流水线寄存器 ----
    // Stage 1 → Stage 2
    reg [15:0] s1_addr;
    reg [7:0]  s1_row_buf [0:2];  // 3行缓冲地址

    // Stage 2 → Stage 3
    reg [WIDTH-1:0] s2_row_above;
    reg [WIDTH-1:0] s2_row_curr;
    reg [WIDTH-1:0] s2_row_below;

    // Stage 3 → Stage 4
    reg [WIDTH-1:0] s3_next_row;

    // ---- 行缓冲存储 ----
    reg [WIDTH-1:0] row_mem [0:HEIGHT-1];
    reg [WIDTH-1:0] row_mem_nxt [0:HEIGHT-1];  // 双缓冲

    // ---- 控制逻辑 ----
    reg [8:0]  row_cnt;
    reg [31:0] step_cnt;
    reg [1:0]  stage;
    reg        busy;

    // ---- Stage 3: 规则计算 ----
    integer x;
    always @(*) begin
        for (x = 0; x < WIDTH; x = x + 1) begin
            // 提取3位邻域
            reg left, self, right;
            left  = (x == 0) ? s2_row_curr[WIDTH-1] : s2_row_curr[x-1];
            self  = s2_row_curr[x];
            right = (x == WIDTH-1) ? s2_row_curr[0] : s2_row_curr[x+1];

            s3_next_row[x] = RULE[{left, self, right}];
        end
    end

    // ---- 流水线主控 ----
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            stage   <= 2'd0;
            row_cnt <= 9'd0;
            step_cnt <= 32'd0;
            busy    <= 1'b0;
        end else if (start && !busy) begin
            busy    <= 1'b1;
            stage   <= 2'd0;
            row_cnt <= 9'd0;
        end else if (busy) begin
            case (stage)
                2'd0: begin  // Stage 1: 读请求
                    s2_row_above <= (row_cnt == 0) ? row_mem[HEIGHT-1] : row_mem[row_cnt-1];
                    s2_row_curr  <= row_mem[row_cnt];
                    s2_row_below <= (row_cnt == HEIGHT-1) ? row_mem[0] : row_mem[row_cnt+1];
                    stage <= 2'd1;
                end
                2'd1: begin  // Stage 3: 计算（Stage 2的读延迟已吸收）
                    // s3_next_row已在组合逻辑中计算
                    stage <= 2'd2;
                end
                2'd2: begin  // Stage 4: 写回
                    row_mem_nxt[row_cnt] <= s3_next_row;
                    if (row_cnt == HEIGHT - 1) begin
                        // 一帧完成，交换缓冲
                        for (integer r = 0; r < HEIGHT; r = r + 1)
                            row_mem[r] <= row_mem_nxt[r];
                        row_cnt  <= 9'd0;
                        step_cnt <= step_cnt + 32'd1;
                    end else begin
                        row_cnt <= row_cnt + 9'd1;
                    end
                    stage <= 2'd0;
                end
            endcase
        end
    end

    assign done           = (step_cnt > 0 && !busy);
    assign pipeline_busy  = busy;
    assign pipeline_stage = stage;
    assign throughput     = step_cnt;

endmodule