// ============================================================================
// ca_multi_rule.v - 多规则可编程CA引擎
// 支持：空间分区规则、时间切换规则、混合邻域
// ============================================================================
module ca_multi_rule #(
    parameter WIDTH  = 128,
    parameter HEIGHT = 128,
    parameter NUM_ZONES = 4           // 规则区域数
)(
    input  wire                     clk,
    input  wire                     rst_n,
    input  wire                     enable,
    input  wire                     init,
    // 规则配置
    input  wire [7:0]               rules [0:NUM_ZONES-1],  // 每区域的规则
    input  wire [7:0]               zone_bounds [0:NUM_ZONES-1],  // 区域边界
    // 邻域选择
    input  wire                     use_moore,   // 1=Moore, 0=VonNeumann
    // 状态
    output wire [WIDTH*HEIGHT-1:0]  state,
    output wire [31:0]              generation
);

    reg [WIDTH*HEIGHT-1:0] curr;
    wire [WIDTH*HEIGHT-1:0] nxt;
    reg [31:0] gen_reg;

    // 区域选择函数
    function [7:0] get_rule;
        input [7:0] y;
        integer z;
        begin
            get_rule = rules[0];  // 默认
            for (z = 0; z < NUM_ZONES; z = z + 1) begin
                if (y < zone_bounds[z])
                    get_rule = rules[z];
            end
        end
    endfunction

    genvar gx, gy;
    generate
        for (gy = 0; gy < HEIGHT; gy = gy + 1) begin : gen_row
            for (gx = 0; gx < WIDTH; gx = gx + 1) begin : gen_col
                localparam integer idx = gy * WIDTH + gx;

                // Moore邻域
                wire [7:0] moore_nb;
                assign moore_nb[0] = (gy>0 && gx>0) ? curr[(gy-1)*WIDTH+gx-1] : 1'b0;
                assign moore_nb[1] = (gy>0) ? curr[(gy-1)*WIDTH+gx] : 1'b0;
                assign moore_nb[2] = (gy>0 && gx<WIDTH-1) ? curr[(gy-1)*WIDTH+gx+1] : 1'b0;
                assign moore_nb[3] = (gx>0) ? curr[gy*WIDTH+gx-1] : 1'b0;
                assign moore_nb[4] = (gx<WIDTH-1) ? curr[gy*WIDTH+gx+1] : 1'b0;
                assign moore_nb[5] = (gy<HEIGHT-1 && gx>0) ? curr[(gy+1)*WIDTH+gx-1] : 1'b0;
                assign moore_nb[6] = (gy<HEIGHT-1) ? curr[(gy+1)*WIDTH+gx] : 1'b0;
                assign moore_nb[7] = (gy<HEIGHT-1 && gx<WIDTH-1) ? curr[(gy+1)*WIDTH+gx+1] : 1'b0;

                // Von Neumann邻域
                wire [3:0] vn_nb;
                assign vn_nb[0] = (gy>0) ? curr[(gy-1)*WIDTH+gx] : 1'b0;
                assign vn_nb[1] = (gx>0) ? curr[gy*WIDTH+gx-1] : 1'b0;
                assign vn_nb[2] = (gx<WIDTH-1) ? curr[gy*WIDTH+gx+1] : 1'b0;
                assign vn_nb[3] = (gy<HEIGHT-1) ? curr[(gy+1)*WIDTH+gx] : 1'b0;

                // 邻域选择
                wire [2:0] vn_3bit = {vn_nb[0], curr[idx], vn_nb[2]};
                wire [7:0] active_nb = use_moore ? moore_nb : {1'b0, vn_nb, 1'b0, curr[idx], 1'b0};

                // 获取当前区域的规则
                wire [7:0] active_rule = get_rule(gy[7:0]);

                // 规则应用
                wire [2:0] nb3 = {active_nb[3], curr[idx], active_nb[4]};
                assign nxt[idx] = active_rule[nb3];

            end
        end
    endgenerate

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            curr    <= {WIDTH*HEIGHT{1'b0}};
            gen_reg <= 32'd0;
        end else if (init) begin
            curr    <= {WIDTH{1'b1}} << (WIDTH*HEIGHT/2);
            gen_reg <= 32'd0;
        end else if (enable) begin
            curr    <= nxt;
            gen_reg <= gen_reg + 32'd1;
        end
    end

    assign state = curr;
    assign generation = gen_reg;

endmodule