// rng_sync.v - 256-bit Galois LFSR PRNG (taps: 255,253,252,247,0)
module rng_sync #(
    parameter [255:0] SEED = 256'hDEADBEEFCAFEBABEFEEDFACEDECAFBAD1234567887654321ABCDEF010FEDCBA9
) (
    input              clk,
    input              rst_n,
    input              valid_i,
    output             ready_o,
    output [255:0]     data_o,
    output             valid_o,
    input              ready_i
);

    reg  [255:0] state;
    reg          valid_r;
    reg  [255:0] lfsr_next;
    wire         feedback;
    integer      i;

    assign ready_o = 1'b1;
    assign valid_o = valid_r;
    assign data_o  = state;
    assign feedback = state[0];

    always @(*) begin
        for (i = 0; i < 255; i = i + 1)
            lfsr_next[i] = state[i+1];
        lfsr_next[255] = feedback;
        lfsr_next[254] = lfsr_next[254] ^ feedback;
        lfsr_next[252] = lfsr_next[252] ^ feedback;
        lfsr_next[251] = lfsr_next[251] ^ feedback;
        lfsr_next[246] = lfsr_next[246] ^ feedback;
    end

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state   <= SEED;
            valid_r <= 1'b0;
        end else begin
            if (valid_r && ready_i)
                valid_r <= 1'b0;

            if (valid_i) begin
                state   <= lfsr_next;
                valid_r <= 1'b1;
            end
        end
    end

endmodule
