+ Contains signals for an incoming copy of the value, decoded into
+ sign / exponent / mantissa.
+ Also contains encoding functions, creation and recognition of
+ zero, NaN and inf (all signed)
+
+ Four extra bits are included in the mantissa: the top bit
+ (m[-1]) is effectively a carry-overflow. The other three are
+ guard (m[2]), round (m[1]), and sticky (m[0])
+ """
+ def __init__(self, op, width, m_extra=True):
+ FPNumBase.__init__(self, width, m_extra)
+ self.op = op
+
+ def elaborate(self, platform):
+ m = FPNumBase.elaborate(self, platform)
+
+ m.d.comb += self.decode(self.v)
+
+ return m
+
+ def decode(self, v):
+ """ decodes a latched value into sign / exponent / mantissa
+
+ bias is subtracted here, from the exponent. exponent
+ is extended to 10 bits so that subtract 127 is done on
+ a 10-bit number
+ """
+ args = [0] * self.m_extra + [v[0:self.e_start]] # pad with extra zeros
+ #print ("decode", self.e_end)
+ return [self.m.eq(Cat(*args)), # mantissa
+ self.e.eq(v[self.e_start:self.e_end] - self.P127), # exp
+ self.s.eq(v[-1]), # sign
+ ]
+
+class FPNumIn(FPNumBase):
+ """ Floating-point Number Class
+
+ Contains signals for an incoming copy of the value, decoded into
+ sign / exponent / mantissa.
+ Also contains encoding functions, creation and recognition of
+ zero, NaN and inf (all signed)
+
+ Four extra bits are included in the mantissa: the top bit
+ (m[-1]) is effectively a carry-overflow. The other three are
+ guard (m[2]), round (m[1]), and sticky (m[0])
+ """
+ def __init__(self, op, width, m_extra=True):
+ FPNumBase.__init__(self, width, m_extra)
+ self.latch_in = Signal()
+ self.op = op
+
+ def decode2(self, m):
+ """ decodes a latched value into sign / exponent / mantissa
+
+ bias is subtracted here, from the exponent. exponent
+ is extended to 10 bits so that subtract 127 is done on
+ a 10-bit number
+ """
+ v = self.v
+ args = [0] * self.m_extra + [v[0:self.e_start]] # pad with extra zeros
+ #print ("decode", self.e_end)
+ res = ObjectProxy(m, pipemode=False)
+ res.m = Cat(*args) # mantissa
+ res.e = v[self.e_start:self.e_end] - self.P127 # exp
+ res.s = v[-1] # sign
+ return res
+
+ def decode(self, v):
+ """ decodes a latched value into sign / exponent / mantissa
+
+ bias is subtracted here, from the exponent. exponent
+ is extended to 10 bits so that subtract 127 is done on
+ a 10-bit number
+ """
+ args = [0] * self.m_extra + [v[0:self.e_start]] # pad with extra zeros
+ #print ("decode", self.e_end)
+ return [self.m.eq(Cat(*args)), # mantissa
+ self.e.eq(v[self.e_start:self.e_end] - self.P127), # exp
+ self.s.eq(v[-1]), # sign
+ ]
+
+ def shift_down(self, inp):
+ """ shifts a mantissa down by one. exponent is increased to compensate
+
+ accuracy is lost as a result in the mantissa however there are 3
+ guard bits (the latter of which is the "sticky" bit)
+ """
+ return [self.e.eq(inp.e + 1),
+ self.m.eq(Cat(inp.m[0] | inp.m[1], inp.m[2:], 0))
+ ]
+
+ def shift_down_multi(self, diff, inp=None):
+ """ shifts a mantissa down. exponent is increased to compensate
+
+ accuracy is lost as a result in the mantissa however there are 3
+ guard bits (the latter of which is the "sticky" bit)
+
+ this code works by variable-shifting the mantissa by up to
+ its maximum bit-length: no point doing more (it'll still be
+ zero).