def get_log2_delta_expansion()

in rtl/log/luts/gen_tables.py [0:0]


def get_log2_delta_expansion(i, in_bits, out_bits, enable_rounding=True):
    prec_bits = out_bits * 4
    fam20 = FixedPoint.FXfamily(prec_bits)

    x = (FixedPoint.FXnum(i, fam20) / (2 ** in_bits))
    orig_x = x
    orig_str = x.toBinaryString()[2:2+in_bits]
    log2_x = (x + 1).log() / math.log(2)
    log2_str = x.toBinaryString()

    round_up = get_r2ne(log2_x, out_bits)

    log2_round_x = log2_x
    if (round_up and enable_rounding):
        add = FixedPoint.FXnum(1, fam20) >> out_bits
        log2_round_x = log2_x + add

    # As an out_bits-sized fixed point number
    fam_out = FixedPoint.FXfamily(out_bits)
    y = FixedPoint.FXnum(log2_round_x, fam_out)
    cur = FixedPoint.FXnum(i, fam_out) / (2 ** in_bits)

    # This is what we are encoding, all values except for 0 are negative
    delta_y = y - cur
    delta_y = delta_y << 3
#    print('cur {} round {} delta {}'.format(cur.toBinaryString(), y.toBinaryString(), delta_y.toBinaryString()))

    delta_y_truncated = FixedPoint.FXnum(delta_y, FixedPoint.FXfamily(out_bits-3))
    delta_y_truncated = delta_y_truncated - 7

    # Now, see if we can recover y from delta_y_truncated
    recover_y = FixedPoint.FXnum(delta_y_truncated, fam_out)
    recover_y = recover_y + 7
    recover_y = recover_y >> 3

    recover_val = cur + recover_y
#    print('here', recover_val.toBinaryString())
    assert recover_val == y

    before_round = get_fraction(log2_x, out_bits)
    after_round = get_fraction(log2_round_x, out_bits)

    return orig_str, after_round, get_fraction(delta_y_truncated)