// ============================================================================
// ca_configurable_1d.v - 运行时可配置规则的一维CA引擎
// 支持动态规则切换、多种边界条件、步数计数
// ============================================================================
module ca_configurable_1d #(
    parameter WIDTH = 64               // 网格宽度
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             enable,     // 步进使能
    input  wire             init,       // 初始化脉冲
    input  wire [WIDTH-1:0] seed,       // 初始种子
    input  wire [7:0]       rule,       // Wolfram规则号(运行时可变)
    input  wire             wrap_en,    // 1=环形边界, 0=固定边界
    input  wire             fixed_val,  // 固定边界值(当wrap_en=0时)
    output wire [WIDTH-1:0] state,      // 当前状态
    output wire [31:0]      step_count  // 已运行步数
);

    // ---- 状态寄存器 ----
    reg [WIDTH-1:0] curr_state;
    reg [WIDTH-1:0] next_state;
    reg [31:0]      step_reg;

    // ---- 边界处理 ----
    wire left_boundary, right_boundary;

    // 左边界：环形 or 固定
    assign left_boundary  = wrap_en ? curr_state[WIDTH-1] : fixed_val;
    assign right_boundary = wrap_en ? curr_state[0]       : fixed_val;

    // ---- 邻域提取与规则应用 ----
    genvar i;
    generate
        for (i = 0; i < WIDTH; i = i + 1) begin : gen_cell
            wire left, self, right;

            // 提取左邻居
            assign left  = (i == 0)        ? left_boundary  : curr_state[i-1];
            // 自身
            assign self  = curr_state[i];
            // 提取右邻居
            assign right = (i == WIDTH-1)  ? right_boundary : curr_state[i+1];

            // 邻域编码
            wire [2:0] neighborhood = {left, self, right};

            // 规则查找：从8位规则中选取对应位
            assign next_state[i] = rule[neighborhood];
        end
    endgenerate

    // ---- 状态更新 ----
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            curr_state <= {WIDTH{1'b0}};
            step_reg    <= 32'd0;
        end else if (init) begin
            curr_state <= seed;
            step_reg    <= 32'd0;
        end else if (enable) begin
            curr_state <= next_state;
            step_reg    <= step_reg + 32'd1;
        end
    end

    assign state      = curr_state;
    assign step_count = step_reg;

endmodule