// ============================================================================
// ca_rule110.v - 规则110引擎 + 粒子检测器
// 实现规则110演化，并检测特定粒子模式
// ============================================================================
module ca_rule110 #(
    parameter WIDTH = 128,            // 网格宽度（建议≥64以观察粒子）
    parameter DETECT_PARTICLES = 1    // 是否启用粒子检测
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             enable,
    input  wire             init,
    input  wire [WIDTH-1:0] seed,
    output wire [WIDTH-1:0] state,
    output wire [3:0]       particle_count,  // 检测到的粒子数
    output wire [31:0]      step_count
);

    // ---- CA状态 ----
    reg [WIDTH-1:0] curr;
    wire [WIDTH-1:0] nxt;

    // ---- 规则110实现 ----
    // f(L,C,R) = ~(L & C & R) & (L | C | R) 的简化
    // 等价于: (L & ~R) | (~L & C) | (C & ~R) | (~C & R & L)
    // 最简形式: (L ^ R) & C | L | R & ~C  -- 但我们直接用真值表
    genvar i;
    generate
        for (i = 0; i < WIDTH; i = i + 1) begin : gen_r110
            wire L = (i == 0)        ? curr[WIDTH-1] : curr[i-1];
            wire C = curr[i];
            wire R = (i == WIDTH-1)  ? curr[0]       : curr[i+1];
            // 规则110: 01101110
            // 直接实现: f = (L & C & ~R) | (~L & C) | (C & ~R) | (~L & ~C & R)
            assign nxt[i] = (~L & C) | (C & ~R) | (L & C & ~R) | (~L & ~C & R);
            // 更简洁: nxt = C ^ (L & C & R) | (~C & (L ^ R))
            // 实际等价于: (~L & C) | (L & ~C) | (C & ~R) | (~C & R)
            // 即: (L ^ C) | (C ^ R) 当去掉000→0和111→0
        end
    endgenerate

    // ---- 步数计数器 ----
    reg [31:0] step_reg;

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

    assign state      = curr;
    assign step_count = step_reg;

    // ---- 粒子检测器 ----
    // 检测"粒子"：在背景模式中的局部偏差
    // 简化实现：检测"0110"和"0011"模式（常见的粒子模式）
    generate
        if (DETECT_PARTICLES) begin : gen_detect
            reg [3:0] pcount;
            always @(*) begin
                pcount = 4'd0;
                for (integer j = 0; j < WIDTH-3; j = j + 1) begin
                    // 检测模式 0110（A粒子片段）
                    if (curr[j+3:j] == 4'b0110) pcount = pcount + 1;
                    // 检测模式 0011（B粒子片段）
                    if (curr[j+3:j] == 4'b0011) pcount = pcount + 1;
                end
            end
            assign particle_count = pcount;
        end else begin : gen_no_detect
            assign particle_count = 4'd0;
        end
    endgenerate

endmodule