in rtl/log/luts/gen_tables.py [0:0]
def get_pow2_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]
pow2_x = pow(2, x)
pow2_str = x.toBinaryString()
round_up = get_r2ne(pow2_x, out_bits)
pow2_round_x = pow2_x
if (round_up and enable_rounding):
add = FixedPoint.FXnum(1, fam20) >> out_bits
pow2_round_x = pow2_x + add
# As an out_bits-sized fixed point number
fam_out = FixedPoint.FXfamily(out_bits)
y = FixedPoint.FXnum(pow2_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
delta_y_truncated = FixedPoint.FXnum(delta_y, FixedPoint.FXfamily(out_bits-3))
delta_y_truncated = delta_y_truncated - 7
# print(y.toBinaryString(), cur.toBinaryString(), (y - cur).toBinaryString(), get_fraction(delta_y_truncated))
# 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
assert recover_val == y
before_round = get_fraction(pow2_x, out_bits)
after_round = get_fraction(pow2_round_x, out_bits)
return orig_str, after_round, get_fraction(delta_y_truncated)