module crc32_generator (
    input  wire        clk,
    input  wire        rst,
    input  wire [7:0]  data_in,
    input  wire        data_valid,
    output reg  [31:0] crc_out,
    output reg         crc_valid
);

    // CRC-32 Standard (Ethernet/ZIP)
    // Polynomial: 0x04C11DB7 (Normal) -> 0xEDB88320 (Reversed/Reflected)
    // Initial Value: 0xFFFFFFFF
    // Final XOR: 0xFFFFFFFF
    // Input/Output Reflected: Yes
    
    // Internal CRC register
    reg [31:0] crc_reg;
    
    // Reversed polynomial for LSB-first processing
    localparam POLY_REV = 32'hEDB88320;
    
    // Function to compute next CRC state for 8 bits
    function automatic [31:0] calc_crc8;
        input [31:0] crc_in;
        input [7:0]  data;
        reg [31:0]   c;
        integer      i;
        begin
            c = crc_in ^ {24'h000000, data};
            for (i = 0; i < 8; i = i + 1) begin
                if (c[0])
                    c = (c >> 1) ^ POLY_REV;
                else
                    c = (c >> 1);
            end
            calc_crc8 = c;
        end
    endfunction
    
    wire [31:0] next_crc;
    assign next_crc = calc_crc8(crc_reg, data_in);

    always @(posedge clk) begin
        if (rst) begin
            crc_reg   <= 32'hFFFFFFFF;
            crc_out   <= 32'hFFFFFFFF; // Initial XOR Out of Initial Value (or 0 if fully cancelled?) 
                                       // Spec says resets to Initial Value. 
                                       // We output 0xFFFFFFFF (Init).
            crc_valid <= 1'b0;
        end else begin
            if (data_valid) begin
                // Update CRC
                crc_reg <= next_crc;
                
                // Output is registered next state with Final XOR
                crc_out <= next_crc ^ 32'hFFFFFFFF;
                
                // Assert valid 1 cycle after processing
                crc_valid <= 1'b1;
            end 
            // Else hold (implicit)
        end
    end

endmodule
