// ============================================================================
// ca_engine_1d.v - 完整一维CA硬件引擎
// 支持：任意Wolfram规则、多种边界、步进/连续运行、状态导出
// ============================================================================
module ca_engine_1d #(
    parameter WIDTH = 128            // 网格宽度
)(
    input  wire             clk,
    input  wire             rst_n,

    // ---- 控制接口 ----
    input  wire             cmd_init,    // 初始化命令
    input  wire             cmd_step,    // 单步命令
    input  wire             cmd_run,     // 连续运行命令
    input  wire             cmd_halt,    // 停止命令
    input  wire [7:0]       rule,        // Wolfram规则号
    input  wire [1:0]       boundary,    // 00=环形 01=固定0 10=固定1 11=镜像
    input  wire [WIDTH-1:0] seed,        // 初始种子

    // ---- 状态输出 ----
    output wire [WIDTH-1:0] state_out,   // 当前状态
    output wire [31:0]      step_count,  // 步数
    output wire             running,     // 正在运行标志
    output wire             step_done    // 单步完成脉冲
);

    // ---- 状态机 ----
    localparam S_IDLE = 2'd0;
    localparam S_INIT = 2'd1;
    localparam S_STEP = 2'd2;
    localparam S_RUN  = 2'd3;

    reg [1:0] fsm_state;
    reg [WIDTH-1:0] curr;
    reg [31:0] steps;

    // ---- 规则查找（组合逻辑） ----
    wire [WIDTH-1:0] nxt;

    // 边界值计算
    wire left_edge, right_edge;
    always @(*) begin
        case (boundary)
            2'b00: begin  // 环形
                left_edge  = curr[WIDTH-1];
                right_edge = curr[0];
            end
            2'b01: begin  // 固定0
                left_edge  = 1'b0;
                right_edge = 1'b0;
            end
            2'b10: begin  // 固定1
                left_edge  = 1'b1;
                right_edge = 1'b1;
            end
            2'b11: begin  // 镜像
                left_edge  = curr[0];
                right_edge = curr[WIDTH-1];
            end
            default: begin
                left_edge  = curr[WIDTH-1];
                right_edge = curr[0];
            end
        endcase
    end

    // 每个元胞的规则查找
    genvar i;
    generate
        for (i = 0; i < WIDTH; i = i + 1) begin : gen_compute
            wire L = (i == 0)        ? left_edge  : curr[i-1];
            wire C = curr[i];
            wire R = (i == WIDTH-1)  ? right_edge : curr[i+1];
            wire [2:0] nb = {L, C, R};
            assign nxt[i] = rule[nb];
        end
    endgenerate

    // ---- 状态机逻辑 ----
    reg step_done_r;
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            fsm_state   <= S_IDLE;
            curr        <= {WIDTH{1'b0}};
            steps       <= 32'd0;
            step_done_r <= 1'b0;
        end else begin
            step_done_r <= 1'b0;  // 默认清除
            case (fsm_state)
                S_IDLE: begin
                    if (cmd_init) begin
                        fsm_state <= S_INIT;
                    end else if (cmd_step) begin
                        fsm_state <= S_STEP;
                    end else if (cmd_run) begin
                        fsm_state <= S_RUN;
                    end
                end
                S_INIT: begin
                    curr        <= seed;
                    steps       <= 32'd0;
                    fsm_state   <= S_IDLE;
                    step_done_r <= 1'b1;
                end
                S_STEP: begin
                    curr        <= nxt;
                    steps       <= steps + 32'd1;
                    fsm_state   <= S_IDLE;
                    step_done_r <= 1'b1;
                end
                S_RUN: begin
                    if (cmd_halt) begin
                        fsm_state <= S_IDLE;
                    end else begin
                        curr  <= nxt;
                        steps <= steps + 32'd1;
                    end
                end
                default: fsm_state <= S_IDLE;
            endcase
        end
    end

    assign state_out = curr;
    assign step_count = steps;
    assign running = (fsm_state == S_RUN);
    assign step_done = step_done_r;

endmodule