module lns_adder #(
    parameter WIDTH = 32,
    parameter FRAC_BITS = 16
)(
    input wire clk,
    input wire rst_n,
    input wire [WIDTH-1:0] la, // Log2(A)
    input wire [WIDTH-1:0] lb, // Log2(B)
    output reg [WIDTH-1:0] lc  // Log2(A + B)
);

    // Precise LNS Addition using Piecewise Linear Approximation
    // log(A + B) = max(la, lb) + log(1 + 2^(-|la-lb|))
    // Let r = |la - lb|. We need to approximate Gaussian Logarithm Phi(r) = log2(1 + 2^-r)

    reg [WIDTH-1:0] diff;
    reg [WIDTH-1:0] max_val;
    reg [WIDTH-1:0] correction;

    // Piecewise approximation logic (Synthesis friendly)
    // Coeffs would be tuned for error minimization.
    // Here we use 4 regions for improved precision over v1.
    function [WIDTH-1:0] approx_phi;
        input [WIDTH-1:0] r;
        begin
            if (r >= 32'h00080000) begin // r >= 8.0
                approx_phi = 0;
            end else if (r >= 32'h00040000) begin // 4.0 <= r < 8.0
                approx_phi = 32'h00000800; // Small constant
            end else if (r >= 32'h00020000) begin // 2.0 <= r < 4.0
                // Linear: y = mx + c approximation
                approx_phi = 32'h00003000 - (r >> 5);
            end else begin // r < 2.0
                // High precision region
                approx_phi = 32'h00010000 - (r >> 2); // 1.0 - 0.25*r
            end
        end
    endfunction

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) lc <= 0;
        else begin
            if (la >= lb) begin
                max_val = la;
                diff = la - lb;
            end else begin
                max_val = lb;
                diff = lb - la;
            end

            correction = approx_phi(diff);
            lc <= max_val + correction;
        end
    end

endmodule
