// ============================================================================
// prng_rule30_parallel.v - 高速并行规则30 PRNG
// 每时钟周期输出一个完整的随机数
// 使用多个CA列同时提取，通过列间延迟保证独立性
// ============================================================================
module prng_rule30_parallel #(
    parameter WIDTH = 128,           // 加宽CA以提供更多独立列
    parameter OUT_W = 32             // 输出位宽
)(
    input  wire              clk,
    input  wire              rst_n,
    input  wire              reseed,        // 重新播种
    input  wire [WIDTH-1:0]  new_seed,
    output wire [OUT_W-1:0]  rand_data,     // 随机数据
    output wire              rand_valid     // 数据有效
);

    // ---- CA阵列 ----
    reg [WIDTH-1:0] ca_state;
    wire [WIDTH-1:0] ca_next;

    // 规则30组合逻辑
    genvar i;
    generate
        for (i = 0; i < WIDTH; i = i + 1) begin : gen_ca
            wire L = (i == 0)        ? ca_state[WIDTH-1] : ca_state[i-1];
            wire C = ca_state[i];
            wire R = (i == WIDTH-1)  ? ca_state[0]       : ca_state[i+1];
            assign ca_next[i] = L ^ (C | R);
        end
    endgenerate

    // ---- 采样逻辑 ----
    // 从CA状态的右半部分均匀采样OUT_W个位
    // 右半部分混沌度更高，随机性更好
    localparam HALF = WIDTH / 2;
    localparam GAP  = HALF / OUT_W;

    genvar k;
    generate
        for (k = 0; k < OUT_W; k = k + 1) begin : gen_out
            assign rand_data[k] = ca_state[HALF + k * GAP];
        end
    endgenerate

    // ---- 状态更新 ----
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            ca_state <= {WIDTH{1'b0}};
        else if (reseed)
            ca_state <= new_seed;
        else
            ca_state <= ca_next;  // 每周期自动步进
    end

    assign rand_valid = ~reseed;  // 非重新播种时输出有效

endmodule