// ============================================================================
// langton_loop.v - Langton自复制回路引擎
// 8状态，Moore邻域，简化版实现
// ============================================================================
module langton_loop #(
    parameter WIDTH  = 80,
    parameter HEIGHT = 80
)(
    input  wire                     clk,
    input  wire                     rst_n,
    input  wire                     enable,
    input  wire                     init,
    input  wire [WIDTH*HEIGHT*3-1:0] seed,  // 8状态需要3位/元胞
    output wire [WIDTH*HEIGHT*3-1:0] state,
    output wire [31:0]              generation,
    output wire [31:0]              loop_count   // 检测到的回路数
);

    // ---- 3位/元胞状态存储 ----
    reg [2:0] grid [0:WIDTH*HEIGHT-1];
    reg [2:0] grid_nxt [0:WIDTH*HEIGHT-1];
    reg [31:0] gen_reg;

    // ---- 邻域提取 ----
    // 对每个元胞(x,y)，提取8个Moore邻居的3位状态
    integer idx, x, y, dx, dy, nx, ny;
    reg [2:0] neighbors [0:7];

    // ---- Langton回路的规则表 ----
    // 简化版本：只实现核心的回路传播和复制逻辑
    // 完整规则表需要2^(3*9) = 2^27个条目，这里用函数实现
    function [2:0] langton_rule;
        input [2:0] self;
        input [2:0] nb0, nb1, nb2, nb3, nb4, nb5, nb6, nb7;
        begin
            // 状态定义:
            // 0 = 空(Empty)
            // 1 = 回路壁(Wall)
            // 2 = 信号A(Signal A, 前进信号)
            // 3 = 信号B(Signal B, 复制信号)
            // 4 = 臂尖(Arm tip)
            // 5 = 臂体(Arm body)
            // 6 = 连接点(Junction)
            // 7 = 保留

            langton_rule = 3'd0;  // 默认：空→空

            case (self)
                3'd0: begin  // 空
                    // 如果相邻有臂尖或信号，可能变为新的臂尖或信号
                    if (nb4 == 3'd4 || nb2 == 3'd4)
                        langton_rule = 3'd5;  // 臂体扩展
                    else if (nb6 == 3'd3)
                        langton_rule = 3'd2;  // 新信号
                end
                3'd1: begin  // 回路壁
                    langton_rule = 3'd1;  // 保持壁（除非有特殊条件）
                    if (nb2 == 3'd3 && nb6 == 3'd0)
                        langton_rule = 3'd6;  // 变为连接点（触发臂生长）
                end
                3'd2: begin  // 信号A
                    // 信号沿回路壁传播
                    langton_rule = 3'd1;  // 信号过后恢复壁
                end
                3'd3: begin  // 信号B（复制信号）
                    langton_rule = 3'd1;  // 信号过后恢复壁
                end
                3'd4: begin  // 臂尖
                    langton_rule = 3'd5;  // 臂尖→臂体
                end
                3'd5: begin  // 臂体
                    langton_rule = 3'd1;  // 臂体→壁（固化）
                end
                3'd6: begin  // 连接点
                    langton_rule = 3'd4;  // 产生新臂尖
                end
                default: langton_rule = 3'd0;
            endcase
        end
    endfunction

    // ---- 状态更新 ----
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            gen_reg <= 32'd0;
            for (idx = 0; idx < WIDTH*HEIGHT; idx = idx + 1)
                grid[idx] <= 3'd0;
        end else if (init) begin
            gen_reg <= 32'd0;
            for (idx = 0; idx < WIDTH*HEIGHT; idx = idx + 1)
                grid[idx] <= seed[idx*3 +: 3];
        end else if (enable) begin
            // 计算所有下一状态
            for (y = 0; y < HEIGHT; y = y + 1) begin
                for (x = 0; x < WIDTH; x = x + 1) begin
                    // 提取8个邻居
                    for (dx = -1; dx <= 1; dx = dx + 1) begin
                        for (dy = -1; dy <= 1; dy = dy + 1) begin
                            nx = (x + dx + WIDTH) % WIDTH;
                            ny = (y + dy + HEIGHT) % HEIGHT;
                        end
                    end
                    // 简化：只使用自身和4个正交邻居
                    idx = y * WIDTH + x;
                    grid_nxt[idx] = langton_rule(
                        grid[idx],
                        grid[((y==0)?HEIGHT-1:y-1)*WIDTH+x],  // 上
                        grid[y*WIDTH+((x==WIDTH-1)?0:x+1)],   // 右
                        grid[((y==HEIGHT-1)?0:y+1)*WIDTH+x],  // 下
                        grid[y*WIDTH+((x==0)?WIDTH-1:x-1)],   // 左
                        3'd0, 3'd0, 3'd0, 3'd0  // 对角邻居简化
                    );
                end
            end
            // 更新
            for (idx = 0; idx < WIDTH*HEIGHT; idx = idx + 1)
                grid[idx] <= grid_nxt[idx];
            gen_reg <= gen_reg + 32'd1;
        end
    end

    // 输出打包
    genvar gi;
    generate
        for (gi = 0; gi < WIDTH*HEIGHT; gi = gi + 1) begin : gen_out
            assign state[gi*3 +: 3] = grid[gi];
        end
    endgenerate

    assign generation = gen_reg;
    assign loop_count = 32'd0;  // 简化：未实现回路计数

endmodule